aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/device-mapper/dm-raid.txt1
-rw-r--r--drivers/md/dm-raid.c44
-rw-r--r--drivers/md/raid1.c7
-rw-r--r--drivers/md/raid10.c10
4 files changed, 54 insertions, 8 deletions
diff --git a/Documentation/device-mapper/dm-raid.txt b/Documentation/device-mapper/dm-raid.txt
index e9192283e5a5..2bb3a6823dc7 100644
--- a/Documentation/device-mapper/dm-raid.txt
+++ b/Documentation/device-mapper/dm-raid.txt
@@ -222,3 +222,4 @@ Version History
2221.4.2 Add RAID10 "far" and "offset" algorithm support. 2221.4.2 Add RAID10 "far" and "offset" algorithm support.
2231.5.0 Add message interface to allow manipulation of the sync_action. 2231.5.0 Add message interface to allow manipulation of the sync_action.
224 New status (STATUSTYPE_INFO) fields: sync_action and mismatch_cnt. 224 New status (STATUSTYPE_INFO) fields: sync_action and mismatch_cnt.
2251.5.1 Add ability to restore transiently failed devices on resume.
diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c
index 1d3fe1a40a9b..facaf9142d5a 100644
--- a/drivers/md/dm-raid.c
+++ b/drivers/md/dm-raid.c
@@ -1574,12 +1574,54 @@ static void raid_postsuspend(struct dm_target *ti)
1574 1574
1575static void raid_resume(struct dm_target *ti) 1575static void raid_resume(struct dm_target *ti)
1576{ 1576{
1577 int i;
1578 uint64_t failed_devices, cleared_failed_devices = 0;
1579 unsigned long flags;
1580 struct dm_raid_superblock *sb;
1577 struct raid_set *rs = ti->private; 1581 struct raid_set *rs = ti->private;
1582 struct md_rdev *r;
1578 1583
1579 set_bit(MD_CHANGE_DEVS, &rs->md.flags); 1584 set_bit(MD_CHANGE_DEVS, &rs->md.flags);
1580 if (!rs->bitmap_loaded) { 1585 if (!rs->bitmap_loaded) {
1581 bitmap_load(&rs->md); 1586 bitmap_load(&rs->md);
1582 rs->bitmap_loaded = 1; 1587 rs->bitmap_loaded = 1;
1588 } else {
1589 /*
1590 * A secondary resume while the device is active.
1591 * Take this opportunity to check whether any failed
1592 * devices are reachable again.
1593 */
1594 for (i = 0; i < rs->md.raid_disks; i++) {
1595 r = &rs->dev[i].rdev;
1596 if (test_bit(Faulty, &r->flags) && r->sb_page &&
1597 sync_page_io(r, 0, r->sb_size,
1598 r->sb_page, READ, 1)) {
1599 DMINFO("Faulty device #%d has readable super"
1600 "block. Attempting to revive it.", i);
1601 r->raid_disk = i;
1602 r->saved_raid_disk = i;
1603 flags = r->flags;
1604 clear_bit(Faulty, &r->flags);
1605 clear_bit(WriteErrorSeen, &r->flags);
1606 clear_bit(In_sync, &r->flags);
1607 if (r->mddev->pers->hot_add_disk(r->mddev, r)) {
1608 r->raid_disk = -1;
1609 r->saved_raid_disk = -1;
1610 r->flags = flags;
1611 } else {
1612 r->recovery_offset = 0;
1613 cleared_failed_devices |= 1 << i;
1614 }
1615 }
1616 }
1617 if (cleared_failed_devices) {
1618 rdev_for_each(r, &rs->md) {
1619 sb = page_address(r->sb_page);
1620 failed_devices = le64_to_cpu(sb->failed_devices);
1621 failed_devices &= ~cleared_failed_devices;
1622 sb->failed_devices = cpu_to_le64(failed_devices);
1623 }
1624 }
1583 } 1625 }
1584 1626
1585 clear_bit(MD_RECOVERY_FROZEN, &rs->md.recovery); 1627 clear_bit(MD_RECOVERY_FROZEN, &rs->md.recovery);
@@ -1588,7 +1630,7 @@ static void raid_resume(struct dm_target *ti)
1588 1630
1589static struct target_type raid_target = { 1631static struct target_type raid_target = {
1590 .name = "raid", 1632 .name = "raid",
1591 .version = {1, 5, 0}, 1633 .version = {1, 5, 1},
1592 .module = THIS_MODULE, 1634 .module = THIS_MODULE,
1593 .ctr = raid_ctr, 1635 .ctr = raid_ctr,
1594 .dtr = raid_dtr, 1636 .dtr = raid_dtr,
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 6e17f8181c4b..ec734588a1c6 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -1519,8 +1519,9 @@ static int raid1_add_disk(struct mddev *mddev, struct md_rdev *rdev)
1519 p = conf->mirrors+mirror; 1519 p = conf->mirrors+mirror;
1520 if (!p->rdev) { 1520 if (!p->rdev) {
1521 1521
1522 disk_stack_limits(mddev->gendisk, rdev->bdev, 1522 if (mddev->gendisk)
1523 rdev->data_offset << 9); 1523 disk_stack_limits(mddev->gendisk, rdev->bdev,
1524 rdev->data_offset << 9);
1524 1525
1525 p->head_position = 0; 1526 p->head_position = 0;
1526 rdev->raid_disk = mirror; 1527 rdev->raid_disk = mirror;
@@ -1559,7 +1560,7 @@ static int raid1_add_disk(struct mddev *mddev, struct md_rdev *rdev)
1559 clear_bit(Unmerged, &rdev->flags); 1560 clear_bit(Unmerged, &rdev->flags);
1560 } 1561 }
1561 md_integrity_add_rdev(rdev, mddev); 1562 md_integrity_add_rdev(rdev, mddev);
1562 if (blk_queue_discard(bdev_get_queue(rdev->bdev))) 1563 if (mddev->queue && blk_queue_discard(bdev_get_queue(rdev->bdev)))
1563 queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, mddev->queue); 1564 queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, mddev->queue);
1564 print_conf(conf); 1565 print_conf(conf);
1565 return err; 1566 return err;
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 6ddae2501b9a..3c6b193cefd5 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -1819,15 +1819,17 @@ static int raid10_add_disk(struct mddev *mddev, struct md_rdev *rdev)
1819 set_bit(Replacement, &rdev->flags); 1819 set_bit(Replacement, &rdev->flags);
1820 rdev->raid_disk = mirror; 1820 rdev->raid_disk = mirror;
1821 err = 0; 1821 err = 0;
1822 disk_stack_limits(mddev->gendisk, rdev->bdev, 1822 if (mddev->gendisk)
1823 rdev->data_offset << 9); 1823 disk_stack_limits(mddev->gendisk, rdev->bdev,
1824 rdev->data_offset << 9);
1824 conf->fullsync = 1; 1825 conf->fullsync = 1;
1825 rcu_assign_pointer(p->replacement, rdev); 1826 rcu_assign_pointer(p->replacement, rdev);
1826 break; 1827 break;
1827 } 1828 }
1828 1829
1829 disk_stack_limits(mddev->gendisk, rdev->bdev, 1830 if (mddev->gendisk)
1830 rdev->data_offset << 9); 1831 disk_stack_limits(mddev->gendisk, rdev->bdev,
1832 rdev->data_offset << 9);
1831 1833
1832 p->head_position = 0; 1834 p->head_position = 0;
1833 p->recovery_disabled = mddev->recovery_disabled - 1; 1835 p->recovery_disabled = mddev->recovery_disabled - 1;