bool ExclusiveLock<I>::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 <typename I>
+void ExclusiveLock<I>::block_requests() {
+ Mutex::Locker locker(m_lock);
+ ++m_request_blockers;
+
+ ldout(m_image_ctx.cct, 20) << this << " " << __func__ << "="
+ << m_request_blockers << dendl;
+}
+
+template <typename I>
+void ExclusiveLock<I>::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 <typename I>
void ExclusiveLock<I>::init(uint64_t features, Context *on_init) {
assert(m_image_ctx.owner_lock.is_locked());
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);
ActionsContexts m_actions_contexts;
+ uint32_t m_request_blockers = 0;
+
std::string encode_lock_cookie() const;
bool is_transition_state() const;
}
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;
}
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) {