From: Alasdair G Kergon Tidy dm_suspend. Signed-Off-By: Alasdair G Kergon From: Christoph Hellwig Signed-off-by: Andrew Morton --- drivers/md/dm.c | 43 +++++++++++++++++++++++-------------------- 1 files changed, 23 insertions(+), 20 deletions(-) diff -puN drivers/md/dm.c~device-mapper-tidy-dm_suspend drivers/md/dm.c --- 25/drivers/md/dm.c~device-mapper-tidy-dm_suspend Wed May 4 13:10:29 2005 +++ 25-akpm/drivers/md/dm.c Wed May 4 13:10:29 2005 @@ -1048,20 +1048,16 @@ int dm_suspend(struct mapped_device *md) { struct dm_table *map; DECLARE_WAITQUEUE(wait, current); - int error; + int error = -EINVAL; /* Flush I/O to the device. */ down_read(&md->lock); - if (test_bit(DMF_BLOCK_IO, &md->flags)) { - up_read(&md->lock); - return -EINVAL; - } + if (test_bit(DMF_BLOCK_IO, &md->flags)) + goto out_read_unlock; error = __lock_fs(md); - if (error) { - up_read(&md->lock); - return error; - } + if (error) + goto out_read_unlock; map = dm_get_table(md); if (map) @@ -1075,15 +1071,14 @@ int dm_suspend(struct mapped_device *md) * If the flag is already set we know another thread is trying to * suspend as well, so we leave the fs locked for this thread. */ + error = -EINVAL; down_write(&md->lock); - if (test_bit(DMF_BLOCK_IO, &md->flags)) { - up_write(&md->lock); + if (test_and_set_bit(DMF_BLOCK_IO, &md->flags)) { if (map) dm_table_put(map); - return -EINVAL; + goto out_write_unlock; } - set_bit(DMF_BLOCK_IO, &md->flags); add_wait_queue(&md->wait, &wait); up_write(&md->lock); @@ -1111,13 +1106,9 @@ int dm_suspend(struct mapped_device *md) remove_wait_queue(&md->wait, &wait); /* were we interrupted ? */ - if (atomic_read(&md->pending)) { - /* FIXME Undo the presuspend_targets */ - __unlock_fs(md); - clear_bit(DMF_BLOCK_IO, &md->flags); - up_write(&md->lock); - return -EINTR; - } + error = -EINTR; + if (atomic_read(&md->pending)) + goto out_unfreeze; set_bit(DMF_SUSPENDED, &md->flags); @@ -1128,6 +1119,18 @@ int dm_suspend(struct mapped_device *md) up_write(&md->lock); return 0; + +out_unfreeze: + /* FIXME Undo dm_table_presuspend_targets */ + __unlock_fs(md); + clear_bit(DMF_BLOCK_IO, &md->flags); +out_write_unlock: + up_write(&md->lock); + return error; + +out_read_unlock: + up_read(&md->lock); + return error; } int dm_resume(struct mapped_device *md) _