super_by_fd: return subarray info explicitly.

Rather than hiding this in the 'st', return it explicitly.

In the one case we still need it, copy it into st where needed.
This will disappear in a future patch.

Signed-off-by: NeilBrown <neilb@suse.de>
This commit is contained in:
NeilBrown 2010-11-22 19:35:25 +11:00
parent feab51f8f7
commit 4725bc31fb
5 changed files with 59 additions and 26 deletions

View File

@ -49,6 +49,7 @@ int Detail(char *dev, int brief, int export, int test, char *homehost)
int is_rebuilding = 0;
int failed = 0;
struct supertype *st;
char *subarray = NULL;
int max_disks = MD_SB_DISKS; /* just a default */
struct mdinfo info;
struct mdinfo *sra;
@ -88,7 +89,7 @@ int Detail(char *dev, int brief, int export, int test, char *homehost)
return rv;
}
sra = sysfs_read(fd, 0, GET_VERSION);
st = super_by_fd(fd);
st = super_by_fd(fd, &subarray);
if (fstat(fd, &stb) != 0 && !S_ISBLK(stb.st_mode))
stb.st_rdev = 0;
@ -139,6 +140,8 @@ int Detail(char *dev, int brief, int export, int test, char *homehost)
if (st->sb)
st->ss->free_super(st);
if (subarray)
strcpy(st->subarray, subarray);
err = st->ss->load_super(st, fd2, NULL);
close(fd2);
if (err)
@ -581,6 +584,7 @@ This is pretty boring
free(disks);
out:
close(fd);
free(subarray);
return rv;
}

57
Grow.c
View File

@ -51,33 +51,41 @@ int Grow_Add_device(char *devname, int fd, char *newdev)
int nfd, fd2;
int d, nd;
struct supertype *st = NULL;
char *subarray = NULL;
if (ioctl(fd, GET_ARRAY_INFO, &info.array) < 0) {
fprintf(stderr, Name ": cannot get array info for %s\n", devname);
return 1;
}
st = super_by_fd(fd);
if (!st) {
fprintf(stderr, Name ": cannot handle arrays with superblock version %d\n", info.array.major_version);
return 1;
}
if (info.array.level != -1) {
fprintf(stderr, Name ": can only add devices to linear arrays\n");
return 1;
}
st = super_by_fd(fd, &subarray);
if (!st) {
fprintf(stderr, Name ": cannot handle arrays with superblock version %d\n", info.array.major_version);
return 1;
}
if (subarray) {
fprintf(stderr, Name ": Cannot grow linear sub-arrays yet\n");
free(subarray);
free(st);
}
nfd = open(newdev, O_RDWR|O_EXCL|O_DIRECT);
if (nfd < 0) {
fprintf(stderr, Name ": cannot open %s\n", newdev);
free(st);
return 1;
}
fstat(nfd, &stb);
if ((stb.st_mode & S_IFMT) != S_IFBLK) {
fprintf(stderr, Name ": %s is not a block device!\n", newdev);
close(nfd);
free(st);
return 1;
}
/* now check out all the devices and make sure we can read the superblock */
@ -85,28 +93,37 @@ int Grow_Add_device(char *devname, int fd, char *newdev)
mdu_disk_info_t disk;
char *dv;
st->ss->free_super(st);
disk.number = d;
if (ioctl(fd, GET_DISK_INFO, &disk) < 0) {
fprintf(stderr, Name ": cannot get device detail for device %d\n",
d);
close(nfd);
free(st);
return 1;
}
dv = map_dev(disk.major, disk.minor, 1);
if (!dv) {
fprintf(stderr, Name ": cannot find device file for device %d\n",
d);
close(nfd);
free(st);
return 1;
}
fd2 = dev_open(dv, O_RDWR);
if (!fd2) {
fprintf(stderr, Name ": cannot open device file %s\n", dv);
close(nfd);
free(st);
return 1;
}
st->ss->free_super(st);
if (st->ss->load_super(st, fd2, NULL)) {
fprintf(stderr, Name ": cannot find super block on %s\n", dv);
close(nfd);
close(fd2);
free(st);
return 1;
}
close(fd2);
@ -204,6 +221,7 @@ int Grow_addbitmap(char *devname, int fd, char *file, int chunk, int delay, int
mdu_bitmap_file_t bmf;
mdu_array_info_t array;
struct supertype *st;
char *subarray = NULL;
int major = BITMAP_MAJOR_HI;
int vers = md_get_version(fd);
unsigned long long bitmapsize, array_size;
@ -253,6 +271,11 @@ int Grow_addbitmap(char *devname, int fd, char *file, int chunk, int delay, int
devname);
return 1;
}
if (strcmp(file, "none") == 0) {
fprintf(stderr, Name ": no bitmap found on %s\n", devname);
return 1;
}
if (array.level <= 0) {
fprintf(stderr, Name ": Bitmaps not meaningful with level %s\n",
map_num(pers, array.level)?:"of this array");
@ -277,16 +300,19 @@ int Grow_addbitmap(char *devname, int fd, char *file, int chunk, int delay, int
bitmapsize = bitmapsize * array.raid_disks / ncopies;
}
st = super_by_fd(fd);
st = super_by_fd(fd, &subarray);
if (!st) {
fprintf(stderr, Name ": Cannot understand version %d.%d\n",
array.major_version, array.minor_version);
return 1;
}
if (strcmp(file, "none") == 0) {
fprintf(stderr, Name ": no bitmap found on %s\n", devname);
if (subarray) {
fprintf(stderr, Name ": Cannot add bitmaps to sub-arrays yet\n");
free(subarray);
free(st);
return 1;
} else if (strcmp(file, "internal") == 0) {
}
if (strcmp(file, "internal") == 0) {
int d;
if (st->ss->add_internal_bitmap == NULL) {
fprintf(stderr, Name ": Internal bitmaps not supported "
@ -501,6 +527,7 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
char *c;
int rv = 0;
struct supertype *st;
char *subarray = NULL;
int nchunk, ochunk;
int nlayout, olayout;
@ -829,7 +856,11 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
* layout/chunksize/raid_disks can be changed
* though the kernel may not support it all.
*/
st = super_by_fd(fd);
st = super_by_fd(fd, &subarray);
if (subarray) {
fprintf(stderr, Name ": Cannot reshape subarrays yet\n");
break;
}
/*
* There are three possibilities.

View File

@ -349,6 +349,7 @@ int Manage_subdevs(char *devname, int fd,
int j, jnext = 0;
int tfd = -1;
struct supertype *st, *tst;
char *subarray = NULL;
int duuid[4];
int ouuid[4];
int lfd = -1;
@ -369,7 +370,7 @@ int Manage_subdevs(char *devname, int fd,
if (array_size <= 0)
array_size = array.size * 2;
tst = super_by_fd(fd);
tst = super_by_fd(fd, &subarray);
if (!tst) {
fprintf(stderr, Name ": unsupport array - version %d.%d\n",
array.major_version, array.minor_version);
@ -548,7 +549,7 @@ int Manage_subdevs(char *devname, int fd,
return 1;
case 'a':
/* add the device */
if (tst->subarray[0]) {
if (subarray) {
fprintf(stderr, Name ": Cannot add disks to a"
" \'member\' array, perform this"
" operation on the parent container\n");
@ -879,7 +880,7 @@ int Manage_subdevs(char *devname, int fd,
case 'r':
/* hot remove */
if (tst->subarray[0]) {
if (subarray) {
fprintf(stderr, Name ": Cannot remove disks from a"
" \'member\' array, perform this"
" operation on the parent container\n");

View File

@ -732,7 +732,7 @@ struct supertype {
};
extern struct supertype *super_by_fd(int fd);
extern struct supertype *super_by_fd(int fd, char **subarray);
enum guess_types { guess_any, guess_array, guess_partitions };
extern struct supertype *guess_super_type(int fd, enum guess_types guess_type);
static inline struct supertype *guess_super(int fd) {

13
util.c
View File

@ -1032,7 +1032,7 @@ struct superswitch *superlist[] =
#if !defined(MDASSEMBLE) || defined(MDASSEMBLE) && defined(MDASSEMBLE_AUTO)
struct supertype *super_by_fd(int fd)
struct supertype *super_by_fd(int fd, char **subarrayp)
{
mdu_array_info_t array;
int vers;
@ -1086,13 +1086,10 @@ struct supertype *super_by_fd(int fd)
sysfs_free(sra);
if (st) {
st->sb = NULL;
if (subarray) {
strncpy(st->subarray, subarray, 32);
st->subarray[31] = 0;
free(subarray);
} else
st->subarray[0] = 0;
}
st->subarray[0] = 0;
*subarrayp = subarray;
} else
free(subarray);
return st;
}
#endif /* !defined(MDASSEMBLE) || defined(MDASSEMBLE) && defined(MDASSEMBLE_AUTO) */