From: Mykola Golub Date: Thu, 19 Nov 2020 10:31:10 +0000 (+0000) Subject: librbd: make sure we are not loosing exclusive lock X-Git-Tag: v16.1.0~434^2~1 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=8b08c7bad67cc61ffc1adab73c4573ee7674b39b;p=ceph.git librbd: make sure we are not loosing exclusive lock when starting a serialized maintenance operation Signed-off-by: Mykola Golub --- diff --git a/src/librbd/Operations.cc b/src/librbd/Operations.cc index eb19175b12d2..27a54cf2fa31 100644 --- a/src/librbd/Operations.cc +++ b/src/librbd/Operations.cc @@ -415,22 +415,31 @@ void Operations::start_op(Operation op, Context *ctx) { CephContext *cct = m_image_ctx.cct; ldout(cct, 20) << __func__ << ": " << op << " " << ctx << dendl; + ceph_assert(ceph_mutex_is_locked(m_image_ctx.owner_lock)); + bool requires_lock = m_image_ctx.exclusive_lock != nullptr; + ctx = util::create_async_context_callback( m_image_ctx, new LambdaContext( - [this, op, ctx](int r) { - if (r == 0) { + [this, op, requires_lock, ctx](int r) { + Context *finish_op_ctx = nullptr; + if (requires_lock && r == 0) { std::shared_lock owner_locker{m_image_ctx.owner_lock}; std::shared_lock image_locker{m_image_ctx.image_lock}; + auto exclusive_lock = m_image_ctx.exclusive_lock; - if (m_image_ctx.exclusive_lock != nullptr && - (!m_image_ctx.exclusive_lock->is_lock_owner())) { - ldout(m_image_ctx.cct, 20) << "lock owner lost, restarting" << dendl; + if (exclusive_lock == nullptr || + (finish_op_ctx = exclusive_lock->start_op(&r)) == nullptr) { + ldout(m_image_ctx.cct, 20) << "lock owner lost, restarting" + << dendl; r = -ERESTART; } } ldout(m_image_ctx.cct, 20) << "start " << op << " " << ctx << dendl; ctx->complete(r); + if (finish_op_ctx != nullptr) { + finish_op_ctx->complete(0); + } })); std::unique_lock locker{m_queue_lock};