]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rbd: reference count objects when invoking async requests
authorMahati Chamarthy <mahati.chamarthy@intel.com>
Mon, 12 Feb 2018 03:28:30 +0000 (22:28 -0500)
committerMahati Chamarthy <mahati.chamarthy@intel.com>
Mon, 11 Nov 2019 07:57:09 +0000 (13:27 +0530)
Track asynchronous Journal, ObjectMap and ExclusiveLock
operations by reference counting the respective objects
when creating context callbacks. Object is ref'd when
context callback object is created and unref'd before
invoking callback handler.

Signed-off-by: Mahati Chamarthy <mahati.chamarthy@intel.com>
Signed-off-by: Venky Shankar <vshankar@redhat.com>
22 files changed:
src/librbd/DeepCopyRequest.cc
src/librbd/ExclusiveLock.cc
src/librbd/ExclusiveLock.h
src/librbd/Journal.cc
src/librbd/Journal.h
src/librbd/ObjectMap.cc
src/librbd/ObjectMap.h
src/librbd/Operations.cc
src/librbd/exclusive_lock/PostAcquireRequest.cc
src/librbd/exclusive_lock/PreReleaseRequest.cc
src/librbd/image/CloseRequest.cc
src/librbd/image/PreRemoveRequest.cc
src/librbd/image/RefreshRequest.cc
src/librbd/image/SetSnapRequest.cc
src/librbd/io/ImageRequestWQ.cc
src/librbd/journal/ObjectDispatch.cc
src/librbd/journal/Replay.cc
src/librbd/mirror/DemoteRequest.cc
src/librbd/operation/DisableFeaturesRequest.cc
src/librbd/operation/DisableFeaturesRequest.h
src/librbd/operation/RebuildObjectMapRequest.cc
src/librbd/operation/SnapshotRollbackRequest.cc

index fee8b0274f1726d8015e7a73a0e3c644eff63714..a8955a769b5c6064ac748daac3f94a60b93e16c7 100644 (file)
@@ -294,7 +294,7 @@ void DeepCopyRequest<I>::handle_refresh_object_map(int r) {
     std::unique_lock image_locker{m_dst_image_ctx->image_lock};
     std::swap(m_dst_image_ctx->object_map, m_object_map);
   }
-  delete m_object_map;
+  m_object_map->put();
 
   send_copy_metadata();
 }
index 48e6a3243b81b5b0e1c2d29d2b6cb97a7e7fa55b..1250c733d676bc56d52e5ae2f4e825aefac28673 100644 (file)
 namespace librbd {
 
 using namespace exclusive_lock;
+using librbd::util::create_context_callback;
 
 template <typename I>
 using ML = ManagedLock<I>;
 
 template <typename I>
 ExclusiveLock<I>::ExclusiveLock(I &image_ctx)
-  : ML<I>(image_ctx.md_ctx, image_ctx.op_work_queue, image_ctx.header_oid,
+  : RefCountedObject(image_ctx.cct),
+    ML<I>(image_ctx.md_ctx, image_ctx.op_work_queue, image_ctx.header_oid,
           image_ctx.image_watcher, managed_lock::EXCLUSIVE,
           image_ctx.config.template get_val<bool>("rbd_blacklist_on_break_lock"),
           image_ctx.config.template get_val<uint64_t>("rbd_blacklist_expire_seconds")),
@@ -105,6 +107,9 @@ int ExclusiveLock<I>::get_unlocked_op_error() const {
 template <typename I>
 void ExclusiveLock<I>::init(uint64_t features, Context *on_init) {
   ceph_assert(ceph_mutex_is_locked(m_image_ctx.owner_lock));
+
+  on_init = create_context_callback<Context>(on_init, this);
+
   ldout(m_image_ctx.cct, 10) << dendl;
 
   {
@@ -120,6 +125,8 @@ template <typename I>
 void ExclusiveLock<I>::shut_down(Context *on_shut_down) {
   ldout(m_image_ctx.cct, 10) << dendl;
 
+  on_shut_down = create_context_callback<Context>(on_shut_down, this);
+
   ML<I>::shut_down(on_shut_down);
 
   // if stalled in request state machine -- abort
index 55a21077828a97564451110b941726c6f4978d79..a77ea817a48a065f0b2b15457797dce41ff6ff49 100644 (file)
@@ -7,11 +7,13 @@
 #include "common/AsyncOpTracker.h"
 #include "librbd/ManagedLock.h"
 #include "librbd/exclusive_lock/Policy.h"
+#include "common/RefCountedObj.h"
 
 namespace librbd {
 
 template <typename ImageCtxT = ImageCtx>
-class ExclusiveLock : public ManagedLock<ImageCtxT> {
+class ExclusiveLock : public RefCountedObject,
+                      public ManagedLock<ImageCtxT> {
 public:
   static ExclusiveLock *create(ImageCtxT &image_ctx) {
     return new ExclusiveLock<ImageCtxT>(image_ctx);
index f7d0cec8352de89020291f9d5e64146cdfd8a8d3..66849c461fad21b87eff0092d5822aae68075001 100644 (file)
@@ -326,7 +326,8 @@ std::ostream &operator<<(std::ostream &os,
 
 template <typename I>
 Journal<I>::Journal(I &image_ctx)
-  : m_image_ctx(image_ctx), m_journaler(NULL),
+  : RefCountedObject(image_ctx.cct),
+    m_image_ctx(image_ctx), m_journaler(NULL),
     m_state(STATE_UNINITIALIZED),
     m_error_result(0), m_replay_handler(this), m_close_pending(false),
     m_event_tid(0),
@@ -566,6 +567,8 @@ void Journal<I>::open(Context *on_finish) {
   CephContext *cct = m_image_ctx.cct;
   ldout(cct, 20) << this << " " << __func__ << dendl;
 
+  on_finish = create_context_callback<Context>(on_finish, this);
+
   on_finish = create_async_context_callback(m_image_ctx, on_finish);
 
   // inject our handler into the object dispatcher chain
@@ -583,6 +586,8 @@ void Journal<I>::close(Context *on_finish) {
   CephContext *cct = m_image_ctx.cct;
   ldout(cct, 20) << this << " " << __func__ << dendl;
 
+  on_finish = create_context_callback<Context>(on_finish, this);
+
   on_finish = new LambdaContext([this, on_finish](int r) {
       // remove our handler from object dispatcher chain - preserve error
       auto ctx = new LambdaContext([on_finish, r](int _) {
@@ -958,6 +963,8 @@ void Journal<I>::flush_event(uint64_t tid, Context *on_safe) {
   ldout(cct, 20) << this << " " << __func__ << ": tid=" << tid << ", "
                  << "on_safe=" << on_safe << dendl;
 
+  on_safe = create_context_callback<Context>(on_safe, this);
+
   Future future;
   {
     std::lock_guard event_locker{m_event_lock};
@@ -975,6 +982,8 @@ void Journal<I>::wait_event(uint64_t tid, Context *on_safe) {
   ldout(cct, 20) << this << " " << __func__ << ": tid=" << tid << ", "
                  << "on_safe=" << on_safe << dendl;
 
+  on_safe = create_context_callback<Context>(on_safe, this);
+
   std::lock_guard event_locker{m_event_lock};
   wait_event(m_lock, tid, on_safe);
 }
index bdd18f99d21781d1661cc8f30009f6f1fe6ad727..1554fed790568f97c6b459a46bd1317f79ed8b15 100644 (file)
@@ -10,6 +10,7 @@
 #include "include/rados/librados_fwd.hpp"
 #include "common/AsyncOpTracker.h"
 #include "common/Cond.h"
+#include "common/RefCountedObj.h"
 #include "common/WorkQueue.h"
 #include "journal/Future.h"
 #include "journal/JournalMetadataListener.h"
@@ -37,7 +38,7 @@ class ImageCtx;
 namespace journal { template <typename> class Replay; }
 
 template <typename ImageCtxT = ImageCtx>
-class Journal {
+class Journal : public RefCountedObject {
 public:
   /**
    * @verbatim
index fb09e3d989a02a60f1bcd6db4575c1fe81606369..0d60cc95f94e5790c012993c2e951a8b62c073f9 100644 (file)
 
 namespace librbd {
 
+using librbd::util::create_context_callback;
+
 template <typename I>
 ObjectMap<I>::ObjectMap(I &image_ctx, uint64_t snap_id)
-  : m_image_ctx(image_ctx), m_snap_id(snap_id),
+  : RefCountedObject(image_ctx.cct),
+    m_image_ctx(image_ctx), m_snap_id(snap_id),
     m_lock(ceph::make_shared_mutex(util::unique_lock_name("librbd::ObjectMap::lock", this))),
     m_update_guard(new UpdateGuard(m_image_ctx.cct)) {
 }
@@ -144,19 +147,23 @@ bool ObjectMap<I>::update_required(const ceph::BitVector<2>::Iterator& it,
 
 template <typename I>
 void ObjectMap<I>::open(Context *on_finish) {
+  Context *ctx = create_context_callback<Context>(on_finish, this);
+
   auto req = object_map::RefreshRequest<I>::create(
-    m_image_ctx, &m_lock, &m_object_map, m_snap_id, on_finish);
+    m_image_ctx, &m_lock, &m_object_map, m_snap_id, ctx);
   req->send();
 }
 
 template <typename I>
 void ObjectMap<I>::close(Context *on_finish) {
+  Context *ctx = create_context_callback<Context>(on_finish, this);
+
   if (m_snap_id != CEPH_NOSNAP) {
-    m_image_ctx.op_work_queue->queue(on_finish, 0);
+    m_image_ctx.op_work_queue->queue(ctx, 0);
     return;
   }
 
-  auto req = object_map::UnlockRequest<I>::create(m_image_ctx, on_finish);
+  auto req = object_map::UnlockRequest<I>::create(m_image_ctx, ctx);
   req->send();
 }
 
@@ -176,8 +183,10 @@ void ObjectMap<I>::rollback(uint64_t snap_id, Context *on_finish) {
   ceph_assert(ceph_mutex_is_locked(m_image_ctx.image_lock));
 
   std::unique_lock locker{m_lock};
+  Context *ctx = create_context_callback<Context>(on_finish, this);
+
   object_map::SnapshotRollbackRequest *req =
-    new object_map::SnapshotRollbackRequest(m_image_ctx, snap_id, on_finish);
+    new object_map::SnapshotRollbackRequest(m_image_ctx, snap_id, ctx);
   req->send();
 }
 
@@ -187,9 +196,11 @@ void ObjectMap<I>::snapshot_add(uint64_t snap_id, Context *on_finish) {
   ceph_assert((m_image_ctx.features & RBD_FEATURE_OBJECT_MAP) != 0);
   ceph_assert(snap_id != CEPH_NOSNAP);
 
+  Context *ctx = create_context_callback<Context>(on_finish, this);
+
   object_map::SnapshotCreateRequest *req =
     new object_map::SnapshotCreateRequest(m_image_ctx, &m_lock, &m_object_map,
-                                          snap_id, on_finish);
+                                          snap_id, ctx);
   req->send();
 }
 
@@ -199,9 +210,11 @@ void ObjectMap<I>::snapshot_remove(uint64_t snap_id, Context *on_finish) {
   ceph_assert((m_image_ctx.features & RBD_FEATURE_OBJECT_MAP) != 0);
   ceph_assert(snap_id != CEPH_NOSNAP);
 
+  Context *ctx = create_context_callback<Context>(on_finish, this);
+
   object_map::SnapshotRemoveRequest *req =
     new object_map::SnapshotRemoveRequest(m_image_ctx, &m_lock, &m_object_map,
-                                          snap_id, on_finish);
+                                          snap_id, ctx);
   req->send();
 }
 
@@ -219,8 +232,10 @@ void ObjectMap<I>::aio_save(Context *on_finish) {
   }
   cls_client::object_map_save(&op, m_object_map);
 
+  Context *ctx = create_context_callback<Context>(on_finish, this);
+
   std::string oid(object_map_name(m_image_ctx.id, m_snap_id));
-  librados::AioCompletion *comp = util::create_rados_callback(on_finish);
+  librados::AioCompletion *comp = util::create_rados_callback(ctx);
 
   int r = m_image_ctx.md_ctx.aio_operate(oid, comp, &op);
   ceph_assert(r == 0);
@@ -238,9 +253,11 @@ void ObjectMap<I>::aio_resize(uint64_t new_size, uint8_t default_object_state,
   ceph_assert(m_image_ctx.exclusive_lock == nullptr ||
               m_image_ctx.exclusive_lock->is_lock_owner());
 
+  Context *ctx = create_context_callback<Context>(on_finish, this);
+
   object_map::ResizeRequest *req = new object_map::ResizeRequest(
     m_image_ctx, &m_lock, &m_object_map, m_snap_id, new_size,
-    default_object_state, on_finish);
+    default_object_state, ctx);
   req->send();
 }
 
index 0d4264887bc2b57fa05d983c62e1ec4bf2808c94..9cadb32910362ea9890e536b172b78f6e77e31f6 100644 (file)
@@ -10,6 +10,7 @@
 #include "include/rbd/object_map_types.h"
 #include "common/bit_vector.hpp"
 #include "common/RWLock.h"
+#include "common/RefCountedObj.h"
 #include "librbd/Utils.h"
 #include <boost/optional.hpp>
 
@@ -23,7 +24,7 @@ struct BlockGuardCell;
 class ImageCtx;
 
 template <typename ImageCtxT = ImageCtx>
-class ObjectMap {
+class ObjectMap : public RefCountedObject {
 public:
   static ObjectMap *create(ImageCtxT &image_ctx, uint64_t snap_id) {
     return new ObjectMap(image_ctx, snap_id);
index c83fe5c0f73c97592efa445119e0f0572eadc036..4334a4a37b9d4c9c2c9ad72c32fe27f8d742342b 100644 (file)
@@ -212,8 +212,9 @@ struct C_InvokeAsyncRequest : public Context {
 
     Context *ctx = util::create_async_context_callback(
       image_ctx, util::create_context_callback<
-        C_InvokeAsyncRequest<I>,
-        &C_InvokeAsyncRequest<I>::handle_acquire_exclusive_lock>(this));
+      C_InvokeAsyncRequest<I>,
+      &C_InvokeAsyncRequest<I>::handle_acquire_exclusive_lock>(
+        this, image_ctx.exclusive_lock));
 
     if (request_lock) {
       // current lock owner doesn't support op -- try to perform
index 7b41fab8e36fa6e5b13865ab5abce42e7968e150..c194a46814a71ae9a1746129aa8b2dfd9e8851c2 100644 (file)
@@ -156,7 +156,7 @@ void PostAcquireRequest<I>::send_allocate_journal_tag() {
   std::shared_lock image_locker{m_image_ctx.image_lock};
   using klass = PostAcquireRequest<I>;
   Context *ctx = create_context_callback<
-    klass, &klass::handle_allocate_journal_tag>(this);
+    klass, &klass::handle_allocate_journal_tag>(this, m_journal);
   m_image_ctx.get_journal_policy()->allocate_tag_on_lock(ctx);
 }
 
@@ -225,7 +225,7 @@ void PostAcquireRequest<I>::handle_open_object_map(int r) {
 
   if (r < 0) {
     lderr(cct) << "failed to open object map: " << cpp_strerror(r) << dendl;
-    delete m_object_map;
+    m_object_map->put();
     m_object_map = nullptr;
 
     if (r != -EFBIG) {
@@ -290,8 +290,12 @@ void PostAcquireRequest<I>::revert() {
   m_image_ctx.object_map = nullptr;
   m_image_ctx.journal = nullptr;
 
-  delete m_object_map;
-  delete m_journal;
+  if (m_object_map) {
+    m_object_map->put();
+  }
+  if (m_journal) {
+    m_journal->put();
+  }
 
   ceph_assert(m_error_result < 0);
 }
index 6632550f7e29a22934b7b48678cbfea039690551..fc833a1c80bcac398d7263735b71aa1d70bbcfd0 100644 (file)
@@ -240,7 +240,8 @@ void PreReleaseRequest<I>::handle_close_journal(int r) {
     lderr(cct) << "failed to close journal: " << cpp_strerror(r) << dendl;
   }
 
-  delete m_journal;
+  m_journal->put();
+  m_journal = nullptr;
 
   send_close_object_map();
 }
@@ -262,7 +263,7 @@ void PreReleaseRequest<I>::send_close_object_map() {
 
   using klass = PreReleaseRequest<I>;
   Context *ctx = create_context_callback<
-    klass, &klass::handle_close_object_map>(this);
+    klass, &klass::handle_close_object_map>(this, m_object_map);
   m_object_map->close(ctx);
 }
 
@@ -274,8 +275,8 @@ void PreReleaseRequest<I>::handle_close_object_map(int r) {
   if (r < 0) {
     lderr(cct) << "failed to close object map: " << cpp_strerror(r) << dendl;
   }
+  m_object_map->put();
 
-  delete m_object_map;
   send_unlock();
 }
 
index a92c96c4190c11ca526b0ae65ea3a69fe49a7726..feae4160e521015440965cbbc536bb60d1f9811f 100644 (file)
@@ -110,8 +110,8 @@ void CloseRequest<I>::send_shut_down_exclusive_lock() {
 
     // if reading a snapshot -- possible object map is open
     std::unique_lock image_locker{m_image_ctx->image_lock};
-    if (m_exclusive_lock == nullptr) {
-      delete m_image_ctx->object_map;
+    if (m_exclusive_lock == nullptr && m_image_ctx->object_map) {
+      m_image_ctx->object_map->put();
       m_image_ctx->object_map = nullptr;
     }
   }
@@ -145,7 +145,7 @@ void CloseRequest<I>::handle_shut_down_exclusive_lock(int r) {
     ceph_assert(m_image_ctx->object_map == nullptr);
   }
 
-  delete m_exclusive_lock;
+  m_exclusive_lock->put();
   m_exclusive_lock = nullptr;
 
   save_result(r);
index 7850d965b9e81ff9c7a353f11fc387e0e4c42d96..f67ca99fd0be1e280dd2b526ec9524db3e93410a 100644 (file)
@@ -68,10 +68,12 @@ void PreRemoveRequest<I>::acquire_exclusive_lock() {
     m_image_ctx->set_journal_policy(new journal::DisabledPolicy());
   }
 
+  m_exclusive_lock = m_image_ctx->exclusive_lock;
+
   auto ctx = create_context_callback<
-    PreRemoveRequest<I>, &PreRemoveRequest<I>::handle_exclusive_lock>(this);
+    PreRemoveRequest<I>, &PreRemoveRequest<I>::handle_exclusive_lock>(this, m_exclusive_lock);
 
-  m_image_ctx->exclusive_lock->try_acquire_lock(ctx);
+  m_exclusive_lock->try_acquire_lock(ctx);
 }
 
 template <typename I>
@@ -118,7 +120,7 @@ void PreRemoveRequest<I>::handle_shut_down_exclusive_lock(int r) {
   auto cct = m_image_ctx->cct;
   ldout(cct, 5) << "r=" << r << dendl;
 
-  delete m_exclusive_lock;
+  m_exclusive_lock->put();
   m_exclusive_lock = nullptr;
 
   if (r < 0) {
index 8f0400a1f47d45ada2db3192dc1d09f32b94616e..eaccf7f36fd7841fd18c1248570b4feb1300a772 100644 (file)
@@ -1043,7 +1043,7 @@ Context *RefreshRequest<I>::handle_v2_open_object_map(int *result) {
   if (*result < 0) {
     lderr(cct) << "failed to open object map: " << cpp_strerror(*result)
                << dendl;
-    delete m_object_map;
+    m_object_map->put();
     m_object_map = nullptr;
 
     if (*result != -EFBIG) {
@@ -1140,7 +1140,7 @@ Context *RefreshRequest<I>::handle_v2_shut_down_exclusive_lock(int *result) {
   }
 
   ceph_assert(m_exclusive_lock != nullptr);
-  delete m_exclusive_lock;
+  m_exclusive_lock->put();
   m_exclusive_lock = nullptr;
 
   return send_v2_close_journal();
@@ -1175,7 +1175,7 @@ Context *RefreshRequest<I>::handle_v2_close_journal(int *result) {
   }
 
   ceph_assert(m_journal != nullptr);
-  delete m_journal;
+  m_journal->put();
   m_journal = nullptr;
 
   ceph_assert(m_blocked_writes);
@@ -1213,7 +1213,8 @@ Context *RefreshRequest<I>::handle_v2_close_object_map(int *result) {
   }
 
   ceph_assert(m_object_map != nullptr);
-  delete m_object_map;
+
+  m_object_map->put();
   m_object_map = nullptr;
 
   return send_flush_aio();
index 43e7d7d67622b70a52aca6e05599711916eb3c6b..0c22ad91ad1124294db4c19c58fae8e2cc45a0e8 100644 (file)
@@ -32,8 +32,12 @@ template <typename I>
 SetSnapRequest<I>::~SetSnapRequest() {
   ceph_assert(!m_writes_blocked);
   delete m_refresh_parent;
-  delete m_object_map;
-  delete m_exclusive_lock;
+  if (m_object_map) {
+    m_object_map->put();
+  }
+  if (m_exclusive_lock) {
+    m_exclusive_lock->put();
+  }
 }
 
 template <typename I>
@@ -275,7 +279,7 @@ Context *SetSnapRequest<I>::handle_open_object_map(int *result) {
   if (*result < 0) {
     lderr(cct) << "failed to open object map: " << cpp_strerror(*result)
                << dendl;
-    delete m_object_map;
+    m_object_map->put();
     m_object_map = nullptr;
   }
 
index 2a7a0df94fa091d3b68773220eef61fed53a3996..845056743c16681b13237bd71794050c555d39ad 100644 (file)
@@ -23,6 +23,9 @@
                            << " " << __func__ << ": "
 
 namespace librbd {
+
+using util::create_context_callback;
+
 namespace io {
 
 namespace {
@@ -889,7 +892,11 @@ void *ImageRequestWQ<I>::_void_dequeue() {
       } else {
         // stall IO until the acquire completes
         ++m_io_blockers;
-        m_image_ctx.exclusive_lock->acquire_lock(new C_AcquireLock(this, item));
+        Context *ctx = new C_AcquireLock(this, item);
+        ctx = create_context_callback<
+          Context, &Context::complete>(
+            ctx, m_image_ctx.exclusive_lock);
+        m_image_ctx.exclusive_lock->acquire_lock(ctx);
       }
     } else {
       // raced with the exclusive lock being disabled
index fe7f28714431eda5c5eadcbd6394e70a7f133d3c..e4bdca007cac12a5a1c097a58487b24b6739f43e 100644 (file)
@@ -20,6 +20,7 @@ namespace librbd {
 namespace journal {
 
 using librbd::util::data_object_name;
+using util::create_context_callback;
 
 namespace {
 
@@ -95,6 +96,8 @@ bool ObjectDispatch<I>::discard(
   *on_finish = new C_CommitIOEvent<I>(m_image_ctx, m_journal, object_no,
                                       object_off, object_len, *journal_tid,
                                       *object_dispatch_flags, *on_finish);
+  *on_finish = create_context_callback<
+    Context, &Context::complete>(*on_finish, m_journal);
 
   *dispatch_result = io::DISPATCH_RESULT_CONTINUE;
   wait_or_flush_event(*journal_tid, *object_dispatch_flags, on_dispatched);
@@ -120,6 +123,8 @@ bool ObjectDispatch<I>::write(
   *on_finish = new C_CommitIOEvent<I>(m_image_ctx, m_journal, object_no,
                                       object_off, data.length(), *journal_tid,
                                       *object_dispatch_flags, *on_finish);
+  *on_finish = create_context_callback<
+    Context, &Context::complete>(*on_finish, m_journal);
 
   *dispatch_result = io::DISPATCH_RESULT_CONTINUE;
   wait_or_flush_event(*journal_tid, *object_dispatch_flags, on_dispatched);
@@ -146,6 +151,8 @@ bool ObjectDispatch<I>::write_same(
   *on_finish = new C_CommitIOEvent<I>(m_image_ctx, m_journal, object_no,
                                       object_off, object_len, *journal_tid,
                                       *object_dispatch_flags, *on_finish);
+  *on_finish = create_context_callback<
+    Context, &Context::complete>(*on_finish, m_journal);
 
   *dispatch_result = io::DISPATCH_RESULT_CONTINUE;
   wait_or_flush_event(*journal_tid, *object_dispatch_flags, on_dispatched);
@@ -174,6 +181,8 @@ bool ObjectDispatch<I>::compare_and_write(
                                       object_off, write_data.length(),
                                       *journal_tid, *object_dispatch_flags,
                                       *on_finish);
+  *on_finish = create_context_callback<
+    Context, &Context::complete>(*on_finish, m_journal);
 
   *dispatch_result = io::DISPATCH_RESULT_CONTINUE;
   wait_or_flush_event(*journal_tid, *object_dispatch_flags, on_dispatched);
@@ -214,14 +223,16 @@ void ObjectDispatch<I>::extent_overwritten(
   ldout(cct, 20) << object_no << " " << object_off << "~" << object_len
                  << dendl;
 
-  auto ctx = new C_CommitIOEvent<I>(m_image_ctx, m_journal, object_no,
-                                    object_off, object_len, journal_tid, false,
-                                    nullptr);
+  Context *ctx = new C_CommitIOEvent<I>(m_image_ctx, m_journal, object_no,
+                                        object_off, object_len, journal_tid, false,
+                                        nullptr);
   if (new_journal_tid != 0) {
     // ensure new journal event is safely committed to disk before
     // committing old event
     m_journal->flush_event(new_journal_tid, ctx);
   } else {
+    ctx = create_context_callback<
+      Context, &Context::complete>(ctx, m_journal);
     ctx->complete(0);
   }
 }
index cd406df7b01ca32afa1d81dc0d357314cea94dd8..1652efb653514f0283c9130d7bba60ed713e4e18 100644 (file)
@@ -178,6 +178,7 @@ Replay<I>::Replay(I &image_ctx)
 
 template <typename I>
 Replay<I>::~Replay() {
+  std::lock_guard locker{m_lock};
   ceph_assert(m_in_flight_aio_flush == 0);
   ceph_assert(m_in_flight_aio_modify == 0);
   ceph_assert(m_aio_modify_unsafe_contexts.empty());
index 0e194dbfb173fdc7dbc73dd8162615bf7c71125b..f075076621ef6554c6d084810097554364c9d2ec 100644 (file)
@@ -88,7 +88,8 @@ void DemoteRequest<I>::acquire_lock() {
   ldout(cct, 20) << dendl;
 
   auto ctx = create_context_callback<
-    DemoteRequest<I>, &DemoteRequest<I>::handle_acquire_lock>(this);
+    DemoteRequest<I>,
+    &DemoteRequest<I>::handle_acquire_lock>(this, m_image_ctx.exclusive_lock);
   m_image_ctx.exclusive_lock->acquire_lock(ctx);
   m_image_ctx.owner_lock.unlock_shared();
 }
@@ -154,7 +155,8 @@ void DemoteRequest<I>::release_lock() {
   }
 
   auto ctx = create_context_callback<
-    DemoteRequest<I>, &DemoteRequest<I>::handle_release_lock>(this);
+    DemoteRequest<I>,
+    &DemoteRequest<I>::handle_release_lock>(this, m_image_ctx.exclusive_lock);
   m_image_ctx.exclusive_lock->release_lock(ctx);
   m_image_ctx.owner_lock.unlock_shared();
 }
index 3dea085aff1abd934f40b92cf0f644897b847519..c46d37f05eb707e75dee2f0daa23131ceb35ae6b 100644 (file)
@@ -124,34 +124,33 @@ Context *DisableFeaturesRequest<I>::handle_block_writes(int *result) {
     }
   }
 
-  send_acquire_exclusive_lock();
-  return nullptr;
+  return send_acquire_exclusive_lock(result);
 }
 
 template <typename I>
-void DisableFeaturesRequest<I>::send_acquire_exclusive_lock() {
+Context *DisableFeaturesRequest<I>::send_acquire_exclusive_lock(int *result) {
   I &image_ctx = this->m_image_ctx;
   CephContext *cct = image_ctx.cct;
   ldout(cct, 20) << this << " " << __func__ << dendl;
 
-  Context *ctx = create_context_callback<
-    DisableFeaturesRequest<I>,
-    &DisableFeaturesRequest<I>::handle_acquire_exclusive_lock>(this);
-
   {
     std::unique_lock locker{image_ctx.owner_lock};
     // if disabling features w/ exclusive lock supported, we need to
     // acquire the lock to temporarily block IO against the image
     if (image_ctx.exclusive_lock != nullptr &&
-       !image_ctx.exclusive_lock->is_lock_owner()) {
+        !image_ctx.exclusive_lock->is_lock_owner()) {
       m_acquired_lock = true;
 
+      Context *ctx = create_context_callback<
+        DisableFeaturesRequest<I>,
+        &DisableFeaturesRequest<I>::handle_acquire_exclusive_lock>(
+          this, image_ctx.exclusive_lock);
       image_ctx.exclusive_lock->acquire_lock(ctx);
-      return;
+      return nullptr;
     }
   }
 
-  ctx->complete(0);
+  return handle_acquire_exclusive_lock(result);
 }
 
 template <typename I>
@@ -385,7 +384,7 @@ Context *DisableFeaturesRequest<I>::handle_close_journal(int *result) {
   }
 
   ceph_assert(m_journal != nullptr);
-  delete m_journal;
+  m_journal->put();
   m_journal = nullptr;
 
   send_remove_journal();
@@ -607,7 +606,8 @@ void DisableFeaturesRequest<I>::send_release_exclusive_lock() {
 
   Context *ctx = create_context_callback<
     DisableFeaturesRequest<I>,
-    &DisableFeaturesRequest<I>::handle_release_exclusive_lock>(this);
+    &DisableFeaturesRequest<I>::handle_release_exclusive_lock>(
+      this, image_ctx.exclusive_lock);
 
   image_ctx.exclusive_lock->release_lock(ctx);
 }
index 22c39e976424082557809be0af5a99d475ca4555..719a033990918c966d206916c746cd421ad50bfb 100644 (file)
@@ -124,7 +124,7 @@ private:
   void send_block_writes();
   Context *handle_block_writes(int *result);
 
-  void send_acquire_exclusive_lock();
+  Context *send_acquire_exclusive_lock(int *result);
   Context *handle_acquire_exclusive_lock(int *result);
 
   void send_get_mirror_mode();
index 1ee15015dab10a09c2af6e585001213007be49d6..5deb182e5602acc021e6eff1c422e7c51016b6ea 100644 (file)
@@ -24,6 +24,8 @@
 namespace librbd {
 namespace operation {
 
+using util::create_context_callback;
+
 template <typename I>
 void RebuildObjectMapRequest<I>::send() {
   send_resize_object_map();
index e718259b5fbc69902e46f467d3cd1173b4dd5bfb..5dd3f2573eb20d544c2d9f379987d47f9796e44f 100644 (file)
@@ -97,8 +97,14 @@ SnapshotRollbackRequest<I>::~SnapshotRollbackRequest() {
   if (m_blocking_writes) {
     image_ctx.io_work_queue->unblock_writes();
   }
-  delete m_object_map;
-  delete m_snap_object_map;
+  if (m_object_map) {
+    m_object_map->put();
+    m_object_map = nullptr;
+  }
+  if (m_snap_object_map) {
+    m_snap_object_map->put();
+    m_snap_object_map = nullptr;
+  }
 }
 
 template <typename I>
@@ -225,7 +231,7 @@ Context *SnapshotRollbackRequest<I>::handle_get_snap_object_map(int *result) {
   if (*result < 0) {
     lderr(cct) << this << " " << __func__ << ": failed to open object map: "
                << cpp_strerror(*result) << dendl;
-    delete m_snap_object_map;
+    m_snap_object_map->put();
     m_snap_object_map = nullptr;
   }
 
@@ -354,7 +360,7 @@ Context *SnapshotRollbackRequest<I>::handle_refresh_object_map(int *result) {
   if (*result < 0) {
     lderr(cct) << this << " " << __func__ << ": failed to open object map: "
                << cpp_strerror(*result) << dendl;
-    delete m_object_map;
+    m_object_map->put();
     m_object_map = nullptr;
     apply();
 
@@ -374,10 +380,18 @@ Context *SnapshotRollbackRequest<I>::send_invalidate_cache() {
   ldout(cct, 5) << this << " " << __func__ << dendl;
 
   std::shared_lock owner_lock{image_ctx.owner_lock};
-  Context *ctx = create_context_callback<
-    SnapshotRollbackRequest<I>,
-    &SnapshotRollbackRequest<I>::handle_invalidate_cache>(this);
-  image_ctx.io_object_dispatcher->invalidate_cache(ctx);
+  if(m_object_map != nullptr) {
+    Context *ctx = create_context_callback<
+      SnapshotRollbackRequest<I>,
+      &SnapshotRollbackRequest<I>::handle_invalidate_cache>(this, m_object_map);
+    image_ctx.io_object_dispatcher->invalidate_cache(ctx);
+  }
+  else {
+    Context *ctx = create_context_callback<
+      SnapshotRollbackRequest<I>,
+      &SnapshotRollbackRequest<I>::handle_invalidate_cache>(this);
+    image_ctx.io_object_dispatcher->invalidate_cache(ctx);
+  }
   return nullptr;
 }