aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShaohua Li <shli@fb.com>2017-02-21 14:27:57 -0800
committerShaohua Li <shli@fb.com>2017-02-23 11:59:44 -0800
commit1ec492232ed659acde8cc00b9ecc7529778e03e1 (patch)
tree5fff4d0691ad377deba45e888e5339708064ba96
parentmd/raid1: handle flush request correctly (diff)
downloadlinux-dev-1ec492232ed659acde8cc00b9ecc7529778e03e1.tar.xz
linux-dev-1ec492232ed659acde8cc00b9ecc7529778e03e1.zip
md/raid1: fix write behind issues introduced by bio_clone_bioset_partial
There are two issues, introduced by commit 8e58e32(md/raid1: use bio_clone_bioset_partial() in case of write behind): - bio_clone_bioset_partial() uses bytes instead of sectors as parameters - in writebehind mode, we return bio if all !writemostly disk bios finish, which could happen before writemostly disk bios run. So all writemostly disk bios should have their bvec. Here we just make sure all bios are cloned instead of fast cloned. Reviewed-by: Ming Lei <tom.leiming@gmail.com> Signed-off-by: Shaohua Li <shli@fb.com>
-rw-r--r--drivers/md/raid1.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 8901f0c8c775..d4e8796b4569 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -1472,8 +1472,8 @@ static void raid1_write_request(struct mddev *mddev, struct bio *bio)
!waitqueue_active(&bitmap->behind_wait)) {
mbio = bio_clone_bioset_partial(bio, GFP_NOIO,
mddev->bio_set,
- offset,
- max_sectors);
+ offset << 9,
+ max_sectors << 9);
alloc_behind_pages(mbio, r1_bio);
}
@@ -1485,8 +1485,15 @@ static void raid1_write_request(struct mddev *mddev, struct bio *bio)
}
if (!mbio) {
- mbio = bio_clone_fast(bio, GFP_NOIO, mddev->bio_set);
- bio_trim(mbio, offset, max_sectors);
+ if (r1_bio->behind_bvecs)
+ mbio = bio_clone_bioset_partial(bio, GFP_NOIO,
+ mddev->bio_set,
+ offset << 9,
+ max_sectors << 9);
+ else {
+ mbio = bio_clone_fast(bio, GFP_NOIO, mddev->bio_set);
+ bio_trim(mbio, offset, max_sectors);
+ }
}
if (r1_bio->behind_bvecs) {