From: Xuehan Xu Date: Sat, 10 Aug 2024 06:22:09 +0000 (+0800) Subject: crimson/osd/backfill_state: support backfilling cancellation X-Git-Tag: v20.0.0~1261^2 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=refs%2Fpull%2F59118%2Fhead;p=ceph.git crimson/osd/backfill_state: support backfilling cancellation Signed-off-by: Xuehan Xu --- diff --git a/src/crimson/osd/backfill_state.cc b/src/crimson/osd/backfill_state.cc index b3f3cce64c1bb..d015a77545cf4 100644 --- a/src/crimson/osd/backfill_state.cc +++ b/src/crimson/osd/backfill_state.cc @@ -498,6 +498,14 @@ BackfillState::Crashed::Crashed() ceph_abort_msg("{}: this should not happen"); } +// -- Cancelled +BackfillState::Cancelled::Cancelled() +{ + backfill_state().backfill_info.clear(); + backfill_state().peer_backfill_info.clear(); + backfill_state().progress_tracker.reset(); +} + // ProgressTracker is an intermediary between the BackfillListener and // BackfillMachine + its states. All requests to push or drop an object // are directed through it. The same happens with notifications about diff --git a/src/crimson/osd/backfill_state.h b/src/crimson/osd/backfill_state.h index 8c441f01abb14..4cdd4daafce6d 100644 --- a/src/crimson/osd/backfill_state.h +++ b/src/crimson/osd/backfill_state.h @@ -58,6 +58,9 @@ struct BackfillState { struct RequestDone : sc::event { }; + struct CancelBackfill : sc::event { + }; + private: // internal events struct RequestPrimaryScanning : sc::event { @@ -132,10 +135,16 @@ public: explicit Crashed(); }; + struct Cancelled : sc::simple_state, + StateHelper { + explicit Cancelled(); + }; + struct Initial : sc::state, StateHelper { using reactions = boost::mpl::list< sc::custom_reaction, + sc::transition, sc::transition>; explicit Initial(my_context); // initialize after triggering backfill by on_activate_complete(). @@ -146,6 +155,7 @@ public: struct Enqueuing : sc::state, StateHelper { using reactions = boost::mpl::list< + sc::transition, sc::transition, sc::transition, sc::transition, @@ -206,6 +216,7 @@ public: sc::custom_reaction, sc::custom_reaction, sc::transition, + sc::transition, sc::transition>; explicit PrimaryScanning(my_context); sc::result react(ObjectPushed); @@ -219,6 +230,7 @@ public: sc::custom_reaction, sc::custom_reaction, sc::transition, + sc::transition, sc::transition>; explicit ReplicasScanning(my_context); // collect scanning result; if all results are collected, transition @@ -243,6 +255,7 @@ public: using reactions = boost::mpl::list< sc::custom_reaction, sc::transition, + sc::transition, sc::transition>; explicit Waiting(my_context); sc::result react(ObjectPushed); diff --git a/src/crimson/osd/pg.h b/src/crimson/osd/pg.h index 6810803867f15..26b39491a703b 100644 --- a/src/crimson/osd/pg.h +++ b/src/crimson/osd/pg.h @@ -417,7 +417,7 @@ public: recovery_handler->on_backfill_reserved(); } void on_backfill_canceled() final { - ceph_assert(0 == "Not implemented"); + recovery_handler->backfill_cancelled(); } void on_recovery_reserved() final { diff --git a/src/crimson/osd/pg_recovery.cc b/src/crimson/osd/pg_recovery.cc index 8c1f13827c6d6..f4a7d8a63db9f 100644 --- a/src/crimson/osd/pg_recovery.cc +++ b/src/crimson/osd/pg_recovery.cc @@ -616,11 +616,30 @@ void PGRecovery::backfilled() PeeringState::Backfilled{}); } +void PGRecovery::backfill_cancelled() +{ + // We are not creating a new BackfillRecovery request here, as we + // need to cancel the backfill synchronously (before this method returns). + using BackfillState = crimson::osd::BackfillState; + backfill_state->process_event( + BackfillState::CancelBackfill{}.intrusive_from_this()); + backfill_state.reset(); +} + void PGRecovery::dispatch_backfill_event( boost::intrusive_ptr evt) { logger().debug("{}", __func__); - backfill_state->process_event(evt); + if (backfill_state) { + backfill_state->process_event(evt); + } else { + // TODO: Do we need to worry about cases in which the pg has + // been through both backfill cancellations and backfill + // restarts between the sendings and replies of + // ReplicaScan/ObjectPush requests? Seems classic OSDs + // doesn't handle these cases. + logger().debug("{}, backfill cancelled, dropping evt"); + } } void PGRecovery::on_backfill_reserved() diff --git a/src/crimson/osd/pg_recovery.h b/src/crimson/osd/pg_recovery.h index e0c87240c0045..f5b8632a38263 100644 --- a/src/crimson/osd/pg_recovery.h +++ b/src/crimson/osd/pg_recovery.h @@ -97,6 +97,7 @@ private: template void start_backfill_recovery( const EventT& evt); + void backfill_cancelled(); void request_replica_scan( const pg_shard_t& target, const hobject_t& begin,