diff options
Diffstat (limited to 'drivers/md/dm.c')
-rw-r--r-- | drivers/md/dm.c | 134 |
1 files changed, 51 insertions, 83 deletions
diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 8d40f27cce89..788ba96a6256 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c | |||
@@ -99,19 +99,9 @@ union map_info *dm_get_mapinfo(struct bio *bio) | |||
99 | /* | 99 | /* |
100 | * Work processed by per-device workqueue. | 100 | * Work processed by per-device workqueue. |
101 | */ | 101 | */ |
102 | struct dm_wq_req { | ||
103 | enum { | ||
104 | DM_WQ_FLUSH_DEFERRED, | ||
105 | } type; | ||
106 | struct work_struct work; | ||
107 | struct mapped_device *md; | ||
108 | void *context; | ||
109 | }; | ||
110 | |||
111 | struct mapped_device { | 102 | struct mapped_device { |
112 | struct rw_semaphore io_lock; | 103 | struct rw_semaphore io_lock; |
113 | struct mutex suspend_lock; | 104 | struct mutex suspend_lock; |
114 | spinlock_t pushback_lock; | ||
115 | rwlock_t map_lock; | 105 | rwlock_t map_lock; |
116 | atomic_t holders; | 106 | atomic_t holders; |
117 | atomic_t open_count; | 107 | atomic_t open_count; |
@@ -129,8 +119,9 @@ struct mapped_device { | |||
129 | */ | 119 | */ |
130 | atomic_t pending; | 120 | atomic_t pending; |
131 | wait_queue_head_t wait; | 121 | wait_queue_head_t wait; |
122 | struct work_struct work; | ||
132 | struct bio_list deferred; | 123 | struct bio_list deferred; |
133 | struct bio_list pushback; | 124 | spinlock_t deferred_lock; |
134 | 125 | ||
135 | /* | 126 | /* |
136 | * Processing queue (flush/barriers) | 127 | * Processing queue (flush/barriers) |
@@ -453,7 +444,9 @@ static int queue_io(struct mapped_device *md, struct bio *bio) | |||
453 | return 1; | 444 | return 1; |
454 | } | 445 | } |
455 | 446 | ||
447 | spin_lock_irq(&md->deferred_lock); | ||
456 | bio_list_add(&md->deferred, bio); | 448 | bio_list_add(&md->deferred, bio); |
449 | spin_unlock_irq(&md->deferred_lock); | ||
457 | 450 | ||
458 | up_write(&md->io_lock); | 451 | up_write(&md->io_lock); |
459 | return 0; /* deferred successfully */ | 452 | return 0; /* deferred successfully */ |
@@ -537,16 +530,14 @@ static void dec_pending(struct dm_io *io, int error) | |||
537 | if (io->error == DM_ENDIO_REQUEUE) { | 530 | if (io->error == DM_ENDIO_REQUEUE) { |
538 | /* | 531 | /* |
539 | * Target requested pushing back the I/O. | 532 | * Target requested pushing back the I/O. |
540 | * This must be handled before the sleeper on | ||
541 | * suspend queue merges the pushback list. | ||
542 | */ | 533 | */ |
543 | spin_lock_irqsave(&md->pushback_lock, flags); | 534 | spin_lock_irqsave(&md->deferred_lock, flags); |
544 | if (__noflush_suspending(md)) | 535 | if (__noflush_suspending(md)) |
545 | bio_list_add(&md->pushback, io->bio); | 536 | bio_list_add(&md->deferred, io->bio); |
546 | else | 537 | else |
547 | /* noflush suspend was interrupted. */ | 538 | /* noflush suspend was interrupted. */ |
548 | io->error = -EIO; | 539 | io->error = -EIO; |
549 | spin_unlock_irqrestore(&md->pushback_lock, flags); | 540 | spin_unlock_irqrestore(&md->deferred_lock, flags); |
550 | } | 541 | } |
551 | 542 | ||
552 | end_io_acct(io); | 543 | end_io_acct(io); |
@@ -834,20 +825,22 @@ static int __clone_and_map(struct clone_info *ci) | |||
834 | } | 825 | } |
835 | 826 | ||
836 | /* | 827 | /* |
837 | * Split the bio into several clones. | 828 | * Split the bio into several clones and submit it to targets. |
838 | */ | 829 | */ |
839 | static int __split_bio(struct mapped_device *md, struct bio *bio) | 830 | static void __split_and_process_bio(struct mapped_device *md, struct bio *bio) |
840 | { | 831 | { |
841 | struct clone_info ci; | 832 | struct clone_info ci; |
842 | int error = 0; | 833 | int error = 0; |
843 | 834 | ||
844 | ci.map = dm_get_table(md); | 835 | ci.map = dm_get_table(md); |
845 | if (unlikely(!ci.map)) | 836 | if (unlikely(!ci.map)) { |
846 | return -EIO; | 837 | bio_io_error(bio); |
838 | return; | ||
839 | } | ||
847 | if (unlikely(bio_barrier(bio) && !dm_table_barrier_ok(ci.map))) { | 840 | if (unlikely(bio_barrier(bio) && !dm_table_barrier_ok(ci.map))) { |
848 | dm_table_put(ci.map); | 841 | dm_table_put(ci.map); |
849 | bio_endio(bio, -EOPNOTSUPP); | 842 | bio_endio(bio, -EOPNOTSUPP); |
850 | return 0; | 843 | return; |
851 | } | 844 | } |
852 | ci.md = md; | 845 | ci.md = md; |
853 | ci.bio = bio; | 846 | ci.bio = bio; |
@@ -867,8 +860,6 @@ static int __split_bio(struct mapped_device *md, struct bio *bio) | |||
867 | /* drop the extra reference count */ | 860 | /* drop the extra reference count */ |
868 | dec_pending(ci.io, error); | 861 | dec_pending(ci.io, error); |
869 | dm_table_put(ci.map); | 862 | dm_table_put(ci.map); |
870 | |||
871 | return 0; | ||
872 | } | 863 | } |
873 | /*----------------------------------------------------------------- | 864 | /*----------------------------------------------------------------- |
874 | * CRUD END | 865 | * CRUD END |
@@ -959,8 +950,9 @@ static int dm_request(struct request_queue *q, struct bio *bio) | |||
959 | down_read(&md->io_lock); | 950 | down_read(&md->io_lock); |
960 | } | 951 | } |
961 | 952 | ||
962 | r = __split_bio(md, bio); | 953 | __split_and_process_bio(md, bio); |
963 | up_read(&md->io_lock); | 954 | up_read(&md->io_lock); |
955 | return 0; | ||
964 | 956 | ||
965 | out_req: | 957 | out_req: |
966 | if (r < 0) | 958 | if (r < 0) |
@@ -1074,6 +1066,8 @@ out: | |||
1074 | 1066 | ||
1075 | static struct block_device_operations dm_blk_dops; | 1067 | static struct block_device_operations dm_blk_dops; |
1076 | 1068 | ||
1069 | static void dm_wq_work(struct work_struct *work); | ||
1070 | |||
1077 | /* | 1071 | /* |
1078 | * Allocate and initialise a blank device with a given minor. | 1072 | * Allocate and initialise a blank device with a given minor. |
1079 | */ | 1073 | */ |
@@ -1101,7 +1095,7 @@ static struct mapped_device *alloc_dev(int minor) | |||
1101 | 1095 | ||
1102 | init_rwsem(&md->io_lock); | 1096 | init_rwsem(&md->io_lock); |
1103 | mutex_init(&md->suspend_lock); | 1097 | mutex_init(&md->suspend_lock); |
1104 | spin_lock_init(&md->pushback_lock); | 1098 | spin_lock_init(&md->deferred_lock); |
1105 | rwlock_init(&md->map_lock); | 1099 | rwlock_init(&md->map_lock); |
1106 | atomic_set(&md->holders, 1); | 1100 | atomic_set(&md->holders, 1); |
1107 | atomic_set(&md->open_count, 0); | 1101 | atomic_set(&md->open_count, 0); |
@@ -1118,6 +1112,7 @@ static struct mapped_device *alloc_dev(int minor) | |||
1118 | md->queue->backing_dev_info.congested_fn = dm_any_congested; | 1112 | md->queue->backing_dev_info.congested_fn = dm_any_congested; |
1119 | md->queue->backing_dev_info.congested_data = md; | 1113 | md->queue->backing_dev_info.congested_data = md; |
1120 | blk_queue_make_request(md->queue, dm_request); | 1114 | blk_queue_make_request(md->queue, dm_request); |
1115 | blk_queue_ordered(md->queue, QUEUE_ORDERED_DRAIN, NULL); | ||
1121 | blk_queue_bounce_limit(md->queue, BLK_BOUNCE_ANY); | 1116 | blk_queue_bounce_limit(md->queue, BLK_BOUNCE_ANY); |
1122 | md->queue->unplug_fn = dm_unplug_all; | 1117 | md->queue->unplug_fn = dm_unplug_all; |
1123 | blk_queue_merge_bvec(md->queue, dm_merge_bvec); | 1118 | blk_queue_merge_bvec(md->queue, dm_merge_bvec); |
@@ -1140,6 +1135,7 @@ static struct mapped_device *alloc_dev(int minor) | |||
1140 | 1135 | ||
1141 | atomic_set(&md->pending, 0); | 1136 | atomic_set(&md->pending, 0); |
1142 | init_waitqueue_head(&md->wait); | 1137 | init_waitqueue_head(&md->wait); |
1138 | INIT_WORK(&md->work, dm_wq_work); | ||
1143 | init_waitqueue_head(&md->eventq); | 1139 | init_waitqueue_head(&md->eventq); |
1144 | 1140 | ||
1145 | md->disk->major = _major; | 1141 | md->disk->major = _major; |
@@ -1379,18 +1375,24 @@ void dm_put(struct mapped_device *md) | |||
1379 | } | 1375 | } |
1380 | EXPORT_SYMBOL_GPL(dm_put); | 1376 | EXPORT_SYMBOL_GPL(dm_put); |
1381 | 1377 | ||
1382 | static int dm_wait_for_completion(struct mapped_device *md) | 1378 | static int dm_wait_for_completion(struct mapped_device *md, int interruptible) |
1383 | { | 1379 | { |
1384 | int r = 0; | 1380 | int r = 0; |
1381 | DECLARE_WAITQUEUE(wait, current); | ||
1382 | |||
1383 | dm_unplug_all(md->queue); | ||
1384 | |||
1385 | add_wait_queue(&md->wait, &wait); | ||
1385 | 1386 | ||
1386 | while (1) { | 1387 | while (1) { |
1387 | set_current_state(TASK_INTERRUPTIBLE); | 1388 | set_current_state(interruptible); |
1388 | 1389 | ||
1389 | smp_mb(); | 1390 | smp_mb(); |
1390 | if (!atomic_read(&md->pending)) | 1391 | if (!atomic_read(&md->pending)) |
1391 | break; | 1392 | break; |
1392 | 1393 | ||
1393 | if (signal_pending(current)) { | 1394 | if (interruptible == TASK_INTERRUPTIBLE && |
1395 | signal_pending(current)) { | ||
1394 | r = -EINTR; | 1396 | r = -EINTR; |
1395 | break; | 1397 | break; |
1396 | } | 1398 | } |
@@ -1399,67 +1401,40 @@ static int dm_wait_for_completion(struct mapped_device *md) | |||
1399 | } | 1401 | } |
1400 | set_current_state(TASK_RUNNING); | 1402 | set_current_state(TASK_RUNNING); |
1401 | 1403 | ||
1404 | remove_wait_queue(&md->wait, &wait); | ||
1405 | |||
1402 | return r; | 1406 | return r; |
1403 | } | 1407 | } |
1404 | 1408 | ||
1405 | /* | 1409 | /* |
1406 | * Process the deferred bios | 1410 | * Process the deferred bios |
1407 | */ | 1411 | */ |
1408 | static void __flush_deferred_io(struct mapped_device *md) | 1412 | static void dm_wq_work(struct work_struct *work) |
1409 | { | 1413 | { |
1414 | struct mapped_device *md = container_of(work, struct mapped_device, | ||
1415 | work); | ||
1410 | struct bio *c; | 1416 | struct bio *c; |
1411 | 1417 | ||
1412 | while ((c = bio_list_pop(&md->deferred))) { | 1418 | down_write(&md->io_lock); |
1413 | if (__split_bio(md, c)) | ||
1414 | bio_io_error(c); | ||
1415 | } | ||
1416 | |||
1417 | clear_bit(DMF_BLOCK_IO, &md->flags); | ||
1418 | } | ||
1419 | 1419 | ||
1420 | static void __merge_pushback_list(struct mapped_device *md) | 1420 | next_bio: |
1421 | { | 1421 | spin_lock_irq(&md->deferred_lock); |
1422 | unsigned long flags; | 1422 | c = bio_list_pop(&md->deferred); |
1423 | spin_unlock_irq(&md->deferred_lock); | ||
1423 | 1424 | ||
1424 | spin_lock_irqsave(&md->pushback_lock, flags); | 1425 | if (c) { |
1425 | clear_bit(DMF_NOFLUSH_SUSPENDING, &md->flags); | 1426 | __split_and_process_bio(md, c); |
1426 | bio_list_merge_head(&md->deferred, &md->pushback); | 1427 | goto next_bio; |
1427 | bio_list_init(&md->pushback); | 1428 | } |
1428 | spin_unlock_irqrestore(&md->pushback_lock, flags); | ||
1429 | } | ||
1430 | 1429 | ||
1431 | static void dm_wq_work(struct work_struct *work) | 1430 | clear_bit(DMF_BLOCK_IO, &md->flags); |
1432 | { | ||
1433 | struct dm_wq_req *req = container_of(work, struct dm_wq_req, work); | ||
1434 | struct mapped_device *md = req->md; | ||
1435 | 1431 | ||
1436 | down_write(&md->io_lock); | ||
1437 | switch (req->type) { | ||
1438 | case DM_WQ_FLUSH_DEFERRED: | ||
1439 | __flush_deferred_io(md); | ||
1440 | break; | ||
1441 | default: | ||
1442 | DMERR("dm_wq_work: unrecognised work type %d", req->type); | ||
1443 | BUG(); | ||
1444 | } | ||
1445 | up_write(&md->io_lock); | 1432 | up_write(&md->io_lock); |
1446 | } | 1433 | } |
1447 | 1434 | ||
1448 | static void dm_wq_queue(struct mapped_device *md, int type, void *context, | 1435 | static void dm_queue_flush(struct mapped_device *md) |
1449 | struct dm_wq_req *req) | ||
1450 | { | ||
1451 | req->type = type; | ||
1452 | req->md = md; | ||
1453 | req->context = context; | ||
1454 | INIT_WORK(&req->work, dm_wq_work); | ||
1455 | queue_work(md->wq, &req->work); | ||
1456 | } | ||
1457 | |||
1458 | static void dm_queue_flush(struct mapped_device *md, int type, void *context) | ||
1459 | { | 1436 | { |
1460 | struct dm_wq_req req; | 1437 | queue_work(md->wq, &md->work); |
1461 | |||
1462 | dm_wq_queue(md, type, context, &req); | ||
1463 | flush_workqueue(md->wq); | 1438 | flush_workqueue(md->wq); |
1464 | } | 1439 | } |
1465 | 1440 | ||
@@ -1534,7 +1509,6 @@ static void unlock_fs(struct mapped_device *md) | |||
1534 | int dm_suspend(struct mapped_device *md, unsigned suspend_flags) | 1509 | int dm_suspend(struct mapped_device *md, unsigned suspend_flags) |
1535 | { | 1510 | { |
1536 | struct dm_table *map = NULL; | 1511 | struct dm_table *map = NULL; |
1537 | DECLARE_WAITQUEUE(wait, current); | ||
1538 | int r = 0; | 1512 | int r = 0; |
1539 | int do_lockfs = suspend_flags & DM_SUSPEND_LOCKFS_FLAG ? 1 : 0; | 1513 | int do_lockfs = suspend_flags & DM_SUSPEND_LOCKFS_FLAG ? 1 : 0; |
1540 | int noflush = suspend_flags & DM_SUSPEND_NOFLUSH_FLAG ? 1 : 0; | 1514 | int noflush = suspend_flags & DM_SUSPEND_NOFLUSH_FLAG ? 1 : 0; |
@@ -1584,28 +1558,22 @@ int dm_suspend(struct mapped_device *md, unsigned suspend_flags) | |||
1584 | down_write(&md->io_lock); | 1558 | down_write(&md->io_lock); |
1585 | set_bit(DMF_BLOCK_IO, &md->flags); | 1559 | set_bit(DMF_BLOCK_IO, &md->flags); |
1586 | 1560 | ||
1587 | add_wait_queue(&md->wait, &wait); | ||
1588 | up_write(&md->io_lock); | 1561 | up_write(&md->io_lock); |
1589 | 1562 | ||
1590 | /* unplug */ | ||
1591 | if (map) | ||
1592 | dm_table_unplug_all(map); | ||
1593 | |||
1594 | /* | 1563 | /* |
1595 | * Wait for the already-mapped ios to complete. | 1564 | * Wait for the already-mapped ios to complete. |
1596 | */ | 1565 | */ |
1597 | r = dm_wait_for_completion(md); | 1566 | r = dm_wait_for_completion(md, TASK_INTERRUPTIBLE); |
1598 | 1567 | ||
1599 | down_write(&md->io_lock); | 1568 | down_write(&md->io_lock); |
1600 | remove_wait_queue(&md->wait, &wait); | ||
1601 | 1569 | ||
1602 | if (noflush) | 1570 | if (noflush) |
1603 | __merge_pushback_list(md); | 1571 | clear_bit(DMF_NOFLUSH_SUSPENDING, &md->flags); |
1604 | up_write(&md->io_lock); | 1572 | up_write(&md->io_lock); |
1605 | 1573 | ||
1606 | /* were we interrupted ? */ | 1574 | /* were we interrupted ? */ |
1607 | if (r < 0) { | 1575 | if (r < 0) { |
1608 | dm_queue_flush(md, DM_WQ_FLUSH_DEFERRED, NULL); | 1576 | dm_queue_flush(md); |
1609 | 1577 | ||
1610 | unlock_fs(md); | 1578 | unlock_fs(md); |
1611 | goto out; /* pushback list is already flushed, so skip flush */ | 1579 | goto out; /* pushback list is already flushed, so skip flush */ |
@@ -1645,7 +1613,7 @@ int dm_resume(struct mapped_device *md) | |||
1645 | if (r) | 1613 | if (r) |
1646 | goto out; | 1614 | goto out; |
1647 | 1615 | ||
1648 | dm_queue_flush(md, DM_WQ_FLUSH_DEFERRED, NULL); | 1616 | dm_queue_flush(md); |
1649 | 1617 | ||
1650 | unlock_fs(md); | 1618 | unlock_fs(md); |
1651 | 1619 | ||