]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
ddf: set Rebuilding flag when adding devices to a degraded array
authorNeilBrown <neilb@suse.de>
Tue, 15 Mar 2011 03:57:46 +0000 (14:57 +1100)
committerNeilBrown <neilb@suse.de>
Tue, 15 Mar 2011 03:57:46 +0000 (14:57 +1100)
This is a big fragile, but DDF has wierd rules that we aren't really
set up to handle properly.

When we add a device to a degraded array it must be a spare, so
mark it as Rebuilding.

Signed-off-by: NeilBrown <neilb@suse.de>
super-ddf.c

index 90133195d17f0e07ddb201a11f0c7c113c92364a..505a5b3f995d24c186f9cb91ce3b7b01d4e06e2f 100644 (file)
@@ -3432,13 +3432,20 @@ static void ddf_process_update(struct supertype *st,
                for (dl = ddf->dlist; dl; dl = dl->next) {
                        unsigned int dn;
                        unsigned int vn = 0;
+                       int in_degraded = 0;
                        for (vcl = ddf->conflist; vcl ; vcl = vcl->next)
                                for (dn=0; dn < ddf->mppe ; dn++)
                                        if (vcl->conf.phys_refnum[dn] ==
                                            dl->disk.refnum) {
+                                               int vstate;
                                                dprintf("dev %d has %p at %d\n",
                                                        dl->pdnum, vcl, vn);
                                                dl->vlist[vn++] = vcl;
+                                               vstate = ddf->virt->entries[vcl->vcnum].state
+                                                       & DDF_state_mask;
+                                               if (vstate == DDF_state_degraded ||
+                                                   vstate == DDF_state_part_optimal)
+                                                       in_degraded = 1;
                                                break;
                                        }
                        while (vn < ddf->max_part)
@@ -3446,8 +3453,14 @@ static void ddf_process_update(struct supertype *st,
                        if (dl->vlist[0]) {
                                ddf->phys->entries[dl->pdnum].type &=
                                        ~__cpu_to_be16(DDF_Global_Spare);
-                               ddf->phys->entries[dl->pdnum].type |=
-                                       __cpu_to_be16(DDF_Active_in_VD);
+                               if (!(ddf->phys->entries[dl->pdnum].type &
+                                     __cpu_to_be16(DDF_Active_in_VD))) {
+                                           ddf->phys->entries[dl->pdnum].type |=
+                                                   __cpu_to_be16(DDF_Active_in_VD);
+                                           if (in_degraded)
+                                                   ddf->phys->entries[dl->pdnum].state |=
+                                                           __cpu_to_be16(DDF_Rebuilding);
+                                   }
                        }
                        if (dl->spare) {
                                ddf->phys->entries[dl->pdnum].type &=