DDF: ddf_open_new: check device status for new subarray

It is possible that mdadm creates a new subarray containing failed
devices. This may happen if a device has failed, but the meta data
containing that information hasn't been written out yet.

This code tests for this situation, and handles it in the monitor.

Signed-off-by: Martin Wilck <mwilck@arcor.de>
Signed-off-by: NeilBrown <neilb@suse.de>
This commit is contained in:
mwilck@arcor.de 2013-08-06 23:38:02 +02:00 committed by NeilBrown
parent 82c8e664cc
commit 5daa35ac1a
1 changed files with 28 additions and 1 deletions

View File

@ -3985,11 +3985,38 @@ static int ddf_open_new(struct supertype *c, struct active_array *a, char *inst)
{
struct ddf_super *ddf = c->sb;
int n = atoi(inst);
struct mdinfo *dev;
struct dl *dl;
static const char faulty[] = "faulty";
if (all_ff(ddf->virt->entries[n].guid)) {
pr_err("%s: subarray %d doesn't exist\n", __func__, n);
return -ENODEV;
}
dprintf("ddf: open_new %d\n", n);
dprintf("%s: new subarray %d, GUID: %s\n", __func__, n,
guid_str(ddf->virt->entries[n].guid));
for (dev = a->info.devs; dev; dev = dev->next) {
for (dl = ddf->dlist; dl; dl = dl->next)
if (dl->major == dev->disk.major &&
dl->minor == dev->disk.minor)
break;
if (!dl) {
pr_err("%s: device %d/%d of subarray %d not found in meta data\n",
__func__, dev->disk.major, dev->disk.minor, n);
return -1;
}
if ((be16_to_cpu(ddf->phys->entries[dl->pdnum].state) &
(DDF_Online|DDF_Missing|DDF_Failed)) != DDF_Online) {
pr_err("%s: new subarray %d contains broken device %d/%d (%02x)\n",
__func__, n, dl->major, dl->minor,
be16_to_cpu(
ddf->phys->entries[dl->pdnum].state));
if (write(dev->state_fd, faulty, sizeof(faulty)-1) !=
sizeof(faulty) - 1)
pr_err("Write to state_fd failed\n");
dev->curr_state = DS_FAULTY;
}
}
a->info.container_member = n;
return 0;
}