]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rbd-mirror: release lock before calling m_async_op_tracker.finish_op() 64092/head
authorVinayBhaskar-V <vvarada@redhat.com>
Wed, 16 Apr 2025 15:52:21 +0000 (21:22 +0530)
committerIlya Dryomov <idryomov@gmail.com>
Mon, 23 Jun 2025 06:46:37 +0000 (08:46 +0200)
m_async_op_tracker.finish_op() in InstanceReplayer::start_image_replayers
may invoke a completion that re-enters code paths that attempt to acquire
the same mutex (m_lock), violating the non-recursive lock constraint.
This can be fixed by releasing the lock before calling
m_async_op_tracker.finish_op().

Fixes: https://tracker.ceph.com/issues/70951
Signed-off-by: VinayBhaskar-V <vvarada@redhat.com>
(cherry picked from commit 07e44074ae5d18dc1248e557fd1aa2dbe39792c6)

src/tools/rbd_mirror/InstanceReplayer.cc
src/tools/rbd_mirror/InstanceReplayer.h

index 54244b52ceb439ae082df22b5a639d4e51bf74b4..f278ab09bc14dad8161927f240c303f69b9be51e 100644 (file)
@@ -370,12 +370,9 @@ void InstanceReplayer<I>::queue_start_image_replayers() {
 }
 
 template <typename I>
-void InstanceReplayer<I>::start_image_replayers(int r) {
-  dout(10) << dendl;
-
-  std::lock_guard locker{m_lock};
+void InstanceReplayer<I>::start_image_replayers(
+    const std::unique_lock<ceph::mutex>&) {
   if (m_on_shut_down != nullptr) {
-    m_async_op_tracker.finish_op();
     return;
   }
 
@@ -407,7 +404,15 @@ void InstanceReplayer<I>::start_image_replayers(int r) {
   m_service_daemon->add_or_update_namespace_attribute(
     m_local_io_ctx.get_id(), m_local_io_ctx.get_namespace(),
     SERVICE_DAEMON_ERROR_COUNT_KEY, error_count);
+}
 
+template <typename I>
+void InstanceReplayer<I>::start_image_replayers(int r) {
+  dout(10) << dendl;
+  {
+    std::unique_lock locker{m_lock};
+    start_image_replayers(locker);
+  }
   m_async_op_tracker.finish_op();
 }
 
index 7a5c79723d3e61a01af1d9042b8990f337b04182..5399c6994a5a6feb49736c05c920afb67419d1dc 100644 (file)
@@ -118,6 +118,7 @@ private:
 
   void start_image_replayer(ImageReplayer<ImageCtxT> *image_replayer);
   void queue_start_image_replayers();
+  void start_image_replayers(const std::unique_lock<ceph::mutex>&);
   void start_image_replayers(int r);
 
   void stop_image_replayer(ImageReplayer<ImageCtxT> *image_replayer,