diff options
author | NeilBrown <neilb@suse.de> | 2011-12-22 18:17:56 -0500 |
---|---|---|
committer | NeilBrown <neilb@suse.de> | 2011-12-22 18:17:56 -0500 |
commit | b7044d41b5a09ce9082699f74c8f10e0fe59f704 (patch) | |
tree | 6eccbaddb40861aeba8459cb4f0efe3c340fb936 /drivers/md/raid10.c | |
parent | 56a2559bb654ae2555b2ae3b29c837615d0c45c9 (diff) |
md/raid10: If there is a spare and a want_replacement device, start replacement.
When attempting to add a spare to a RAID10 array, also consider
adding it as a replacement for a want_replacement device.
Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'drivers/md/raid10.c')
-rw-r--r-- | drivers/md/raid10.c | 40 |
1 files changed, 36 insertions, 4 deletions
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 011827d0df25..6e8aa213f0d5 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c | |||
@@ -419,6 +419,9 @@ static void raid10_end_write_request(struct bio *bio, int error) | |||
419 | md_error(rdev->mddev, rdev); | 419 | md_error(rdev->mddev, rdev); |
420 | else { | 420 | else { |
421 | set_bit(WriteErrorSeen, &rdev->flags); | 421 | set_bit(WriteErrorSeen, &rdev->flags); |
422 | if (!test_and_set_bit(WantReplacement, &rdev->flags)) | ||
423 | set_bit(MD_RECOVERY_NEEDED, | ||
424 | &rdev->mddev->recovery); | ||
422 | set_bit(R10BIO_WriteError, &r10_bio->state); | 425 | set_bit(R10BIO_WriteError, &r10_bio->state); |
423 | dec_rdev = 0; | 426 | dec_rdev = 0; |
424 | } | 427 | } |
@@ -1481,8 +1484,25 @@ static int raid10_add_disk(struct mddev *mddev, struct md_rdev *rdev) | |||
1481 | struct mirror_info *p = &conf->mirrors[mirror]; | 1484 | struct mirror_info *p = &conf->mirrors[mirror]; |
1482 | if (p->recovery_disabled == mddev->recovery_disabled) | 1485 | if (p->recovery_disabled == mddev->recovery_disabled) |
1483 | continue; | 1486 | continue; |
1484 | if (p->rdev) | 1487 | if (p->rdev) { |
1485 | continue; | 1488 | if (!test_bit(WantReplacement, &p->rdev->flags) || |
1489 | p->replacement != NULL) | ||
1490 | continue; | ||
1491 | clear_bit(In_sync, &rdev->flags); | ||
1492 | set_bit(Replacement, &rdev->flags); | ||
1493 | rdev->raid_disk = mirror; | ||
1494 | err = 0; | ||
1495 | disk_stack_limits(mddev->gendisk, rdev->bdev, | ||
1496 | rdev->data_offset << 9); | ||
1497 | if (rdev->bdev->bd_disk->queue->merge_bvec_fn) { | ||
1498 | blk_queue_max_segments(mddev->queue, 1); | ||
1499 | blk_queue_segment_boundary(mddev->queue, | ||
1500 | PAGE_CACHE_SIZE - 1); | ||
1501 | } | ||
1502 | conf->fullsync = 1; | ||
1503 | rcu_assign_pointer(p->replacement, rdev); | ||
1504 | break; | ||
1505 | } | ||
1486 | 1506 | ||
1487 | disk_stack_limits(mddev->gendisk, rdev->bdev, | 1507 | disk_stack_limits(mddev->gendisk, rdev->bdev, |
1488 | rdev->data_offset << 9); | 1508 | rdev->data_offset << 9); |
@@ -1658,6 +1678,9 @@ static void end_sync_write(struct bio *bio, int error) | |||
1658 | md_error(mddev, rdev); | 1678 | md_error(mddev, rdev); |
1659 | else { | 1679 | else { |
1660 | set_bit(WriteErrorSeen, &rdev->flags); | 1680 | set_bit(WriteErrorSeen, &rdev->flags); |
1681 | if (!test_and_set_bit(WantReplacement, &rdev->flags)) | ||
1682 | set_bit(MD_RECOVERY_NEEDED, | ||
1683 | &rdev->mddev->recovery); | ||
1661 | set_bit(R10BIO_WriteError, &r10_bio->state); | 1684 | set_bit(R10BIO_WriteError, &r10_bio->state); |
1662 | } | 1685 | } |
1663 | } else if (is_badblock(rdev, | 1686 | } else if (is_badblock(rdev, |
@@ -1852,8 +1875,13 @@ static void fix_recovery_read_error(struct r10bio *r10_bio) | |||
1852 | s << 9, | 1875 | s << 9, |
1853 | bio->bi_io_vec[idx].bv_page, | 1876 | bio->bi_io_vec[idx].bv_page, |
1854 | WRITE, false); | 1877 | WRITE, false); |
1855 | if (!ok) | 1878 | if (!ok) { |
1856 | set_bit(WriteErrorSeen, &rdev->flags); | 1879 | set_bit(WriteErrorSeen, &rdev->flags); |
1880 | if (!test_and_set_bit(WantReplacement, | ||
1881 | &rdev->flags)) | ||
1882 | set_bit(MD_RECOVERY_NEEDED, | ||
1883 | &rdev->mddev->recovery); | ||
1884 | } | ||
1857 | } | 1885 | } |
1858 | if (!ok) { | 1886 | if (!ok) { |
1859 | /* We don't worry if we cannot set a bad block - | 1887 | /* We don't worry if we cannot set a bad block - |
@@ -1971,8 +1999,12 @@ static int r10_sync_page_io(struct md_rdev *rdev, sector_t sector, | |||
1971 | if (sync_page_io(rdev, sector, sectors << 9, page, rw, false)) | 1999 | if (sync_page_io(rdev, sector, sectors << 9, page, rw, false)) |
1972 | /* success */ | 2000 | /* success */ |
1973 | return 1; | 2001 | return 1; |
1974 | if (rw == WRITE) | 2002 | if (rw == WRITE) { |
1975 | set_bit(WriteErrorSeen, &rdev->flags); | 2003 | set_bit(WriteErrorSeen, &rdev->flags); |
2004 | if (!test_and_set_bit(WantReplacement, &rdev->flags)) | ||
2005 | set_bit(MD_RECOVERY_NEEDED, | ||
2006 | &rdev->mddev->recovery); | ||
2007 | } | ||
1976 | /* need to record an error - either for the block or the device */ | 2008 | /* need to record an error - either for the block or the device */ |
1977 | if (!rdev_set_badblocks(rdev, sector, sectors, 0)) | 2009 | if (!rdev_set_badblocks(rdev, sector, sectors, 0)) |
1978 | md_error(rdev->mddev, rdev); | 2010 | md_error(rdev->mddev, rdev); |