diff options
Diffstat (limited to 'drivers/md/dm-raid1.c')
-rw-r--r-- | drivers/md/dm-raid1.c | 19 |
1 files changed, 14 insertions, 5 deletions
diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index 19a59b041c27..dee326775c60 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c | |||
@@ -261,7 +261,7 @@ static int mirror_flush(struct dm_target *ti) | |||
261 | struct dm_io_request io_req = { | 261 | struct dm_io_request io_req = { |
262 | .bi_rw = WRITE_FLUSH, | 262 | .bi_rw = WRITE_FLUSH, |
263 | .mem.type = DM_IO_KMEM, | 263 | .mem.type = DM_IO_KMEM, |
264 | .mem.ptr.bvec = NULL, | 264 | .mem.ptr.addr = NULL, |
265 | .client = ms->io_client, | 265 | .client = ms->io_client, |
266 | }; | 266 | }; |
267 | 267 | ||
@@ -637,6 +637,12 @@ static void do_write(struct mirror_set *ms, struct bio *bio) | |||
637 | .client = ms->io_client, | 637 | .client = ms->io_client, |
638 | }; | 638 | }; |
639 | 639 | ||
640 | if (bio->bi_rw & REQ_DISCARD) { | ||
641 | io_req.bi_rw |= REQ_DISCARD; | ||
642 | io_req.mem.type = DM_IO_KMEM; | ||
643 | io_req.mem.ptr.addr = NULL; | ||
644 | } | ||
645 | |||
640 | for (i = 0, m = ms->mirror; i < ms->nr_mirrors; i++, m++) | 646 | for (i = 0, m = ms->mirror; i < ms->nr_mirrors; i++, m++) |
641 | map_region(dest++, m, bio); | 647 | map_region(dest++, m, bio); |
642 | 648 | ||
@@ -670,7 +676,8 @@ static void do_writes(struct mirror_set *ms, struct bio_list *writes) | |||
670 | bio_list_init(&requeue); | 676 | bio_list_init(&requeue); |
671 | 677 | ||
672 | while ((bio = bio_list_pop(writes))) { | 678 | while ((bio = bio_list_pop(writes))) { |
673 | if (bio->bi_rw & REQ_FLUSH) { | 679 | if ((bio->bi_rw & REQ_FLUSH) || |
680 | (bio->bi_rw & REQ_DISCARD)) { | ||
674 | bio_list_add(&sync, bio); | 681 | bio_list_add(&sync, bio); |
675 | continue; | 682 | continue; |
676 | } | 683 | } |
@@ -1076,8 +1083,10 @@ static int mirror_ctr(struct dm_target *ti, unsigned int argc, char **argv) | |||
1076 | ti->private = ms; | 1083 | ti->private = ms; |
1077 | ti->split_io = dm_rh_get_region_size(ms->rh); | 1084 | ti->split_io = dm_rh_get_region_size(ms->rh); |
1078 | ti->num_flush_requests = 1; | 1085 | ti->num_flush_requests = 1; |
1086 | ti->num_discard_requests = 1; | ||
1079 | 1087 | ||
1080 | ms->kmirrord_wq = create_singlethread_workqueue("kmirrord"); | 1088 | ms->kmirrord_wq = alloc_workqueue("kmirrord", |
1089 | WQ_NON_REENTRANT | WQ_MEM_RECLAIM, 0); | ||
1081 | if (!ms->kmirrord_wq) { | 1090 | if (!ms->kmirrord_wq) { |
1082 | DMERR("couldn't start kmirrord"); | 1091 | DMERR("couldn't start kmirrord"); |
1083 | r = -ENOMEM; | 1092 | r = -ENOMEM; |
@@ -1130,7 +1139,7 @@ static void mirror_dtr(struct dm_target *ti) | |||
1130 | 1139 | ||
1131 | del_timer_sync(&ms->timer); | 1140 | del_timer_sync(&ms->timer); |
1132 | flush_workqueue(ms->kmirrord_wq); | 1141 | flush_workqueue(ms->kmirrord_wq); |
1133 | flush_scheduled_work(); | 1142 | flush_work_sync(&ms->trigger_event); |
1134 | dm_kcopyd_client_destroy(ms->kcopyd_client); | 1143 | dm_kcopyd_client_destroy(ms->kcopyd_client); |
1135 | destroy_workqueue(ms->kmirrord_wq); | 1144 | destroy_workqueue(ms->kmirrord_wq); |
1136 | free_context(ms, ti, ms->nr_mirrors); | 1145 | free_context(ms, ti, ms->nr_mirrors); |
@@ -1406,7 +1415,7 @@ static int mirror_iterate_devices(struct dm_target *ti, | |||
1406 | 1415 | ||
1407 | static struct target_type mirror_target = { | 1416 | static struct target_type mirror_target = { |
1408 | .name = "mirror", | 1417 | .name = "mirror", |
1409 | .version = {1, 12, 0}, | 1418 | .version = {1, 12, 1}, |
1410 | .module = THIS_MODULE, | 1419 | .module = THIS_MODULE, |
1411 | .ctr = mirror_ctr, | 1420 | .ctr = mirror_ctr, |
1412 | .dtr = mirror_dtr, | 1421 | .dtr = mirror_dtr, |