aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/raid1.c
diff options
context:
space:
mode:
authorMing Lei <tom.leiming@gmail.com>2017-02-14 10:29:01 -0500
committerShaohua Li <shli@fb.com>2017-02-15 14:23:49 -0500
commit8e58e327e25c7fffc3fb79a24c76637bdda37716 (patch)
tree8fff78e94d9383628b0ffa09438c399116732897 /drivers/md/raid1.c
parent10273170fd5602d8090b1312e66ad4746ab02c94 (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.c20
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;