From: Amnon Hanuhov Date: Thu, 26 Nov 2020 15:37:00 +0000 (-0500) Subject: crimson/osd: Recover missing object when receiving an EIO from pg backend due to... X-Git-Tag: v17.1.0~3042^2~1 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=f76bda83fd6a36a175464b3e8f0cb4625a3c09e0;p=ceph.git crimson/osd: Recover missing object when receiving an EIO from pg backend due to disk failure or CRC mismatch Signed-off-by: Amnon Hanuhov --- diff --git a/src/crimson/osd/pg.cc b/src/crimson/osd/pg.cc index e9dd078de6c..9f2296a5028 100644 --- a/src/crimson/osd/pg.cc +++ b/src/crimson/osd/pg.cc @@ -661,7 +661,23 @@ seastar::future> PG::handle_failed_op( }, load_obc_ertr::assert_all{ "can't live with object state messed up" }); } -seastar::future> PG::do_osd_ops( +seastar::future<> PG::rep_repair_primary_object( + Ref m, + const hobject_t& oid, + eversion_t& v) +{ + assert(is_primary()); + logger().debug("{}: {} peers osd.{}", __func__, oid, get_acting_recovery_backfill()); + // Add object to PG's missing set if it isn't there already + assert(!get_local_missing().is_missing(oid)); + peering_state.force_object_missing(pg_whoami, oid, v); + auto [op, fut] = get_shard_services().start_operation( + oid, v, this, get_shard_services(), m->get_min_epoch()); + return std::move(fut); +} + +PG::do_osd_ops_ertr::future> +PG::do_osd_ops( Ref m, ObjectContextRef obc, const OpInfo &op_info) @@ -718,7 +734,7 @@ seastar::future> PG::do_osd_ops( }).safe_then([this, m, obc, - rvec = op_info.allows_returnvec()] { + rvec = op_info.allows_returnvec()]() -> PG::do_osd_ops_ertr::future> { // TODO: should stop at the first op which returns a negative retval, // cmpext uses it for returning the index of first unmatched byte int result = m->ops.empty() ? 0 : m->ops.back().rval.code; @@ -736,19 +752,18 @@ seastar::future> PG::do_osd_ops( *m, obc->obs.oi.soid); return seastar::make_ready_future>(std::move(reply)); - }, osd_op_errorator::all_same_way([ox = ox.get(), + }, crimson::ct_error::object_corrupted::handle([m, + obc, + this] () { + return rep_repair_primary_object(m, obc->obs.oi.soid, obc->obs.oi.version).then([]() -> PG::do_osd_ops_ertr::future> { + return crimson::ct_error::eagain::make(); + }); + }), OpsExecuter::osd_op_errorator::all_same_way([ox = ox.get(), m, obc, this] (const std::error_code& e) { return handle_failed_op(e, std::move(obc), *ox, *m); - })).handle_exception_type([ox_deleter = std::move(ox), - m, - obc, - this] (const crimson::osd::error& e) { - // we need this handler because throwing path which aren't errorated yet. - logger().debug("encountered the legacy error handling path!"); - return handle_failed_op(e.code(), std::move(obc), *ox_deleter, *m); - }); + })); } seastar::future> PG::do_pg_ops(Ref m) diff --git a/src/crimson/osd/pg.h b/src/crimson/osd/pg.h index 88d39fde9ad..7487e7edca1 100644 --- a/src/crimson/osd/pg.h +++ b/src/crimson/osd/pg.h @@ -547,7 +547,9 @@ private: ObjectContextRef obc, const OpsExecuter& ox, const MOSDOp& m) const; - seastar::future> do_osd_ops( + using do_osd_ops_ertr = crimson::errorator< + crimson::ct_error::eagain>; + do_osd_ops_ertr::future> do_osd_ops( Ref m, ObjectContextRef obc, const OpInfo &op_info); @@ -557,6 +559,9 @@ private: ObjectContextRef&& obc, ceph::os::Transaction&& txn, const osd_op_params_t& oop); + seastar::future<> rep_repair_primary_object(Ref m, + const hobject_t& oid, + eversion_t& v); private: OSDMapGate osdmap_gate;