]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
DDF: get_svd_state: Status logic for secondary RAID level
authormwilck@arcor.de <mwilck@arcor.de>
Wed, 3 Jul 2013 20:27:49 +0000 (22:27 +0200)
committerNeilBrown <neilb@suse.de>
Mon, 8 Jul 2013 05:28:31 +0000 (15:28 +1000)
Implement logic to derive the status of a secondary RAID
from its members. Use it in ddf_set_disk.

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

index 322ad5e1b25f9e088ee54ec295eda101370f429a..8b7a6216210d8203b002b410f86a89f096962e9e 100644 (file)
@@ -3861,6 +3861,38 @@ static int get_bvd_state(const struct ddf_super *ddf,
        return state;
 }
 
+static int secondary_state(int state, int other, int seclevel)
+{
+       if (state == DDF_state_optimal && other == DDF_state_optimal)
+               return DDF_state_optimal;
+       if (seclevel == DDF_2MIRRORED) {
+               if (state == DDF_state_optimal || other == DDF_state_optimal)
+                       return DDF_state_part_optimal;
+               if (state == DDF_state_failed && other == DDF_state_failed)
+                       return DDF_state_failed;
+               return DDF_state_degraded;
+       } else {
+               if (state == DDF_state_failed || other == DDF_state_failed)
+                       return DDF_state_failed;
+               if (state == DDF_state_degraded || other == DDF_state_degraded)
+                       return DDF_state_degraded;
+               return DDF_state_part_optimal;
+       }
+}
+
+static int get_svd_state(const struct ddf_super *ddf, const struct vcl *vcl)
+{
+       int state = get_bvd_state(ddf, &vcl->conf);
+       unsigned int i;
+       for (i = 1; i < vcl->conf.sec_elmnt_count; i++) {
+               state = secondary_state(
+                       state,
+                       get_bvd_state(ddf, vcl->other_bvds[i-1]),
+                       vcl->conf.srl);
+       }
+       return state;
+}
+
 /*
  * The state of each disk is stored in the global phys_disk structure
  * in phys_disk.entries[n].state.
@@ -3946,10 +3978,7 @@ static void ddf_set_disk(struct active_array *a, int n, int state)
         * It needs to be one of "optimal", "degraded", "failed".
         * I don't understand 'deleted' or 'missing'.
         */
-       state = get_bvd_state(ddf, vc);
-       if (vc->sec_elmnt_count > 1) {
-               /* treat secondary level */
-       }
+       state = get_svd_state(ddf, vcl);
 
        if (ddf->virt->entries[inst].state !=
            ((ddf->virt->entries[inst].state & ~DDF_state_mask)