Commit a15b60a2 authored by Neil Brown's avatar Neil Brown Committed by Trond Myklebust

[PATCH] MD - Pass the correct bdev to md_error

Pass the correct bdev to md_error

After a call to generic_make_request, bio->bi_bdev can have changed
(e.g. by a re-mapped like raid0).  So we cannot trust it for reporting
the source of an error.  This patch takes care to find the correct
bdev.
parent 2a9400e9
......@@ -128,7 +128,8 @@ void multipath_end_request(struct bio *bio)
{
int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
struct multipath_bh * mp_bh = (struct multipath_bh *)(bio->bi_private);
multipath_conf_t *conf;
struct block_device *bdev;
if (uptodate) {
multipath_end_bh_io(mp_bh, uptodate);
return;
......@@ -136,9 +137,11 @@ void multipath_end_request(struct bio *bio)
/*
* oops, IO error:
*/
md_error (mp_bh->mddev, bio->bi_bdev);
conf = mddev_to_conf(mp_bh->mddev);
bdev = conf->multipaths[mp_bh->path].bdev;
md_error (mp_bh->mddev, bdev);
printk(KERN_ERR "multipath: %s: rescheduling sector %lu\n",
bdev_partition_name(bio->bi_bdev), bio->bi_sector);
bdev_partition_name(bdev), bio->bi_sector);
multipath_reschedule_retry(mp_bh);
return;
}
......@@ -174,7 +177,8 @@ static int multipath_make_request (request_queue_t *q, struct bio * bio)
/*
* read balancing logic:
*/
multipath = conf->multipaths + multipath_read_balance(conf);
mp_bh->path = multipath_read_balance(conf);
multipath = conf->multipaths + mp_bh->path;
mp_bh->bio = *bio;
mp_bh->bio.bi_bdev = multipath->bdev;
......
......@@ -251,13 +251,21 @@ static void end_request(struct bio *bio)
{
int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
r1bio_t * r1_bio = (r1bio_t *)(bio->bi_private);
int i;
int mirror;
conf_t *conf = mddev_to_conf(r1_bio->mddev);
if (r1_bio->cmd == READ || r1_bio->cmd == READA)
mirror = r1_bio->read_disk;
else {
for (mirror = 0; mirror < MD_SB_DISKS; mirror++)
if (r1_bio->write_bios[mirror] == bio)
break;
}
/*
* this branch is our 'one mirror IO has finished' event handler:
*/
if (!uptodate)
md_error(r1_bio->mddev, bio->bi_bdev);
md_error(r1_bio->mddev, conf->mirrors[mirror].bdev);
else
/*
* Set R1BIO_Uptodate in our master bio, so that
......@@ -270,10 +278,10 @@ static void end_request(struct bio *bio)
*/
set_bit(R1BIO_Uptodate, &r1_bio->state);
update_head_pos(mirror, r1_bio);
if ((r1_bio->cmd == READ) || (r1_bio->cmd == READA)) {
if (!r1_bio->read_bio)
BUG();
update_head_pos(r1_bio->read_disk, r1_bio);
/*
* we have only one bio on the read side
*/
......@@ -295,14 +303,6 @@ static void end_request(struct bio *bio)
/*
* WRITE:
*
* First, find the disk this bio belongs to.
*/
for (i = 0; i < MD_SB_DISKS; i++)
if (r1_bio->write_bios[i] == bio) {
update_head_pos(i, r1_bio);
break;
}
/*
* Let's see if all mirrored write operations have finished
* already.
*/
......@@ -911,6 +911,7 @@ static void end_sync_read(struct bio *bio)
{
int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
r1bio_t * r1_bio = (r1bio_t *)(bio->bi_private);
conf_t *conf = mddev_to_conf(r1_bio->mddev);
if (r1_bio->read_bio != bio)
BUG();
......@@ -921,7 +922,8 @@ static void end_sync_read(struct bio *bio)
* We don't do much here, just schedule handling by raid1d
*/
if (!uptodate)
md_error (r1_bio->mddev, bio->bi_bdev);
md_error(r1_bio->mddev,
conf->mirrors[r1_bio->read_disk].bdev);
else
set_bit(R1BIO_Uptodate, &r1_bio->state);
reschedule_retry(r1_bio);
......@@ -932,19 +934,20 @@ static void end_sync_write(struct bio *bio)
int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
r1bio_t * r1_bio = (r1bio_t *)(bio->bi_private);
mddev_t *mddev = r1_bio->mddev;
conf_t *conf = mddev_to_conf(mddev);
int i;
if (!uptodate)
md_error(mddev, bio->bi_bdev);
int mirror=0;
for (i = 0; i < MD_SB_DISKS; i++)
if (r1_bio->write_bios[i] == bio) {
update_head_pos(i, r1_bio);
mirror = i;
break;
}
if (!uptodate)
md_error(mddev, conf->mirrors[mirror].bdev);
update_head_pos(mirror, r1_bio);
if (atomic_dec_and_test(&r1_bio->remaining)) {
conf_t *conf = mddev_to_conf(mddev);
md_done_sync(mddev, r1_bio->master_bio->bi_size >> 9, uptodate);
resume_device(conf);
put_buf(r1_bio);
......
......@@ -371,7 +371,7 @@ static void raid5_end_read_request (struct bio * bi)
set_bit(R5_UPTODATE, &sh->dev[i].flags);
#endif
} else {
md_error(conf->mddev, bi->bi_bdev);
md_error(conf->mddev, conf->disks[i].bdev);
clear_bit(R5_UPTODATE, &sh->dev[i].flags);
}
#if 0
......@@ -407,7 +407,7 @@ static void raid5_end_write_request (struct bio *bi)
spin_lock_irqsave(&conf->device_lock, flags);
if (!uptodate)
md_error(conf->mddev, bi->bi_bdev);
md_error(conf->mddev, conf->disks[i].bdev);
clear_bit(R5_LOCKED, &sh->dev[i].flags);
set_bit(STRIPE_HANDLE, &sh->state);
......
......@@ -48,6 +48,7 @@ struct multipath_bh {
mddev_t *mddev;
struct bio *master_bio;
struct bio bio;
int path;
struct multipath_bh *next_mp; /* next for retry */
};
#endif
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