aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/dm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/md/dm.c')
-rw-r--r--drivers/md/dm.c43
1 files changed, 27 insertions, 16 deletions
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index 11f422ecfda0..9ca012e639a8 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -1259,6 +1259,29 @@ void dm_put(struct mapped_device *md)
1259} 1259}
1260EXPORT_SYMBOL_GPL(dm_put); 1260EXPORT_SYMBOL_GPL(dm_put);
1261 1261
1262static int dm_wait_for_completion(struct mapped_device *md)
1263{
1264 int r = 0;
1265
1266 while (1) {
1267 set_current_state(TASK_INTERRUPTIBLE);
1268
1269 smp_mb();
1270 if (!atomic_read(&md->pending))
1271 break;
1272
1273 if (signal_pending(current)) {
1274 r = -EINTR;
1275 break;
1276 }
1277
1278 io_schedule();
1279 }
1280 set_current_state(TASK_RUNNING);
1281
1282 return r;
1283}
1284
1262/* 1285/*
1263 * Process the deferred bios 1286 * Process the deferred bios
1264 */ 1287 */
@@ -1357,7 +1380,7 @@ int dm_suspend(struct mapped_device *md, unsigned suspend_flags)
1357{ 1380{
1358 struct dm_table *map = NULL; 1381 struct dm_table *map = NULL;
1359 DECLARE_WAITQUEUE(wait, current); 1382 DECLARE_WAITQUEUE(wait, current);
1360 int pending, r = 0; 1383 int r = 0;
1361 int do_lockfs = suspend_flags & DM_SUSPEND_LOCKFS_FLAG ? 1 : 0; 1384 int do_lockfs = suspend_flags & DM_SUSPEND_LOCKFS_FLAG ? 1 : 0;
1362 int noflush = suspend_flags & DM_SUSPEND_NOFLUSH_FLAG ? 1 : 0; 1385 int noflush = suspend_flags & DM_SUSPEND_NOFLUSH_FLAG ? 1 : 0;
1363 1386
@@ -1414,20 +1437,9 @@ int dm_suspend(struct mapped_device *md, unsigned suspend_flags)
1414 dm_table_unplug_all(map); 1437 dm_table_unplug_all(map);
1415 1438
1416 /* 1439 /*
1417 * Then we wait for the already mapped ios to 1440 * Wait for the already-mapped ios to complete.
1418 * complete.
1419 */ 1441 */
1420 while (1) { 1442 r = dm_wait_for_completion(md);
1421 set_current_state(TASK_INTERRUPTIBLE);
1422
1423 smp_mb();
1424 pending = atomic_read(&md->pending);
1425 if (!pending || signal_pending(current))
1426 break;
1427
1428 io_schedule();
1429 }
1430 set_current_state(TASK_RUNNING);
1431 1443
1432 down_write(&md->io_lock); 1444 down_write(&md->io_lock);
1433 remove_wait_queue(&md->wait, &wait); 1445 remove_wait_queue(&md->wait, &wait);
@@ -1437,13 +1449,12 @@ int dm_suspend(struct mapped_device *md, unsigned suspend_flags)
1437 up_write(&md->io_lock); 1449 up_write(&md->io_lock);
1438 1450
1439 /* were we interrupted ? */ 1451 /* were we interrupted ? */
1440 if (pending) { 1452 if (r < 0) {
1441 down_write(&md->io_lock); 1453 down_write(&md->io_lock);
1442 __flush_deferred_io(md); 1454 __flush_deferred_io(md);
1443 up_write(&md->io_lock); 1455 up_write(&md->io_lock);
1444 1456
1445 unlock_fs(md); 1457 unlock_fs(md);
1446 r = -EINTR;
1447 goto out; /* pushback list is already flushed, so skip flush */ 1458 goto out; /* pushback list is already flushed, so skip flush */
1448 } 1459 }
1449 1460