]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: add "skip notify quiesce" flag to "snap create"
authorMykola Golub <mgolub@suse.com>
Thu, 21 May 2020 09:10:35 +0000 (10:10 +0100)
committerMykola Golub <mgolub@suse.com>
Fri, 22 May 2020 08:20:00 +0000 (09:20 +0100)
Signed-off-by: Mykola Golub <mgolub@suse.com>
src/librbd/Types.h
src/librbd/operation/SnapshotCreateRequest.cc
src/librbd/operation/SnapshotCreateRequest.h
src/test/librbd/operation/test_mock_SnapshotCreateRequest.cc

index 42d605be7200b83b48a1f56595613adb0eab7fd8..733f133ba008a66420b45cefd0d1901447f75b2e 100644 (file)
@@ -101,6 +101,7 @@ enum ImageReadOnlyFlag {
 
 enum SnapCreateFlag {
   SNAP_CREATE_FLAG_SKIP_OBJECT_MAP     = 1 << 0,
+  SNAP_CREATE_FLAG_SKIP_NOTIFY_QUIESCE = 1 << 1,
 };
 
 struct MigrationInfo {
index 38f489c408dcff7c33c279bf96996cf08799a598..5966095caea290319a9d07def38b46321b2c6e5e 100644 (file)
@@ -35,6 +35,7 @@ SnapshotCreateRequest<I>::SnapshotCreateRequest(I &image_ctx,
   : Request<I>(image_ctx, on_finish, journal_op_tid),
     m_snap_namespace(snap_namespace), m_snap_name(snap_name),
     m_skip_object_map(flags & SNAP_CREATE_FLAG_SKIP_OBJECT_MAP),
+    m_skip_notify_quiesce(flags & SNAP_CREATE_FLAG_SKIP_NOTIFY_QUIESCE),
     m_prog_ctx(prog_ctx) {
 }
 
@@ -54,8 +55,12 @@ void SnapshotCreateRequest<I>::send_op() {
 
 template <typename I>
 void SnapshotCreateRequest<I>::send_notify_quiesce() {
-  I &image_ctx = this->m_image_ctx;
+  if (m_skip_notify_quiesce) {
+    send_suspend_requests();
+    return;
+  }
 
+  I &image_ctx = this->m_image_ctx;
   CephContext *cct = image_ctx.cct;
   ldout(cct, 5) << this << " " << __func__ << dendl;
 
@@ -77,6 +82,7 @@ Context *SnapshotCreateRequest<I>::handle_notify_quiesce(int *result) {
     return this->create_context_finisher(*result);
   }
 
+  std::shared_lock owner_locker{image_ctx.owner_lock};
   send_suspend_requests();
   return nullptr;
 }
@@ -105,7 +111,7 @@ Context *SnapshotCreateRequest<I>::handle_suspend_requests(int *result) {
 template <typename I>
 void SnapshotCreateRequest<I>::send_suspend_aio() {
   I &image_ctx = this->m_image_ctx;
-  std::shared_lock owner_locker{image_ctx.owner_lock};
+  ceph_assert(ceph_mutex_is_locked(image_ctx.owner_lock));
 
   CephContext *cct = image_ctx.cct;
   ldout(cct, 5) << this << " " << __func__ << dendl;
@@ -124,8 +130,7 @@ Context *SnapshotCreateRequest<I>::handle_suspend_aio(int *result) {
   if (*result < 0) {
     lderr(cct) << "failed to block writes: " << cpp_strerror(*result) << dendl;
     save_result(result);
-    send_notify_unquiesce();
-    return nullptr;
+    return send_notify_unquiesce();
   }
 
   send_append_op_event();
@@ -156,8 +161,7 @@ Context *SnapshotCreateRequest<I>::handle_append_op_event(int *result) {
     lderr(cct) << "failed to commit journal entry: " << cpp_strerror(*result)
                << dendl;
     save_result(result);
-    send_notify_unquiesce();
-    return nullptr;
+    return send_notify_unquiesce();
   }
 
   send_allocate_snap_id();
@@ -188,8 +192,7 @@ Context *SnapshotCreateRequest<I>::handle_allocate_snap_id(int *result) {
     lderr(cct) << "failed to allocate snapshot id: " << cpp_strerror(*result)
                << dendl;
     save_result(result);
-    send_notify_unquiesce();
-    return nullptr;
+    return send_notify_unquiesce();
   }
 
   send_create_snap();
@@ -281,8 +284,7 @@ Context *SnapshotCreateRequest<I>::handle_create_object_map(int *result) {
 
     save_result(result);
     update_snap_context();
-    send_notify_unquiesce();
-    return nullptr;
+    return send_notify_unquiesce();
   }
 
   return send_create_image_state();
@@ -295,8 +297,7 @@ Context *SnapshotCreateRequest<I>::send_create_image_state() {
     &m_snap_namespace);
   if (mirror_ns == nullptr || !mirror_ns->is_primary()) {
     update_snap_context();
-    send_notify_unquiesce();
-    return nullptr;
+    return send_notify_unquiesce();
   }
 
   CephContext *cct = image_ctx.cct;
@@ -323,8 +324,7 @@ Context *SnapshotCreateRequest<I>::handle_create_image_state(int *result) {
     save_result(result);
   }
 
-  send_notify_unquiesce();
-  return nullptr;
+  return send_notify_unquiesce();
 }
 
 template <typename I>
@@ -348,23 +348,27 @@ Context *SnapshotCreateRequest<I>::handle_release_snap_id(int *result) {
   CephContext *cct = image_ctx.cct;
   ldout(cct, 5) << this << " " << __func__ << ": r=" << *result << dendl;
 
-  send_notify_unquiesce();
-  return nullptr;
+  return send_notify_unquiesce();
 }
 
 template <typename I>
-void SnapshotCreateRequest<I>::send_notify_unquiesce() {
+Context *SnapshotCreateRequest<I>::send_notify_unquiesce() {
   I &image_ctx = this->m_image_ctx;
-
   CephContext *cct = image_ctx.cct;
   ldout(cct, 5) << this << " " << __func__ << dendl;
 
   image_ctx.io_image_dispatcher->unblock_writes();
 
+  if (m_skip_notify_quiesce) {
+    return this->create_context_finisher(m_ret_val);
+  }
+
   image_ctx.image_watcher->notify_unquiesce(
     m_request_id, create_context_callback<
       SnapshotCreateRequest<I>,
       &SnapshotCreateRequest<I>::handle_notify_unquiesce>(this));
+
+  return nullptr;
 }
 
 template <typename I>
index 9f53399a9fb98859a10bbfe11a6c9109c0560a9e..db653817e7f81423b64acb9edc81542b602132fb 100644 (file)
@@ -89,6 +89,7 @@ private:
   cls::rbd::SnapshotNamespace m_snap_namespace;
   std::string m_snap_name;
   bool m_skip_object_map;
+  bool m_skip_notify_quiesce;
   ProgressContext &m_prog_ctx;
 
   uint64_t m_request_id = 0;
@@ -125,7 +126,7 @@ private:
   void send_release_snap_id();
   Context *handle_release_snap_id(int *result);
 
-  void send_notify_unquiesce();
+  Context *send_notify_unquiesce();
   Context *handle_notify_unquiesce(int *result);
 
   void update_snap_context();
index cba2d5633e0c2a8c0f011957c546362f875c0732..f43b39f36014be665c555d7cc735e46249325661 100644 (file)
@@ -402,6 +402,49 @@ TEST_F(TestMockOperationSnapshotCreateRequest, SkipObjectMap) {
   ASSERT_EQ(0, cond_ctx.wait());
 }
 
+TEST_F(TestMockOperationSnapshotCreateRequest, SkipNotifyQuiesce) {
+  REQUIRE_FORMAT_V2();
+
+  librbd::ImageCtx *ictx;
+  ASSERT_EQ(0, open_image(m_image_name, &ictx));
+
+  MockImageCtx mock_image_ctx(*ictx);
+
+  MockExclusiveLock mock_exclusive_lock;
+  if (ictx->test_features(RBD_FEATURE_EXCLUSIVE_LOCK)) {
+    mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
+  }
+
+  MockObjectMap mock_object_map;
+  if (ictx->test_features(RBD_FEATURE_OBJECT_MAP)) {
+    mock_image_ctx.object_map = &mock_object_map;
+  }
+
+  expect_verify_lock_ownership(mock_image_ctx);
+  expect_op_work_queue(mock_image_ctx);
+
+  ::testing::InSequence seq;
+  expect_block_writes(mock_image_ctx);
+  expect_allocate_snap_id(mock_image_ctx, 0);
+  expect_snap_create(mock_image_ctx, 0);
+  if (!mock_image_ctx.old_format) {
+    expect_object_map_snap_create(mock_image_ctx);
+    expect_update_snap_context(mock_image_ctx);
+  }
+  expect_unblock_writes(mock_image_ctx);
+
+  C_SaferCond cond_ctx;
+  librbd::NoOpProgressContext prog_ctx;
+  MockSnapshotCreateRequest *req = new MockSnapshotCreateRequest(
+    mock_image_ctx, &cond_ctx, cls::rbd::UserSnapshotNamespace(),
+    "snap1", 0, SNAP_CREATE_FLAG_SKIP_NOTIFY_QUIESCE, prog_ctx);
+  {
+    std::shared_lock owner_locker{mock_image_ctx.owner_lock};
+    req->send();
+  }
+  ASSERT_EQ(0, cond_ctx.wait());
+}
+
 TEST_F(TestMockOperationSnapshotCreateRequest, SetImageState) {
   REQUIRE_FORMAT_V2();