DDF: container_content_ddf: check for secondary RAID

Check for supportable secondary RAID configurations.
There is currently only one: RAID 10, if the stripe
sizes and Basic volume sizes are all equal.

With this patch, mdadm will not try to start unsupported
secondary RAID level configurations any more.

Signed-off-by: Martin Wilck <mwilck@arcor.de>
Signed-off-by: NeilBrown <neilb@suse.de>
This commit is contained in:
mwilck@arcor.de 2013-03-01 23:28:28 +01:00 committed by NeilBrown
parent 8a38db8674
commit a5c7adb310
1 changed files with 73 additions and 0 deletions

View File

@ -3050,6 +3050,74 @@ static int load_container_ddf(struct supertype *st, int fd,
#endif /* MDASSEMBLE */
static int check_secondary(const struct vcl *vc)
{
const struct vd_config *conf = &vc->conf;
int i;
/* The only DDF secondary RAID level md can support is
* RAID 10, if the stripe sizes and Basic volume sizes
* are all equal.
* Other configurations could in theory be supported by exposing
* the BVDs to user space and using device mapper for the secondary
* mapping. So far we don't support that.
*/
__u64 sec_elements[4] = {0, 0, 0, 0};
#define __set_sec_seen(n) (sec_elements[(n)>>6] |= (1<<((n)&63)))
#define __was_sec_seen(n) ((sec_elements[(n)>>6] & (1<<((n)&63))) != 0)
if (vc->other_bvds == NULL) {
pr_err("No BVDs for secondary RAID found\n");
return -1;
}
if (conf->prl != DDF_RAID1) {
pr_err("Secondary RAID level only supported for mirrored BVD\n");
return -1;
}
if (conf->srl != DDF_2STRIPED && conf->srl != DDF_2SPANNED) {
pr_err("Secondary RAID level %d is unsupported\n",
conf->srl);
return -1;
}
__set_sec_seen(conf->sec_elmnt_seq);
for (i = 0; i < conf->sec_elmnt_count-1; i++) {
const struct vd_config *bvd = vc->other_bvds[i];
if (bvd == NULL) {
pr_err("BVD %d is missing", i+1);
return -1;
}
if (bvd->srl != conf->srl) {
pr_err("Inconsistent secondary RAID level across BVDs\n");
return -1;
}
if (bvd->prl != conf->prl) {
pr_err("Different RAID levels for BVDs are unsupported\n");
return -1;
}
if (bvd->prim_elmnt_count != conf->prim_elmnt_count) {
pr_err("All BVDs must have the same number of primary elements\n");
return -1;
}
if (bvd->chunk_shift != conf->chunk_shift) {
pr_err("Different strip sizes for BVDs are unsupported\n");
return -1;
}
if (bvd->array_blocks != conf->array_blocks) {
pr_err("Different BVD sizes are unsupported\n");
return -1;
}
__set_sec_seen(bvd->sec_elmnt_seq);
}
for (i = 0; i < conf->sec_elmnt_count; i++) {
if (!__was_sec_seen(i)) {
pr_err("BVD %d is missing\n", i);
return -1;
}
}
return 0;
}
#define NO_SUCH_REFNUM (0xFFFFFFFF)
static unsigned int get_pd_index_from_refnum(const struct vcl *vc,
__u32 refnum, unsigned int nmax)
@ -3089,6 +3157,11 @@ static struct mdinfo *container_content_ddf(struct supertype *st, char *subarray
*ep != '\0'))
continue;
if (vc->conf.sec_elmnt_count > 1) {
if (check_secondary(vc) != 0)
continue;
}
this = xcalloc(1, sizeof(*this));
this->next = rest;
rest = this;