From db7aaff0f6d7a57e2b36d22b609f915f9b2b3893 Mon Sep 17 00:00:00 2001 From: Jason Dillaman Date: Thu, 28 Apr 2016 12:48:59 -0400 Subject: [PATCH] librbd: block RPC requests while updating features Disabling the journal and object map require acquiring the exclusive lock locally. We don't want to start executing long-running ops for this quick process. Signed-off-by: Jason Dillaman --- src/librbd/ExclusiveLock.cc | 22 +++++++++++++++++++++- src/librbd/ExclusiveLock.h | 5 +++++ src/librbd/internal.cc | 17 +++++++++++++++-- 3 files changed, 41 insertions(+), 3 deletions(-) diff --git a/src/librbd/ExclusiveLock.cc b/src/librbd/ExclusiveLock.cc index 01043e5dcfca6..932fe042d3e79 100644 --- a/src/librbd/ExclusiveLock.cc +++ b/src/librbd/ExclusiveLock.cc @@ -78,12 +78,32 @@ template bool ExclusiveLock::accept_requests() const { Mutex::Locker locker(m_lock); - bool accept_requests = (!is_shutdown() && m_state == STATE_LOCKED); + bool accept_requests = (!is_shutdown() && m_state == STATE_LOCKED && + m_request_blockers == 0); ldout(m_image_ctx.cct, 20) << this << " " << __func__ << "=" << accept_requests << dendl; return accept_requests; } +template +void ExclusiveLock::block_requests() { + Mutex::Locker locker(m_lock); + ++m_request_blockers; + + ldout(m_image_ctx.cct, 20) << this << " " << __func__ << "=" + << m_request_blockers << dendl; +} + +template +void ExclusiveLock::unblock_requests() { + Mutex::Locker locker(m_lock); + assert(m_request_blockers > 0); + --m_request_blockers; + + ldout(m_image_ctx.cct, 20) << this << " " << __func__ << "=" + << m_request_blockers << dendl; +} + template void ExclusiveLock::init(uint64_t features, Context *on_init) { assert(m_image_ctx.owner_lock.is_locked()); diff --git a/src/librbd/ExclusiveLock.h b/src/librbd/ExclusiveLock.h index e2e14160a9caf..6268c8080be11 100644 --- a/src/librbd/ExclusiveLock.h +++ b/src/librbd/ExclusiveLock.h @@ -32,6 +32,9 @@ public: bool is_lock_owner() const; bool accept_requests() const; + void block_requests(); + void unblock_requests(); + void init(uint64_t features, Context *on_init); void shut_down(Context *on_shutdown); @@ -127,6 +130,8 @@ private: ActionsContexts m_actions_contexts; + uint32_t m_request_blockers = 0; + std::string encode_lock_cookie() const; bool is_transition_state() const; diff --git a/src/librbd/internal.cc b/src/librbd/internal.cc index 3ac77935baffe..81328f970e6cd 100644 --- a/src/librbd/internal.cc +++ b/src/librbd/internal.cc @@ -1590,8 +1590,10 @@ remove_mirroring_image: } RWLock::RLocker owner_locker(ictx->owner_lock); - RWLock::WLocker md_locker(ictx->md_lock); - r = ictx->flush(); + r = ictx->aio_work_queue->block_writes(); + BOOST_SCOPE_EXIT_ALL( (ictx) ) { + ictx->aio_work_queue->unblock_writes(); + }; if (r < 0) { return r; } @@ -1607,6 +1609,17 @@ remove_mirroring_image: return -EINVAL; } + // avoid accepting new requests from peers while we manipulate + // the image features + if (ictx->exclusive_lock != nullptr) { + ictx->exclusive_lock->block_requests(); + } + BOOST_SCOPE_EXIT_ALL( (ictx) ) { + if (ictx->exclusive_lock != nullptr) { + ictx->exclusive_lock->unblock_requests(); + } + }; + // if disabling features w/ exclusive lock supported, we need to // acquire the lock to temporarily block IO against the image if (ictx->exclusive_lock != nullptr && !enabled) { -- 2.39.5