FAILED: patch "[PATCH] rbd: don't assume RBD_LOCK_STATE_LOCKED for exclusive" failed to apply to 6.6-stable tree
Subsystems (3)
[email protected]
maintainerThe patch below does not apply to the 6.6-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.6.y
git checkout FETCH_HEAD
git cherry-pick -x 2237ceb71f89837ac47c5dce2aaa2c2b3a337a3c
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2024073022-profound-unsigned-6302@gregkh' --subject-prefix 'PATCH 6.6.y' HEAD^..
Possible dependencies:
2237ceb71f89 ("rbd: don't assume RBD_LOCK_STATE_LOCKED for exclusive mappings") ded080c86b3f ("rbd: don't move requests to the running list on errors")
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 2237ceb71f89837ac47c5dce2aaa2c2b3a337a3c Mon Sep 17 00:00:00 2001
From: Ilya Dryomov <[email protected]>
Date: Tue, 23 Jul 2024 18:07:59 +0200
Subject: [PATCH] rbd: don't assume RBD_LOCK_STATE_LOCKED for exclusive
mappings
Every time a watch is reestablished after getting lost, we need to update the cookie which involves quiescing exclusive lock. For this, we transition from RBD_LOCK_STATE_LOCKED to RBD_LOCK_STATE_QUIESCING roughly for the duration of rbd_reacquire_lock() call. If the mapping is exclusive and I/O happens to arrive in this time window, it's failed with EROFS (later translated to EIO) based on the wrong assumption in rbd_img_exclusive_lock() -- "lock got released?" check there stopped making sense with commit a2b1da09793d ("rbd: lock should be quiesced on reacquire").
To make it worse, any such I/O is added to the acquiring list before EROFS is returned and this sets up for violating rbd_lock_del_request() precondition that the request is either on the running list or not on any list at all -- see commit ded080c86b3f ("rbd: don't move requests to the running list on errors"). rbd_lock_del_request() ends up processing these requests as if they were on the running list which screws up quiescing_wait completion counter and ultimately leads to
rbd_assert(!completion_done(&rbd_dev->quiescing_wait));
being triggered on the next watch error.
drivers/block/rbd.c +5 -5
@@ -3457,6 +3457,7 @@ static void rbd_lock_del_request(struct rbd_img_request *img_req)lockdep_assert_held (&rbd_dev->lock_rwsem);spin_lock (&rbd_dev->lock_lists_lock);if (!list_empty (&img_req->lock_item)) { +rbd_assert (!list_empty (&rbd_dev->running_list));list_del_init (&img_req->lock_item); need_wakeup = (rbd_dev->lock_state ==RBD_LOCK_STATE_QUIESCING &&list_empty (&rbd_dev->running_list));
@@ -3476,11 +3477,6 @@ static int rbd_img_exclusive_lock(struct rbd_img_request *img_req)if (rbd_lock_add_request (img_req))return 1 ; -if (rbd_dev->opts->exclusive) { -WARN_ON (1 );/* lock got released? */ -return -EROFS ; - } -/* * Note the use of mod_delayed_work() in rbd_acquire_lock() * and cancel_delayed_work() in wake_lock_waiters().
@@ -4601,6 +4597,10 @@ static void rbd_reacquire_lock(struct rbd_device *rbd_dev)rbd_warn (rbd_dev,"failed to update lock cookie: %d" , ret); +if (rbd_dev->opts->exclusive) +rbd_warn (rbd_dev, +"temporarily releasing lock on exclusive mapping" ); +/* * Lock cookie cannot be updated on older OSDs, so do * a manual release and queue an acquire.