diff options
| author | NeilBrown <neilb@suse.de> | 2009-12-13 20:50:06 -0500 | 
|---|---|---|
| committer | NeilBrown <neilb@suse.de> | 2009-12-13 20:51:41 -0500 | 
| commit | 93be75ffde6dfd1ad17cc3ff1dbd135bd711baf4 (patch) | |
| tree | 56006efccad176da1b806978faf60d77c817e6ac | |
| parent | aa98aa31987ad9831711ae71ea2270228ab62532 (diff) | |
md: integrate spares into array at earliest opportunity.
As v1.x metadata can record that a member of the array is
not completely recovered, it make sense to record that a
spare has become a regular member of the array at the earliest
opportunity.
So remove the tests on "recovery_offset > 0" in super_1_sync
as they really aren't needed, and schedule a metadata update
immediately after adding spares to a degraded array.
This means that if a crash happens immediately after a recovery
starts, the new device will be included in the array and recovery will
continue from wherever it was up to.  Previously this didn't happen
unless recovery was at least 1/16 of the way through.
Signed-off-by: NeilBrown <neilb@suse.de>
| -rw-r--r-- | drivers/md/md.c | 13 | 
1 files changed, 6 insertions, 7 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c index 08564375d6b5..68a8a29a9012 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c  | |||
| @@ -1508,12 +1508,10 @@ static void super_1_sync(mddev_t *mddev, mdk_rdev_t *rdev) | |||
| 1508 | 1508 | ||
| 1509 | if (rdev->raid_disk >= 0 && | 1509 | if (rdev->raid_disk >= 0 && | 
| 1510 | !test_bit(In_sync, &rdev->flags)) { | 1510 | !test_bit(In_sync, &rdev->flags)) { | 
| 1511 | if (rdev->recovery_offset > 0) { | 1511 | sb->feature_map |= | 
| 1512 | sb->feature_map |= | 1512 | cpu_to_le32(MD_FEATURE_RECOVERY_OFFSET); | 
| 1513 | cpu_to_le32(MD_FEATURE_RECOVERY_OFFSET); | 1513 | sb->recovery_offset = | 
| 1514 | sb->recovery_offset = | 1514 | cpu_to_le64(rdev->recovery_offset); | 
| 1515 | cpu_to_le64(rdev->recovery_offset); | ||
| 1516 | } | ||
| 1517 | } | 1515 | } | 
| 1518 | 1516 | ||
| 1519 | if (mddev->reshape_position != MaxSector) { | 1517 | if (mddev->reshape_position != MaxSector) { | 
| @@ -1547,7 +1545,7 @@ static void super_1_sync(mddev_t *mddev, mdk_rdev_t *rdev) | |||
| 1547 | sb->dev_roles[i] = cpu_to_le16(0xfffe); | 1545 | sb->dev_roles[i] = cpu_to_le16(0xfffe); | 
| 1548 | else if (test_bit(In_sync, &rdev2->flags)) | 1546 | else if (test_bit(In_sync, &rdev2->flags)) | 
| 1549 | sb->dev_roles[i] = cpu_to_le16(rdev2->raid_disk); | 1547 | sb->dev_roles[i] = cpu_to_le16(rdev2->raid_disk); | 
| 1550 | else if (rdev2->raid_disk >= 0 && rdev2->recovery_offset > 0) | 1548 | else if (rdev2->raid_disk >= 0) | 
| 1551 | sb->dev_roles[i] = cpu_to_le16(rdev2->raid_disk); | 1549 | sb->dev_roles[i] = cpu_to_le16(rdev2->raid_disk); | 
| 1552 | else | 1550 | else | 
| 1553 | sb->dev_roles[i] = cpu_to_le16(0xffff); | 1551 | sb->dev_roles[i] = cpu_to_le16(0xffff); | 
| @@ -6786,6 +6784,7 @@ static int remove_and_add_spares(mddev_t *mddev) | |||
| 6786 | nm, mdname(mddev)); | 6784 | nm, mdname(mddev)); | 
| 6787 | spares++; | 6785 | spares++; | 
| 6788 | md_new_event(mddev); | 6786 | md_new_event(mddev); | 
| 6787 | set_bit(MD_CHANGE_DEVS, &mddev->flags); | ||
| 6789 | } else | 6788 | } else | 
| 6790 | break; | 6789 | break; | 
| 6791 | } | 6790 | } | 
