aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/md/dm.c21
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
1275static void __merge_pushback_list(struct mapped_device *md) 1277static 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
1450flush_and_out: 1453flush_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