@@ -45,10 +45,22 @@ class RecoveryBackend {
4545 backend{backend} {}
4646 virtual ~RecoveryBackend () {}
4747 std::pair<WaitForObjectRecovery&, bool > add_recovering (const hobject_t & soid) {
48- auto [it, added] = recovering.emplace (soid, new WaitForObjectRecovery{} );
48+ auto [it, added] = recovering.emplace (soid, new WaitForObjectRecovery (pg) );
4949 assert (it->second );
5050 return {*(it->second ), added};
5151 }
52+ seastar::future<> add_unfound (const hobject_t &soid) {
53+ auto [it, added] = unfound.emplace (soid, seastar::shared_promise ());
54+ return it->second .get_shared_future ();
55+ }
56+ void found_and_remove (const hobject_t &soid) {
57+ auto it = unfound.find (soid);
58+ if (it != unfound.end ()) {
59+ auto &found_promise = it->second ;
60+ found_promise.set_value ();
61+ unfound.erase (it);
62+ }
63+ }
5264 WaitForObjectRecovery& get_recovering (const hobject_t & soid) {
5365 assert (is_recovering (soid));
5466 return *(recovering.at (soid));
@@ -82,14 +94,22 @@ class RecoveryBackend {
8294 std::int64_t min,
8395 std::int64_t max);
8496
97+ enum interrupt_cause_t : uint8_t {
98+ INTERVAL_CHANGE,
99+ MAX
100+ };
85101 void on_peering_interval_change (ceph::os::Transaction& t) {
86- clean_up (t, " new peering interval " );
102+ clean_up (t, interrupt_cause_t ::INTERVAL_CHANGE );
87103 }
88104
89105 seastar::future<> stop () {
90106 for (auto & [soid, recovery_waiter] : recovering) {
91107 recovery_waiter->stop ();
92108 }
109+ for (auto & [soid, promise] : unfound) {
110+ promise.set_exception (
111+ crimson::common::system_shutdown_exception ());
112+ }
93113 return on_stop ();
94114 }
95115protected:
@@ -124,11 +144,14 @@ class RecoveryBackend {
124144 public boost::intrusive_ref_counter<
125145 WaitForObjectRecovery, boost::thread_unsafe_counter>,
126146 public crimson::BlockerT<WaitForObjectRecovery> {
147+ crimson::osd::PG &pg;
127148 std::optional<seastar::shared_promise<>> readable, recovered, pulled;
128149 std::map<pg_shard_t , seastar::shared_promise<>> pushes;
129150 public:
130151 static constexpr const char * type_name = " WaitForObjectRecovery" ;
131152
153+ WaitForObjectRecovery (crimson::osd::PG &pg) : pg(pg) {}
154+
132155 crimson::osd::ObjectContextRef obc;
133156 std::optional<pull_info_t > pull_info;
134157 std::map<pg_shard_t , push_info_t > pushing;
@@ -204,28 +227,7 @@ class RecoveryBackend {
204227 pushes.erase (it);
205228 }
206229 }
207- void interrupt (std::string_view why) {
208- if (readable) {
209- readable->set_exception (std::system_error (
210- std::make_error_code (std::errc::interrupted), why.data ()));
211- readable.reset ();
212- }
213- if (recovered) {
214- recovered->set_exception (std::system_error (
215- std::make_error_code (std::errc::interrupted), why.data ()));
216- recovered.reset ();
217- }
218- if (pulled) {
219- pulled->set_exception (std::system_error (
220- std::make_error_code (std::errc::interrupted), why.data ()));
221- pulled.reset ();
222- }
223- for (auto & [pg_shard, pr] : pushes) {
224- pr.set_exception (std::system_error (
225- std::make_error_code (std::errc::interrupted), why.data ()));
226- }
227- pushes.clear ();
228- }
230+ void interrupt (interrupt_cause_t why);
229231 void stop ();
230232 void dump_detail (Formatter* f) const {
231233 }
@@ -235,6 +237,7 @@ class RecoveryBackend {
235237 using WaitForObjectRecoveryRef = boost::intrusive_ptr<WaitForObjectRecovery>;
236238protected:
237239 std::map<hobject_t , WaitForObjectRecoveryRef> recovering;
240+ std::map<hobject_t , seastar::shared_promise<>> unfound;
238241 hobject_t get_temp_recovery_object (
239242 const hobject_t & target,
240243 eversion_t version) const ;
@@ -249,7 +252,7 @@ class RecoveryBackend {
249252 backend->clear_temp_objs ();
250253 }
251254
252- void clean_up (ceph::os::Transaction& t, std::string_view why);
255+ void clean_up (ceph::os::Transaction& t, interrupt_cause_t why);
253256 virtual seastar::future<> on_stop () = 0;
254257private:
255258 void handle_backfill_finish (
0 commit comments