From: Jason Dillaman Date: Fri, 26 May 2017 18:06:35 +0000 (-0400) Subject: rbd-mirror: permit release of exclusive lock if promoted X-Git-Tag: ses5-milestone6~8^2~5^2~6 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=62cce4738a751f1280986bd34f51512045624643;p=ceph.git rbd-mirror: permit release of exclusive lock if promoted Signed-off-by: Jason Dillaman --- diff --git a/src/tools/rbd_mirror/image_replayer/OpenLocalImageRequest.cc b/src/tools/rbd_mirror/image_replayer/OpenLocalImageRequest.cc index 2d7b8d125040..a54216a8328c 100644 --- a/src/tools/rbd_mirror/image_replayer/OpenLocalImageRequest.cc +++ b/src/tools/rbd_mirror/image_replayer/OpenLocalImageRequest.cc @@ -30,17 +30,33 @@ using librbd::util::create_context_callback; namespace { +template struct MirrorExclusiveLockPolicy : public librbd::exclusive_lock::Policy { + I *image_ctx; + + MirrorExclusiveLockPolicy(I *image_ctx) : image_ctx(image_ctx) { + } bool may_auto_request_lock() override { return false; } int lock_requested(bool force) override { - // TODO: interlock is being requested (e.g. local promotion) - // Wait for demote event from peer or abort replay on forced - // promotion. - return -EROFS; + int r = -EROFS; + { + RWLock::RLocker owner_locker(image_ctx->owner_lock); + RWLock::RLocker snap_locker(image_ctx->snap_lock); + if (image_ctx->journal == nullptr || image_ctx->journal->is_tag_owner()) { + r = 0; + } + } + + if (r == 0) { + // if the local image journal has been closed or if it was (force) + // promoted allow the lock to be released to another client + image_ctx->exclusive_lock->release_lock(nullptr); + } + return r; } }; @@ -93,7 +109,7 @@ void OpenLocalImageRequest::send_open_image() { RWLock::WLocker owner_locker((*m_local_image_ctx)->owner_lock); RWLock::WLocker snap_locker((*m_local_image_ctx)->snap_lock); (*m_local_image_ctx)->set_exclusive_lock_policy( - new MirrorExclusiveLockPolicy()); + new MirrorExclusiveLockPolicy(*m_local_image_ctx)); (*m_local_image_ctx)->set_journal_policy( new MirrorJournalPolicy(m_work_queue)); }