diff options
author | NeilBrown <neilb@suse.de> | 2014-04-01 07:15:06 +0200 |
---|---|---|
committer | NeilBrown <neilb@suse.de> | 2014-04-01 07:15:06 +0200 |
commit | e5a03804dc27e662be94290c62760dbc544c0211 (patch) | |
tree | ea054fcc7676e2503ad9c8e0df8850a06405f881 /super-ddf.c | |
parent | DDF: Fix assorted typos and do some reformatting. (diff) | |
download | mdadm-e5a03804dc27e662be94290c62760dbc544c0211.tar.xz mdadm-e5a03804dc27e662be94290c62760dbc544c0211.zip |
DDF: mark missing-on-assembly device properly.
As well as removing from the array we really should mark
it is 'failed', and mark the array as degraded.
Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'super-ddf.c')
-rw-r--r-- | super-ddf.c | 31 |
1 files changed, 28 insertions, 3 deletions
diff --git a/super-ddf.c b/super-ddf.c index 07ba5bd9..55fa03ee 100644 --- a/super-ddf.c +++ b/super-ddf.c @@ -4126,7 +4126,7 @@ static int ddf_open_new(struct supertype *c, struct active_array *a, char *inst) return 0; } -static void handle_missing(struct ddf_super *ddf, int inst) +static void handle_missing(struct ddf_super *ddf, struct active_array *a, int inst) { /* This member array is being activated. If any devices * are missing they must now be marked as failed. @@ -4135,7 +4135,9 @@ static void handle_missing(struct ddf_super *ddf, int inst) unsigned int n_bvd; struct vcl *vcl; struct dl *dl; + int pd; int n; + int state; for (n = 0; ; n++) { vc = find_vdcr(ddf, inst, n, &n_bvd, &vcl); @@ -4147,7 +4149,30 @@ static void handle_missing(struct ddf_super *ddf, int inst) if (dl) /* Found this disk, so not missing */ continue; - vc->phys_refnum[n_bvd] = cpu_to_be32(0); + + /* Mark the device as failed/missing. */ + pd = find_phys(ddf, vc->phys_refnum[n_bvd]); + if (pd >= 0 && be16_and(ddf->phys->entries[pd].state, + cpu_to_be16(DDF_Online))) { + be16_clear(ddf->phys->entries[pd].state, + cpu_to_be16(DDF_Online)); + be16_set(ddf->phys->entries[pd].state, + cpu_to_be16(DDF_Failed|DDF_Missing)); + vc->phys_refnum[n_bvd] = cpu_to_be32(0); + ddf_set_updates_pending(ddf); + } + + /* Mark the array as Degraded */ + state = get_svd_state(ddf, vcl); + if (ddf->virt->entries[inst].state != + ((ddf->virt->entries[inst].state & ~DDF_state_mask) + | state)) { + ddf->virt->entries[inst].state = + (ddf->virt->entries[inst].state & ~DDF_state_mask) + | state; + a->check_degraded = 1; + ddf_set_updates_pending(ddf); + } } } @@ -4166,7 +4191,7 @@ static int ddf_set_array_state(struct active_array *a, int consistent) int inst = a->info.container_member; int old = ddf->virt->entries[inst].state; if (consistent == 2) { - handle_missing(ddf, inst); + handle_missing(ddf, a, inst); /* Should check if a recovery should be started FIXME */ consistent = 1; if (!is_resync_complete(&a->info)) |