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 <dan.j.williams@intel.com>
This commit is contained in:
parent
1770662bca
commit
e553d2a458
|
@ -2510,9 +2510,10 @@ static struct dl *imsm_readd(struct intel_super *super, int idx, struct active_a
|
||||||
return dl;
|
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);
|
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);
|
struct imsm_map *map = get_imsm_map(dev, 0);
|
||||||
unsigned long long esize;
|
unsigned long long esize;
|
||||||
unsigned long long pos;
|
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) {
|
for (dl = super->disks; dl; dl = dl->next) {
|
||||||
/* If in this array, skip */
|
/* If in this array, skip */
|
||||||
for (d = a->info.devs ; d ; d = d->next)
|
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) {
|
d->disk.minor == dl->minor) {
|
||||||
dprintf("%x:%x already in array\n", dl->major, dl->minor);
|
dprintf("%x:%x already in array\n", dl->major, dl->minor);
|
||||||
break;
|
break;
|
||||||
|
@ -2535,13 +2537,13 @@ static struct dl *imsm_add_spare(struct intel_super *super, int idx, struct acti
|
||||||
if (d)
|
if (d)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* skip marked in use or failed drives */
|
/* skip in use or failed drives */
|
||||||
status = __le32_to_cpu(dl->disk.status);
|
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",
|
dprintf("%x:%x status ( %s%s)\n",
|
||||||
dl->major, dl->minor,
|
dl->major, dl->minor,
|
||||||
status & FAILED_DISK ? "failed " : "",
|
status & FAILED_DISK ? "failed " : "",
|
||||||
status & CONFIGURED_DISK ? "configured " : "");
|
idx == dl->index ? "in use " : "");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2946,23 +2948,16 @@ static void imsm_process_update(struct supertype *st,
|
||||||
for (a = st->arrays; a; a = a->next)
|
for (a = st->arrays; a; a = a->next)
|
||||||
a->check_degraded = 1;
|
a->check_degraded = 1;
|
||||||
}
|
}
|
||||||
/* check if we can add / replace some disks in the
|
/* add some spares to the metadata */
|
||||||
* metadata */
|
|
||||||
while (super->add) {
|
while (super->add) {
|
||||||
struct dl **dlp, *dl, *al;
|
struct dl *al;
|
||||||
|
|
||||||
al = super->add;
|
al = super->add;
|
||||||
super->add = al->next;
|
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;
|
al->next = super->disks;
|
||||||
super->disks = al;
|
super->disks = al;
|
||||||
|
dprintf("%s: added %x:%x\n",
|
||||||
|
__func__, al->major, al->minor);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue