From ba41e491b9fd203e9241080afa3d4b19bdffa138 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 30 Jul 2024 12:59:17 +0200 Subject: [PATCH] 5.15-stable patches added patches: rbd-don-t-assume-rbd_lock_state_locked-for-exclusive-mappings.patch rbd-rename-rbd_lock_state_releasing-and-releasing_wait.patch --- ..._state_locked-for-exclusive-mappings.patch | 74 ++++++++++++++ ...k_state_releasing-and-releasing_wait.patch | 98 +++++++++++++++++++ queue-5.15/series | 2 + 3 files changed, 174 insertions(+) create mode 100644 queue-5.15/rbd-don-t-assume-rbd_lock_state_locked-for-exclusive-mappings.patch create mode 100644 queue-5.15/rbd-rename-rbd_lock_state_releasing-and-releasing_wait.patch diff --git a/queue-5.15/rbd-don-t-assume-rbd_lock_state_locked-for-exclusive-mappings.patch b/queue-5.15/rbd-don-t-assume-rbd_lock_state_locked-for-exclusive-mappings.patch new file mode 100644 index 00000000000..1ab7eb7335c --- /dev/null +++ b/queue-5.15/rbd-don-t-assume-rbd_lock_state_locked-for-exclusive-mappings.patch @@ -0,0 +1,74 @@ +From 2237ceb71f89837ac47c5dce2aaa2c2b3a337a3c Mon Sep 17 00:00:00 2001 +From: Ilya Dryomov +Date: Tue, 23 Jul 2024 18:07:59 +0200 +Subject: rbd: don't assume RBD_LOCK_STATE_LOCKED for exclusive mappings + +From: Ilya Dryomov + +commit 2237ceb71f89837ac47c5dce2aaa2c2b3a337a3c upstream. + +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. + +Cc: stable@vger.kernel.org # 06ef84c4e9c4: rbd: rename RBD_LOCK_STATE_RELEASING and releasing_wait +Cc: stable@vger.kernel.org +Fixes: 637cd060537d ("rbd: new exclusive lock wait/wake code") +Signed-off-by: Ilya Dryomov +Reviewed-by: Dongsheng Yang +Signed-off-by: Greg Kroah-Hartman +--- + drivers/block/rbd.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +--- a/drivers/block/rbd.c ++++ b/drivers/block/rbd.c +@@ -3459,6 +3459,7 @@ static void rbd_lock_del_request(struct + 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)); +@@ -3478,11 +3479,6 @@ static int rbd_img_exclusive_lock(struct + 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(). +@@ -4603,6 +4599,10 @@ static void rbd_reacquire_lock(struct rb + 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. diff --git a/queue-5.15/rbd-rename-rbd_lock_state_releasing-and-releasing_wait.patch b/queue-5.15/rbd-rename-rbd_lock_state_releasing-and-releasing_wait.patch new file mode 100644 index 00000000000..0af0a39aa97 --- /dev/null +++ b/queue-5.15/rbd-rename-rbd_lock_state_releasing-and-releasing_wait.patch @@ -0,0 +1,98 @@ +From f5c466a0fdb2d9f3650d2e3911b0735f17ba00cf Mon Sep 17 00:00:00 2001 +From: Ilya Dryomov +Date: Tue, 23 Jul 2024 17:54:39 +0200 +Subject: rbd: rename RBD_LOCK_STATE_RELEASING and releasing_wait + +From: Ilya Dryomov + +commit f5c466a0fdb2d9f3650d2e3911b0735f17ba00cf upstream. + +... to RBD_LOCK_STATE_QUIESCING and quiescing_wait to recognize that +this state and the associated completion are backing rbd_quiesce_lock(), +which isn't specific to releasing the lock. + +While exclusive lock does get quiesced before it's released, it also +gets quiesced before an attempt to update the cookie is made and there +the lock is not released as long as ceph_cls_set_cookie() succeeds. + +Signed-off-by: Ilya Dryomov +Reviewed-by: Dongsheng Yang +Signed-off-by: Greg Kroah-Hartman +--- + drivers/block/rbd.c | 20 ++++++++++---------- + 1 file changed, 10 insertions(+), 10 deletions(-) + +--- a/drivers/block/rbd.c ++++ b/drivers/block/rbd.c +@@ -362,7 +362,7 @@ enum rbd_watch_state { + enum rbd_lock_state { + RBD_LOCK_STATE_UNLOCKED, + RBD_LOCK_STATE_LOCKED, +- RBD_LOCK_STATE_RELEASING, ++ RBD_LOCK_STATE_QUIESCING, + }; + + /* WatchNotify::ClientId */ +@@ -422,7 +422,7 @@ struct rbd_device { + struct list_head running_list; + struct completion acquire_wait; + int acquire_err; +- struct completion releasing_wait; ++ struct completion quiescing_wait; + + spinlock_t object_map_lock; + u8 *object_map; +@@ -525,7 +525,7 @@ static bool __rbd_is_lock_owner(struct r + lockdep_assert_held(&rbd_dev->lock_rwsem); + + return rbd_dev->lock_state == RBD_LOCK_STATE_LOCKED || +- rbd_dev->lock_state == RBD_LOCK_STATE_RELEASING; ++ rbd_dev->lock_state == RBD_LOCK_STATE_QUIESCING; + } + + static bool rbd_is_lock_owner(struct rbd_device *rbd_dev) +@@ -3460,12 +3460,12 @@ static void rbd_lock_del_request(struct + spin_lock(&rbd_dev->lock_lists_lock); + if (!list_empty(&img_req->lock_item)) { + list_del_init(&img_req->lock_item); +- need_wakeup = (rbd_dev->lock_state == RBD_LOCK_STATE_RELEASING && ++ need_wakeup = (rbd_dev->lock_state == RBD_LOCK_STATE_QUIESCING && + list_empty(&rbd_dev->running_list)); + } + spin_unlock(&rbd_dev->lock_lists_lock); + if (need_wakeup) +- complete(&rbd_dev->releasing_wait); ++ complete(&rbd_dev->quiescing_wait); + } + + static int rbd_img_exclusive_lock(struct rbd_img_request *img_req) +@@ -4183,16 +4183,16 @@ static bool rbd_quiesce_lock(struct rbd_ + /* + * Ensure that all in-flight IO is flushed. + */ +- rbd_dev->lock_state = RBD_LOCK_STATE_RELEASING; +- rbd_assert(!completion_done(&rbd_dev->releasing_wait)); ++ rbd_dev->lock_state = RBD_LOCK_STATE_QUIESCING; ++ rbd_assert(!completion_done(&rbd_dev->quiescing_wait)); + if (list_empty(&rbd_dev->running_list)) + return true; + + up_write(&rbd_dev->lock_rwsem); +- wait_for_completion(&rbd_dev->releasing_wait); ++ wait_for_completion(&rbd_dev->quiescing_wait); + + down_write(&rbd_dev->lock_rwsem); +- if (rbd_dev->lock_state != RBD_LOCK_STATE_RELEASING) ++ if (rbd_dev->lock_state != RBD_LOCK_STATE_QUIESCING) + return false; + + rbd_assert(list_empty(&rbd_dev->running_list)); +@@ -5387,7 +5387,7 @@ static struct rbd_device *__rbd_dev_crea + INIT_LIST_HEAD(&rbd_dev->acquiring_list); + INIT_LIST_HEAD(&rbd_dev->running_list); + init_completion(&rbd_dev->acquire_wait); +- init_completion(&rbd_dev->releasing_wait); ++ init_completion(&rbd_dev->quiescing_wait); + + spin_lock_init(&rbd_dev->object_map_lock); + diff --git a/queue-5.15/series b/queue-5.15/series index 4349b2ad08e..dc9362600ec 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -251,3 +251,5 @@ mips-loongson64-remove-memory-node-for-builtin-dtb.patch mips-loongson64-reset-prioritise-firmware-service.patch mips-loongson64-test-register-availability-before-use.patch drm-panfrost-mark-simple_ondemand-governor-as-softdep.patch +rbd-rename-rbd_lock_state_releasing-and-releasing_wait.patch +rbd-don-t-assume-rbd_lock_state_locked-for-exclusive-mappings.patch -- 2.47.3