diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/md/dm.c | 21 |
1 files changed, 11 insertions, 10 deletions
diff --git a/drivers/md/dm.c b/drivers/md/dm.c index c1ad7d77dbcd..5191954a18b2 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c | |||
@@ -1270,6 +1270,8 @@ static void __flush_deferred_io(struct mapped_device *md) | |||
1270 | if (__split_bio(md, c)) | 1270 | if (__split_bio(md, c)) |
1271 | bio_io_error(c); | 1271 | bio_io_error(c); |
1272 | } | 1272 | } |
1273 | |||
1274 | clear_bit(DMF_BLOCK_IO, &md->flags); | ||
1273 | } | 1275 | } |
1274 | 1276 | ||
1275 | static void __merge_pushback_list(struct mapped_device *md) | 1277 | static void __merge_pushback_list(struct mapped_device *md) |
@@ -1355,14 +1357,16 @@ int dm_suspend(struct mapped_device *md, unsigned suspend_flags) | |||
1355 | { | 1357 | { |
1356 | struct dm_table *map = NULL; | 1358 | struct dm_table *map = NULL; |
1357 | DECLARE_WAITQUEUE(wait, current); | 1359 | DECLARE_WAITQUEUE(wait, current); |
1358 | int r = -EINVAL; | 1360 | int pending, r = 0; |
1359 | int do_lockfs = suspend_flags & DM_SUSPEND_LOCKFS_FLAG ? 1 : 0; | 1361 | int do_lockfs = suspend_flags & DM_SUSPEND_LOCKFS_FLAG ? 1 : 0; |
1360 | int noflush = suspend_flags & DM_SUSPEND_NOFLUSH_FLAG ? 1 : 0; | 1362 | int noflush = suspend_flags & DM_SUSPEND_NOFLUSH_FLAG ? 1 : 0; |
1361 | 1363 | ||
1362 | mutex_lock(&md->suspend_lock); | 1364 | mutex_lock(&md->suspend_lock); |
1363 | 1365 | ||
1364 | if (dm_suspended(md)) | 1366 | if (dm_suspended(md)) { |
1367 | r = -EINVAL; | ||
1365 | goto out_unlock; | 1368 | goto out_unlock; |
1369 | } | ||
1366 | 1370 | ||
1367 | map = dm_get_table(md); | 1371 | map = dm_get_table(md); |
1368 | 1372 | ||
@@ -1417,7 +1421,8 @@ int dm_suspend(struct mapped_device *md, unsigned suspend_flags) | |||
1417 | set_current_state(TASK_INTERRUPTIBLE); | 1421 | set_current_state(TASK_INTERRUPTIBLE); |
1418 | 1422 | ||
1419 | smp_mb(); | 1423 | smp_mb(); |
1420 | if (!atomic_read(&md->pending) || signal_pending(current)) | 1424 | pending = atomic_read(&md->pending); |
1425 | if (!pending || signal_pending(current)) | ||
1421 | break; | 1426 | break; |
1422 | 1427 | ||
1423 | io_schedule(); | 1428 | io_schedule(); |
@@ -1431,12 +1436,12 @@ int dm_suspend(struct mapped_device *md, unsigned suspend_flags) | |||
1431 | __merge_pushback_list(md); | 1436 | __merge_pushback_list(md); |
1432 | 1437 | ||
1433 | /* were we interrupted ? */ | 1438 | /* were we interrupted ? */ |
1434 | r = -EINTR; | 1439 | if (pending) { |
1435 | if (atomic_read(&md->pending)) { | ||
1436 | clear_bit(DMF_BLOCK_IO, &md->flags); | ||
1437 | __flush_deferred_io(md); | 1440 | __flush_deferred_io(md); |
1438 | up_write(&md->io_lock); | 1441 | up_write(&md->io_lock); |
1442 | |||
1439 | unlock_fs(md); | 1443 | unlock_fs(md); |
1444 | r = -EINTR; | ||
1440 | goto out; /* pushback list is already flushed, so skip flush */ | 1445 | goto out; /* pushback list is already flushed, so skip flush */ |
1441 | } | 1446 | } |
1442 | up_write(&md->io_lock); | 1447 | up_write(&md->io_lock); |
@@ -1445,8 +1450,6 @@ int dm_suspend(struct mapped_device *md, unsigned suspend_flags) | |||
1445 | 1450 | ||
1446 | set_bit(DMF_SUSPENDED, &md->flags); | 1451 | set_bit(DMF_SUSPENDED, &md->flags); |
1447 | 1452 | ||
1448 | r = 0; | ||
1449 | |||
1450 | flush_and_out: | 1453 | flush_and_out: |
1451 | if (r && noflush) { | 1454 | if (r && noflush) { |
1452 | /* | 1455 | /* |
@@ -1490,8 +1493,6 @@ int dm_resume(struct mapped_device *md) | |||
1490 | goto out; | 1493 | goto out; |
1491 | 1494 | ||
1492 | down_write(&md->io_lock); | 1495 | down_write(&md->io_lock); |
1493 | clear_bit(DMF_BLOCK_IO, &md->flags); | ||
1494 | |||
1495 | __flush_deferred_io(md); | 1496 | __flush_deferred_io(md); |
1496 | up_write(&md->io_lock); | 1497 | up_write(&md->io_lock); |
1497 | 1498 | ||