}
#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
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.
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;
* 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)