From 1d943f8c47b3510e47d40701e9acd213706754e5 Mon Sep 17 00:00:00 2001 From: Ilya Dryomov Date: Tue, 28 Mar 2023 19:52:42 +0200 Subject: [PATCH] librbd: fix recursive locking on owner_lock in ImageDispatch 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 --- src/librbd/exclusive_lock/ImageDispatch.cc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/librbd/exclusive_lock/ImageDispatch.cc b/src/librbd/exclusive_lock/ImageDispatch.cc index cd7f450f27515..6b403e2e3156e 100644 --- a/src/librbd/exclusive_lock/ImageDispatch.cc +++ b/src/librbd/exclusive_lock/ImageDispatch.cc @@ -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 ImageDispatch::ImageDispatch(I* image_ctx) @@ -271,8 +273,9 @@ bool ImageDispatch::needs_exclusive_lock(bool read_op, uint64_t tid, locker.unlock(); *dispatch_result = io::DISPATCH_RESULT_RESTART; - auto ctx = create_context_callback< - ImageDispatch, &ImageDispatch::handle_acquire_lock>(this); + auto ctx = create_async_context_callback( + *m_image_ctx, create_context_callback< + ImageDispatch, &ImageDispatch::handle_acquire_lock>(this)); m_image_ctx->exclusive_lock->acquire_lock(ctx); return true; } -- 2.39.5