
From: NeilBrown <neilb@cse.unsw.edu.au>

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 <neilb@cse.unsw.edu.au>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 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<<BIO_CLONED);
-				bio->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);
 			}
_
