]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commit
librbd: fix ExclusiveLock::accept_request() when !is_state_locked() 66627/head
authorIlya Dryomov <idryomov@gmail.com>
Tue, 9 Dec 2025 14:22:02 +0000 (15:22 +0100)
committerIlya Dryomov <idryomov@gmail.com>
Sun, 14 Dec 2025 21:04:01 +0000 (22:04 +0100)
commitbf83e6b049950d6288e7f470233e6de1c1c909b6
tree7d8d69f8335354b25f22e53d1cfdcbbb19c7ba7e
parent0b89d978463f7fd74185659a4376bf2c9634e908
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>
(cherry picked from commit e4855895a9f14a07fda03fbc736f596b87f92327)
src/librbd/ExclusiveLock.cc
src/test/librbd/test_mock_ExclusiveLock.cc