]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: fix potential recursive lock of ImageCtx::image_lock
authorJason Dillaman <dillaman@redhat.com>
Wed, 21 Oct 2020 19:58:20 +0000 (15:58 -0400)
committerJason Dillaman <dillaman@redhat.com>
Sun, 1 Nov 2020 14:22:38 +0000 (09:22 -0500)
If the "list_snaps" IO call returns immediately, it can result
in an attempted recursive lock starting from CopyupRequest.

Signed-off-by: Jason Dillaman <dillaman@redhat.com>
src/librbd/deep_copy/ObjectCopyRequest.cc
src/test/librbd/deep_copy/test_mock_ObjectCopyRequest.cc

index dcbed85fd951ef42966de794a6c2b2ba9e378e8c..aa8dfdfe8c39d435bbcf6523178a7d2626181bb7 100644 (file)
@@ -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<I>::send_list_snaps() {
 
   m_snapshot_delta.clear();
 
-  auto ctx = create_context_callback<
-    ObjectCopyRequest, &ObjectCopyRequest<I>::handle_list_snaps>(this);
+  auto ctx = create_async_context_callback(
+    *m_src_image_ctx, create_context_callback<
+      ObjectCopyRequest, &ObjectCopyRequest<I>::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(
index 984c30943044030ba5ec71a4e8bdfd1b31570bef..3860a9aa1c93a009526cccad20b4d86dc873aea6 100644 (file)
@@ -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);