Commit 0cad9c2f authored by Neil Brown's avatar Neil Brown Committed by Linus Torvalds

[PATCH] md: make read retry use a new bio in raid1 and raid10

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: default avatarNeil Brown <neilb@cse.unsw.edu.au>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 53a7c0ec
...@@ -943,6 +943,8 @@ static void raid1d(mddev_t *mddev) ...@@ -943,6 +943,8 @@ static void raid1d(mddev_t *mddev)
} else { } else {
r1_bio->bios[r1_bio->read_disk] = NULL; r1_bio->bios[r1_bio->read_disk] = NULL;
r1_bio->read_disk = disk; 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; r1_bio->bios[r1_bio->read_disk] = bio;
rdev = conf->mirrors[disk].rdev; rdev = conf->mirrors[disk].rdev;
if (printk_ratelimit()) if (printk_ratelimit())
...@@ -950,9 +952,11 @@ static void raid1d(mddev_t *mddev) ...@@ -950,9 +952,11 @@ static void raid1d(mddev_t *mddev)
" another mirror\n", " another mirror\n",
bdevname(rdev->bdev,b), bdevname(rdev->bdev,b),
(unsigned long long)r1_bio->sector); (unsigned long long)r1_bio->sector);
bio->bi_bdev = rdev->bdev;
bio->bi_sector = r1_bio->sector + rdev->data_offset; 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_rw = READ;
bio->bi_private = r1_bio;
unplug = 1; unplug = 1;
generic_make_request(bio); generic_make_request(bio);
} }
......
...@@ -1237,8 +1237,8 @@ static void raid10d(mddev_t *mddev) ...@@ -1237,8 +1237,8 @@ static void raid10d(mddev_t *mddev)
int mirror; int mirror;
bio = r10_bio->devs[r10_bio->read_slot].bio; bio = r10_bio->devs[r10_bio->read_slot].bio;
r10_bio->devs[r10_bio->read_slot].bio = NULL; r10_bio->devs[r10_bio->read_slot].bio = NULL;
bio_put(bio);
mirror = read_balance(conf, r10_bio); mirror = read_balance(conf, r10_bio);
r10_bio->devs[r10_bio->read_slot].bio = bio;
if (mirror == -1) { if (mirror == -1) {
printk(KERN_ALERT "raid10: %s: unrecoverable I/O" printk(KERN_ALERT "raid10: %s: unrecoverable I/O"
" read error for block %llu\n", " read error for block %llu\n",
...@@ -1252,15 +1252,14 @@ static void raid10d(mddev_t *mddev) ...@@ -1252,15 +1252,14 @@ static void raid10d(mddev_t *mddev)
" another mirror\n", " another mirror\n",
bdevname(rdev->bdev,b), bdevname(rdev->bdev,b),
(unsigned long long)r10_bio->sector); (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 bio->bi_sector = r10_bio->devs[r10_bio->read_slot].addr
+ rdev->data_offset; + rdev->data_offset;
bio->bi_next = NULL; bio->bi_bdev = rdev->bdev;
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_rw = READ; bio->bi_rw = READ;
bio->bi_private = r10_bio;
bio->bi_end_io = raid10_end_read_request;
unplug = 1; unplug = 1;
generic_make_request(bio); generic_make_request(bio);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment