[Devel] [PATCH hci-8.1 v6 10/12] dm-ploop: fix flip_upper_deltas racing with resume

Alexander Ivanov alexander.ivanov at virtuozzo.com
Tue Oct 13 14:16:02 MSK 2026


ploop_preresume() checks noresume under ctl_rwsem, drops the lock and
only then clears ->suspended. Messages are not serialized with resume:
target_message() uses the live table without md->suspend_lock, so
"set_noresume 1" followed by "flip_upper_deltas" can pass the check
in ploop_flip_upper_deltas() in that gap. The device then goes live
with noresume set and the top deltas swapped.

Clear ->suspended in the same critical section as the noresume check,
and only if it passes.
---
 drivers/md/dm-ploop-target.c | 21 +++++++++++----------
 1 file changed, 11 insertions(+), 10 deletions(-)

diff --git a/drivers/md/dm-ploop-target.c b/drivers/md/dm-ploop-target.c
index dc9410212831..abb60aa6a1e9 100644
--- a/drivers/md/dm-ploop-target.c
+++ b/drivers/md/dm-ploop-target.c
@@ -757,19 +757,20 @@ static int ploop_preresume(struct dm_target *ti)
 	struct ploop *ploop = ti->private;
 	int ret = 0;
 
-	down_read(&ploop->ctl_rwsem);
+	down_write(&ploop->ctl_rwsem);
 	if (ploop->noresume)
 		ret = -EAGAIN;
-	up_read(&ploop->ctl_rwsem);
-
-	if (ret == 0) {
-		/*
-		 * We are singleton target. There will be
-		 * no more reasons to break resume.
-		 */
-		ploop_set_suspended(ti, false);
+	/*
+	 * We are singleton target. There will be no more reasons to break
+	 * resume. Clear it under the same lock as the noresume check, so
+	 * that flip_upper_deltas can't sneak in before the device goes live.
+	 */
+	if (ret == 0)
+		ploop->suspended = false;
+	up_write(&ploop->ctl_rwsem);
+
+	if (ret == 0)
 		ploop_set_wants_suspend(ti, false);
-	}
 	return ret;
 }
 ALLOW_ERROR_INJECTION(ploop_preresume, ERRNO);
-- 
2.53.0



More information about the Devel mailing list