]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: avoid completing mirror:DisableRequest while holding its lock 35074/head
authorJason Dillaman <dillaman@redhat.com>
Thu, 14 May 2020 18:01:35 +0000 (14:01 -0400)
committerJason Dillaman <dillaman@redhat.com>
Mon, 18 May 2020 12:38:28 +0000 (08:38 -0400)
Ensure that the lock is released before another thread has the chance
to complete the state machine and attempt to destruct the in-use lock.

Fixes: https://tracker.ceph.com/issues/45544
Signed-off-by: Jason Dillaman <dillaman@redhat.com>
src/librbd/mirror/DisableRequest.cc

index 2d2dd874a80a4093b659c9f7a457aee46c6673a2..05652d1c9dd3c6e705ee2e46cc4541b3b1492696 100644 (file)
@@ -219,16 +219,15 @@ Context *DisableRequest<I>::handle_get_clients(int *result) {
   CephContext *cct = m_image_ctx->cct;
   ldout(cct, 10) << "r=" << *result << dendl;
 
+  std::unique_lock locker{m_lock};
+  ceph_assert(m_current_ops.empty());
+
   if (*result < 0) {
     lderr(cct) << "failed to get registered clients: " << cpp_strerror(*result)
                << dendl;
     return m_on_finish;
   }
 
-  std::lock_guard locker{m_lock};
-
-  ceph_assert(m_current_ops.empty());
-
   for (auto client : m_clients) {
     journal::ClientData client_data;
     auto bl_it = client.data.cbegin();
@@ -276,6 +275,7 @@ Context *DisableRequest<I>::handle_get_clients(int *result) {
     } else if (!m_remove) {
       return m_on_finish;
     }
+    locker.unlock();
 
     // no mirror clients to unregister
     send_remove_mirror_image();
@@ -342,7 +342,7 @@ Context *DisableRequest<I>::handle_remove_snap(int *result,
   CephContext *cct = m_image_ctx->cct;
   ldout(cct, 10) << "r=" << *result << dendl;
 
-  std::lock_guard locker{m_lock};
+  std::unique_lock locker{m_lock};
 
   ceph_assert(m_current_ops[client_id] > 0);
   m_current_ops[client_id]--;
@@ -360,6 +360,8 @@ Context *DisableRequest<I>::handle_remove_snap(int *result,
       if (m_ret[client_id] < 0) {
         return m_on_finish;
       }
+      locker.unlock();
+
       send_remove_mirror_image();
       return nullptr;
     }
@@ -404,7 +406,7 @@ Context *DisableRequest<I>::handle_unregister_client(
   CephContext *cct = m_image_ctx->cct;
   ldout(cct, 10) << "r=" << *result << dendl;
 
-  std::lock_guard locker{m_lock};
+  std::unique_lock locker{m_lock};
   ceph_assert(m_current_ops[client_id] == 0);
   m_current_ops.erase(client_id);
 
@@ -422,6 +424,7 @@ Context *DisableRequest<I>::handle_unregister_client(
     *result = m_error_result;
     return m_on_finish;
   }
+  locker.unlock();
 
   send_get_clients();
   return nullptr;