[PATCH] device-mapper multipath: Avoid possible suspension deadlock
To avoid deadlock when suspending a multipath device after all its paths have failed, stop queueing any I/O that is about to fail *before* calling freeze_bdev instead of after. Instead of setting a multipath 'suspended' flag which would have to be reset if an error occurs during the process, save the previous queueing state and leave userspace to restore if it wishes. Signed-off-by: Alasdair G Kergon <agk@redhat.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:

committed by
Linus Torvalds

parent
a044d01689
commit
436d41087d
@@ -1055,14 +1055,17 @@ int dm_suspend(struct mapped_device *md)
|
||||
if (test_bit(DMF_BLOCK_IO, &md->flags))
|
||||
goto out_read_unlock;
|
||||
|
||||
error = __lock_fs(md);
|
||||
if (error)
|
||||
goto out_read_unlock;
|
||||
|
||||
map = dm_get_table(md);
|
||||
if (map)
|
||||
/* This does not get reverted if there's an error later. */
|
||||
dm_table_presuspend_targets(map);
|
||||
|
||||
error = __lock_fs(md);
|
||||
if (error) {
|
||||
dm_table_put(map);
|
||||
goto out_read_unlock;
|
||||
}
|
||||
|
||||
up_read(&md->lock);
|
||||
|
||||
/*
|
||||
@@ -1121,7 +1124,6 @@ int dm_suspend(struct mapped_device *md)
|
||||
return 0;
|
||||
|
||||
out_unfreeze:
|
||||
/* FIXME Undo dm_table_presuspend_targets */
|
||||
__unlock_fs(md);
|
||||
clear_bit(DMF_BLOCK_IO, &md->flags);
|
||||
out_write_unlock:
|
||||
|
Reference in New Issue
Block a user