aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorShaohua Li <shli@fusionio.com>2012-10-10 22:28:54 -0400
committerNeilBrown <neilb@suse.de>2012-10-10 22:28:54 -0400
commit2ff8cc2c6d4e323de71a42affeb3041fa17d5b10 (patch)
tree12534cc77da4d06872e29b7eb114ca2c57b97478 /drivers
parentc83057a1f4f987327c49448b046d9625c612ed8e (diff)
md: raid 1 supports TRIM
This makes md raid 1 support TRIM. If one disk supports discard and another not, or one has discard_zero_data and another not, there could be inconsistent between data from such disks. But this should not matter, discarded data is useless. This will add extra copy in rebuild though. Signed-off-by: Shaohua Li <shli@fusionio.com> Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/md/raid1.c23
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);