From: Jason Dillaman Date: Wed, 21 Oct 2020 19:58:20 +0000 (-0400) Subject: librbd: fix potential recursive lock of ImageCtx::image_lock X-Git-Tag: v16.1.0~702^2~10 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=bb38c391b656a1bead77283001d60237b4db7f70;p=ceph.git librbd: fix potential recursive lock of ImageCtx::image_lock If the "list_snaps" IO call returns immediately, it can result in an attempted recursive lock starting from CopyupRequest. Signed-off-by: Jason Dillaman --- diff --git a/src/librbd/deep_copy/ObjectCopyRequest.cc b/src/librbd/deep_copy/ObjectCopyRequest.cc index dcbed85fd951..aa8dfdfe8c39 100644 --- a/src/librbd/deep_copy/ObjectCopyRequest.cc +++ b/src/librbd/deep_copy/ObjectCopyRequest.cc @@ -8,6 +8,7 @@ #include "librbd/ExclusiveLock.h" #include "librbd/ObjectMap.h" #include "librbd/Utils.h" +#include "librbd/asio/ContextWQ.h" #include "librbd/deep_copy/Handler.h" #include "librbd/io/AioCompletion.h" #include "librbd/io/AsyncOperation.h" @@ -24,6 +25,7 @@ namespace librbd { namespace deep_copy { +using librbd::util::create_async_context_callback; using librbd::util::create_context_callback; using librbd::util::create_rados_callback; @@ -83,8 +85,9 @@ void ObjectCopyRequest::send_list_snaps() { m_snapshot_delta.clear(); - auto ctx = create_context_callback< - ObjectCopyRequest, &ObjectCopyRequest::handle_list_snaps>(this); + auto ctx = create_async_context_callback( + *m_src_image_ctx, create_context_callback< + ObjectCopyRequest, &ObjectCopyRequest::handle_list_snaps>(this)); auto aio_comp = io::AioCompletion::create_and_start( ctx, util::get_image_ctx(m_src_image_ctx), io::AIO_TYPE_GENERIC); auto req = io::ImageDispatchSpec::create_list_snaps( diff --git a/src/test/librbd/deep_copy/test_mock_ObjectCopyRequest.cc b/src/test/librbd/deep_copy/test_mock_ObjectCopyRequest.cc index 984c30943044..3860a9aa1c93 100644 --- a/src/test/librbd/deep_copy/test_mock_ObjectCopyRequest.cc +++ b/src/test/librbd/deep_copy/test_mock_ObjectCopyRequest.cc @@ -475,6 +475,7 @@ TEST_F(TestMockDeepCopyObjectCopyRequest, DNE) { librbd::MockObjectMap mock_object_map; mock_dst_image_ctx.object_map = &mock_object_map; + expect_op_work_queue(mock_src_image_ctx); expect_test_features(mock_dst_image_ctx); expect_get_object_count(mock_dst_image_ctx); @@ -505,6 +506,7 @@ TEST_F(TestMockDeepCopyObjectCopyRequest, Write) { librbd::MockObjectMap mock_object_map; mock_dst_image_ctx.object_map = &mock_object_map; + expect_op_work_queue(mock_src_image_ctx); expect_test_features(mock_dst_image_ctx); expect_get_object_count(mock_dst_image_ctx); @@ -546,6 +548,7 @@ TEST_F(TestMockDeepCopyObjectCopyRequest, ReadError) { librbd::MockObjectMap mock_object_map; mock_dst_image_ctx.object_map = &mock_object_map; + expect_op_work_queue(mock_src_image_ctx); expect_test_features(mock_dst_image_ctx); expect_get_object_count(mock_dst_image_ctx); @@ -578,6 +581,7 @@ TEST_F(TestMockDeepCopyObjectCopyRequest, WriteError) { librbd::MockObjectMap mock_object_map; mock_dst_image_ctx.object_map = &mock_object_map; + expect_op_work_queue(mock_src_image_ctx); expect_test_features(mock_dst_image_ctx); expect_get_object_count(mock_dst_image_ctx); @@ -631,6 +635,7 @@ TEST_F(TestMockDeepCopyObjectCopyRequest, WriteSnaps) { librbd::MockObjectMap mock_object_map; mock_dst_image_ctx.object_map = &mock_object_map; + expect_op_work_queue(mock_src_image_ctx); expect_test_features(mock_dst_image_ctx); expect_get_object_count(mock_dst_image_ctx); @@ -694,6 +699,7 @@ TEST_F(TestMockDeepCopyObjectCopyRequest, Trim) { librbd::MockObjectMap mock_object_map; mock_dst_image_ctx.object_map = &mock_object_map; + expect_op_work_queue(mock_src_image_ctx); expect_test_features(mock_dst_image_ctx); expect_get_object_count(mock_dst_image_ctx); @@ -747,6 +753,7 @@ TEST_F(TestMockDeepCopyObjectCopyRequest, Remove) { librbd::MockObjectMap mock_object_map; mock_dst_image_ctx.object_map = &mock_object_map; + expect_op_work_queue(mock_src_image_ctx); expect_test_features(mock_dst_image_ctx); expect_get_object_count(mock_dst_image_ctx); @@ -799,6 +806,7 @@ TEST_F(TestMockDeepCopyObjectCopyRequest, ObjectMapUpdateError) { librbd::MockObjectMap mock_object_map; mock_dst_image_ctx.object_map = &mock_object_map; + expect_op_work_queue(mock_src_image_ctx); expect_test_features(mock_dst_image_ctx); expect_get_object_count(mock_dst_image_ctx); @@ -865,6 +873,7 @@ TEST_F(TestMockDeepCopyObjectCopyRequest, WriteSnapsStart) { librbd::MockObjectMap mock_object_map; mock_dst_image_ctx.object_map = &mock_object_map; + expect_op_work_queue(mock_src_image_ctx); expect_test_features(mock_dst_image_ctx); expect_get_object_count(mock_dst_image_ctx);