Patch "md/raid1: fix writebehind bio clone" has been added to the 4.12-stable tree
Subsystems (2)
This is a note to let you know that I've just added the patch titled
md/raid1: fix writebehind bio clone
to the 4.12-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
md-raid1-fix-writebehind-bio-clone.patch
and it can be found in the queue-4.12 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
16d56e2fcc1fc15b981369653c3b41d7ff0b443dMon Sep 17 00:00:00 2001
From: Shaohua Li <[email protected]>
Date: Mon, 17 Jul 2017 14:33:48 -0700
Subject: md/raid1: fix writebehind bio clone
From: Shaohua Li <[email protected]>
commit 16d56e2fcc1fc15b981369653c3b41d7ff0b443d upstream.
After bio is submitted, we should not clone it as its bi_iter might be invalid by driver. This is the case of behind_master_bio. In certain situration, we could dispatch behind_master_bio immediately for the first disk and then clone it for other disks.
https://bugzilla.kernel.org/show_bug.cgi?id=196383
Fix: 841c1316c7da(md: raid1: improve write behind)
--- drivers/md/raid1.c | 34 +++++++++++++--------------------- 1 file changed, 13 insertions(+), 21 deletions(-)
drivers/md/raid1.c +13 -21
@@ -491,10 +491,6 @@ static void raid1_end_write_request(stru }if (behind) { -/* we release behind master bio when all write are done */ -if (r1_bio->behind_master_bio == bio) - to_put =NULL ; -if (test_bit (WriteMostly, &rdev->flags))atomic_dec (&r1_bio->behind_remaining);
@@ -1087,7 +1083,7 @@ static void unfreeze_array(struct r1confwake_up (&conf->wait_barrier); } -static struct bio *alloc_behind_master_bio (struct r1bio *r1_bio, +static void alloc_behind_master_bio (struct r1bio *r1_bio,struct bio *bio) {int size = bio->bi_iter.bi_size;
@@ -1097,11 +1093,13 @@ static struct bio *alloc_behind_master_b behind_bio =bio_alloc_mddev (GFP_NOIO , vcnt, r1_bio->mddev);if (!behind_bio) - goto fail; +return ;/* discard op, we don't support writezero/writesame yet */ -if (!bio_has_data (bio)) +if (!bio_has_data (bio)) { + behind_bio->bi_iter.bi_size = size; goto skip_copy; + }while (i < vcnt && size) {struct page *page;
@@ -1122,14 +1120,13 @@ skip_copy: r1_bio->behind_master_bio = behind_bio;;set_bit (R1BIO_BehindIO, &r1_bio->state); -return behind_bio; +return ; free_pages:pr_debug ("%dB behind alloc failed, doing sync I/O\n" , bio->bi_iter.bi_size);bio_free_pages (behind_bio); -fail: -return behind_bio; +bio_put (behind_bio); }struct raid1_plug_cb {
@@ -1482,7 +1479,7 @@ static void raid1_write_request(struct m (atomic_read(&bitmap->behind_writes) < mddev->bitmap_info.max_write_behind) && !waitqueue_active(&bitmap->behind_wait)) { - mbio =alloc_behind_master_bio (r1_bio, bio); +alloc_behind_master_bio (r1_bio, bio); } bitmap_startwrite(bitmap, r1_bio->sector,
@@ -1492,14 +1489,11 @@ static void raid1_write_request(struct m first_clone =0 ; } -if (!mbio) { -if (r1_bio->behind_master_bio) - mbio =bio_clone_fast (r1_bio->behind_master_bio, -GFP_NOIO , - mddev->bio_set); -else - mbio =bio_clone_fast (bio,GFP_NOIO , mddev->bio_set); - } +if (r1_bio->behind_master_bio) + mbio =bio_clone_fast (r1_bio->behind_master_bio, +GFP_NOIO , mddev->bio_set); +else + mbio =bio_clone_fast (bio,GFP_NOIO , mddev->bio_set);if (r1_bio->behind_master_bio) {if (test_bit (WriteMostly, &conf->mirrors[i].rdev->flags))
@@ -2367,8 +2361,6 @@ static int narrow_write_error(struct r1b wbio =bio_clone_fast (r1_bio->behind_master_bio,GFP_NOIO , mddev->bio_set); -/* We really need a _all clone */ - wbio->bi_iter = (struct bvec_iter ){0 }; }else { wbio =bio_clone_fast (r1_bio->master_bio,GFP_NOIO , mddev->bio_set);
Patches currently in stable-queue which might be from [email protected] are
queue-4.12/md-remove-idx-from-struct-resync_pages.patch queue-4.12/md-raid1-fix-writebehind-bio-clone.patch queue-4.12/md-raid5-add-thread_group-worker-async_tx_issue_pending_all.patch