From e66db76354093009c254aabce9e4654e27045375 Mon Sep 17 00:00:00 2001 From: Ramana Raja Date: Mon, 14 Aug 2023 11:27:13 -0400 Subject: [PATCH] librbd/ImageWatcher: kick-start ExclusiveLock state machine MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit ... that is stalled on waiting for lock and let it detect client blocklisting. This would propagate the blocklist error to the caller requesting an operation needing an exclusive lock. When a caller requests a librbd operation that requires an exclusive lock, the librbd client checks whether the exclusive lock is held by another client. If the lock is held by another client, librbd stalls its ExclusiveLock state machine and through its ImageWatcher notifies the lock owner that it wants the exclusive lock. After receiving the response from the lock owner, the ImageWatcher schedules another lock request. Meanwhile if the client gets blocklisted, the ImageWatcher fails to schedule another lock request and returns. The ExclusiveLock state machine remains stalled and the blocklist error is not propagated to the caller. Instead, when scheduling another lock request, make the ImageWatcher call the ExclusiveLock state machine's peer notification handler if the client is blocklisted. This allows the Exclusive lock state machine to detect that the client has been blocklisted in its send_acquire_lock() member function and propagate the blocklist error to the caller. Fixes: https://tracker.ceph.com/issues/61607 Signed-off-by: Ramana Raja --- src/librbd/ImageWatcher.cc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/librbd/ImageWatcher.cc b/src/librbd/ImageWatcher.cc index f3405102fda..a3d565520e8 100644 --- a/src/librbd/ImageWatcher.cc +++ b/src/librbd/ImageWatcher.cc @@ -576,8 +576,7 @@ void ImageWatcher::schedule_request_lock(bool use_timer, int timer_delay) { return; } - std::shared_lock watch_locker{this->m_watch_lock}; - if (this->is_registered(this->m_watch_lock)) { + if (is_registered()) { ldout(m_image_ctx.cct, 15) << this << " requesting exclusive lock" << dendl; auto ctx = new LambdaContext([this](int r) { @@ -595,6 +594,10 @@ void ImageWatcher::schedule_request_lock(bool use_timer, int timer_delay) { } else { m_task_finisher->queue(TASK_CODE_REQUEST_LOCK, ctx); } + } else if (is_blocklisted()) { + lderr(m_image_ctx.cct) << this << " blocklisted waiting for exclusive lock" + << dendl; + m_image_ctx.exclusive_lock->handle_peer_notification(0); } } -- 2.39.5