diff options
Diffstat (limited to 'drivers/md')
-rw-r--r-- | drivers/md/raid1.c | 23 |
1 files changed, 21 insertions, 2 deletions
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 611b5f797618..05c557e8f862 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c | |||
@@ -781,7 +781,12 @@ static void flush_pending_writes(struct r1conf *conf) | |||
781 | while (bio) { /* submit pending writes */ | 781 | while (bio) { /* submit pending writes */ |
782 | struct bio *next = bio->bi_next; | 782 | struct bio *next = bio->bi_next; |
783 | bio->bi_next = NULL; | 783 | bio->bi_next = NULL; |
784 | generic_make_request(bio); | 784 | if (unlikely((bio->bi_rw & REQ_DISCARD) && |
785 | !blk_queue_discard(bdev_get_queue(bio->bi_bdev)))) | ||
786 | /* Just ignore it */ | ||
787 | bio_endio(bio, 0); | ||
788 | else | ||
789 | generic_make_request(bio); | ||
785 | bio = next; | 790 | bio = next; |
786 | } | 791 | } |
787 | } else | 792 | } else |
@@ -994,6 +999,8 @@ static void make_request(struct mddev *mddev, struct bio * bio) | |||
994 | const int rw = bio_data_dir(bio); | 999 | const int rw = bio_data_dir(bio); |
995 | const unsigned long do_sync = (bio->bi_rw & REQ_SYNC); | 1000 | const unsigned long do_sync = (bio->bi_rw & REQ_SYNC); |
996 | const unsigned long do_flush_fua = (bio->bi_rw & (REQ_FLUSH | REQ_FUA)); | 1001 | const unsigned long do_flush_fua = (bio->bi_rw & (REQ_FLUSH | REQ_FUA)); |
1002 | const unsigned long do_discard = (bio->bi_rw | ||
1003 | & (REQ_DISCARD | REQ_SECURE)); | ||
997 | struct md_rdev *blocked_rdev; | 1004 | struct md_rdev *blocked_rdev; |
998 | struct blk_plug_cb *cb; | 1005 | struct blk_plug_cb *cb; |
999 | struct raid1_plug_cb *plug = NULL; | 1006 | struct raid1_plug_cb *plug = NULL; |
@@ -1295,7 +1302,7 @@ read_again: | |||
1295 | conf->mirrors[i].rdev->data_offset); | 1302 | conf->mirrors[i].rdev->data_offset); |
1296 | mbio->bi_bdev = conf->mirrors[i].rdev->bdev; | 1303 | mbio->bi_bdev = conf->mirrors[i].rdev->bdev; |
1297 | mbio->bi_end_io = raid1_end_write_request; | 1304 | mbio->bi_end_io = raid1_end_write_request; |
1298 | mbio->bi_rw = WRITE | do_flush_fua | do_sync; | 1305 | mbio->bi_rw = WRITE | do_flush_fua | do_sync | do_discard; |
1299 | mbio->bi_private = r1_bio; | 1306 | mbio->bi_private = r1_bio; |
1300 | 1307 | ||
1301 | atomic_inc(&r1_bio->remaining); | 1308 | atomic_inc(&r1_bio->remaining); |
@@ -1549,6 +1556,8 @@ static int raid1_add_disk(struct mddev *mddev, struct md_rdev *rdev) | |||
1549 | clear_bit(Unmerged, &rdev->flags); | 1556 | clear_bit(Unmerged, &rdev->flags); |
1550 | } | 1557 | } |
1551 | md_integrity_add_rdev(rdev, mddev); | 1558 | md_integrity_add_rdev(rdev, mddev); |
1559 | if (blk_queue_discard(bdev_get_queue(rdev->bdev))) | ||
1560 | queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, mddev->queue); | ||
1552 | print_conf(conf); | 1561 | print_conf(conf); |
1553 | return err; | 1562 | return err; |
1554 | } | 1563 | } |
@@ -2783,6 +2792,7 @@ static int run(struct mddev *mddev) | |||
2783 | int i; | 2792 | int i; |
2784 | struct md_rdev *rdev; | 2793 | struct md_rdev *rdev; |
2785 | int ret; | 2794 | int ret; |
2795 | bool discard_supported = false; | ||
2786 | 2796 | ||
2787 | if (mddev->level != 1) { | 2797 | if (mddev->level != 1) { |
2788 | printk(KERN_ERR "md/raid1:%s: raid level not set to mirroring (%d)\n", | 2798 | printk(KERN_ERR "md/raid1:%s: raid level not set to mirroring (%d)\n", |
@@ -2812,6 +2822,8 @@ static int run(struct mddev *mddev) | |||
2812 | continue; | 2822 | continue; |
2813 | disk_stack_limits(mddev->gendisk, rdev->bdev, | 2823 | disk_stack_limits(mddev->gendisk, rdev->bdev, |
2814 | rdev->data_offset << 9); | 2824 | rdev->data_offset << 9); |
2825 | if (blk_queue_discard(bdev_get_queue(rdev->bdev))) | ||
2826 | discard_supported = true; | ||
2815 | } | 2827 | } |
2816 | 2828 | ||
2817 | mddev->degraded = 0; | 2829 | mddev->degraded = 0; |
@@ -2846,6 +2858,13 @@ static int run(struct mddev *mddev) | |||
2846 | mddev->queue->backing_dev_info.congested_fn = raid1_congested; | 2858 | mddev->queue->backing_dev_info.congested_fn = raid1_congested; |
2847 | mddev->queue->backing_dev_info.congested_data = mddev; | 2859 | mddev->queue->backing_dev_info.congested_data = mddev; |
2848 | blk_queue_merge_bvec(mddev->queue, raid1_mergeable_bvec); | 2860 | blk_queue_merge_bvec(mddev->queue, raid1_mergeable_bvec); |
2861 | |||
2862 | if (discard_supported) | ||
2863 | queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, | ||
2864 | mddev->queue); | ||
2865 | else | ||
2866 | queue_flag_clear_unlocked(QUEUE_FLAG_DISCARD, | ||
2867 | mddev->queue); | ||
2849 | } | 2868 | } |
2850 | 2869 | ||
2851 | ret = md_integrity_register(mddev); | 2870 | ret = md_integrity_register(mddev); |