aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/raid10.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/md/raid10.c')
-rw-r--r--drivers/md/raid10.c40
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);