Add subarray field to supertype.

When loading the metadata for a subarray (super_by_fd), we set
->subarray to be the name read from md/metadata_version so that
getinfo_super can return info about the correct array.

With this we can differentiate between a container and
an array within the container by looking at ->subarray[0].
This commit is contained in:
Neil Brown 2008-07-12 20:27:38 +10:00
parent 6adfd3affd
commit f7e7067b47
8 changed files with 59 additions and 14 deletions

View File

@ -550,7 +550,7 @@ int Create(struct supertype *st, char *mddev, int mdfd,
char ver[100];
strcat(strcpy(ver, "external:"),
info.text_version);
if (st->ss->external == 2) {
if (st->ss->external && st->subarray[0]) {
/* member */
/* When creating a member, we need to be careful
@ -651,7 +651,7 @@ int Create(struct supertype *st, char *mddev, int mdfd,
strcasecmp(dv->devname, "missing")==0)
continue;
if (st->ss->external == 2)
if (st->ss->external && st->subarray[0])
fd = open(dv->devname, O_RDWR, 0);
else
fd = open(dv->devname, O_RDWR|O_EXCL,0);
@ -732,7 +732,7 @@ int Create(struct supertype *st, char *mddev, int mdfd,
}
if (verbose >= 0)
fprintf(stderr, Name ": array %s started.\n", mddev);
if (st->ss->external == 2) {
if (st->ss->external && st->subarray[0]) {
if (need_mdmon) {
int dn = st->container_dev;
int i;

View File

@ -354,7 +354,7 @@ int Manage_subdevs(char *devname, int fd,
return 1;
case 'a':
/* add the device */
if (tst == &supertype_container_member) {
if (tst->subarray[0]) {
fprintf(stderr, Name ": Cannot add disks to a"
" \'member\' array, perform this"
" operation on the parent container\n");
@ -551,7 +551,7 @@ int Manage_subdevs(char *devname, int fd,
case 'r':
/* hot remove */
if (tst == &supertype_container_member) {
if (tst->subarray[0]) {
fprintf(stderr, Name ": Cannot remove disks from a"
" \'member\' array, perform this"
" operation on the parent container\n");

View File

@ -563,6 +563,7 @@ struct supertype {
int minor_version;
int max_devs;
int container_dev; /* devnum of container */
char subarray[32]; /* name of array inside container */
void *sb;
void *info;
@ -582,7 +583,6 @@ struct supertype {
};
extern struct supertype supertype_container_member;
extern struct supertype *super_by_fd(int fd);
extern struct supertype *guess_super(int fd);
extern struct supertype *dup_super(struct supertype *st);

View File

@ -733,6 +733,8 @@ static int load_super_ddf(struct supertype *st, int fd,
if (load_super_ddf_all(st, fd, &st->sb, devname, 1) == 0)
return 0;
#endif
if (st->subarray[0])
return 1; /* FIXME Is this correct */
if (get_dev_size(fd, devname, &dsize) == 0)
return 1;
@ -1826,6 +1828,7 @@ static int init_super_ddf_bvd(struct supertype *st,
vcl = malloc(offsetof(struct vcl, conf) + ddf->conf_rec_len * 512);
vcl->lba_offset = (__u64*) &vcl->conf.phys_refnum[ddf->mppe];
vcl->vcnum = venum;
sprintf(st->subarray, "%d", venum);
vcl->block_sizes = NULL; /* FIXME not for CONCAT */
vc = &vcl->conf;
@ -2449,6 +2452,15 @@ static int load_super_ddf_all(struct supertype *st, int fd,
seq = load_ddf_local(dfd, super, NULL, keep_fd);
if (!keep_fd) close(dfd);
}
if (st->subarray[0]) {
struct vcl *v;
for (v = super->conflist; v; v = v->next)
if (v->vcnum == atoi(st->subarray))
super->newconf = v;
if (!super->newconf)
return 1;
}
*sbp = super;
if (st->ss == NULL) {
st->ss = &super_ddf_container;

View File

@ -980,6 +980,10 @@ static int load_super_imsm_all(struct supertype *st, int fd, void **sbp,
close(dfd);
}
if (st->subarray[0]) {
/* FIXME */
}
*sbp = super;
if (st->ss == NULL) {
st->ss = &super_imsm_container;
@ -1001,6 +1005,8 @@ static int load_super_imsm(struct supertype *st, int fd, char *devname)
if (load_super_imsm_all(st, fd, &st->sb, devname, 1) == 0)
return 0;
#endif
if (st->subarray[0])
return 1; /* FIXME */
super = alloc_super(0);
if (!super) {

View File

@ -783,6 +783,9 @@ static int load_super0(struct supertype *st, int fd, char *devname)
free_super0(st);
if (st->subarray[0])
return 1;
if (!get_dev_size(fd, devname, &dsize))
return 1;

View File

@ -1065,6 +1065,9 @@ static int load_super1(struct supertype *st, int fd, char *devname)
free_super1(st);
if (st->subarray[0])
return 1;
if (st->ss == NULL || st->minor_version == -1) {
int bestvers = -1;
struct supertype tst;

37
util.c
View File

@ -788,8 +788,6 @@ struct superswitch *superlist[] = { &super0, &super1, &super_ddf, &super_imsm, N
#if !defined(MDASSEMBLE) || defined(MDASSEMBLE) && defined(MDASSEMBLE_AUTO)
struct supertype supertype_container_member;
struct supertype *super_by_fd(int fd)
{
mdu_array_info_t array;
@ -800,6 +798,7 @@ struct supertype *super_by_fd(int fd)
char *verstr;
char version[20];
int i;
char *subarray = NULL;
sra = sysfs_read(fd, 0, GET_VERSION);
@ -819,16 +818,37 @@ struct supertype *super_by_fd(int fd)
sprintf(version, "%d.%d", vers, minor);
verstr = version;
}
if (minor == -2 && verstr[0] == '/')
st = &supertype_container_member;
else
for (i = 0; st == NULL && superlist[i] ; i++)
st = superlist[i]->match_metadata_desc(verstr);
if (minor == -2 && verstr[0] == '/') {
char *dev = verstr+1;
subarray = strchr(dev, '/');
int devnum;
if (subarray)
*subarray++ = '\0';
if (strncmp(dev, "md_d", 4) == 0)
devnum = -1-atoi(dev+4);
else
devnum = atoi(dev+2);
subarray = strdup(subarray);
if (sra)
sysfs_free(sra);
sra = sysfs_read(-1, devnum, GET_VERSION);
verstr = sra->text_version ? : "-no-metadata-";
}
for (i = 0; st == NULL && superlist[i] ; i++)
st = superlist[i]->match_metadata_desc(verstr);
if (sra)
sysfs_free(sra);
if (st)
if (st) {
st->sb = NULL;
if (subarray) {
strncpy(st->subarray, subarray, 32);
st->subarray[31] = 0;
free(subarray);
} else
st->subarray[0] = 0;
}
return st;
}
#endif /* !defined(MDASSEMBLE) || defined(MDASSEMBLE) && defined(MDASSEMBLE_AUTO) */
@ -845,6 +865,7 @@ struct supertype *dup_super(struct supertype *orig)
st->ss = orig->ss;
st->max_devs = orig->max_devs;
st->minor_version = orig->minor_version;
strcpy(st->subarray, orig->subarray);
st->sb = NULL;
st->info = NULL;
return st;