diff options
author | NeilBrown <neilb@suse.de> | 2012-10-10 22:44:30 -0400 |
---|---|---|
committer | NeilBrown <neilb@suse.de> | 2012-10-10 22:44:30 -0400 |
commit | 7ad4d4a68a1a19f21c7b39cb3f51bf17fba6e3d0 (patch) | |
tree | 9a93ab26f6354988241dc003a9ab16b77a3d75d3 /drivers/md/raid1.c | |
parent | fd177481b440c3f7b5ee9b821a76b29fdf2a6712 (diff) |
md/raid1: Don't release reference to device while handling read error.
When we get a read error, we arrange for raid1d to handle it.
Currently we release the reference on the device. This can result
in
conf->mirrors[read_disk].rdev
being NULL in fix_read_error, if the device happens to get removed
before the read error is handled.
So instead keep the reference until the read error has been fully
handled.
Reported-by: hank <pyu@redhat.com>
Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'drivers/md/raid1.c')
-rw-r--r-- | drivers/md/raid1.c | 9 |
1 files changed, 5 insertions, 4 deletions
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 55ccf4730536..e913356b257e 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c | |||
@@ -333,9 +333,10 @@ static void raid1_end_read_request(struct bio *bio, int error) | |||
333 | spin_unlock_irqrestore(&conf->device_lock, flags); | 333 | spin_unlock_irqrestore(&conf->device_lock, flags); |
334 | } | 334 | } |
335 | 335 | ||
336 | if (uptodate) | 336 | if (uptodate) { |
337 | raid_end_bio_io(r1_bio); | 337 | raid_end_bio_io(r1_bio); |
338 | else { | 338 | rdev_dec_pending(conf->mirrors[mirror].rdev, conf->mddev); |
339 | } else { | ||
339 | /* | 340 | /* |
340 | * oops, read error: | 341 | * oops, read error: |
341 | */ | 342 | */ |
@@ -349,9 +350,8 @@ static void raid1_end_read_request(struct bio *bio, int error) | |||
349 | (unsigned long long)r1_bio->sector); | 350 | (unsigned long long)r1_bio->sector); |
350 | set_bit(R1BIO_ReadError, &r1_bio->state); | 351 | set_bit(R1BIO_ReadError, &r1_bio->state); |
351 | reschedule_retry(r1_bio); | 352 | reschedule_retry(r1_bio); |
353 | /* don't drop the reference on read_disk yet */ | ||
352 | } | 354 | } |
353 | |||
354 | rdev_dec_pending(conf->mirrors[mirror].rdev, conf->mddev); | ||
355 | } | 355 | } |
356 | 356 | ||
357 | static void close_write(struct r1bio *r1_bio) | 357 | static void close_write(struct r1bio *r1_bio) |
@@ -2229,6 +2229,7 @@ static void handle_read_error(struct r1conf *conf, struct r1bio *r1_bio) | |||
2229 | unfreeze_array(conf); | 2229 | unfreeze_array(conf); |
2230 | } else | 2230 | } else |
2231 | md_error(mddev, conf->mirrors[r1_bio->read_disk].rdev); | 2231 | md_error(mddev, conf->mirrors[r1_bio->read_disk].rdev); |
2232 | rdev_dec_pending(conf->mirrors[r1_bio->read_disk].rdev, conf->mddev); | ||
2232 | 2233 | ||
2233 | bio = r1_bio->bios[r1_bio->read_disk]; | 2234 | bio = r1_bio->bios[r1_bio->read_disk]; |
2234 | bdevname(bio->bi_bdev, b); | 2235 | bdevname(bio->bi_bdev, b); |