aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/md.c
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2011-01-30 21:47:13 -0500
committerNeilBrown <neilb@suse.de>2011-01-30 21:47:13 -0500
commita8c42c7f476b5bb39bb3a5b32d5473b9a46cadb9 (patch)
tree59b82042476e6b92ee293570d30a2580dba56d09 /drivers/md/md.c
parentfc3a08b85b7a4f6c1069e5f71f6ad40d925ff55b (diff)
md: Don't use remove_and_add_spares to remove failed devices from a read-only array
remove_and_add_spares is called in two places where the needs really are very different. remove_and_add_spares should not be called on an array which is about to be reshaped as some extra devices might have been manually added and that would remove them. However if the array is 'read-auto', that will currently happen, which is bad. So in the 'ro != 0' case don't call remove_and_add_spares but simply remove the failed devices as the comment suggests is needed. Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'drivers/md/md.c')
-rw-r--r--drivers/md/md.c17
1 files changed, 15 insertions, 2 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c
index f539b587ca72..5b93829f3d49 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -7027,7 +7027,7 @@ static int remove_and_add_spares(mddev_t *mddev)
7027 } 7027 }
7028 } 7028 }
7029 7029
7030 if (mddev->degraded && ! mddev->ro && !mddev->recovery_disabled) { 7030 if (mddev->degraded && !mddev->recovery_disabled) {
7031 list_for_each_entry(rdev, &mddev->disks, same_set) { 7031 list_for_each_entry(rdev, &mddev->disks, same_set) {
7032 if (rdev->raid_disk >= 0 && 7032 if (rdev->raid_disk >= 0 &&
7033 !test_bit(In_sync, &rdev->flags) && 7033 !test_bit(In_sync, &rdev->flags) &&
@@ -7150,7 +7150,20 @@ void md_check_recovery(mddev_t *mddev)
7150 /* Only thing we do on a ro array is remove 7150 /* Only thing we do on a ro array is remove
7151 * failed devices. 7151 * failed devices.
7152 */ 7152 */
7153 remove_and_add_spares(mddev); 7153 mdk_rdev_t *rdev;
7154 list_for_each_entry(rdev, &mddev->disks, same_set)
7155 if (rdev->raid_disk >= 0 &&
7156 !test_bit(Blocked, &rdev->flags) &&
7157 test_bit(Faulty, &rdev->flags) &&
7158 atomic_read(&rdev->nr_pending)==0) {
7159 if (mddev->pers->hot_remove_disk(
7160 mddev, rdev->raid_disk)==0) {
7161 char nm[20];
7162 sprintf(nm,"rd%d", rdev->raid_disk);
7163 sysfs_remove_link(&mddev->kobj, nm);
7164 rdev->raid_disk = -1;
7165 }
7166 }
7154 clear_bit(MD_RECOVERY_NEEDED, &mddev->recovery); 7167 clear_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
7155 goto unlock; 7168 goto unlock;
7156 } 7169 }