* [PATCH 1/2] block: add bio_rewind() to reset bio_vec
2013-07-08 20:06 ` Joe Lawrence
@ 2013-07-08 20:25 ` Joe Lawrence
2013-07-14 23:40 ` NeilBrown
2013-07-08 20:25 ` [PATCH 2/2] md: raid1: use bio_rewind() before bio_copy_data() Joe Lawrence
2013-07-17 6:12 ` RAID1 repair GPF crash w/3.10-rc7 NeilBrown
2 siblings, 1 reply; 10+ messages in thread
From: Joe Lawrence @ 2013-07-08 20:25 UTC (permalink / raw)
To: linux-raid; +Cc: NeilBrown, kmo, Joe Lawrence
Provide a mechanism for drivers to "rewind" a bio, essentially undoing
all bio_advance() calls on the bio. After the rewind, the bio idx will
be 0, size and sector reset, and each bio_vec len and offset restored to
their initial values.
Suggested-by: NeilBrown <neilb@suse.de>
Signed-off-by: Joe Lawrence <joe.lawrence@stratus.com>
---
fs/bio.c | 27 +++++++++++++++++++++++++++
include/linux/bio.h | 1 +
2 files changed, 28 insertions(+)
diff --git a/fs/bio.c b/fs/bio.c
index 94bbc04..04309df 100644
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -833,6 +833,33 @@ void bio_advance(struct bio *bio, unsigned bytes)
EXPORT_SYMBOL(bio_advance);
/**
+ * bio_rewind - reset a bio to its start
+ * @bio: bio to rewind
+ *
+ * This resets bi_sector, bi_size and bi_idx; completely undoing all
+ * bio_advances on the @bio.
+ */
+void bio_rewind(struct bio *bio)
+{
+ int bytes = 0;
+
+ if (bio->bi_idx < bio->bi_vcnt && bio_iovec(bio)->bv_offset > 0) {
+ bytes = bio_iovec(bio)->bv_offset;
+ bio_iovec(bio)->bv_offset -= bytes;
+ bio_iovec(bio)->bv_len += bytes;
+ }
+ while (bio->bi_idx) {
+ bio->bi_idx -= 1;
+ bio_iovec(bio)->bv_len += bio_iovec(bio)->bv_offset;
+ bio_iovec(bio)->bv_offset = 0;
+ bytes += bio_iovec(bio)->bv_len;
+ }
+ bio->bi_size += bytes;
+ bio->bi_sector -= bytes >> 9;
+}
+EXPORT_SYMBOL(bio_rewind);
+
+/**
* bio_alloc_pages - allocates a single page for each bvec in a bio
* @bio: bio to allocate pages for
* @gfp_mask: flags for allocation
diff --git a/include/linux/bio.h b/include/linux/bio.h
index ef24466..e2082fb 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -258,6 +258,7 @@ extern int bio_phys_segments(struct request_queue *, struct bio *);
extern int submit_bio_wait(int rw, struct bio *bio);
extern void bio_advance(struct bio *, unsigned);
+extern void bio_rewind(struct bio *);
extern void bio_init(struct bio *);
extern void bio_reset(struct bio *);
--
1.8.1.4
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH 1/2] block: add bio_rewind() to reset bio_vec
2013-07-08 20:25 ` [PATCH 1/2] block: add bio_rewind() to reset bio_vec Joe Lawrence
@ 2013-07-14 23:40 ` NeilBrown
0 siblings, 0 replies; 10+ messages in thread
From: NeilBrown @ 2013-07-14 23:40 UTC (permalink / raw)
To: Jens Axboe; +Cc: Joe Lawrence, linux-raid, kmo
[-- Attachment #1: Type: text/plain, Size: 2745 bytes --]
Hi Jens,
(I tried sending this a week ago but managed to not include your email - no
wonder I didn't get a reply!)
Are you OK with adding this to fs/bio.c?
The follow-on patch which uses it to fix a crash in md in 3.10 is at
http://marc.info/?l=linux-raid&m=137331514131503&w=2
If so: will you submit or should I? Both patches are in my "for-next" and
so should be in linux-next.
If not, I'll just do something local in raid1 to reset the bio before
calling bio_copy_data().
Thanks,
NeilBrown
On Mon, 8 Jul 2013 16:25:13 -0400 Joe Lawrence <joe.lawrence@stratus.com>
wrote:
> Provide a mechanism for drivers to "rewind" a bio, essentially undoing
> all bio_advance() calls on the bio. After the rewind, the bio idx will
> be 0, size and sector reset, and each bio_vec len and offset restored to
> their initial values.
>
> Suggested-by: NeilBrown <neilb@suse.de>
> Signed-off-by: Joe Lawrence <joe.lawrence@stratus.com>
> ---
> fs/bio.c | 27 +++++++++++++++++++++++++++
> include/linux/bio.h | 1 +
> 2 files changed, 28 insertions(+)
>
> diff --git a/fs/bio.c b/fs/bio.c
> index 94bbc04..04309df 100644
> --- a/fs/bio.c
> +++ b/fs/bio.c
> @@ -833,6 +833,33 @@ void bio_advance(struct bio *bio, unsigned bytes)
> EXPORT_SYMBOL(bio_advance);
>
> /**
> + * bio_rewind - reset a bio to its start
> + * @bio: bio to rewind
> + *
> + * This resets bi_sector, bi_size and bi_idx; completely undoing all
> + * bio_advances on the @bio.
> + */
> +void bio_rewind(struct bio *bio)
> +{
> + int bytes = 0;
> +
> + if (bio->bi_idx < bio->bi_vcnt && bio_iovec(bio)->bv_offset > 0) {
> + bytes = bio_iovec(bio)->bv_offset;
> + bio_iovec(bio)->bv_offset -= bytes;
> + bio_iovec(bio)->bv_len += bytes;
> + }
> + while (bio->bi_idx) {
> + bio->bi_idx -= 1;
> + bio_iovec(bio)->bv_len += bio_iovec(bio)->bv_offset;
> + bio_iovec(bio)->bv_offset = 0;
> + bytes += bio_iovec(bio)->bv_len;
> + }
> + bio->bi_size += bytes;
> + bio->bi_sector -= bytes >> 9;
> +}
> +EXPORT_SYMBOL(bio_rewind);
> +
> +/**
> * bio_alloc_pages - allocates a single page for each bvec in a bio
> * @bio: bio to allocate pages for
> * @gfp_mask: flags for allocation
> diff --git a/include/linux/bio.h b/include/linux/bio.h
> index ef24466..e2082fb 100644
> --- a/include/linux/bio.h
> +++ b/include/linux/bio.h
> @@ -258,6 +258,7 @@ extern int bio_phys_segments(struct request_queue *, struct bio *);
>
> extern int submit_bio_wait(int rw, struct bio *bio);
> extern void bio_advance(struct bio *, unsigned);
> +extern void bio_rewind(struct bio *);
>
> extern void bio_init(struct bio *);
> extern void bio_reset(struct bio *);
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 828 bytes --]
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 2/2] md: raid1: use bio_rewind() before bio_copy_data()
2013-07-08 20:06 ` Joe Lawrence
2013-07-08 20:25 ` [PATCH 1/2] block: add bio_rewind() to reset bio_vec Joe Lawrence
@ 2013-07-08 20:25 ` Joe Lawrence
2013-07-09 4:33 ` NeilBrown
2013-07-17 6:12 ` RAID1 repair GPF crash w/3.10-rc7 NeilBrown
2 siblings, 1 reply; 10+ messages in thread
From: Joe Lawrence @ 2013-07-08 20:25 UTC (permalink / raw)
To: linux-raid; +Cc: NeilBrown, kmo, Joe Lawrence
bio_copy_data() cannot execute on a fully completed source (or
destination) bio. MD RAID1 is recycling a completed read bio for RAID
repair purposes and needs to fix up the source and destination bios for
bio_copy_data(): in particular, the io-vector index needs to be rewound
and the bios unchained.
Suggested-by: NeilBrown <neilb@suse.de>
Signed-off-by: Joe Lawrence <joe.lawrence@stratus.com>
---
drivers/md/raid1.c | 28 +++++-----------------------
1 file changed, 5 insertions(+), 23 deletions(-)
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 6e17f81..bb1e80f 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -1861,7 +1861,6 @@ static int process_checks(struct r1bio *r1_bio)
int j;
struct bio *pbio = r1_bio->bios[primary];
struct bio *sbio = r1_bio->bios[i];
- int size;
if (sbio->bi_end_io != end_sync_read)
continue;
@@ -1887,28 +1886,11 @@ static int process_checks(struct r1bio *r1_bio)
rdev_dec_pending(conf->mirrors[i].rdev, mddev);
continue;
}
- /* fixup the bio for reuse */
- bio_reset(sbio);
- sbio->bi_vcnt = vcnt;
- sbio->bi_size = r1_bio->sectors << 9;
- sbio->bi_sector = r1_bio->sector +
- conf->mirrors[i].rdev->data_offset;
- sbio->bi_bdev = conf->mirrors[i].rdev->bdev;
- sbio->bi_end_io = end_sync_read;
- sbio->bi_private = r1_bio;
-
- size = sbio->bi_size;
- for (j = 0; j < vcnt ; j++) {
- struct bio_vec *bi;
- bi = &sbio->bi_io_vec[j];
- bi->bv_offset = 0;
- if (size > PAGE_SIZE)
- bi->bv_len = PAGE_SIZE;
- else
- bi->bv_len = size;
- size -= PAGE_SIZE;
- }
-
+ /* copy pbio io_vec data into sbio, but first reset io_vec
+ * index and unchain both */
+ bio_rewind(pbio);
+ bio_rewind(sbio);
+ pbio->bi_next = sbio->bi_next = NULL;
bio_copy_data(sbio, pbio);
}
return 0;
--
1.8.1.4
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH 2/2] md: raid1: use bio_rewind() before bio_copy_data()
2013-07-08 20:25 ` [PATCH 2/2] md: raid1: use bio_rewind() before bio_copy_data() Joe Lawrence
@ 2013-07-09 4:33 ` NeilBrown
0 siblings, 0 replies; 10+ messages in thread
From: NeilBrown @ 2013-07-09 4:33 UTC (permalink / raw)
To: Joe Lawrence; +Cc: linux-raid, kmo
[-- Attachment #1: Type: text/plain, Size: 2447 bytes --]
On Mon, 8 Jul 2013 16:25:14 -0400 Joe Lawrence <joe.lawrence@stratus.com>
wrote:
> bio_copy_data() cannot execute on a fully completed source (or
> destination) bio. MD RAID1 is recycling a completed read bio for RAID
> repair purposes and needs to fix up the source and destination bios for
> bio_copy_data(): in particular, the io-vector index needs to be rewound
> and the bios unchained.
>
> Suggested-by: NeilBrown <neilb@suse.de>
> Signed-off-by: Joe Lawrence <joe.lawrence@stratus.com>
Thanks Joe.
Jens: are you happy with this? If so is it OK for me to forward to Linus
and -stable for 3.10, or would you rather?
The follow-on patch which uses the so avoid a crash is
http://marc.info/?l=linux-raid&m=137331514131503&w=2
(This is sitting near the top of "git://neil.brown.name/md for-next" if you
want to cherry-pick it).
Thanks,
NeilBrown
> ---
> drivers/md/raid1.c | 28 +++++-----------------------
> 1 file changed, 5 insertions(+), 23 deletions(-)
>
> diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
> index 6e17f81..bb1e80f 100644
> --- a/drivers/md/raid1.c
> +++ b/drivers/md/raid1.c
> @@ -1861,7 +1861,6 @@ static int process_checks(struct r1bio *r1_bio)
> int j;
> struct bio *pbio = r1_bio->bios[primary];
> struct bio *sbio = r1_bio->bios[i];
> - int size;
>
> if (sbio->bi_end_io != end_sync_read)
> continue;
> @@ -1887,28 +1886,11 @@ static int process_checks(struct r1bio *r1_bio)
> rdev_dec_pending(conf->mirrors[i].rdev, mddev);
> continue;
> }
> - /* fixup the bio for reuse */
> - bio_reset(sbio);
> - sbio->bi_vcnt = vcnt;
> - sbio->bi_size = r1_bio->sectors << 9;
> - sbio->bi_sector = r1_bio->sector +
> - conf->mirrors[i].rdev->data_offset;
> - sbio->bi_bdev = conf->mirrors[i].rdev->bdev;
> - sbio->bi_end_io = end_sync_read;
> - sbio->bi_private = r1_bio;
> -
> - size = sbio->bi_size;
> - for (j = 0; j < vcnt ; j++) {
> - struct bio_vec *bi;
> - bi = &sbio->bi_io_vec[j];
> - bi->bv_offset = 0;
> - if (size > PAGE_SIZE)
> - bi->bv_len = PAGE_SIZE;
> - else
> - bi->bv_len = size;
> - size -= PAGE_SIZE;
> - }
> -
> + /* copy pbio io_vec data into sbio, but first reset io_vec
> + * index and unchain both */
> + bio_rewind(pbio);
> + bio_rewind(sbio);
> + pbio->bi_next = sbio->bi_next = NULL;
> bio_copy_data(sbio, pbio);
> }
> return 0;
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 828 bytes --]
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: RAID1 repair GPF crash w/3.10-rc7
2013-07-08 20:06 ` Joe Lawrence
2013-07-08 20:25 ` [PATCH 1/2] block: add bio_rewind() to reset bio_vec Joe Lawrence
2013-07-08 20:25 ` [PATCH 2/2] md: raid1: use bio_rewind() before bio_copy_data() Joe Lawrence
@ 2013-07-17 6:12 ` NeilBrown
2013-07-17 21:01 ` Joe Lawrence
2 siblings, 1 reply; 10+ messages in thread
From: NeilBrown @ 2013-07-17 6:12 UTC (permalink / raw)
To: Joe Lawrence; +Cc: linux-raid, kmo
[-- Attachment #1: Type: text/plain, Size: 5599 bytes --]
On Mon, 8 Jul 2013 16:06:56 -0400 Joe Lawrence <joe.lawrence@stratus.com>
wrote:
> [+cc Kent's new mail?]
>
> On Thu, 4 Jul 2013 10:53:37 +1000
> NeilBrown <neilb@suse.de> wrote:
> >
> > I would propose "bio_rewind" that exactly undoes any "bio_advance".
> >
> > [ ... snip ...]
> >
> > Then call that on pbio at the same place we call bio_reset on sbio.
> >
> > You could probably also call bio_rewind on sbio, and remove lots of that
> > code for setting the bio up again.
>
> This appears to work for my test case (no crashes or post repair
> mismatch_cnt):
>
> mdadm --fail /dev/$MD /dev/sda3
> mdadm --remove /dev/$MD /dev/sda3
> dd if=/dev/urandom of=/dev/$MD bs=1M count=500
> mdadm --stop /dev/$MD
>
> mdadm --create /dev/$MD --level=1 --assume-clean --raid-devices=2 \
> --bitmap=internal /dev/sda3 /dev/sdi3
> echo repair > /sys/block/$MD/md/sync_action
>
> I'll reply to this email with the patches that implement your
> suggested changes. Feel free to combine or redo them, posting them here
> was the easiest way to provide my signed-off should you need it.
>
> Although it works, having to rewind the bio io_vec index (and
> clearing the bi_next pointers) before calling bio_copy_data feels a
> bit clunky. What bio_copy_data is really doing is
> "bio_copy_remaining_data in a bio chain," whereas MD wants
> "bio_copy_completed_data from a single bio".
>
> I took a look at Kent's tree and a lot of the block layer handling was
> simplified through the bvec_iter. I don't know if that code is
> destined for 3.11. If so, it would probably be easier to retest and
> base any MD changes off of his. And for 3.10 stable, the minimal
> fix would be for MD to just manipulate the bi_idx itself (or revert
> calling bio_copy_data altogether.)
>
Hi,
just letting you know I've decided to fix this differently for 3.11 and
3.10.y.
I noticed there was another problem in that code, in that the len argument
passed to memcmp was bv_len which might have been modified.
So I moved the "fix up the bio" code to the top of the function and applied
it to all relevant bios.
I'd still like to go with bio_rewind or similar, but it's probably best for
that to wait for the other bio stuff to settle. Maybe it won't be needed.
NeilBrown
commit 9a3856f56b467425e13a19d95524524e76eab040
Author: NeilBrown <neilb@suse.de>
Date: Wed Jul 17 15:19:29 2013 +1000
md/raid1: fix bio handling problems in process_checks()
Recent change to use bio_copy_data() in raid1 when repairing
an array is faulty.
The underlying may have changed the bio in various ways using
bio_advance and these need to be undone not just for the 'sbio' which
is being copied to, but also the 'pbio' (primary) which is being
copied from.
So perform the reset on all bios that were read from and do it early.
This also ensure that the sbio->bi_io_vec[j].bv_len passed to
memcmp is correct.
Reported-by: Joe Lawrence <joe.lawrence@stratus.com>
Signed-off-by: NeilBrown <neilb@suse.de>
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index ec73458..d60412c 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -1849,6 +1849,36 @@ static int process_checks(struct r1bio *r1_bio)
int i;
int vcnt;
+ /* Fix variable parts of all bios */
+ vcnt = (r1_bio->sectors + PAGE_SIZE / 512 - 1) >> (PAGE_SHIFT - 9);
+ for (i = 0; i < conf->raid_disks * 2; i++) {
+ int j;
+ int size;
+ struct bio *b = r1_bio->bios[i];
+ if (b->bi_end_io != end_sync_read)
+ continue;
+ /* fixup the bio for reuse */
+ bio_reset(b);
+ b->bi_vcnt = vcnt;
+ b->bi_size = r1_bio->sectors << 9;
+ b->bi_sector = r1_bio->sector +
+ conf->mirrors[i].rdev->data_offset;
+ b->bi_bdev = conf->mirrors[i].rdev->bdev;
+ b->bi_end_io = end_sync_read;
+ b->bi_private = r1_bio;
+
+ size = b->bi_size;
+ for (j = 0; j < vcnt ; j++) {
+ struct bio_vec *bi;
+ bi = &b->bi_io_vec[j];
+ bi->bv_offset = 0;
+ if (size > PAGE_SIZE)
+ bi->bv_len = PAGE_SIZE;
+ else
+ bi->bv_len = size;
+ size -= PAGE_SIZE;
+ }
+ }
for (primary = 0; primary < conf->raid_disks * 2; primary++)
if (r1_bio->bios[primary]->bi_end_io == end_sync_read &&
test_bit(BIO_UPTODATE, &r1_bio->bios[primary]->bi_flags)) {
@@ -1857,12 +1887,10 @@ static int process_checks(struct r1bio *r1_bio)
break;
}
r1_bio->read_disk = primary;
- vcnt = (r1_bio->sectors + PAGE_SIZE / 512 - 1) >> (PAGE_SHIFT - 9);
for (i = 0; i < conf->raid_disks * 2; i++) {
int j;
struct bio *pbio = r1_bio->bios[primary];
struct bio *sbio = r1_bio->bios[i];
- int size;
if (sbio->bi_end_io != end_sync_read)
continue;
@@ -1888,27 +1916,6 @@ static int process_checks(struct r1bio *r1_bio)
rdev_dec_pending(conf->mirrors[i].rdev, mddev);
continue;
}
- /* fixup the bio for reuse */
- bio_reset(sbio);
- sbio->bi_vcnt = vcnt;
- sbio->bi_size = r1_bio->sectors << 9;
- sbio->bi_sector = r1_bio->sector +
- conf->mirrors[i].rdev->data_offset;
- sbio->bi_bdev = conf->mirrors[i].rdev->bdev;
- sbio->bi_end_io = end_sync_read;
- sbio->bi_private = r1_bio;
-
- size = sbio->bi_size;
- for (j = 0; j < vcnt ; j++) {
- struct bio_vec *bi;
- bi = &sbio->bi_io_vec[j];
- bi->bv_offset = 0;
- if (size > PAGE_SIZE)
- bi->bv_len = PAGE_SIZE;
- else
- bi->bv_len = size;
- size -= PAGE_SIZE;
- }
bio_copy_data(sbio, pbio);
}
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 828 bytes --]
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: RAID1 repair GPF crash w/3.10-rc7
2013-07-17 6:12 ` RAID1 repair GPF crash w/3.10-rc7 NeilBrown
@ 2013-07-17 21:01 ` Joe Lawrence
0 siblings, 0 replies; 10+ messages in thread
From: Joe Lawrence @ 2013-07-17 21:01 UTC (permalink / raw)
To: NeilBrown; +Cc: linux-raid, kmo
On Wed, 17 Jul 2013 16:12:30 +1000
NeilBrown <neilb@suse.de> wrote:
> Hi,
> just letting you know I've decided to fix this differently for 3.11 and
> 3.10.y.
>
> I noticed there was another problem in that code, in that the len argument
> passed to memcmp was bv_len which might have been modified.
>
> So I moved the "fix up the bio" code to the top of the function and applied
> it to all relevant bios.
>
> I'd still like to go with bio_rewind or similar, but it's probably best for
> that to wait for the other bio stuff to settle. Maybe it won't be needed.
>
> NeilBrown
>
>
> commit 9a3856f56b467425e13a19d95524524e76eab040
> Author: NeilBrown <neilb@suse.de>
> Date: Wed Jul 17 15:19:29 2013 +1000
>
> md/raid1: fix bio handling problems in process_checks()
>
> Recent change to use bio_copy_data() in raid1 when repairing
> an array is faulty.
>
> The underlying may have changed the bio in various ways using
> bio_advance and these need to be undone not just for the 'sbio' which
> is being copied to, but also the 'pbio' (primary) which is being
> copied from.
>
> So perform the reset on all bios that were read from and do it early.
>
> This also ensure that the sbio->bi_io_vec[j].bv_len passed to
> memcmp is correct.
>
> Reported-by: Joe Lawrence <joe.lawrence@stratus.com>
> Signed-off-by: NeilBrown <neilb@suse.de>
>
> diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
> index ec73458..d60412c 100644
> --- a/drivers/md/raid1.c
> +++ b/drivers/md/raid1.c
> @@ -1849,6 +1849,36 @@ static int process_checks(struct r1bio *r1_bio)
> int i;
> int vcnt;
>
> + /* Fix variable parts of all bios */
> + vcnt = (r1_bio->sectors + PAGE_SIZE / 512 - 1) >> (PAGE_SHIFT - 9);
> + for (i = 0; i < conf->raid_disks * 2; i++) {
> + int j;
> + int size;
> + struct bio *b = r1_bio->bios[i];
> + if (b->bi_end_io != end_sync_read)
> + continue;
> + /* fixup the bio for reuse */
> + bio_reset(b);
> + b->bi_vcnt = vcnt;
> + b->bi_size = r1_bio->sectors << 9;
> + b->bi_sector = r1_bio->sector +
> + conf->mirrors[i].rdev->data_offset;
> + b->bi_bdev = conf->mirrors[i].rdev->bdev;
> + b->bi_end_io = end_sync_read;
> + b->bi_private = r1_bio;
> +
> + size = b->bi_size;
> + for (j = 0; j < vcnt ; j++) {
> + struct bio_vec *bi;
> + bi = &b->bi_io_vec[j];
> + bi->bv_offset = 0;
> + if (size > PAGE_SIZE)
> + bi->bv_len = PAGE_SIZE;
> + else
> + bi->bv_len = size;
> + size -= PAGE_SIZE;
> + }
> + }
> for (primary = 0; primary < conf->raid_disks * 2; primary++)
> if (r1_bio->bios[primary]->bi_end_io == end_sync_read &&
> test_bit(BIO_UPTODATE, &r1_bio->bios[primary]->bi_flags)) {
> @@ -1857,12 +1887,10 @@ static int process_checks(struct r1bio *r1_bio)
> break;
> }
> r1_bio->read_disk = primary;
> - vcnt = (r1_bio->sectors + PAGE_SIZE / 512 - 1) >> (PAGE_SHIFT - 9);
> for (i = 0; i < conf->raid_disks * 2; i++) {
> int j;
> struct bio *pbio = r1_bio->bios[primary];
> struct bio *sbio = r1_bio->bios[i];
> - int size;
>
> if (sbio->bi_end_io != end_sync_read)
> continue;
> @@ -1888,27 +1916,6 @@ static int process_checks(struct r1bio *r1_bio)
> rdev_dec_pending(conf->mirrors[i].rdev, mddev);
> continue;
> }
> - /* fixup the bio for reuse */
> - bio_reset(sbio);
> - sbio->bi_vcnt = vcnt;
> - sbio->bi_size = r1_bio->sectors << 9;
> - sbio->bi_sector = r1_bio->sector +
> - conf->mirrors[i].rdev->data_offset;
> - sbio->bi_bdev = conf->mirrors[i].rdev->bdev;
> - sbio->bi_end_io = end_sync_read;
> - sbio->bi_private = r1_bio;
> -
> - size = sbio->bi_size;
> - for (j = 0; j < vcnt ; j++) {
> - struct bio_vec *bi;
> - bi = &sbio->bi_io_vec[j];
> - bi->bv_offset = 0;
> - if (size > PAGE_SIZE)
> - bi->bv_len = PAGE_SIZE;
> - else
> - bi->bv_len = size;
> - size -= PAGE_SIZE;
> - }
>
> bio_copy_data(sbio, pbio);
> }
Hi Neil, this version looks good so far in my testing. Thanks for fixing.
-- Joe
^ permalink raw reply [flat|nested] 10+ messages in thread