aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/md.c
diff options
context:
space:
mode:
authorAndrei Warkentin <andreiw@vmware.com>2011-10-17 21:16:48 -0400
committerNeilBrown <neilb@suse.de>2011-10-17 21:16:48 -0400
commitd70ed2e4fafdbef0800e73942482bb075c21578b (patch)
treea0fb7f9b6993b44e37dc2f724df251bd6fcffae3 /drivers/md/md.c
parentd30519fc59c5cc2f7772fa67b16b1a2426d36c95 (diff)
MD: Allow restarting an interrupted incremental recovery.
If an incremental recovery was interrupted, a subsequent re-add will result in a full recovery, even though an incremental should be possible (seen with raid1). Solve this problem by not updating the superblock on the recovering device until array is not degraded any longer. Cc: Neil Brown <neilb@suse.de> Signed-off-by: Andrei Warkentin <andreiw@vmware.com> Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'drivers/md/md.c')
-rw-r--r--drivers/md/md.c22
1 files changed, 15 insertions, 7 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 0ea34858637a..e8d198da917c 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -2449,7 +2449,8 @@ repeat:
2449 if (rdev->sb_loaded != 1) 2449 if (rdev->sb_loaded != 1)
2450 continue; /* no noise on spare devices */ 2450 continue; /* no noise on spare devices */
2451 2451
2452 if (!test_bit(Faulty, &rdev->flags)) { 2452 if (!test_bit(Faulty, &rdev->flags) &&
2453 rdev->saved_raid_disk == -1) {
2453 md_super_write(mddev,rdev, 2454 md_super_write(mddev,rdev,
2454 rdev->sb_start, rdev->sb_size, 2455 rdev->sb_start, rdev->sb_size,
2455 rdev->sb_page); 2456 rdev->sb_page);
@@ -2465,9 +2466,12 @@ repeat:
2465 rdev->badblocks.size = 0; 2466 rdev->badblocks.size = 0;
2466 } 2467 }
2467 2468
2468 } else 2469 } else if (test_bit(Faulty, &rdev->flags))
2469 pr_debug("md: %s (skipping faulty)\n", 2470 pr_debug("md: %s (skipping faulty)\n",
2470 bdevname(rdev->bdev, b)); 2471 bdevname(rdev->bdev, b));
2472 else
2473 pr_debug("(skipping incremental s/r ");
2474
2471 if (mddev->level == LEVEL_MULTIPATH) 2475 if (mddev->level == LEVEL_MULTIPATH)
2472 /* only need to write one superblock... */ 2476 /* only need to write one superblock... */
2473 break; 2477 break;
@@ -7366,15 +7370,19 @@ static void reap_sync_thread(struct mddev *mddev)
7366 if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery) && 7370 if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery) &&
7367 mddev->pers->finish_reshape) 7371 mddev->pers->finish_reshape)
7368 mddev->pers->finish_reshape(mddev); 7372 mddev->pers->finish_reshape(mddev);
7369 md_update_sb(mddev, 1);
7370 7373
7371 /* if array is no-longer degraded, then any saved_raid_disk 7374 /* If array is no-longer degraded, then any saved_raid_disk
7372 * information must be scrapped 7375 * information must be scrapped. Also if any device is now
7376 * In_sync we must scrape the saved_raid_disk for that device
7377 * do the superblock for an incrementally recovered device
7378 * written out.
7373 */ 7379 */
7374 if (!mddev->degraded) 7380 list_for_each_entry(rdev, &mddev->disks, same_set)
7375 list_for_each_entry(rdev, &mddev->disks, same_set) 7381 if (!mddev->degraded ||
7382 test_bit(In_sync, &rdev->flags))
7376 rdev->saved_raid_disk = -1; 7383 rdev->saved_raid_disk = -1;
7377 7384
7385 md_update_sb(mddev, 1);
7378 clear_bit(MD_RECOVERY_RUNNING, &mddev->recovery); 7386 clear_bit(MD_RECOVERY_RUNNING, &mddev->recovery);
7379 clear_bit(MD_RECOVERY_SYNC, &mddev->recovery); 7387 clear_bit(MD_RECOVERY_SYNC, &mddev->recovery);
7380 clear_bit(MD_RECOVERY_RESHAPE, &mddev->recovery); 7388 clear_bit(MD_RECOVERY_RESHAPE, &mddev->recovery);