]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commit
librbd: fix ExclusiveLock::accept_request() when !is_state_locked() 66581/head
authorIlya Dryomov <idryomov@gmail.com>
Tue, 9 Dec 2025 14:22:02 +0000 (15:22 +0100)
committerIlya Dryomov <idryomov@gmail.com>
Tue, 9 Dec 2025 21:23:41 +0000 (22:23 +0100)
commite4855895a9f14a07fda03fbc736f596b87f92327
tree56bb8d0b7998698ac90af95e393c5ffb7f435d3e
parent3327001c8f65aebf9eb08fe5d28c8e344f338d4d
librbd: fix ExclusiveLock::accept_request() when !is_state_locked()

To accept an async request, two conditions must be met: a) exclusive
lock must be a firm STATE_LOCKED state and b) async requests shouldn't
be blocked or if they are blocked there should be an exception in place
for a given request_type.  If a) is met but b) isn't, ret_val is set
to m_request_blocked_ret_val, as expected -- the reason for denying
the request is that async requests are blocked.  However, if a) isn't
met, ret_val also gets set to m_request_blocked_ret_val.  This is wrong
because the reason for denying the request in this case isn't that
async requests are blocked (they may or may not be) but a much heavier
circumstance of exclusive lock being in a transient state or not held
at all.

In such scenarios, whether async requests are blocked or not isn't
relevant and ExclusiveLock::accept_request() behaving otherwise can
lead to bogus "duplicate lock owners detected" errors getting raised
during an attempt to handle any maintenance operation notification in
ImageWatcher::handle_operation_request().  This error isn't considered
retryable so the entire operation that needed the exclusive lock would
be spuriously failed with EINVAL.

Fixes: https://tracker.ceph.com/issues/74168
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
src/librbd/ExclusiveLock.cc
src/test/librbd/test_mock_ExclusiveLock.cc