DDF: ddf_set_disk: move status logic to separate function
Moved code to determine RAID status to a separate function get_bvd_status(). I need this to account for secondary RAID level. Signed-off-by: Martin Wilck <mwilck@arcor.de> Signed-off-by: NeilBrown <neilb@suse.de>
This commit is contained in:
parent
baba3f4e81
commit
5ec636b7ad
94
super-ddf.c
94
super-ddf.c
|
@ -1515,7 +1515,7 @@ bad:
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int find_phys(struct ddf_super *ddf, __u32 phys_refnum)
|
static int find_phys(const struct ddf_super *ddf, __u32 phys_refnum)
|
||||||
{
|
{
|
||||||
/* Find the entry in phys_disk which has the given refnum
|
/* Find the entry in phys_disk which has the given refnum
|
||||||
* and return it's index
|
* and return it's index
|
||||||
|
@ -3812,9 +3812,55 @@ static int ddf_set_array_state(struct active_array *a, int consistent)
|
||||||
return consistent;
|
return consistent;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define container_of(ptr, type, member) ({ \
|
static int get_bvd_state(const struct ddf_super *ddf,
|
||||||
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
|
const struct vd_config *vc)
|
||||||
(type *)( (char *)__mptr - offsetof(type,member) );})
|
{
|
||||||
|
unsigned int i, n_bvd, working = 0;
|
||||||
|
unsigned int n_prim = __be16_to_cpu(vc->prim_elmnt_count);
|
||||||
|
int pd, st, state;
|
||||||
|
for (i = 0; i < n_prim; i++) {
|
||||||
|
if (!find_index_in_bvd(ddf, vc, i, &n_bvd))
|
||||||
|
continue;
|
||||||
|
pd = find_phys(ddf, vc->phys_refnum[n_bvd]);
|
||||||
|
if (pd < 0)
|
||||||
|
continue;
|
||||||
|
st = __be16_to_cpu(ddf->phys->entries[pd].state);
|
||||||
|
if ((st & (DDF_Online|DDF_Failed|DDF_Rebuilding))
|
||||||
|
== DDF_Online)
|
||||||
|
working++;
|
||||||
|
}
|
||||||
|
|
||||||
|
state = DDF_state_degraded;
|
||||||
|
if (working == n_prim)
|
||||||
|
state = DDF_state_optimal;
|
||||||
|
else
|
||||||
|
switch (vc->prl) {
|
||||||
|
case DDF_RAID0:
|
||||||
|
case DDF_CONCAT:
|
||||||
|
case DDF_JBOD:
|
||||||
|
state = DDF_state_failed;
|
||||||
|
break;
|
||||||
|
case DDF_RAID1:
|
||||||
|
if (working == 0)
|
||||||
|
state = DDF_state_failed;
|
||||||
|
else if (working >= 2)
|
||||||
|
state = DDF_state_part_optimal;
|
||||||
|
break;
|
||||||
|
case DDF_RAID4:
|
||||||
|
case DDF_RAID5:
|
||||||
|
if (working < n_prim - 1)
|
||||||
|
state = DDF_state_failed;
|
||||||
|
break;
|
||||||
|
case DDF_RAID6:
|
||||||
|
if (working < n_prim - 2)
|
||||||
|
state = DDF_state_failed;
|
||||||
|
else if (working == n_prim - 1)
|
||||||
|
state = DDF_state_part_optimal;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The state of each disk is stored in the global phys_disk structure
|
* The state of each disk is stored in the global phys_disk structure
|
||||||
* in phys_disk.entries[n].state.
|
* in phys_disk.entries[n].state.
|
||||||
|
@ -3837,7 +3883,6 @@ static void ddf_set_disk(struct active_array *a, int n, int state)
|
||||||
struct vd_config *vc = find_vdcr(ddf, inst, (unsigned int)n,
|
struct vd_config *vc = find_vdcr(ddf, inst, (unsigned int)n,
|
||||||
&n_bvd, &vcl);
|
&n_bvd, &vcl);
|
||||||
int pd;
|
int pd;
|
||||||
int i, st, working;
|
|
||||||
struct mdinfo *mdi;
|
struct mdinfo *mdi;
|
||||||
struct dl *dl;
|
struct dl *dl;
|
||||||
|
|
||||||
|
@ -3901,42 +3946,9 @@ static void ddf_set_disk(struct active_array *a, int n, int state)
|
||||||
* It needs to be one of "optimal", "degraded", "failed".
|
* It needs to be one of "optimal", "degraded", "failed".
|
||||||
* I don't understand 'deleted' or 'missing'.
|
* I don't understand 'deleted' or 'missing'.
|
||||||
*/
|
*/
|
||||||
working = 0;
|
state = get_bvd_state(ddf, vc);
|
||||||
for (i=0; i < a->info.array.raid_disks; i++) {
|
if (vc->sec_elmnt_count > 1) {
|
||||||
pd = find_phys(ddf, vc->phys_refnum[i]);
|
/* treat secondary level */
|
||||||
if (pd < 0)
|
|
||||||
continue;
|
|
||||||
st = __be16_to_cpu(ddf->phys->entries[pd].state);
|
|
||||||
if ((st & (DDF_Online|DDF_Failed|DDF_Rebuilding))
|
|
||||||
== DDF_Online)
|
|
||||||
working++;
|
|
||||||
}
|
|
||||||
state = DDF_state_degraded;
|
|
||||||
if (working == a->info.array.raid_disks)
|
|
||||||
state = DDF_state_optimal;
|
|
||||||
else switch(vc->prl) {
|
|
||||||
case DDF_RAID0:
|
|
||||||
case DDF_CONCAT:
|
|
||||||
case DDF_JBOD:
|
|
||||||
state = DDF_state_failed;
|
|
||||||
break;
|
|
||||||
case DDF_RAID1:
|
|
||||||
if (working == 0)
|
|
||||||
state = DDF_state_failed;
|
|
||||||
else if (working == 2 && state == DDF_state_degraded)
|
|
||||||
state = DDF_state_part_optimal;
|
|
||||||
break;
|
|
||||||
case DDF_RAID4:
|
|
||||||
case DDF_RAID5:
|
|
||||||
if (working < a->info.array.raid_disks-1)
|
|
||||||
state = DDF_state_failed;
|
|
||||||
break;
|
|
||||||
case DDF_RAID6:
|
|
||||||
if (working < a->info.array.raid_disks-2)
|
|
||||||
state = DDF_state_failed;
|
|
||||||
else if (working == a->info.array.raid_disks-1)
|
|
||||||
state = DDF_state_part_optimal;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ddf->virt->entries[inst].state !=
|
if (ddf->virt->entries[inst].state !=
|
||||||
|
|
Loading…
Reference in New Issue