From c337c5388c8b34fc28873eebe62cf619b49358c7 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Fri, 9 Jan 2009 08:31:11 +1100 Subject: [PATCH] --- yaml --- r: 127733 b: refs/heads/master c: 4044ba58dd15cb01797c4fd034f39ef4a75f7cc3 h: refs/heads/master i: 127731: 7284bea483aa3342e9bc2c27b7a1b469614b8c89 v: v3 --- [refs] | 2 +- trunk/drivers/md/md.c | 5 ++++- trunk/drivers/md/raid1.c | 8 ++++++-- trunk/include/linux/raid/md_k.h | 3 +++ 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/[refs] b/[refs] index 46a094464a77..a4210b32186d 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: efeb53c0e57213e843b7ef3cc6ebcdea7d6186ac +refs/heads/master: 4044ba58dd15cb01797c4fd034f39ef4a75f7cc3 diff --git a/trunk/drivers/md/md.c b/trunk/drivers/md/md.c index f5cbb9d2371a..41e2509bf896 100644 --- a/trunk/drivers/md/md.c +++ b/trunk/drivers/md/md.c @@ -1500,6 +1500,9 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev) list_add_rcu(&rdev->same_set, &mddev->disks); bd_claim_by_disk(rdev->bdev, rdev->bdev->bd_holder, mddev->gendisk); + + /* May as well allow recovery to be retried once */ + mddev->recovery_disabled = 0; return 0; fail: @@ -6175,7 +6178,7 @@ static int remove_and_add_spares(mddev_t *mddev) } } - if (mddev->degraded && ! mddev->ro) { + if (mddev->degraded && ! mddev->ro && !mddev->recovery_disabled) { list_for_each_entry(rdev, &mddev->disks, same_set) { if (rdev->raid_disk >= 0 && !test_bit(In_sync, &rdev->flags) && diff --git a/trunk/drivers/md/raid1.c b/trunk/drivers/md/raid1.c index c165b1eed8bb..7b4f5f7155d8 100644 --- a/trunk/drivers/md/raid1.c +++ b/trunk/drivers/md/raid1.c @@ -1016,12 +1016,16 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev) * else mark the drive as failed */ if (test_bit(In_sync, &rdev->flags) - && (conf->raid_disks - mddev->degraded) == 1) + && (conf->raid_disks - mddev->degraded) == 1) { /* * Don't fail the drive, act as though we were just a - * normal single drive + * normal single drive. + * However don't try a recovery from this drive as + * it is very likely to fail. */ + mddev->recovery_disabled = 1; return; + } if (test_and_clear_bit(In_sync, &rdev->flags)) { unsigned long flags; spin_lock_irqsave(&conf->device_lock, flags); diff --git a/trunk/include/linux/raid/md_k.h b/trunk/include/linux/raid/md_k.h index dac4217194b8..9743e4dbc918 100644 --- a/trunk/include/linux/raid/md_k.h +++ b/trunk/include/linux/raid/md_k.h @@ -218,6 +218,9 @@ struct mddev_s #define MD_RECOVERY_FROZEN 9 unsigned long recovery; + int recovery_disabled; /* if we detect that recovery + * will always fail, set this + * so we don't loop trying */ int in_sync; /* know to not need resync */ struct mutex reconfig_mutex;