aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2011-12-22 18:17:57 -0500
committerNeilBrown <neilb@suse.de>2011-12-22 18:17:57 -0500
commit8c7a2c2bcfaf0ee29c74437a4814d1aa780d6a26 (patch)
tree74093a74ea43965f04502bc5d71b6976a74c7305 /drivers/md
parentb014f14c81bc5db4e40e2a4db10998fd79c1c64c (diff)
md/raid1: handle activation of replacement device when recovery completes.
When recovery completes ->spare_active is called. This checks if the replacement is ready and if so it fails the original. Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'drivers/md')
-rw-r--r--drivers/md/raid1.c36
1 files changed, 33 insertions, 3 deletions
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 3d9aa0c92821..f68075189df8 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -1265,6 +1265,25 @@ static int raid1_spare_active(struct mddev *mddev)
1265 */ 1265 */
1266 for (i = 0; i < conf->raid_disks; i++) { 1266 for (i = 0; i < conf->raid_disks; i++) {
1267 struct md_rdev *rdev = conf->mirrors[i].rdev; 1267 struct md_rdev *rdev = conf->mirrors[i].rdev;
1268 struct md_rdev *repl = conf->mirrors[conf->raid_disks + i].rdev;
1269 if (repl
1270 && repl->recovery_offset == MaxSector
1271 && !test_bit(Faulty, &repl->flags)
1272 && !test_and_set_bit(In_sync, &repl->flags)) {
1273 /* replacement has just become active */
1274 if (!rdev ||
1275 !test_and_clear_bit(In_sync, &rdev->flags))
1276 count++;
1277 if (rdev) {
1278 /* Replaced device not technically
1279 * faulty, but we need to be sure
1280 * it gets removed and never re-added
1281 */
1282 set_bit(Faulty, &rdev->flags);
1283 sysfs_notify_dirent_safe(
1284 rdev->sysfs_state);
1285 }
1286 }
1268 if (rdev 1287 if (rdev
1269 && !test_bit(Faulty, &rdev->flags) 1288 && !test_bit(Faulty, &rdev->flags)
1270 && !test_and_set_bit(In_sync, &rdev->flags)) { 1289 && !test_and_set_bit(In_sync, &rdev->flags)) {
@@ -1362,10 +1381,21 @@ static int raid1_remove_disk(struct mddev *mddev, struct md_rdev *rdev)
1362 err = -EBUSY; 1381 err = -EBUSY;
1363 p->rdev = rdev; 1382 p->rdev = rdev;
1364 goto abort; 1383 goto abort;
1365 } else { 1384 } else if (conf->mirrors[conf->raid_disks + number].rdev) {
1366 clear_bit(Replacement, &rdev->flags); 1385 /* We just removed a device that is being replaced.
1386 * Move down the replacement. We drain all IO before
1387 * doing this to avoid confusion.
1388 */
1389 struct md_rdev *repl =
1390 conf->mirrors[conf->raid_disks + number].rdev;
1391 raise_barrier(conf);
1392 clear_bit(Replacement, &repl->flags);
1393 p->rdev = repl;
1394 conf->mirrors[conf->raid_disks + number].rdev = NULL;
1395 lower_barrier(conf);
1396 clear_bit(WantReplacement, &rdev->flags);
1397 } else
1367 clear_bit(WantReplacement, &rdev->flags); 1398 clear_bit(WantReplacement, &rdev->flags);
1368 }
1369 err = md_integrity_register(mddev); 1399 err = md_integrity_register(mddev);
1370 } 1400 }
1371abort: 1401abort: