From mboxrd@z Thu Jan 1 00:00:00 1970 From: Andrei Warkentin Subject: [RFC] MD: Allow restarting an interrupted incremental recovery. Date: Wed, 12 Oct 2011 19:05:33 -0400 Message-ID: <1318460733-886-1-git-send-email-andreiw@vmware.com> References: Return-path: In-Reply-To: Sender: linux-raid-owner@vger.kernel.org To: linux-raid@vger.kernel.org Cc: Andrei Warkentin , Neil Brown List-Id: linux-raid.ids 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 Signed-off-by: Andrei Warkentin --- drivers/md/md.c | 19 +++++++++++++------ drivers/md/md.h | 6 ++++++ 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/drivers/md/md.c b/drivers/md/md.c index 5404b22..153b3c6 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -2444,9 +2444,12 @@ repeat: continue; /* no noise on spare devices */ if (test_bit(Faulty, &rdev->flags)) dprintk("(skipping faulty "); + else if (test_bit(InIncremental, &rdev->flags)) + dprintk("(skipping incremental s/r "); dprintk("%s ", bdevname(rdev->bdev,b)); - if (!test_bit(Faulty, &rdev->flags)) { + if (!test_bit(Faulty, &rdev->flags) && + !test_bit(InIncremental, &rdev->flags)) { md_super_write(mddev,rdev, rdev->sb_start, rdev->sb_size, rdev->sb_page); @@ -5490,9 +5493,10 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info) return -EINVAL; } - if (test_bit(In_sync, &rdev->flags)) + if (test_bit(In_sync, &rdev->flags)) { rdev->saved_raid_disk = rdev->raid_disk; - else + set_bit(InIncremental, &rdev->flags); + } else rdev->saved_raid_disk = -1; clear_bit(In_sync, &rdev->flags); /* just to be sure */ @@ -7353,15 +7357,18 @@ static void reap_sync_thread(mddev_t *mddev) if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery) && mddev->pers->finish_reshape) mddev->pers->finish_reshape(mddev); - md_update_sb(mddev, 1); /* if array is no-longer degraded, then any saved_raid_disk - * information must be scrapped + * information must be scrapped, and superblock for + * incrementally recovered device written out. */ if (!mddev->degraded) - list_for_each_entry(rdev, &mddev->disks, same_set) + list_for_each_entry(rdev, &mddev->disks, same_set) { rdev->saved_raid_disk = -1; + clear_bit(InIncremental, &rdev->flags); + } + md_update_sb(mddev, 1); clear_bit(MD_RECOVERY_RUNNING, &mddev->recovery); clear_bit(MD_RECOVERY_SYNC, &mddev->recovery); clear_bit(MD_RECOVERY_RESHAPE, &mddev->recovery); diff --git a/drivers/md/md.h b/drivers/md/md.h index 1e586bb..5e5399a 100644 --- a/drivers/md/md.h +++ b/drivers/md/md.h @@ -104,6 +104,12 @@ struct mdk_rdev_s * accurately as possible is good, but * not absolutely critical. */ +#define InIncremental 12 /* Device is undergoing incremental + * recovery, hence its superblock + * is not written out until the recovery + * ends, allowing the later to be + * restared if interrupted. + */ wait_queue_head_t blocked_wait; int desc_nr; /* descriptor index in the superblock */ -- 1.7.4.1