]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: fix recursive locking on owner_lock in ImageDispatch
authorIlya Dryomov <idryomov@gmail.com>
Tue, 28 Mar 2023 17:52:42 +0000 (19:52 +0200)
committerIlya Dryomov <idryomov@gmail.com>
Tue, 4 Apr 2023 15:58:36 +0000 (17:58 +0200)
needs_exclusive_lock() calls acquire_lock() with owner_lock held.
If lock acquisiton races with lock shut down, ManagedLock completes
ImageDispatch context directly and dispatch is retried immediately on
the same thread (due to DISPATCH_RESULT_RESTART).  This results in
recursion into needs_exclusive_lock() and, barring locking issues, can
lead to unbounded stack growth if lock shut down takes its time.

Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
src/librbd/exclusive_lock/ImageDispatch.cc

index cd7f450f2751532677076413ab612c8378464f55..6b403e2e3156e44aeeb13112969f03ca75b84ac0 100644 (file)
@@ -8,6 +8,7 @@
 #include "librbd/ExclusiveLock.h"
 #include "librbd/ImageCtx.h"
 #include "librbd/Utils.h"
+#include "librbd/asio/ContextWQ.h"
 #include "librbd/exclusive_lock/Policy.h"
 #include "librbd/io/AioCompletion.h"
 #include "librbd/io/ImageDispatchSpec.h"
@@ -22,6 +23,7 @@ namespace librbd {
 namespace exclusive_lock {
 
 using util::create_context_callback;
+using util::create_async_context_callback;
 
 template <typename I>
 ImageDispatch<I>::ImageDispatch(I* image_ctx)
@@ -271,8 +273,9 @@ bool ImageDispatch<I>::needs_exclusive_lock(bool read_op, uint64_t tid,
     locker.unlock();
 
     *dispatch_result = io::DISPATCH_RESULT_RESTART;
-    auto ctx = create_context_callback<
-      ImageDispatch<I>, &ImageDispatch<I>::handle_acquire_lock>(this);
+    auto ctx = create_async_context_callback(
+      *m_image_ctx, create_context_callback<
+        ImageDispatch<I>, &ImageDispatch<I>::handle_acquire_lock>(this));
     m_image_ctx->exclusive_lock->acquire_lock(ctx);
     return true;
   }