diff options
Diffstat (limited to 'drivers/md/dm.c')
-rw-r--r-- | drivers/md/dm.c | 67 |
1 files changed, 29 insertions, 38 deletions
diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 52427e15189b..c1ad7d77dbcd 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c | |||
@@ -1262,19 +1262,27 @@ EXPORT_SYMBOL_GPL(dm_put); | |||
1262 | /* | 1262 | /* |
1263 | * Process the deferred bios | 1263 | * Process the deferred bios |
1264 | */ | 1264 | */ |
1265 | static void __flush_deferred_io(struct mapped_device *md, struct bio *c) | 1265 | static void __flush_deferred_io(struct mapped_device *md) |
1266 | { | 1266 | { |
1267 | struct bio *n; | 1267 | struct bio *c; |
1268 | 1268 | ||
1269 | while (c) { | 1269 | while ((c = bio_list_pop(&md->deferred))) { |
1270 | n = c->bi_next; | ||
1271 | c->bi_next = NULL; | ||
1272 | if (__split_bio(md, c)) | 1270 | if (__split_bio(md, c)) |
1273 | bio_io_error(c); | 1271 | bio_io_error(c); |
1274 | c = n; | ||
1275 | } | 1272 | } |
1276 | } | 1273 | } |
1277 | 1274 | ||
1275 | static void __merge_pushback_list(struct mapped_device *md) | ||
1276 | { | ||
1277 | unsigned long flags; | ||
1278 | |||
1279 | spin_lock_irqsave(&md->pushback_lock, flags); | ||
1280 | clear_bit(DMF_NOFLUSH_SUSPENDING, &md->flags); | ||
1281 | bio_list_merge_head(&md->deferred, &md->pushback); | ||
1282 | bio_list_init(&md->pushback); | ||
1283 | spin_unlock_irqrestore(&md->pushback_lock, flags); | ||
1284 | } | ||
1285 | |||
1278 | /* | 1286 | /* |
1279 | * Swap in a new table (destroying old one). | 1287 | * Swap in a new table (destroying old one). |
1280 | */ | 1288 | */ |
@@ -1346,9 +1354,7 @@ static void unlock_fs(struct mapped_device *md) | |||
1346 | int dm_suspend(struct mapped_device *md, unsigned suspend_flags) | 1354 | int dm_suspend(struct mapped_device *md, unsigned suspend_flags) |
1347 | { | 1355 | { |
1348 | struct dm_table *map = NULL; | 1356 | struct dm_table *map = NULL; |
1349 | unsigned long flags; | ||
1350 | DECLARE_WAITQUEUE(wait, current); | 1357 | DECLARE_WAITQUEUE(wait, current); |
1351 | struct bio *def; | ||
1352 | int r = -EINVAL; | 1358 | int r = -EINVAL; |
1353 | int do_lockfs = suspend_flags & DM_SUSPEND_LOCKFS_FLAG ? 1 : 0; | 1359 | int do_lockfs = suspend_flags & DM_SUSPEND_LOCKFS_FLAG ? 1 : 0; |
1354 | int noflush = suspend_flags & DM_SUSPEND_NOFLUSH_FLAG ? 1 : 0; | 1360 | int noflush = suspend_flags & DM_SUSPEND_NOFLUSH_FLAG ? 1 : 0; |
@@ -1378,16 +1384,16 @@ int dm_suspend(struct mapped_device *md, unsigned suspend_flags) | |||
1378 | r = -ENOMEM; | 1384 | r = -ENOMEM; |
1379 | goto flush_and_out; | 1385 | goto flush_and_out; |
1380 | } | 1386 | } |
1381 | } | ||
1382 | 1387 | ||
1383 | /* | 1388 | /* |
1384 | * Flush I/O to the device. | 1389 | * Flush I/O to the device. noflush supersedes do_lockfs, |
1385 | * noflush supersedes do_lockfs, because lock_fs() needs to flush I/Os. | 1390 | * because lock_fs() needs to flush I/Os. |
1386 | */ | 1391 | */ |
1387 | if (do_lockfs && !noflush) { | 1392 | if (do_lockfs) { |
1388 | r = lock_fs(md); | 1393 | r = lock_fs(md); |
1389 | if (r) | 1394 | if (r) |
1390 | goto out; | 1395 | goto out; |
1396 | } | ||
1391 | } | 1397 | } |
1392 | 1398 | ||
1393 | /* | 1399 | /* |
@@ -1421,20 +1427,14 @@ int dm_suspend(struct mapped_device *md, unsigned suspend_flags) | |||
1421 | down_write(&md->io_lock); | 1427 | down_write(&md->io_lock); |
1422 | remove_wait_queue(&md->wait, &wait); | 1428 | remove_wait_queue(&md->wait, &wait); |
1423 | 1429 | ||
1424 | if (noflush) { | 1430 | if (noflush) |
1425 | spin_lock_irqsave(&md->pushback_lock, flags); | 1431 | __merge_pushback_list(md); |
1426 | clear_bit(DMF_NOFLUSH_SUSPENDING, &md->flags); | ||
1427 | bio_list_merge_head(&md->deferred, &md->pushback); | ||
1428 | bio_list_init(&md->pushback); | ||
1429 | spin_unlock_irqrestore(&md->pushback_lock, flags); | ||
1430 | } | ||
1431 | 1432 | ||
1432 | /* were we interrupted ? */ | 1433 | /* were we interrupted ? */ |
1433 | r = -EINTR; | 1434 | r = -EINTR; |
1434 | if (atomic_read(&md->pending)) { | 1435 | if (atomic_read(&md->pending)) { |
1435 | clear_bit(DMF_BLOCK_IO, &md->flags); | 1436 | clear_bit(DMF_BLOCK_IO, &md->flags); |
1436 | def = bio_list_get(&md->deferred); | 1437 | __flush_deferred_io(md); |
1437 | __flush_deferred_io(md, def); | ||
1438 | up_write(&md->io_lock); | 1438 | up_write(&md->io_lock); |
1439 | unlock_fs(md); | 1439 | unlock_fs(md); |
1440 | goto out; /* pushback list is already flushed, so skip flush */ | 1440 | goto out; /* pushback list is already flushed, so skip flush */ |
@@ -1454,15 +1454,8 @@ flush_and_out: | |||
1454 | * flush them before return. | 1454 | * flush them before return. |
1455 | */ | 1455 | */ |
1456 | down_write(&md->io_lock); | 1456 | down_write(&md->io_lock); |
1457 | 1457 | __merge_pushback_list(md); | |
1458 | spin_lock_irqsave(&md->pushback_lock, flags); | 1458 | __flush_deferred_io(md); |
1459 | clear_bit(DMF_NOFLUSH_SUSPENDING, &md->flags); | ||
1460 | bio_list_merge_head(&md->deferred, &md->pushback); | ||
1461 | bio_list_init(&md->pushback); | ||
1462 | spin_unlock_irqrestore(&md->pushback_lock, flags); | ||
1463 | |||
1464 | def = bio_list_get(&md->deferred); | ||
1465 | __flush_deferred_io(md, def); | ||
1466 | up_write(&md->io_lock); | 1459 | up_write(&md->io_lock); |
1467 | } | 1460 | } |
1468 | 1461 | ||
@@ -1482,7 +1475,6 @@ out_unlock: | |||
1482 | int dm_resume(struct mapped_device *md) | 1475 | int dm_resume(struct mapped_device *md) |
1483 | { | 1476 | { |
1484 | int r = -EINVAL; | 1477 | int r = -EINVAL; |
1485 | struct bio *def; | ||
1486 | struct dm_table *map = NULL; | 1478 | struct dm_table *map = NULL; |
1487 | 1479 | ||
1488 | mutex_lock(&md->suspend_lock); | 1480 | mutex_lock(&md->suspend_lock); |
@@ -1500,8 +1492,7 @@ int dm_resume(struct mapped_device *md) | |||
1500 | down_write(&md->io_lock); | 1492 | down_write(&md->io_lock); |
1501 | clear_bit(DMF_BLOCK_IO, &md->flags); | 1493 | clear_bit(DMF_BLOCK_IO, &md->flags); |
1502 | 1494 | ||
1503 | def = bio_list_get(&md->deferred); | 1495 | __flush_deferred_io(md); |
1504 | __flush_deferred_io(md, def); | ||
1505 | up_write(&md->io_lock); | 1496 | up_write(&md->io_lock); |
1506 | 1497 | ||
1507 | unlock_fs(md); | 1498 | unlock_fs(md); |