DDF: layout_ddf2md: new DDF->md RAID layout conversion
layout_ddf2md() is a new RAID layout conversion routine. It obsoletes the previous separate routines for obtaining md level and layout (map_num1, rlq_to_layout). Signed-off-by: Martin Wilck <mwilck@arcor.de> Signed-off-by: NeilBrown <neilb@suse.de>
This commit is contained in:
parent
fb9d0acbbc
commit
8a2848a700
179
super-ddf.c
179
super-ddf.c
|
@ -484,6 +484,102 @@ static unsigned int calc_crc(void *buf, int len)
|
||||||
return __cpu_to_be32(newcrc);
|
return __cpu_to_be32(newcrc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int err_bad_ddf_layout(const struct vd_config *conf)
|
||||||
|
{
|
||||||
|
pr_err("DDF RAID %u qualifier %u with %u disks is unsupported\n",
|
||||||
|
conf->prl, conf->rlq, __be16_to_cpu(conf->prim_elmnt_count));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int layout_ddf2md(const struct vd_config *conf,
|
||||||
|
mdu_array_info_t *array)
|
||||||
|
{
|
||||||
|
int level = LEVEL_UNSUPPORTED;
|
||||||
|
int layout = 0;
|
||||||
|
int raiddisks = __be16_to_cpu(conf->prim_elmnt_count);
|
||||||
|
|
||||||
|
if (conf->sec_elmnt_count > 1) {
|
||||||
|
/* see also check_secondary() */
|
||||||
|
if (conf->prl != DDF_RAID1 ||
|
||||||
|
(conf->srl != DDF_2STRIPED && conf->srl != DDF_2SPANNED)) {
|
||||||
|
pr_err("Unsupported secondary RAID level %u/%u\n",
|
||||||
|
conf->prl, conf->srl);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (raiddisks == 2 && conf->rlq == DDF_RAID1_SIMPLE)
|
||||||
|
layout = 0x102;
|
||||||
|
else if (raiddisks == 3 && conf->rlq == DDF_RAID1_MULTI)
|
||||||
|
layout = 0x103;
|
||||||
|
else
|
||||||
|
return err_bad_ddf_layout(conf);
|
||||||
|
raiddisks *= conf->sec_elmnt_count;
|
||||||
|
level = 10;
|
||||||
|
goto good;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (conf->prl) {
|
||||||
|
case DDF_CONCAT:
|
||||||
|
level = LEVEL_LINEAR;
|
||||||
|
break;
|
||||||
|
case DDF_RAID0:
|
||||||
|
if (conf->rlq != DDF_RAID0_SIMPLE)
|
||||||
|
return err_bad_ddf_layout(conf);
|
||||||
|
level = 0;
|
||||||
|
break;
|
||||||
|
case DDF_RAID1:
|
||||||
|
if (!((conf->rlq == DDF_RAID1_SIMPLE && raiddisks == 2) ||
|
||||||
|
(conf->rlq == DDF_RAID1_MULTI && raiddisks == 3)))
|
||||||
|
return err_bad_ddf_layout(conf);
|
||||||
|
level = 1;
|
||||||
|
break;
|
||||||
|
case DDF_RAID4:
|
||||||
|
if (conf->rlq != DDF_RAID4_N)
|
||||||
|
return err_bad_ddf_layout(conf);
|
||||||
|
level = 4;
|
||||||
|
break;
|
||||||
|
case DDF_RAID5:
|
||||||
|
switch (conf->rlq) {
|
||||||
|
case DDF_RAID5_N_RESTART:
|
||||||
|
layout = ALGORITHM_LEFT_ASYMMETRIC;
|
||||||
|
break;
|
||||||
|
case DDF_RAID5_0_RESTART:
|
||||||
|
layout = ALGORITHM_RIGHT_ASYMMETRIC;
|
||||||
|
break;
|
||||||
|
case DDF_RAID5_N_CONTINUE:
|
||||||
|
layout = ALGORITHM_LEFT_SYMMETRIC;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return err_bad_ddf_layout(conf);
|
||||||
|
}
|
||||||
|
level = 5;
|
||||||
|
break;
|
||||||
|
case DDF_RAID6:
|
||||||
|
switch (conf->rlq) {
|
||||||
|
case DDF_RAID5_N_RESTART:
|
||||||
|
layout = ALGORITHM_ROTATING_N_RESTART;
|
||||||
|
break;
|
||||||
|
case DDF_RAID6_0_RESTART:
|
||||||
|
layout = ALGORITHM_ROTATING_ZERO_RESTART;
|
||||||
|
break;
|
||||||
|
case DDF_RAID5_N_CONTINUE:
|
||||||
|
layout = ALGORITHM_ROTATING_N_CONTINUE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return err_bad_ddf_layout(conf);
|
||||||
|
}
|
||||||
|
level = 6;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return err_bad_ddf_layout(conf);
|
||||||
|
};
|
||||||
|
|
||||||
|
good:
|
||||||
|
array->level = level;
|
||||||
|
array->layout = layout;
|
||||||
|
array->raid_disks = raiddisks;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int load_ddf_header(int fd, unsigned long long lba,
|
static int load_ddf_header(int fd, unsigned long long lba,
|
||||||
unsigned long long size,
|
unsigned long long size,
|
||||||
int type,
|
int type,
|
||||||
|
@ -1050,15 +1146,6 @@ static struct num_mapping ddf_level_num[] = {
|
||||||
{ MAXINT, MAXINT }
|
{ MAXINT, MAXINT }
|
||||||
};
|
};
|
||||||
|
|
||||||
static int map_num1(struct num_mapping *map, int num)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
for (i=0 ; map[i].num1 != MAXINT; i++)
|
|
||||||
if (map[i].num1 == num)
|
|
||||||
break;
|
|
||||||
return map[i].num2;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int all_ff(const char *guid)
|
static int all_ff(const char *guid)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -1638,8 +1725,6 @@ static void getinfo_super_ddf(struct supertype *st, struct mdinfo *info, char *m
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rlq_to_layout(int rlq, int prl, int raiddisks);
|
|
||||||
|
|
||||||
static void getinfo_super_ddf_bvd(struct supertype *st, struct mdinfo *info, char *map)
|
static void getinfo_super_ddf_bvd(struct supertype *st, struct mdinfo *info, char *map)
|
||||||
{
|
{
|
||||||
struct ddf_super *ddf = st->sb;
|
struct ddf_super *ddf = st->sb;
|
||||||
|
@ -1651,12 +1736,8 @@ static void getinfo_super_ddf_bvd(struct supertype *st, struct mdinfo *info, cha
|
||||||
__u32 *cptr;
|
__u32 *cptr;
|
||||||
|
|
||||||
memset(info, 0, sizeof(*info));
|
memset(info, 0, sizeof(*info));
|
||||||
/* FIXME this returns BVD info - what if we want SVD ?? */
|
if (layout_ddf2md(&vc->conf, &info->array) == -1)
|
||||||
|
return;
|
||||||
info->array.raid_disks = __be16_to_cpu(vc->conf.prim_elmnt_count);
|
|
||||||
info->array.level = map_num1(ddf_level_num, vc->conf.prl);
|
|
||||||
info->array.layout = rlq_to_layout(vc->conf.rlq, vc->conf.prl,
|
|
||||||
info->array.raid_disks);
|
|
||||||
info->array.md_minor = -1;
|
info->array.md_minor = -1;
|
||||||
cptr = (__u32 *)(vc->conf.guid + 16);
|
cptr = (__u32 *)(vc->conf.guid + 16);
|
||||||
info->array.ctime = DECADE + __be32_to_cpu(*cptr);
|
info->array.ctime = DECADE + __be32_to_cpu(*cptr);
|
||||||
|
@ -2140,48 +2221,6 @@ static int layout_to_rlq(int level, int layout, int raiddisks)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rlq_to_layout(int rlq, int prl, int raiddisks)
|
|
||||||
{
|
|
||||||
switch(prl) {
|
|
||||||
case DDF_RAID0:
|
|
||||||
return 0; /* hopefully rlq == DDF_RAID0_SIMPLE */
|
|
||||||
case DDF_RAID1:
|
|
||||||
return 0; /* hopefully rlq == SIMPLE or MULTI depending
|
|
||||||
on raiddisks*/
|
|
||||||
case DDF_RAID4:
|
|
||||||
switch(rlq) {
|
|
||||||
case DDF_RAID4_N:
|
|
||||||
return 0;
|
|
||||||
default:
|
|
||||||
/* not supported */
|
|
||||||
return -1; /* FIXME this isn't checked */
|
|
||||||
}
|
|
||||||
case DDF_RAID5:
|
|
||||||
switch(rlq) {
|
|
||||||
case DDF_RAID5_N_RESTART:
|
|
||||||
return ALGORITHM_LEFT_ASYMMETRIC;
|
|
||||||
case DDF_RAID5_0_RESTART:
|
|
||||||
return ALGORITHM_RIGHT_ASYMMETRIC;
|
|
||||||
case DDF_RAID5_N_CONTINUE:
|
|
||||||
return ALGORITHM_LEFT_SYMMETRIC;
|
|
||||||
default:
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
case DDF_RAID6:
|
|
||||||
switch(rlq) {
|
|
||||||
case DDF_RAID5_N_RESTART:
|
|
||||||
return ALGORITHM_ROTATING_N_RESTART;
|
|
||||||
case DDF_RAID6_0_RESTART:
|
|
||||||
return ALGORITHM_ROTATING_ZERO_RESTART;
|
|
||||||
case DDF_RAID5_N_CONTINUE:
|
|
||||||
return ALGORITHM_ROTATING_N_CONTINUE;
|
|
||||||
default:
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef MDASSEMBLE
|
#ifndef MDASSEMBLE
|
||||||
struct extent {
|
struct extent {
|
||||||
unsigned long long start, size;
|
unsigned long long start, size;
|
||||||
|
@ -3433,26 +3472,8 @@ static struct mdinfo *container_content_ddf(struct supertype *st, char *subarray
|
||||||
this->next = rest;
|
this->next = rest;
|
||||||
rest = this;
|
rest = this;
|
||||||
|
|
||||||
if (vc->conf.sec_elmnt_count == 1) {
|
if (layout_ddf2md(&vc->conf, &this->array))
|
||||||
this->array.level = map_num1(ddf_level_num,
|
continue;
|
||||||
vc->conf.prl);
|
|
||||||
this->array.raid_disks =
|
|
||||||
__be16_to_cpu(vc->conf.prim_elmnt_count);
|
|
||||||
this->array.layout =
|
|
||||||
rlq_to_layout(vc->conf.rlq, vc->conf.prl,
|
|
||||||
this->array.raid_disks);
|
|
||||||
} else {
|
|
||||||
/* The only supported layout is RAID 10.
|
|
||||||
* Compatibility has been checked in check_secondary()
|
|
||||||
* above.
|
|
||||||
*/
|
|
||||||
this->array.level = 10;
|
|
||||||
this->array.raid_disks =
|
|
||||||
__be16_to_cpu(vc->conf.prim_elmnt_count)
|
|
||||||
* vc->conf.sec_elmnt_count;
|
|
||||||
this->array.layout = 0x100 |
|
|
||||||
__be16_to_cpu(vc->conf.prim_elmnt_count);
|
|
||||||
}
|
|
||||||
this->array.md_minor = -1;
|
this->array.md_minor = -1;
|
||||||
this->array.major_version = -1;
|
this->array.major_version = -1;
|
||||||
this->array.minor_version = -2;
|
this->array.minor_version = -2;
|
||||||
|
|
Loading…
Reference in New Issue