aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2011-12-22 18:17:52 -0500
committerNeilBrown <neilb@suse.de>2011-12-22 18:17:52 -0500
commit657e3e4d88461a5ab660dd87f8f773f55e748da4 (patch)
tree1eecf97f8e5eac95cf37b4f28e262a37dd3e116d
parent14a75d3e07c784c004b4b44b34af996b8e4ac453 (diff)
md/raid5: allow removal for failed replacement devices.
Enhance raid5_remove_disk to be able to remove ->replacement as well as ->rdev. Reviewed-by: Dan Williams <dan.j.williams@intel.com> Signed-off-by: NeilBrown <neilb@suse.de>
-rw-r--r--drivers/md/raid5.c58
1 files changed, 32 insertions, 26 deletions
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 2ae63c5b1c25..e5795d39d418 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -5086,36 +5086,42 @@ static int raid5_remove_disk(struct mddev *mddev, struct md_rdev *rdev)
5086 struct r5conf *conf = mddev->private; 5086 struct r5conf *conf = mddev->private;
5087 int err = 0; 5087 int err = 0;
5088 int number = rdev->raid_disk; 5088 int number = rdev->raid_disk;
5089 struct md_rdev **rdevp;
5089 struct disk_info *p = conf->disks + number; 5090 struct disk_info *p = conf->disks + number;
5090 5091
5091 print_raid5_conf(conf); 5092 print_raid5_conf(conf);
5092 if (rdev == p->rdev) { 5093 if (rdev == p->rdev)
5093 if (number >= conf->raid_disks && 5094 rdevp = &p->rdev;
5094 conf->reshape_progress == MaxSector) 5095 else if (rdev == p->replacement)
5095 clear_bit(In_sync, &rdev->flags); 5096 rdevp = &p->replacement;
5097 else
5098 return 0;
5096 5099
5097 if (test_bit(In_sync, &rdev->flags) || 5100 if (number >= conf->raid_disks &&
5098 atomic_read(&rdev->nr_pending)) { 5101 conf->reshape_progress == MaxSector)
5099 err = -EBUSY; 5102 clear_bit(In_sync, &rdev->flags);
5100 goto abort; 5103
5101 } 5104 if (test_bit(In_sync, &rdev->flags) ||
5102 /* Only remove non-faulty devices if recovery 5105 atomic_read(&rdev->nr_pending)) {
5103 * isn't possible. 5106 err = -EBUSY;
5104 */ 5107 goto abort;
5105 if (!test_bit(Faulty, &rdev->flags) && 5108 }
5106 mddev->recovery_disabled != conf->recovery_disabled && 5109 /* Only remove non-faulty devices if recovery
5107 !has_failed(conf) && 5110 * isn't possible.
5108 number < conf->raid_disks) { 5111 */
5109 err = -EBUSY; 5112 if (!test_bit(Faulty, &rdev->flags) &&
5110 goto abort; 5113 mddev->recovery_disabled != conf->recovery_disabled &&
5111 } 5114 !has_failed(conf) &&
5112 p->rdev = NULL; 5115 number < conf->raid_disks) {
5113 synchronize_rcu(); 5116 err = -EBUSY;
5114 if (atomic_read(&rdev->nr_pending)) { 5117 goto abort;
5115 /* lost the race, try later */ 5118 }
5116 err = -EBUSY; 5119 *rdevp = NULL;
5117 p->rdev = rdev; 5120 synchronize_rcu();
5118 } 5121 if (atomic_read(&rdev->nr_pending)) {
5122 /* lost the race, try later */
5123 err = -EBUSY;
5124 *rdevp = rdev;
5119 } 5125 }
5120abort: 5126abort:
5121 5127