Skip to content

Commit

Permalink
md: raid 1 supports TRIM
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Shaohua Li authored and NeilBrown committed Oct 11, 2012
1 parent c83057a commit 2ff8cc2
Showing 1 changed file with 21 additions and 2 deletions.
23 changes: 21 additions & 2 deletions drivers/md/raid1.c
Original file line number Diff line number Diff line change
Expand Up @@ -781,7 +781,12 @@ static void flush_pending_writes(struct r1conf *conf)
while (bio) { /* submit pending writes */
struct bio *next = bio->bi_next;
bio->bi_next = NULL;
generic_make_request(bio);
if (unlikely((bio->bi_rw & REQ_DISCARD) &&
!blk_queue_discard(bdev_get_queue(bio->bi_bdev))))
/* Just ignore it */
bio_endio(bio, 0);
else
generic_make_request(bio);
bio = next;
}
} else
Expand Down Expand Up @@ -994,6 +999,8 @@ static void make_request(struct mddev *mddev, struct bio * bio)
const int rw = bio_data_dir(bio);
const unsigned long do_sync = (bio->bi_rw & REQ_SYNC);
const unsigned long do_flush_fua = (bio->bi_rw & (REQ_FLUSH | REQ_FUA));
const unsigned long do_discard = (bio->bi_rw
& (REQ_DISCARD | REQ_SECURE));
struct md_rdev *blocked_rdev;
struct blk_plug_cb *cb;
struct raid1_plug_cb *plug = NULL;
Expand Down Expand Up @@ -1295,7 +1302,7 @@ static void make_request(struct mddev *mddev, struct bio * bio)
conf->mirrors[i].rdev->data_offset);
mbio->bi_bdev = conf->mirrors[i].rdev->bdev;
mbio->bi_end_io = raid1_end_write_request;
mbio->bi_rw = WRITE | do_flush_fua | do_sync;
mbio->bi_rw = WRITE | do_flush_fua | do_sync | do_discard;
mbio->bi_private = r1_bio;

atomic_inc(&r1_bio->remaining);
Expand Down Expand Up @@ -1549,6 +1556,8 @@ static int raid1_add_disk(struct mddev *mddev, struct md_rdev *rdev)
clear_bit(Unmerged, &rdev->flags);
}
md_integrity_add_rdev(rdev, mddev);
if (blk_queue_discard(bdev_get_queue(rdev->bdev)))
queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, mddev->queue);
print_conf(conf);
return err;
}
Expand Down Expand Up @@ -2783,6 +2792,7 @@ static int run(struct mddev *mddev)
int i;
struct md_rdev *rdev;
int ret;
bool discard_supported = false;

if (mddev->level != 1) {
printk(KERN_ERR "md/raid1:%s: raid level not set to mirroring (%d)\n",
Expand Down Expand Up @@ -2812,6 +2822,8 @@ static int run(struct mddev *mddev)
continue;
disk_stack_limits(mddev->gendisk, rdev->bdev,
rdev->data_offset << 9);
if (blk_queue_discard(bdev_get_queue(rdev->bdev)))
discard_supported = true;
}

mddev->degraded = 0;
Expand Down Expand Up @@ -2846,6 +2858,13 @@ static int run(struct mddev *mddev)
mddev->queue->backing_dev_info.congested_fn = raid1_congested;
mddev->queue->backing_dev_info.congested_data = mddev;
blk_queue_merge_bvec(mddev->queue, raid1_mergeable_bvec);

if (discard_supported)
queue_flag_set_unlocked(QUEUE_FLAG_DISCARD,
mddev->queue);
else
queue_flag_clear_unlocked(QUEUE_FLAG_DISCARD,
mddev->queue);
}

ret = md_integrity_register(mddev);
Expand Down

0 comments on commit 2ff8cc2

Please sign in to comment.