瀏覽代碼

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>
Shaohua Li 8 年之前
父節點
當前提交
1ec492232e
共有 1 個文件被更改,包括 11 次插入4 次删除
  1. 11 4
      drivers/md/raid1.c

+ 11 - 4
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) {