]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: make sure we are not loosing exclusive lock
authorMykola Golub <mgolub@suse.com>
Thu, 19 Nov 2020 10:31:10 +0000 (10:31 +0000)
committerMykola Golub <mgolub@suse.com>
Wed, 25 Nov 2020 10:13:35 +0000 (10:13 +0000)
when starting a serialized maintenance operation

Signed-off-by: Mykola Golub <mgolub@suse.com>
src/librbd/Operations.cc

index eb19175b12d2cca7aed19f66ea9659ab2ca616b1..27a54cf2fa31904b234c2a69838b4d27daf101cb 100644 (file)
@@ -415,22 +415,31 @@ void Operations<I>::start_op(Operation op, Context *ctx) {
   CephContext *cct = m_image_ctx.cct;
   ldout(cct, 20) << __func__ << ": " << op << " " << ctx << dendl;
 
+  ceph_assert(ceph_mutex_is_locked(m_image_ctx.owner_lock));
+  bool requires_lock = m_image_ctx.exclusive_lock != nullptr;
+
   ctx = util::create_async_context_callback(
       m_image_ctx, new LambdaContext(
-        [this, op, ctx](int r) {
-          if (r == 0) {
+        [this, op, requires_lock, ctx](int r) {
+          Context *finish_op_ctx = nullptr;
+          if (requires_lock && r == 0) {
             std::shared_lock owner_locker{m_image_ctx.owner_lock};
             std::shared_lock image_locker{m_image_ctx.image_lock};
+            auto exclusive_lock = m_image_ctx.exclusive_lock;
 
-            if (m_image_ctx.exclusive_lock != nullptr &&
-                (!m_image_ctx.exclusive_lock->is_lock_owner())) {
-              ldout(m_image_ctx.cct, 20) << "lock owner lost, restarting" << dendl;
+            if (exclusive_lock == nullptr ||
+                (finish_op_ctx = exclusive_lock->start_op(&r)) == nullptr) {
+              ldout(m_image_ctx.cct, 20) << "lock owner lost, restarting"
+                                         << dendl;
               r = -ERESTART;
             }
           }
 
           ldout(m_image_ctx.cct, 20) << "start " << op << " " << ctx << dendl;
           ctx->complete(r);
+          if (finish_op_ctx != nullptr) {
+            finish_op_ctx->complete(0);
+          }
         }));
 
   std::unique_lock locker{m_queue_lock};