@@ -3542,6 +3542,82 @@ int Objecter::take_linger_budget(LingerOp *info)
35423542 return 1 ;
35433543}
35443544
3545+ bs::error_code Objecter::handle_osd_op_reply2 (Op *op, vector<OSDOp> &out_ops) {
3546+
3547+ ceph_assert (op->ops .size () == op->out_bl .size ());
3548+ ceph_assert (op->ops .size () == op->out_rval .size ());
3549+ ceph_assert (op->ops .size () == op->out_ec .size ());
3550+ ceph_assert (op->ops .size () == op->out_handler .size ());
3551+ auto pb = op->out_bl .begin ();
3552+ auto pr = op->out_rval .begin ();
3553+ auto pe = op->out_ec .begin ();
3554+ auto ph = op->out_handler .begin ();
3555+ ceph_assert (op->out_bl .size () == op->out_rval .size ());
3556+ ceph_assert (op->out_bl .size () == op->out_handler .size ());
3557+ auto p = out_ops.begin ();
3558+ // Propagates handler error to Op::completion. In the event of
3559+ // multiple handler errors, the most recent wins.
3560+ bs::error_code handler_error;
3561+ // Holds OSD error code, so handlers downstream of a failing op are
3562+ // made aware of it.
3563+ bs::error_code first_osd_error;
3564+ for (unsigned i = 0 ;
3565+ p != out_ops.end () && pb != op->out_bl .end ();
3566+ ++i, ++p, ++pb, ++pr, ++pe, ++ph) {
3567+ ldout (cct, 10 ) << " op " << i << " rval " << p->rval
3568+ << " len " << p->outdata .length () << dendl;
3569+ // Track when we get an OSD error and supply it to subsequent
3570+ // handlers so they won't attempt to operate on data that isn't
3571+ // there.
3572+ if (!first_osd_error && (p->rval < 0 )) {
3573+ first_osd_error = bs::error_code (-p->rval , osd_category ());
3574+ }
3575+ if (*pb)
3576+ **pb = p->outdata ;
3577+ // set rval before running handlers so that handlers
3578+ // can change it if e.g. decoding fails
3579+ if (*pr)
3580+ **pr = ceph_to_hostos_errno (p->rval );
3581+ if (*pe)
3582+ **pe = p->rval < 0 ? bs::error_code (-p->rval , osd_category ()) :
3583+ bs::error_code ();
3584+ if (*ph) {
3585+ try {
3586+ bs::error_code e;
3587+ if (first_osd_error) {
3588+ e = first_osd_error;
3589+ } else if (p->rval < 0 ) {
3590+ e = bs::error_code (-p->rval , osd_category ());
3591+ }
3592+ std::move ((*ph))(e, p->rval , p->outdata );
3593+ } catch (const bs::system_error& e) {
3594+ ldout (cct, 10 ) << " ERROR: tid " << op->tid << " : handler function threw "
3595+ << e.what () << dendl;
3596+ handler_error = e.code ();
3597+ if (*pe) {
3598+ **pe = e.code ();
3599+ }
3600+ if (*pr && **pr == 0 ) {
3601+ **pr = ceph::from_error_code (e.code ());
3602+ }
3603+ } catch (const std::exception& e) {
3604+ ldout (cct, 0 ) << " ERROR: tid " << op->tid << " : handler function threw "
3605+ << e.what () << dendl;
3606+ handler_error = osdc_errc::handler_failed;
3607+ if (*pe) {
3608+ **pe = osdc_errc::handler_failed;
3609+ }
3610+ if (*pr && **pr == 0 ) {
3611+ **pr = -EIO;
3612+ }
3613+ }
3614+ }
3615+ }
3616+
3617+ return handler_error;
3618+ }
3619+
3620+
35453621/* This function DOES put the passed message before returning */
35463622void Objecter::handle_osd_op_reply (MOSDOpReply *m)
35473623{
@@ -3712,75 +3788,7 @@ void Objecter::handle_osd_op_reply(MOSDOpReply *m)
37123788 << " != request ops " << op->ops
37133789 << " from " << m->get_source_inst () << dendl;
37143790
3715- ceph_assert (op->ops .size () == op->out_bl .size ());
3716- ceph_assert (op->ops .size () == op->out_rval .size ());
3717- ceph_assert (op->ops .size () == op->out_ec .size ());
3718- ceph_assert (op->ops .size () == op->out_handler .size ());
3719- auto pb = op->out_bl .begin ();
3720- auto pr = op->out_rval .begin ();
3721- auto pe = op->out_ec .begin ();
3722- auto ph = op->out_handler .begin ();
3723- ceph_assert (op->out_bl .size () == op->out_rval .size ());
3724- ceph_assert (op->out_bl .size () == op->out_handler .size ());
3725- auto p = out_ops.begin ();
3726- // Propagates handler error to Op::completion. In the event of
3727- // multiple handler errors, the most recent wins.
3728- bs::error_code handler_error;
3729- // Holds OSD error code, so handlers downstream of a failing op are
3730- // made aware of it.
3731- bs::error_code first_osd_error;
3732- for (unsigned i = 0 ;
3733- p != out_ops.end () && pb != op->out_bl .end ();
3734- ++i, ++p, ++pb, ++pr, ++pe, ++ph) {
3735- ldout (cct, 10 ) << " op " << i << " rval " << p->rval
3736- << " len " << p->outdata .length () << dendl;
3737- // Track when we get an OSD error and supply it to subsequent
3738- // handlers so they won't attempt to operate on data that isn't
3739- // there.
3740- if (!first_osd_error && (p->rval < 0 )) {
3741- first_osd_error = bs::error_code (-p->rval , osd_category ());
3742- }
3743- if (*pb)
3744- **pb = p->outdata ;
3745- // set rval before running handlers so that handlers
3746- // can change it if e.g. decoding fails
3747- if (*pr)
3748- **pr = ceph_to_hostos_errno (p->rval );
3749- if (*pe)
3750- **pe = p->rval < 0 ? bs::error_code (-p->rval , osd_category ()) :
3751- bs::error_code ();
3752- if (*ph) {
3753- try {
3754- bs::error_code e;
3755- if (first_osd_error) {
3756- e = first_osd_error;
3757- } else if (p->rval < 0 ) {
3758- e = bs::error_code (-p->rval , osd_category ());
3759- }
3760- std::move ((*ph))(e, p->rval , p->outdata );
3761- } catch (const bs::system_error& e) {
3762- ldout (cct, 10 ) << " ERROR: tid " << op->tid << " : handler function threw "
3763- << e.what () << dendl;
3764- handler_error = e.code ();
3765- if (*pe) {
3766- **pe = e.code ();
3767- }
3768- if (*pr && **pr == 0 ) {
3769- **pr = ceph::from_error_code (e.code ());
3770- }
3771- } catch (const std::exception& e) {
3772- ldout (cct, 0 ) << " ERROR: tid " << op->tid << " : handler function threw "
3773- << e.what () << dendl;
3774- handler_error = osdc_errc::handler_failed;
3775- if (*pe) {
3776- **pe = osdc_errc::handler_failed;
3777- }
3778- if (*pr && **pr == 0 ) {
3779- **pr = -EIO;
3780- }
3781- }
3782- }
3783- }
3791+ bs::error_code handler_error = handle_osd_op_reply2 (op, out_ops);
37843792
37853793 // NOTE: we assume that since we only request ONDISK ever we will
37863794 // only ever get back one (type of) ack ever.
0 commit comments