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:
mwilck@arcor.de 2013-07-03 22:27:48 +02:00 committed by NeilBrown
parent baba3f4e81
commit 5ec636b7ad
1 changed files with 53 additions and 41 deletions

View File

@ -1515,7 +1515,7 @@ bad:
}
#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
* and return it's index
@ -3812,9 +3812,55 @@ static int ddf_set_array_state(struct active_array *a, int consistent)
return consistent;
}
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
static int get_bvd_state(const struct ddf_super *ddf,
const struct vd_config *vc)
{
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
* 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,
&n_bvd, &vcl);
int pd;
int i, st, working;
struct mdinfo *mdi;
struct dl *dl;
@ -3901,43 +3946,10 @@ 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'.
*/
working = 0;
for (i=0; i < a->info.array.raid_disks; i++) {
pd = find_phys(ddf, vc->phys_refnum[i]);
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 = get_bvd_state(ddf, vc);
if (vc->sec_elmnt_count > 1) {
/* treat secondary level */
}
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 !=
((ddf->virt->entries[inst].state & ~DDF_state_mask)