diff options
Diffstat (limited to 'drivers/md/dm-raid1.c')
-rw-r--r-- | drivers/md/dm-raid1.c | 37 |
1 files changed, 22 insertions, 15 deletions
diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index 7c081bcbc3cf..9bfd057be686 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c | |||
@@ -22,8 +22,6 @@ | |||
22 | #define DM_MSG_PREFIX "raid1" | 22 | #define DM_MSG_PREFIX "raid1" |
23 | 23 | ||
24 | #define MAX_RECOVERY 1 /* Maximum number of regions recovered in parallel. */ | 24 | #define MAX_RECOVERY 1 /* Maximum number of regions recovered in parallel. */ |
25 | #define DM_IO_PAGES 64 | ||
26 | #define DM_KCOPYD_PAGES 64 | ||
27 | 25 | ||
28 | #define DM_RAID1_HANDLE_ERRORS 0x01 | 26 | #define DM_RAID1_HANDLE_ERRORS 0x01 |
29 | #define errors_handled(p) ((p)->features & DM_RAID1_HANDLE_ERRORS) | 27 | #define errors_handled(p) ((p)->features & DM_RAID1_HANDLE_ERRORS) |
@@ -259,9 +257,9 @@ static int mirror_flush(struct dm_target *ti) | |||
259 | struct dm_io_region io[ms->nr_mirrors]; | 257 | struct dm_io_region io[ms->nr_mirrors]; |
260 | struct mirror *m; | 258 | struct mirror *m; |
261 | struct dm_io_request io_req = { | 259 | struct dm_io_request io_req = { |
262 | .bi_rw = WRITE_BARRIER, | 260 | .bi_rw = WRITE_FLUSH, |
263 | .mem.type = DM_IO_KMEM, | 261 | .mem.type = DM_IO_KMEM, |
264 | .mem.ptr.bvec = NULL, | 262 | .mem.ptr.addr = NULL, |
265 | .client = ms->io_client, | 263 | .client = ms->io_client, |
266 | }; | 264 | }; |
267 | 265 | ||
@@ -629,7 +627,7 @@ static void do_write(struct mirror_set *ms, struct bio *bio) | |||
629 | struct dm_io_region io[ms->nr_mirrors], *dest = io; | 627 | struct dm_io_region io[ms->nr_mirrors], *dest = io; |
630 | struct mirror *m; | 628 | struct mirror *m; |
631 | struct dm_io_request io_req = { | 629 | struct dm_io_request io_req = { |
632 | .bi_rw = WRITE | (bio->bi_rw & WRITE_BARRIER), | 630 | .bi_rw = WRITE | (bio->bi_rw & WRITE_FLUSH_FUA), |
633 | .mem.type = DM_IO_BVEC, | 631 | .mem.type = DM_IO_BVEC, |
634 | .mem.ptr.bvec = bio->bi_io_vec + bio->bi_idx, | 632 | .mem.ptr.bvec = bio->bi_io_vec + bio->bi_idx, |
635 | .notify.fn = write_callback, | 633 | .notify.fn = write_callback, |
@@ -637,6 +635,12 @@ static void do_write(struct mirror_set *ms, struct bio *bio) | |||
637 | .client = ms->io_client, | 635 | .client = ms->io_client, |
638 | }; | 636 | }; |
639 | 637 | ||
638 | if (bio->bi_rw & REQ_DISCARD) { | ||
639 | io_req.bi_rw |= REQ_DISCARD; | ||
640 | io_req.mem.type = DM_IO_KMEM; | ||
641 | io_req.mem.ptr.addr = NULL; | ||
642 | } | ||
643 | |||
640 | for (i = 0, m = ms->mirror; i < ms->nr_mirrors; i++, m++) | 644 | for (i = 0, m = ms->mirror; i < ms->nr_mirrors; i++, m++) |
641 | map_region(dest++, m, bio); | 645 | map_region(dest++, m, bio); |
642 | 646 | ||
@@ -670,7 +674,8 @@ static void do_writes(struct mirror_set *ms, struct bio_list *writes) | |||
670 | bio_list_init(&requeue); | 674 | bio_list_init(&requeue); |
671 | 675 | ||
672 | while ((bio = bio_list_pop(writes))) { | 676 | while ((bio = bio_list_pop(writes))) { |
673 | if (unlikely(bio_empty_barrier(bio))) { | 677 | if ((bio->bi_rw & REQ_FLUSH) || |
678 | (bio->bi_rw & REQ_DISCARD)) { | ||
674 | bio_list_add(&sync, bio); | 679 | bio_list_add(&sync, bio); |
675 | continue; | 680 | continue; |
676 | } | 681 | } |
@@ -835,8 +840,6 @@ static void do_mirror(struct work_struct *work) | |||
835 | do_reads(ms, &reads); | 840 | do_reads(ms, &reads); |
836 | do_writes(ms, &writes); | 841 | do_writes(ms, &writes); |
837 | do_failures(ms, &failures); | 842 | do_failures(ms, &failures); |
838 | |||
839 | dm_table_unplug_all(ms->ti->table); | ||
840 | } | 843 | } |
841 | 844 | ||
842 | /*----------------------------------------------------------------- | 845 | /*----------------------------------------------------------------- |
@@ -882,7 +885,7 @@ static struct mirror_set *alloc_context(unsigned int nr_mirrors, | |||
882 | return NULL; | 885 | return NULL; |
883 | } | 886 | } |
884 | 887 | ||
885 | ms->io_client = dm_io_client_create(DM_IO_PAGES); | 888 | ms->io_client = dm_io_client_create(); |
886 | if (IS_ERR(ms->io_client)) { | 889 | if (IS_ERR(ms->io_client)) { |
887 | ti->error = "Error creating dm_io client"; | 890 | ti->error = "Error creating dm_io client"; |
888 | mempool_destroy(ms->read_record_pool); | 891 | mempool_destroy(ms->read_record_pool); |
@@ -1076,8 +1079,10 @@ static int mirror_ctr(struct dm_target *ti, unsigned int argc, char **argv) | |||
1076 | ti->private = ms; | 1079 | ti->private = ms; |
1077 | ti->split_io = dm_rh_get_region_size(ms->rh); | 1080 | ti->split_io = dm_rh_get_region_size(ms->rh); |
1078 | ti->num_flush_requests = 1; | 1081 | ti->num_flush_requests = 1; |
1082 | ti->num_discard_requests = 1; | ||
1079 | 1083 | ||
1080 | ms->kmirrord_wq = create_singlethread_workqueue("kmirrord"); | 1084 | ms->kmirrord_wq = alloc_workqueue("kmirrord", |
1085 | WQ_NON_REENTRANT | WQ_MEM_RECLAIM, 0); | ||
1081 | if (!ms->kmirrord_wq) { | 1086 | if (!ms->kmirrord_wq) { |
1082 | DMERR("couldn't start kmirrord"); | 1087 | DMERR("couldn't start kmirrord"); |
1083 | r = -ENOMEM; | 1088 | r = -ENOMEM; |
@@ -1110,9 +1115,11 @@ static int mirror_ctr(struct dm_target *ti, unsigned int argc, char **argv) | |||
1110 | goto err_destroy_wq; | 1115 | goto err_destroy_wq; |
1111 | } | 1116 | } |
1112 | 1117 | ||
1113 | r = dm_kcopyd_client_create(DM_KCOPYD_PAGES, &ms->kcopyd_client); | 1118 | ms->kcopyd_client = dm_kcopyd_client_create(); |
1114 | if (r) | 1119 | if (IS_ERR(ms->kcopyd_client)) { |
1120 | r = PTR_ERR(ms->kcopyd_client); | ||
1115 | goto err_destroy_wq; | 1121 | goto err_destroy_wq; |
1122 | } | ||
1116 | 1123 | ||
1117 | wakeup_mirrord(ms); | 1124 | wakeup_mirrord(ms); |
1118 | return 0; | 1125 | return 0; |
@@ -1130,7 +1137,7 @@ static void mirror_dtr(struct dm_target *ti) | |||
1130 | 1137 | ||
1131 | del_timer_sync(&ms->timer); | 1138 | del_timer_sync(&ms->timer); |
1132 | flush_workqueue(ms->kmirrord_wq); | 1139 | flush_workqueue(ms->kmirrord_wq); |
1133 | flush_scheduled_work(); | 1140 | flush_work_sync(&ms->trigger_event); |
1134 | dm_kcopyd_client_destroy(ms->kcopyd_client); | 1141 | dm_kcopyd_client_destroy(ms->kcopyd_client); |
1135 | destroy_workqueue(ms->kmirrord_wq); | 1142 | destroy_workqueue(ms->kmirrord_wq); |
1136 | free_context(ms, ti, ms->nr_mirrors); | 1143 | free_context(ms, ti, ms->nr_mirrors); |
@@ -1203,7 +1210,7 @@ static int mirror_end_io(struct dm_target *ti, struct bio *bio, | |||
1203 | * We need to dec pending if this was a write. | 1210 | * We need to dec pending if this was a write. |
1204 | */ | 1211 | */ |
1205 | if (rw == WRITE) { | 1212 | if (rw == WRITE) { |
1206 | if (likely(!bio_empty_barrier(bio))) | 1213 | if (!(bio->bi_rw & REQ_FLUSH)) |
1207 | dm_rh_dec(ms->rh, map_context->ll); | 1214 | dm_rh_dec(ms->rh, map_context->ll); |
1208 | return error; | 1215 | return error; |
1209 | } | 1216 | } |
@@ -1406,7 +1413,7 @@ static int mirror_iterate_devices(struct dm_target *ti, | |||
1406 | 1413 | ||
1407 | static struct target_type mirror_target = { | 1414 | static struct target_type mirror_target = { |
1408 | .name = "mirror", | 1415 | .name = "mirror", |
1409 | .version = {1, 12, 0}, | 1416 | .version = {1, 12, 1}, |
1410 | .module = THIS_MODULE, | 1417 | .module = THIS_MODULE, |
1411 | .ctr = mirror_ctr, | 1418 | .ctr = mirror_ctr, |
1412 | .dtr = mirror_dtr, | 1419 | .dtr = mirror_dtr, |