summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2011-03-15 14:57:46 +1100
committerNeilBrown <neilb@suse.de>2011-03-15 14:57:46 +1100
commit8401644c3a8b2a15bfed25cedc3c4ec0beff07c2 (patch)
tree3bb187ac30b1bf674e81dbf480f6840988b7f3be
parente5cc7d469f09faa2f6666d61b7c719136e959d09 (diff)
downloadmdadm-8401644c3a8b2a15bfed25cedc3c4ec0beff07c2.tar.gz
ddf: set Rebuilding flag when adding devices to a degraded array
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>
-rw-r--r--super-ddf.c17
1 files changed, 15 insertions, 2 deletions
diff --git a/super-ddf.c b/super-ddf.c
index 9013319..505a5b3 100644
--- a/super-ddf.c
+++ b/super-ddf.c
@@ -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 &=