diff options
author | Ming Lei <tom.leiming@gmail.com> | 2017-02-14 23:29:01 +0800 |
---|---|---|
committer | Shaohua Li <shli@fb.com> | 2017-02-15 11:23:49 -0800 |
commit | 8e58e327e25c7fffc3fb79a24c76637bdda37716 (patch) | |
tree | 8fff78e94d9383628b0ffa09438c399116732897 /drivers/md/raid1.c | |
parent | 10273170fd5602d8090b1312e66ad4746ab02c94 (diff) |
md/raid1: use bio_clone_bioset_partial() in case of write behind
Write behind need to replace pages in bio's bvecs, and we have
to clone a fresh bio with new bvec table, so use the introduced
bio_clone_bioset_partial() for it.
For other bio_clone_mddev() cases, we will use fast clone since
they don't need to touch bvec table.
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Ming Lei <tom.leiming@gmail.com>
Signed-off-by: Shaohua Li <shli@fb.com>
Diffstat (limited to 'drivers/md/raid1.c')
-rw-r--r-- | drivers/md/raid1.c | 20 |
1 files changed, 15 insertions, 5 deletions
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 7b0f647bcccb..691d6d9bf740 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -1345,13 +1345,12 @@ static void raid1_write_request(struct mddev *mddev, struct bio *bio, first_clone = 1; for (i = 0; i < disks; i++) { - struct bio *mbio; + struct bio *mbio = NULL; + sector_t offset; if (!r1_bio->bios[i]) continue; - mbio = bio_clone_mddev(bio, GFP_NOIO, mddev); - bio_trim(mbio, r1_bio->sector - bio->bi_iter.bi_sector, - max_sectors); + offset = r1_bio->sector - bio->bi_iter.bi_sector; if (first_clone) { /* do behind I/O ? @@ -1361,8 +1360,13 @@ static void raid1_write_request(struct mddev *mddev, struct bio *bio, if (bitmap && (atomic_read(&bitmap->behind_writes) < mddev->bitmap_info.max_write_behind) && - !waitqueue_active(&bitmap->behind_wait)) + !waitqueue_active(&bitmap->behind_wait)) { + mbio = bio_clone_bioset_partial(bio, GFP_NOIO, + mddev->bio_set, + offset, + max_sectors); alloc_behind_pages(mbio, r1_bio); + } bitmap_startwrite(bitmap, r1_bio->sector, r1_bio->sectors, @@ -1370,6 +1374,12 @@ static void raid1_write_request(struct mddev *mddev, struct bio *bio, &r1_bio->state)); first_clone = 0; } + + if (!mbio) { + mbio = bio_clone_mddev(bio, GFP_NOIO, mddev); + bio_trim(mbio, offset, max_sectors); + } + if (r1_bio->behind_bvecs) { struct bio_vec *bvec; int j; |