Skip to content

Commit 38d11da

Browse files
Li LingfengMike Snitzer
authored andcommitted
dm: don't lock fs when the map is NULL in process of resume
Commit fa24708 ("dm: requeue IO if mapping table not yet available") added a detection of whether the mapping table is available in the IO submission process. If the mapping table is unavailable, it returns BLK_STS_RESOURCE and requeues the IO. This can lead to the following deadlock problem: dm create mount ioctl(DM_DEV_CREATE_CMD) ioctl(DM_TABLE_LOAD_CMD) do_mount vfs_get_tree ext4_get_tree get_tree_bdev sget_fc alloc_super // got &s->s_umount down_write_nested(&s->s_umount, ...); ext4_fill_super ext4_load_super ext4_read_bh submit_bio // submit and wait io end ioctl(DM_DEV_SUSPEND_CMD) dev_suspend do_resume dm_suspend __dm_suspend lock_fs freeze_bdev get_active_super grab_super // wait for &s->s_umount down_write(&s->s_umount); dm_swap_table __bind // set md->map(can't get here) IO will be continuously requeued while holding the lock since mapping table is NULL. At the same time, mapping table won't be set since the lock is not available. Like request-based DM, bio-based DM also has the same problem. It's not proper to just abort IO if the mapping table not available. So clear DM_SKIP_LOCKFS_FLAG when the mapping table is NULL, this allows the DM table to be loaded and the IO submitted upon resume. Fixes: fa24708 ("dm: requeue IO if mapping table not yet available") Cc: [email protected] Signed-off-by: Li Lingfeng <[email protected]> Signed-off-by: Mike Snitzer <[email protected]>
1 parent aa7d7bc commit 38d11da

File tree

1 file changed

+4
-1
lines changed

1 file changed

+4
-1
lines changed

drivers/md/dm-ioctl.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1168,10 +1168,13 @@ static int do_resume(struct dm_ioctl *param)
11681168
/* Do we need to load a new map ? */
11691169
if (new_map) {
11701170
sector_t old_size, new_size;
1171+
int srcu_idx;
11711172

11721173
/* Suspend if it isn't already suspended */
1173-
if (param->flags & DM_SKIP_LOCKFS_FLAG)
1174+
old_map = dm_get_live_table(md, &srcu_idx);
1175+
if ((param->flags & DM_SKIP_LOCKFS_FLAG) || !old_map)
11741176
suspend_flags &= ~DM_SUSPEND_LOCKFS_FLAG;
1177+
dm_put_live_table(md, srcu_idx);
11751178
if (param->flags & DM_NOFLUSH_FLAG)
11761179
suspend_flags |= DM_SUSPEND_NOFLUSH_FLAG;
11771180
if (!dm_suspended_md(md))

0 commit comments

Comments
 (0)