Skip to content

Commit acbbb12

Browse files
committed
dm thin: resume even if in FAIL mode
Bugzilla: https://bugzilla.redhat.com/2162536 Upstream Status: kernel/git/torvalds/linux.git commit 19eb165 Author: Luo Meng <luomeng12@huawei.com> Date: Wed Nov 30 10:09:45 2022 +0800 dm thin: resume even if in FAIL mode If a thinpool set fail_io while suspending, resume will fail with: device-mapper: resume ioctl on vg-thinpool failed: Invalid argument The thin-pool also can't be removed if an in-flight bio is in the deferred list. This can be easily reproduced using: echo "offline" > /sys/block/sda/device/state dd if=/dev/zero of=/dev/mapper/thin bs=4K count=1 dmsetup suspend /dev/mapper/pool mkfs.ext4 /dev/mapper/thin dmsetup resume /dev/mapper/pool The root cause is maybe_resize_data_dev() will check fail_io and return error before called dm_resume. Fix this by adding FAIL mode check at the end of pool_preresume(). Cc: stable@vger.kernel.org Fixes: da105ed ("dm thin metadata: introduce dm_pool_abort_metadata") Signed-off-by: Luo Meng <luomeng12@huawei.com> Signed-off-by: Mike Snitzer <snitzer@kernel.org> Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
1 parent 3eb6f26 commit acbbb12

File tree

1 file changed

+12
-4
lines changed

1 file changed

+12
-4
lines changed

drivers/md/dm-thin.c

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3542,20 +3542,28 @@ static int pool_preresume(struct dm_target *ti)
35423542
*/
35433543
r = bind_control_target(pool, ti);
35443544
if (r)
3545-
return r;
3545+
goto out;
35463546

35473547
r = maybe_resize_data_dev(ti, &need_commit1);
35483548
if (r)
3549-
return r;
3549+
goto out;
35503550

35513551
r = maybe_resize_metadata_dev(ti, &need_commit2);
35523552
if (r)
3553-
return r;
3553+
goto out;
35543554

35553555
if (need_commit1 || need_commit2)
35563556
(void) commit(pool);
3557+
out:
3558+
/*
3559+
* When a thin-pool is PM_FAIL, it cannot be rebuilt if
3560+
* bio is in deferred list. Therefore need to return 0
3561+
* to allow pool_resume() to flush IO.
3562+
*/
3563+
if (r && get_pool_mode(pool) == PM_FAIL)
3564+
r = 0;
35573565

3558-
return 0;
3566+
return r;
35593567
}
35603568

35613569
static void pool_suspend_active_thins(struct pool *pool)

0 commit comments

Comments
 (0)