From: NeilBrown When retrying a read request, we need to "Reset" the bio. It is easiest to get this right if we discard the bio we have and re-clone it. Signed-off-by: Neil Brown Signed-off-by: Andrew Morton --- 25-akpm/drivers/md/raid1.c | 6 +++++- 25-akpm/drivers/md/raid10.c | 13 ++++++------- 2 files changed, 11 insertions(+), 8 deletions(-) diff -puN drivers/md/raid10.c~md-make-read-retry-use-a-new-bio-in-raid1-and-raid10 drivers/md/raid10.c --- 25/drivers/md/raid10.c~md-make-read-retry-use-a-new-bio-in-raid1-and-raid10 Wed Oct 20 16:01:43 2004 +++ 25-akpm/drivers/md/raid10.c Wed Oct 20 16:01:43 2004 @@ -1237,8 +1237,8 @@ static void raid10d(mddev_t *mddev) int mirror; bio = r10_bio->devs[r10_bio->read_slot].bio; r10_bio->devs[r10_bio->read_slot].bio = NULL; + bio_put(bio); mirror = read_balance(conf, r10_bio); - r10_bio->devs[r10_bio->read_slot].bio = bio; if (mirror == -1) { printk(KERN_ALERT "raid10: %s: unrecoverable I/O" " read error for block %llu\n", @@ -1252,15 +1252,14 @@ static void raid10d(mddev_t *mddev) " another mirror\n", bdevname(rdev->bdev,b), (unsigned long long)r10_bio->sector); - bio->bi_bdev = rdev->bdev; + bio = bio_clone(r10_bio->master_bio, GFP_NOIO); + r10_bio->devs[r10_bio->read_slot].bio = bio; bio->bi_sector = r10_bio->devs[r10_bio->read_slot].addr + rdev->data_offset; - bio->bi_next = NULL; - bio->bi_flags &= (1<bi_flags |= 1 << BIO_UPTODATE; - bio->bi_idx = 0; - bio->bi_size = r10_bio->sectors << 9; + bio->bi_bdev = rdev->bdev; bio->bi_rw = READ; + bio->bi_private = r10_bio; + bio->bi_end_io = raid10_end_read_request; unplug = 1; generic_make_request(bio); } diff -puN drivers/md/raid1.c~md-make-read-retry-use-a-new-bio-in-raid1-and-raid10 drivers/md/raid1.c --- 25/drivers/md/raid1.c~md-make-read-retry-use-a-new-bio-in-raid1-and-raid10 Wed Oct 20 16:01:43 2004 +++ 25-akpm/drivers/md/raid1.c Wed Oct 20 16:01:43 2004 @@ -943,6 +943,8 @@ static void raid1d(mddev_t *mddev) } else { r1_bio->bios[r1_bio->read_disk] = NULL; r1_bio->read_disk = disk; + bio_put(bio); + bio = bio_clone(r1_bio->master_bio, GFP_NOIO); r1_bio->bios[r1_bio->read_disk] = bio; rdev = conf->mirrors[disk].rdev; if (printk_ratelimit()) @@ -950,9 +952,11 @@ static void raid1d(mddev_t *mddev) " another mirror\n", bdevname(rdev->bdev,b), (unsigned long long)r1_bio->sector); - bio->bi_bdev = rdev->bdev; bio->bi_sector = r1_bio->sector + rdev->data_offset; + bio->bi_bdev = rdev->bdev; + bio->bi_end_io = raid1_end_read_request; bio->bi_rw = READ; + bio->bi_private = r1_bio; unplug = 1; generic_make_request(bio); } _