aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2011-12-22 18:17:54 -0500
committerNeilBrown <neilb@suse.de>2011-12-22 18:17:54 -0500
commitc8ab903ea9d7309044910c33dc087418be84f9b5 (patch)
tree1113f320a71e50bc5ed22b7f6ca0ec1800b37b08 /drivers
parentabbf098e6e1e23d5d247b9eaaf325e67f67b0328 (diff)
md/raid10: allow removal of failed replacement devices.
Enhance raid10_remove_disk to be able to remove ->replacement as well as ->rdev Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/md/raid10.c57
1 files changed, 32 insertions, 25 deletions
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 5b886218110e..b2c8998e1397 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -1429,34 +1429,41 @@ static int raid10_remove_disk(struct mddev *mddev, struct md_rdev *rdev)
1429 struct r10conf *conf = mddev->private; 1429 struct r10conf *conf = mddev->private;
1430 int err = 0; 1430 int err = 0;
1431 int number = rdev->raid_disk; 1431 int number = rdev->raid_disk;
1432 struct mirror_info *p = conf->mirrors+ number; 1432 struct md_rdev **rdevp;
1433 struct mirror_info *p = conf->mirrors + number;
1433 1434
1434 print_conf(conf); 1435 print_conf(conf);
1435 if (rdev == p->rdev) { 1436 if (rdev == p->rdev)
1436 if (test_bit(In_sync, &rdev->flags) || 1437 rdevp = &p->rdev;
1437 atomic_read(&rdev->nr_pending)) { 1438 else if (rdev == p->replacement)
1438 err = -EBUSY; 1439 rdevp = &p->replacement;
1439 goto abort; 1440 else
1440 } 1441 return 0;
1441 /* Only remove faulty devices in recovery 1442
1442 * is not possible. 1443 if (test_bit(In_sync, &rdev->flags) ||
1443 */ 1444 atomic_read(&rdev->nr_pending)) {
1444 if (!test_bit(Faulty, &rdev->flags) && 1445 err = -EBUSY;
1445 mddev->recovery_disabled != p->recovery_disabled && 1446 goto abort;
1446 enough(conf, -1)) { 1447 }
1447 err = -EBUSY; 1448 /* Only remove faulty devices if recovery
1448 goto abort; 1449 * is not possible.
1449 } 1450 */
1450 p->rdev = NULL; 1451 if (!test_bit(Faulty, &rdev->flags) &&
1451 synchronize_rcu(); 1452 mddev->recovery_disabled != p->recovery_disabled &&
1452 if (atomic_read(&rdev->nr_pending)) { 1453 enough(conf, -1)) {
1453 /* lost the race, try later */ 1454 err = -EBUSY;
1454 err = -EBUSY; 1455 goto abort;
1455 p->rdev = rdev;
1456 goto abort;
1457 }
1458 err = md_integrity_register(mddev);
1459 } 1456 }
1457 *rdevp = NULL;
1458 synchronize_rcu();
1459 if (atomic_read(&rdev->nr_pending)) {
1460 /* lost the race, try later */
1461 err = -EBUSY;
1462 *rdevp = rdev;
1463 goto abort;
1464 }
1465 err = md_integrity_register(mddev);
1466
1460abort: 1467abort:
1461 1468
1462 print_conf(conf); 1469 print_conf(conf);