diff options
author | Ming Lei <tom.leiming@gmail.com> | 2017-02-14 10:29:01 -0500 |
---|---|---|
committer | Shaohua Li <shli@fb.com> | 2017-02-15 14:23:49 -0500 |
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, | |||
1345 | 1345 | ||
1346 | first_clone = 1; | 1346 | first_clone = 1; |
1347 | for (i = 0; i < disks; i++) { | 1347 | for (i = 0; i < disks; i++) { |
1348 | struct bio *mbio; | 1348 | struct bio *mbio = NULL; |
1349 | sector_t offset; | ||
1349 | if (!r1_bio->bios[i]) | 1350 | if (!r1_bio->bios[i]) |
1350 | continue; | 1351 | continue; |
1351 | 1352 | ||
1352 | mbio = bio_clone_mddev(bio, GFP_NOIO, mddev); | 1353 | offset = r1_bio->sector - bio->bi_iter.bi_sector; |
1353 | bio_trim(mbio, r1_bio->sector - bio->bi_iter.bi_sector, | ||
1354 | max_sectors); | ||
1355 | 1354 | ||
1356 | if (first_clone) { | 1355 | if (first_clone) { |
1357 | /* do behind I/O ? | 1356 | /* do behind I/O ? |
@@ -1361,8 +1360,13 @@ static void raid1_write_request(struct mddev *mddev, struct bio *bio, | |||
1361 | if (bitmap && | 1360 | if (bitmap && |
1362 | (atomic_read(&bitmap->behind_writes) | 1361 | (atomic_read(&bitmap->behind_writes) |
1363 | < mddev->bitmap_info.max_write_behind) && | 1362 | < mddev->bitmap_info.max_write_behind) && |
1364 | !waitqueue_active(&bitmap->behind_wait)) | 1363 | !waitqueue_active(&bitmap->behind_wait)) { |
1364 | mbio = bio_clone_bioset_partial(bio, GFP_NOIO, | ||
1365 | mddev->bio_set, | ||
1366 | offset, | ||
1367 | max_sectors); | ||
1365 | alloc_behind_pages(mbio, r1_bio); | 1368 | alloc_behind_pages(mbio, r1_bio); |
1369 | } | ||
1366 | 1370 | ||
1367 | bitmap_startwrite(bitmap, r1_bio->sector, | 1371 | bitmap_startwrite(bitmap, r1_bio->sector, |
1368 | r1_bio->sectors, | 1372 | r1_bio->sectors, |
@@ -1370,6 +1374,12 @@ static void raid1_write_request(struct mddev *mddev, struct bio *bio, | |||
1370 | &r1_bio->state)); | 1374 | &r1_bio->state)); |
1371 | first_clone = 0; | 1375 | first_clone = 0; |
1372 | } | 1376 | } |
1377 | |||
1378 | if (!mbio) { | ||
1379 | mbio = bio_clone_mddev(bio, GFP_NOIO, mddev); | ||
1380 | bio_trim(mbio, offset, max_sectors); | ||
1381 | } | ||
1382 | |||
1373 | if (r1_bio->behind_bvecs) { | 1383 | if (r1_bio->behind_bvecs) { |
1374 | struct bio_vec *bvec; | 1384 | struct bio_vec *bvec; |
1375 | int j; | 1385 | int j; |