]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
crimson/object_context: make obc interruptible
authorXuehan Xu <xxhdx1985126@gmail.com>
Fri, 11 Sep 2020 11:01:52 +0000 (19:01 +0800)
committerKefu Chai <kchai@redhat.com>
Tue, 15 Sep 2020 08:48:27 +0000 (16:48 +0800)
* add tri_mutex::abort() to pass given exception to all waiters
* add ObjectContext::interrupt() to abort all pending consumers
  of current object context

Fixes: https://tracker.ceph.com/issues/47311
Signed-off-by: Xuehan Xu <xxhdx1985126@gmail.com>
Signed-off-by: Kefu Chai <kchai@redhat.com>
src/crimson/common/tri_mutex.h
src/crimson/osd/object_context.h
src/crimson/osd/recovery_backend.cc

index 63ca81a15423455b222aa46e143881b80fff9cdb..d8c8e66fbb667e8e5948ddd9a1c127191a969205 100644 (file)
@@ -35,6 +35,16 @@ public:
 
   bool is_acquired() const;
 
+  /// pass the provided exception to any waiting waiters
+  template<typename Exception>
+  void abort(Exception ex) {
+    while (!waiters.empty()) {
+      auto& waiter = waiters.front();
+      waiter.pr.set_exception(std::make_exception_ptr(ex));
+      waiters.pop_front();
+    }
+  }
+
 private:
   void wake();
   unsigned readers = 0;
index 3bd6073d9e6243f6af883407cb92bc775e484532..6f158bbd64ecf8c3bb70ae75fb7a6857dd31776f 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "common/intrusive_lru.h"
 #include "osd/object_state.h"
+#include "crimson/common/exception.h"
 #include "crimson/common/tri_mutex.h"
 #include "crimson/osd/osd_operation.h"
 
@@ -84,6 +85,15 @@ public:
     loaded = true;
   }
 
+  /// pass the provided exception to any waiting consumers of this ObjectContext
+  template<typename Exception>
+  void interrupt(Exception ex) {
+    rwlock.abort(std::move(ex));
+    if (recovery_read_marker) {
+      drop_recovery_read();
+    }
+  }
+
 private:
   tri_mutex rwlock;
   bool recovery_read_marker = false;
index 77a5480a9750965f80b3950e1098f6b0014419a4..c3c4ed9a5c88bb333c5a55832a3e5531bf0e2ab5 100644 (file)
@@ -42,7 +42,9 @@ void RecoveryBackend::clean_up(ceph::os::Transaction& t,
     if ((recovery_waiter.pi && recovery_waiter.pi->is_complete())
        || (!recovery_waiter.pi
          && recovery_waiter.obc && recovery_waiter.obc->obs.exists)) {
-      recovery_waiter.obc->drop_recovery_read();
+      recovery_waiter.obc->interrupt(
+         ::crimson::common::actingset_changed(
+             pg.is_primary()));
       recovery_waiter.interrupt(why);
     }
   }