From e553d2a45890e7341612a0f670d3ff00a2986678 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 15 Sep 2008 20:58:42 -0700 Subject: [PATCH] imsm: allow a failed disk to be readded Allow the following sequence to rebuild the array mdadm --fail /dev/md/r1 /dev/disk mdadm --remove /dev/imsm /dev/disk mdadm --add /dev/imsm /dev/disk Signed-off-by: Dan Williams --- super-intel.c | 29 ++++++++++++----------------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/super-intel.c b/super-intel.c index 55f748d0..6170587f 100644 --- a/super-intel.c +++ b/super-intel.c @@ -2510,9 +2510,10 @@ static struct dl *imsm_readd(struct intel_super *super, int idx, struct active_a return dl; } -static struct dl *imsm_add_spare(struct intel_super *super, int idx, struct active_array *a) +static struct dl *imsm_add_spare(struct intel_super *super, int slot, struct active_array *a) { struct imsm_dev *dev = get_imsm_dev(super, a->info.container_member); + int idx = get_imsm_disk_idx(dev, slot); struct imsm_map *map = get_imsm_map(dev, 0); unsigned long long esize; unsigned long long pos; @@ -2527,7 +2528,8 @@ static struct dl *imsm_add_spare(struct intel_super *super, int idx, struct acti for (dl = super->disks; dl; dl = dl->next) { /* If in this array, skip */ for (d = a->info.devs ; d ; d = d->next) - if (d->disk.major == dl->major && + if (d->state_fd >= 0 && + d->disk.major == dl->major && d->disk.minor == dl->minor) { dprintf("%x:%x already in array\n", dl->major, dl->minor); break; @@ -2535,13 +2537,13 @@ static struct dl *imsm_add_spare(struct intel_super *super, int idx, struct acti if (d) continue; - /* skip marked in use or failed drives */ + /* skip in use or failed drives */ status = __le32_to_cpu(dl->disk.status); - if (status & FAILED_DISK || status & CONFIGURED_DISK) { + if (status & FAILED_DISK || idx == dl->index) { dprintf("%x:%x status ( %s%s)\n", dl->major, dl->minor, status & FAILED_DISK ? "failed " : "", - status & CONFIGURED_DISK ? "configured " : ""); + idx == dl->index ? "in use " : ""); continue; } @@ -2946,23 +2948,16 @@ static void imsm_process_update(struct supertype *st, for (a = st->arrays; a; a = a->next) a->check_degraded = 1; } - /* check if we can add / replace some disks in the - * metadata */ + /* add some spares to the metadata */ while (super->add) { - struct dl **dlp, *dl, *al; + struct dl *al; + al = super->add; super->add = al->next; - for (dlp = &super->disks; *dlp ; ) { - if (serialcmp(al->serial, (*dlp)->serial) == 0) { - dl = *dlp; - *dlp = (*dlp)->next; - __free_imsm_disk(dl); - break; - } else - dlp = &(*dlp)->next; - } al->next = super->disks; super->disks = al; + dprintf("%s: added %x:%x\n", + __func__, al->major, al->minor); } break; -- 2.39.2