Commit 1ec49223 authored by Shaohua Li's avatar Shaohua Li

md/raid1: fix write behind issues introduced by bio_clone_bioset_partial

There are two issues, introduced by commit 8e58e327(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: default avatarMing Lei <tom.leiming@gmail.com>
Signed-off-by: default avatarShaohua Li <shli@fb.com>
parent aff8da09
...@@ -1472,8 +1472,8 @@ static void raid1_write_request(struct mddev *mddev, struct bio *bio) ...@@ -1472,8 +1472,8 @@ static void raid1_write_request(struct mddev *mddev, struct bio *bio)
!waitqueue_active(&bitmap->behind_wait)) { !waitqueue_active(&bitmap->behind_wait)) {
mbio = bio_clone_bioset_partial(bio, GFP_NOIO, mbio = bio_clone_bioset_partial(bio, GFP_NOIO,
mddev->bio_set, mddev->bio_set,
offset, offset << 9,
max_sectors); max_sectors << 9);
alloc_behind_pages(mbio, r1_bio); alloc_behind_pages(mbio, r1_bio);
} }
...@@ -1485,9 +1485,16 @@ static void raid1_write_request(struct mddev *mddev, struct bio *bio) ...@@ -1485,9 +1485,16 @@ static void raid1_write_request(struct mddev *mddev, struct bio *bio)
} }
if (!mbio) { if (!mbio) {
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); mbio = bio_clone_fast(bio, GFP_NOIO, mddev->bio_set);
bio_trim(mbio, offset, max_sectors); bio_trim(mbio, offset, max_sectors);
} }
}
if (r1_bio->behind_bvecs) { if (r1_bio->behind_bvecs) {
struct bio_vec *bvec; struct bio_vec *bvec;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment