From: Jason Dillaman Date: Wed, 27 May 2020 23:14:14 +0000 (-0400) Subject: librbd: exclusive lock image dispatch should not wait on IO when setting lock X-Git-Tag: v17.0.0~2184^2~4 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=48456f8c5fdc43f4dca464c61f7b287d57a08e20;p=ceph.git librbd: exclusive lock image dispatch should not wait on IO when setting lock IO from later dispatch layers might have caused the need to acquire the lock (i.e. like an image refresh). In that case, the IO will be blocked waiting for the exclusive lock to be acquired -- but will deadlock waiting for the IO to flush. Signed-off-by: Jason Dillaman --- diff --git a/src/librbd/exclusive_lock/ImageDispatch.cc b/src/librbd/exclusive_lock/ImageDispatch.cc index 253ae149ce675..dccb340a95446 100644 --- a/src/librbd/exclusive_lock/ImageDispatch.cc +++ b/src/librbd/exclusive_lock/ImageDispatch.cc @@ -63,27 +63,21 @@ void ImageDispatch::shut_down(Context* on_finish) { template void ImageDispatch::set_require_lock(io::Direction direction, Context* on_finish) { - auto cct = m_image_ctx->cct; - // pause any matching IO from proceeding past this layer set_require_lock(direction, true); - auto ctx = new C_Gather(cct, on_finish); - - // passive wait for in-flight IO to complete - m_flush_tracker->flush(ctx->new_sub()); - - if (direction != io::DIRECTION_READ) { - // push through an flush for any in-flight writes at lower levels - auto aio_comp = io::AioCompletion::create_and_start( - ctx->new_sub(), util::get_image_ctx(m_image_ctx), io::AIO_TYPE_FLUSH); - auto req = io::ImageDispatchSpec::create_flush( - *m_image_ctx, io::IMAGE_DISPATCH_LAYER_EXCLUSIVE_LOCK, aio_comp, - io::FLUSH_SOURCE_INTERNAL, {}); - req->send(); + if (direction == io::DIRECTION_READ) { + on_finish->complete(0); + return; } - ctx->activate(); + // push through a flush for any in-flight writes at lower levels + auto aio_comp = io::AioCompletion::create_and_start( + on_finish, util::get_image_ctx(m_image_ctx), io::AIO_TYPE_FLUSH); + auto req = io::ImageDispatchSpec::create_flush( + *m_image_ctx, io::IMAGE_DISPATCH_LAYER_EXCLUSIVE_LOCK, aio_comp, + io::FLUSH_SOURCE_INTERNAL, {}); + req->send(); } template