]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
DDF: ddf_open_new: check device status for new subarray
authormwilck@arcor.de <mwilck@arcor.de>
Tue, 6 Aug 2013 21:38:02 +0000 (23:38 +0200)
committerNeilBrown <neilb@suse.de>
Thu, 8 Aug 2013 00:33:21 +0000 (10:33 +1000)
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>
super-ddf.c

index 8ebc00307183b28d1cbb8cd6881addb86b246b8d..e3b3dcaa11ecc78c94d226b4f316fd12de0aa85b 100644 (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;
 }