Add 'container' level and ->validate_geometry method.

These will be used for ddf.
This commit is contained in:
Neil Brown 2008-05-15 16:47:41 +10:00
parent 2270232245
commit 17f25ca6fb
5 changed files with 112 additions and 22 deletions

View File

@ -182,6 +182,7 @@ int Create(struct supertype *st, char *mddev, int mdfd,
case 1:
case LEVEL_FAULTY:
case LEVEL_MULTIPATH:
case LEVEL_CONTAINER:
if (chunk) {
chunk = 0;
if (verbose > 0)
@ -193,13 +194,17 @@ int Create(struct supertype *st, char *mddev, int mdfd,
return 1;
}
if (st && ! st->ss->validate_geometry(st, level, layout, raiddisks,
chunk, size, NULL, NULL))
return 1;
/* now look at the subdevs */
info.array.active_disks = 0;
info.array.working_disks = 0;
dnum = 0;
for (dv=devlist; dv; dv=dv->next, dnum++) {
char *dname = dv->devname;
unsigned long long ldsize, freesize;
unsigned long long freesize;
int fd;
if (strcasecmp(dname, "missing")==0) {
if (first_missing > dnum)
@ -219,11 +224,6 @@ int Create(struct supertype *st, char *mddev, int mdfd,
fail=1;
continue;
}
if (!get_dev_size(fd, dname, &ldsize)) {
fail = 1;
close(fd);
continue;
}
if (st == NULL) {
struct createinfo *ci = conf_get_create_info();
if (ci)
@ -231,17 +231,22 @@ int Create(struct supertype *st, char *mddev, int mdfd,
}
if (st == NULL) {
/* Need to choose a default metadata, which is different
* depending on the sizes of devices
* depending on geometry of array.
*/
int i;
char *name = "default";
if (level >= 1 && ldsize > (0x7fffffffULL<<10))
name = "default/large";
for(i=0; !st && superlist[i]; i++)
for(i=0; !st && superlist[i]; i++) {
st = superlist[i]->match_metadata_desc(name);
if (st && !st->ss->validate_geometry
(st, level, layout, raiddisks,
chunk, size, dname, &freesize))
st = NULL;
}
if (!st) {
fprintf(stderr, Name ": internal error - no default metadata style\n");
fprintf(stderr, Name ": device %s not suitable "
"for any style of array\n",
dname);
exit(2);
}
if (st->ss->major != 0 ||
@ -250,14 +255,19 @@ int Create(struct supertype *st, char *mddev, int mdfd,
" %d.%d metadata\n",
st->ss->major,
st->minor_version);
}
freesize = st->ss->avail_size(st, ldsize >> 9);
if (freesize == 0) {
fprintf(stderr, Name ": %s is too small: %luK\n",
dname, (unsigned long)(ldsize>>10));
fail = 1;
close(fd);
continue;
} else {
if (!st->ss->validate_geometry(st, level, layout,
raiddisks,
chunk, size, dname,
&freesize)) {
fprintf(stderr,
Name ": %s is not suitable for "
"this array.\n",
dname);
fail = 1;
continue;
}
}
freesize /= 2; /* convert to K */
@ -268,7 +278,8 @@ int Create(struct supertype *st, char *mddev, int mdfd,
if (size && freesize < size) {
fprintf(stderr, Name ": %s is smaller that given size."
" %lluK < %lluK + superblock\n", dname, freesize, size);
" %lluK < %lluK + metadata\n",
dname, freesize, size);
fail = 1;
close(fd);
continue;
@ -581,7 +592,10 @@ int Create(struct supertype *st, char *mddev, int mdfd,
st->ss->free_super(st);
/* param is not actually used */
if (runstop == 1 || subdevs >= raiddisks) {
if (level == LEVEL_CONTAINER)
/* No need to start */
;
else if (runstop == 1 || subdevs >= raiddisks) {
mdu_param_t param;
if (ioctl(mdfd, RUN_ARRAY, &param)) {
fprintf(stderr, Name ": RUN_ARRAY failed: %s\n",

View File

@ -610,6 +610,7 @@ mapping_t pers[] = {
{ "raid10", 10},
{ "10", 10},
{ "faulty", LEVEL_FAULTY},
{ "container", LEVEL_CONTAINER},
{ NULL, 0}
};

View File

@ -358,6 +358,10 @@ extern struct superswitch {
void (*locate_bitmap)(struct supertype *st, int fd);
int (*write_bitmap)(struct supertype *st, int fd);
void (*free_super)(struct supertype *st);
int (*validate_geometry)(struct supertype *st, int level, int layout,
int raiddisks,
int chunk, unsigned long long size,
char *subdev, unsigned long long *freesize);
int major;
int swapuuid; /* true if uuid is bigending rather than hostendian */
} super0, super1, *superlist[];
@ -531,6 +535,9 @@ extern int open_mddev_devnum(char *devname, int devnum, char *name,
#define LEVEL_LINEAR (-1)
#define LEVEL_FAULTY (-5)
/* kernel module doesn't know about these */
#define LEVEL_CONTAINER (-100)
/* faulty stuff */

View File

@ -991,6 +991,43 @@ static void free_super0(struct supertype *st)
st->sb = NULL;
}
static int validate_geometry0(struct supertype *st, int level,
int layout, int raiddisks,
int chunk, unsigned long long size,
char *subdev, unsigned long long *freesize)
{
unsigned long long ldsize;
int fd;
if (level == LEVEL_CONTAINER)
return 0;
if (raiddisks > MD_SB_DISKS)
return 0;
if (size > (0x7fffffffULL<<10))
return 0;
if (!subdev)
return 1;
fd = open(subdev, O_RDONLY|O_EXCL, 0);
if (fd < 0) {
fprintf(stderr, Name ": Cannot open %s: %s\n",
subdev, strerror(errno));
return 0;
}
if (!get_dev_size(fd, subdev, &ldsize)) {
close(fd);
return 0;
}
close(fd);
if (ldsize < MD_RESERVED_SECTORS * 512)
return 0;
if (size > (0x7fffffffULL<<10))
return 0;
*freesize = MD_NEW_SIZE_SECTORS(ldsize >> 9);
return 1;
}
struct superswitch super0 = {
#ifndef MDASSEMBLE
.examine_super = examine_super0,
@ -1016,6 +1053,7 @@ struct superswitch super0 = {
.locate_bitmap = locate_bitmap0,
.write_bitmap = write_bitmap0,
.free_super = free_super0,
.validate_geometry = validate_geometry0,
.major = 0,
.swapuuid = 0,
};

View File

@ -1199,7 +1199,7 @@ static struct supertype *match_metadata_desc1(char *arg)
return st;
}
if (strcmp(arg, "1") == 0 ||
strcmp(arg, "default/large") == 0) {
strcmp(arg, "default") == 0) {
st->minor_version = -1;
return st;
}
@ -1416,6 +1416,35 @@ static void free_super1(struct supertype *st)
st->sb = NULL;
}
static int validate_geometry1(struct supertype *st, int level,
int layout, int raiddisks,
int chunk, unsigned long long size,
char *subdev, unsigned long long *freesize)
{
unsigned long long ldsize;
int fd;
if (level == LEVEL_CONTAINER)
return 0;
if (!subdev)
return 1;
fd = open(subdev, O_RDONLY|O_EXCL, 0);
if (fd < 0) {
fprintf(stderr, Name ": Cannot open %s: %s\n",
subdev, strerror(errno));
return 0;
}
if (!get_dev_size(fd, subdev, &ldsize)) {
close(fd);
return 0;
}
close(fd);
*freesize = avail_size1(st, ldsize >> 9);
return 1;
}
struct superswitch super1 = {
#ifndef MDASSEMBLE
.examine_super = examine_super1,
@ -1441,6 +1470,7 @@ struct superswitch super1 = {
.locate_bitmap = locate_bitmap1,
.write_bitmap = write_bitmap1,
.free_super = free_super1,
.validate_geometry = validate_geometry1,
.major = 1,
#if __BYTE_ORDER == BIG_ENDIAN
.swapuuid = 0,