From: Mahati Chamarthy Date: Mon, 12 Feb 2018 03:28:30 +0000 (-0500) Subject: rbd: reference count objects when invoking async requests X-Git-Tag: v15.1.0~867^2~3 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=90b4f29b0241ee2f650f1bdd622fb0042134a3ec;p=ceph.git rbd: reference count objects when invoking async requests 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 Signed-off-by: Venky Shankar --- diff --git a/src/librbd/DeepCopyRequest.cc b/src/librbd/DeepCopyRequest.cc index fee8b0274f1..a8955a769b5 100644 --- a/src/librbd/DeepCopyRequest.cc +++ b/src/librbd/DeepCopyRequest.cc @@ -294,7 +294,7 @@ void DeepCopyRequest::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(); } diff --git a/src/librbd/ExclusiveLock.cc b/src/librbd/ExclusiveLock.cc index 48e6a3243b8..1250c733d67 100644 --- a/src/librbd/ExclusiveLock.cc +++ b/src/librbd/ExclusiveLock.cc @@ -21,13 +21,15 @@ namespace librbd { using namespace exclusive_lock; +using librbd::util::create_context_callback; template using ML = ManagedLock; template ExclusiveLock::ExclusiveLock(I &image_ctx) - : ML(image_ctx.md_ctx, image_ctx.op_work_queue, image_ctx.header_oid, + : RefCountedObject(image_ctx.cct), + ML(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("rbd_blacklist_on_break_lock"), image_ctx.config.template get_val("rbd_blacklist_expire_seconds")), @@ -105,6 +107,9 @@ int ExclusiveLock::get_unlocked_op_error() const { template void ExclusiveLock::init(uint64_t features, Context *on_init) { ceph_assert(ceph_mutex_is_locked(m_image_ctx.owner_lock)); + + on_init = create_context_callback(on_init, this); + ldout(m_image_ctx.cct, 10) << dendl; { @@ -120,6 +125,8 @@ template void ExclusiveLock::shut_down(Context *on_shut_down) { ldout(m_image_ctx.cct, 10) << dendl; + on_shut_down = create_context_callback(on_shut_down, this); + ML::shut_down(on_shut_down); // if stalled in request state machine -- abort diff --git a/src/librbd/ExclusiveLock.h b/src/librbd/ExclusiveLock.h index 55a21077828..a77ea817a48 100644 --- a/src/librbd/ExclusiveLock.h +++ b/src/librbd/ExclusiveLock.h @@ -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 -class ExclusiveLock : public ManagedLock { +class ExclusiveLock : public RefCountedObject, + public ManagedLock { public: static ExclusiveLock *create(ImageCtxT &image_ctx) { return new ExclusiveLock(image_ctx); diff --git a/src/librbd/Journal.cc b/src/librbd/Journal.cc index f7d0cec8352..66849c461fa 100644 --- a/src/librbd/Journal.cc +++ b/src/librbd/Journal.cc @@ -326,7 +326,8 @@ std::ostream &operator<<(std::ostream &os, template Journal::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::open(Context *on_finish) { CephContext *cct = m_image_ctx.cct; ldout(cct, 20) << this << " " << __func__ << dendl; + on_finish = create_context_callback(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::close(Context *on_finish) { CephContext *cct = m_image_ctx.cct; ldout(cct, 20) << this << " " << __func__ << dendl; + on_finish = create_context_callback(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::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(on_safe, this); + Future future; { std::lock_guard event_locker{m_event_lock}; @@ -975,6 +982,8 @@ void Journal::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(on_safe, this); + std::lock_guard event_locker{m_event_lock}; wait_event(m_lock, tid, on_safe); } diff --git a/src/librbd/Journal.h b/src/librbd/Journal.h index bdd18f99d21..1554fed7905 100644 --- a/src/librbd/Journal.h +++ b/src/librbd/Journal.h @@ -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 class Replay; } template -class Journal { +class Journal : public RefCountedObject { public: /** * @verbatim diff --git a/src/librbd/ObjectMap.cc b/src/librbd/ObjectMap.cc index fb09e3d989a..0d60cc95f94 100644 --- a/src/librbd/ObjectMap.cc +++ b/src/librbd/ObjectMap.cc @@ -32,9 +32,12 @@ namespace librbd { +using librbd::util::create_context_callback; + template ObjectMap::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::update_required(const ceph::BitVector<2>::Iterator& it, template void ObjectMap::open(Context *on_finish) { + Context *ctx = create_context_callback(on_finish, this); + auto req = object_map::RefreshRequest::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 void ObjectMap::close(Context *on_finish) { + Context *ctx = create_context_callback(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::create(m_image_ctx, on_finish); + auto req = object_map::UnlockRequest::create(m_image_ctx, ctx); req->send(); } @@ -176,8 +183,10 @@ void ObjectMap::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(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::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(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::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(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::aio_save(Context *on_finish) { } cls_client::object_map_save(&op, m_object_map); + Context *ctx = create_context_callback(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::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(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(); } diff --git a/src/librbd/ObjectMap.h b/src/librbd/ObjectMap.h index 0d4264887bc..9cadb329103 100644 --- a/src/librbd/ObjectMap.h +++ b/src/librbd/ObjectMap.h @@ -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 @@ -23,7 +24,7 @@ struct BlockGuardCell; class ImageCtx; template -class ObjectMap { +class ObjectMap : public RefCountedObject { public: static ObjectMap *create(ImageCtxT &image_ctx, uint64_t snap_id) { return new ObjectMap(image_ctx, snap_id); diff --git a/src/librbd/Operations.cc b/src/librbd/Operations.cc index c83fe5c0f73..4334a4a37b9 100644 --- a/src/librbd/Operations.cc +++ b/src/librbd/Operations.cc @@ -212,8 +212,9 @@ struct C_InvokeAsyncRequest : public Context { Context *ctx = util::create_async_context_callback( image_ctx, util::create_context_callback< - C_InvokeAsyncRequest, - &C_InvokeAsyncRequest::handle_acquire_exclusive_lock>(this)); + C_InvokeAsyncRequest, + &C_InvokeAsyncRequest::handle_acquire_exclusive_lock>( + this, image_ctx.exclusive_lock)); if (request_lock) { // current lock owner doesn't support op -- try to perform diff --git a/src/librbd/exclusive_lock/PostAcquireRequest.cc b/src/librbd/exclusive_lock/PostAcquireRequest.cc index 7b41fab8e36..c194a46814a 100644 --- a/src/librbd/exclusive_lock/PostAcquireRequest.cc +++ b/src/librbd/exclusive_lock/PostAcquireRequest.cc @@ -156,7 +156,7 @@ void PostAcquireRequest::send_allocate_journal_tag() { std::shared_lock image_locker{m_image_ctx.image_lock}; using klass = PostAcquireRequest; 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::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::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); } diff --git a/src/librbd/exclusive_lock/PreReleaseRequest.cc b/src/librbd/exclusive_lock/PreReleaseRequest.cc index 6632550f7e2..fc833a1c80b 100644 --- a/src/librbd/exclusive_lock/PreReleaseRequest.cc +++ b/src/librbd/exclusive_lock/PreReleaseRequest.cc @@ -240,7 +240,8 @@ void PreReleaseRequest::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::send_close_object_map() { using klass = PreReleaseRequest; 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::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(); } diff --git a/src/librbd/image/CloseRequest.cc b/src/librbd/image/CloseRequest.cc index a92c96c4190..feae4160e52 100644 --- a/src/librbd/image/CloseRequest.cc +++ b/src/librbd/image/CloseRequest.cc @@ -110,8 +110,8 @@ void CloseRequest::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::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); diff --git a/src/librbd/image/PreRemoveRequest.cc b/src/librbd/image/PreRemoveRequest.cc index 7850d965b9e..f67ca99fd0b 100644 --- a/src/librbd/image/PreRemoveRequest.cc +++ b/src/librbd/image/PreRemoveRequest.cc @@ -68,10 +68,12 @@ void PreRemoveRequest::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, &PreRemoveRequest::handle_exclusive_lock>(this); + PreRemoveRequest, &PreRemoveRequest::handle_exclusive_lock>(this, m_exclusive_lock); - m_image_ctx->exclusive_lock->try_acquire_lock(ctx); + m_exclusive_lock->try_acquire_lock(ctx); } template @@ -118,7 +120,7 @@ void PreRemoveRequest::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) { diff --git a/src/librbd/image/RefreshRequest.cc b/src/librbd/image/RefreshRequest.cc index 8f0400a1f47..eaccf7f36fd 100644 --- a/src/librbd/image/RefreshRequest.cc +++ b/src/librbd/image/RefreshRequest.cc @@ -1043,7 +1043,7 @@ Context *RefreshRequest::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::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::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::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(); diff --git a/src/librbd/image/SetSnapRequest.cc b/src/librbd/image/SetSnapRequest.cc index 43e7d7d6762..0c22ad91ad1 100644 --- a/src/librbd/image/SetSnapRequest.cc +++ b/src/librbd/image/SetSnapRequest.cc @@ -32,8 +32,12 @@ template SetSnapRequest::~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 @@ -275,7 +279,7 @@ Context *SetSnapRequest::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; } diff --git a/src/librbd/io/ImageRequestWQ.cc b/src/librbd/io/ImageRequestWQ.cc index 2a7a0df94fa..845056743c1 100644 --- a/src/librbd/io/ImageRequestWQ.cc +++ b/src/librbd/io/ImageRequestWQ.cc @@ -23,6 +23,9 @@ << " " << __func__ << ": " namespace librbd { + +using util::create_context_callback; + namespace io { namespace { @@ -889,7 +892,11 @@ void *ImageRequestWQ::_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 diff --git a/src/librbd/journal/ObjectDispatch.cc b/src/librbd/journal/ObjectDispatch.cc index fe7f2871443..e4bdca007ca 100644 --- a/src/librbd/journal/ObjectDispatch.cc +++ b/src/librbd/journal/ObjectDispatch.cc @@ -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::discard( *on_finish = new C_CommitIOEvent(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::write( *on_finish = new C_CommitIOEvent(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::write_same( *on_finish = new C_CommitIOEvent(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::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::extent_overwritten( ldout(cct, 20) << object_no << " " << object_off << "~" << object_len << dendl; - auto ctx = new C_CommitIOEvent(m_image_ctx, m_journal, object_no, - object_off, object_len, journal_tid, false, - nullptr); + Context *ctx = new C_CommitIOEvent(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); } } diff --git a/src/librbd/journal/Replay.cc b/src/librbd/journal/Replay.cc index cd406df7b01..1652efb6535 100644 --- a/src/librbd/journal/Replay.cc +++ b/src/librbd/journal/Replay.cc @@ -178,6 +178,7 @@ Replay::Replay(I &image_ctx) template Replay::~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()); diff --git a/src/librbd/mirror/DemoteRequest.cc b/src/librbd/mirror/DemoteRequest.cc index 0e194dbfb17..f075076621e 100644 --- a/src/librbd/mirror/DemoteRequest.cc +++ b/src/librbd/mirror/DemoteRequest.cc @@ -88,7 +88,8 @@ void DemoteRequest::acquire_lock() { ldout(cct, 20) << dendl; auto ctx = create_context_callback< - DemoteRequest, &DemoteRequest::handle_acquire_lock>(this); + DemoteRequest, + &DemoteRequest::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::release_lock() { } auto ctx = create_context_callback< - DemoteRequest, &DemoteRequest::handle_release_lock>(this); + DemoteRequest, + &DemoteRequest::handle_release_lock>(this, m_image_ctx.exclusive_lock); m_image_ctx.exclusive_lock->release_lock(ctx); m_image_ctx.owner_lock.unlock_shared(); } diff --git a/src/librbd/operation/DisableFeaturesRequest.cc b/src/librbd/operation/DisableFeaturesRequest.cc index 3dea085aff1..c46d37f05eb 100644 --- a/src/librbd/operation/DisableFeaturesRequest.cc +++ b/src/librbd/operation/DisableFeaturesRequest.cc @@ -124,34 +124,33 @@ Context *DisableFeaturesRequest::handle_block_writes(int *result) { } } - send_acquire_exclusive_lock(); - return nullptr; + return send_acquire_exclusive_lock(result); } template -void DisableFeaturesRequest::send_acquire_exclusive_lock() { +Context *DisableFeaturesRequest::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, - &DisableFeaturesRequest::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, + &DisableFeaturesRequest::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 @@ -385,7 +384,7 @@ Context *DisableFeaturesRequest::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::send_release_exclusive_lock() { Context *ctx = create_context_callback< DisableFeaturesRequest, - &DisableFeaturesRequest::handle_release_exclusive_lock>(this); + &DisableFeaturesRequest::handle_release_exclusive_lock>( + this, image_ctx.exclusive_lock); image_ctx.exclusive_lock->release_lock(ctx); } diff --git a/src/librbd/operation/DisableFeaturesRequest.h b/src/librbd/operation/DisableFeaturesRequest.h index 22c39e97642..719a0339909 100644 --- a/src/librbd/operation/DisableFeaturesRequest.h +++ b/src/librbd/operation/DisableFeaturesRequest.h @@ -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(); diff --git a/src/librbd/operation/RebuildObjectMapRequest.cc b/src/librbd/operation/RebuildObjectMapRequest.cc index 1ee15015dab..5deb182e560 100644 --- a/src/librbd/operation/RebuildObjectMapRequest.cc +++ b/src/librbd/operation/RebuildObjectMapRequest.cc @@ -24,6 +24,8 @@ namespace librbd { namespace operation { +using util::create_context_callback; + template void RebuildObjectMapRequest::send() { send_resize_object_map(); diff --git a/src/librbd/operation/SnapshotRollbackRequest.cc b/src/librbd/operation/SnapshotRollbackRequest.cc index e718259b5fb..5dd3f2573eb 100644 --- a/src/librbd/operation/SnapshotRollbackRequest.cc +++ b/src/librbd/operation/SnapshotRollbackRequest.cc @@ -97,8 +97,14 @@ SnapshotRollbackRequest::~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 @@ -225,7 +231,7 @@ Context *SnapshotRollbackRequest::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::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::send_invalidate_cache() { ldout(cct, 5) << this << " " << __func__ << dendl; std::shared_lock owner_lock{image_ctx.owner_lock}; - Context *ctx = create_context_callback< - SnapshotRollbackRequest, - &SnapshotRollbackRequest::handle_invalidate_cache>(this); - image_ctx.io_object_dispatcher->invalidate_cache(ctx); + if(m_object_map != nullptr) { + Context *ctx = create_context_callback< + SnapshotRollbackRequest, + &SnapshotRollbackRequest::handle_invalidate_cache>(this, m_object_map); + image_ctx.io_object_dispatcher->invalidate_cache(ctx); + } + else { + Context *ctx = create_context_callback< + SnapshotRollbackRequest, + &SnapshotRollbackRequest::handle_invalidate_cache>(this); + image_ctx.io_object_dispatcher->invalidate_cache(ctx); + } return nullptr; }