Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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: da105ed5fd7e ("dm thin metadata: introduce dm_pool_abort_metadata")
Signed-off-by: Luo Meng <luomeng12@huawei.com>
Signed-off-by: Mike Snitzer <snitzer@kernel.org>

authored by

Luo Meng and committed by
Mike Snitzer
19eb1650 6b997386

+12 -4
+12 -4
drivers/md/dm-thin.c
··· 3542 3542 */ 3543 3543 r = bind_control_target(pool, ti); 3544 3544 if (r) 3545 - return r; 3545 + goto out; 3546 3546 3547 3547 r = maybe_resize_data_dev(ti, &need_commit1); 3548 3548 if (r) 3549 - return r; 3549 + goto out; 3550 3550 3551 3551 r = maybe_resize_metadata_dev(ti, &need_commit2); 3552 3552 if (r) 3553 - return r; 3553 + goto out; 3554 3554 3555 3555 if (need_commit1 || need_commit2) 3556 3556 (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; 3557 3565 3558 - return 0; 3566 + return r; 3559 3567 } 3560 3568 3561 3569 static void pool_suspend_active_thins(struct pool *pool)