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 is_rebuilding = 0;
int failed = 0; int failed = 0;
struct supertype *st; struct supertype *st;
char *subarray = NULL;
int max_disks = MD_SB_DISKS; /* just a default */ int max_disks = MD_SB_DISKS; /* just a default */
struct mdinfo info; struct mdinfo info;
struct mdinfo *sra; struct mdinfo *sra;
@ -88,7 +89,7 @@ int Detail(char *dev, int brief, int export, int test, char *homehost)
return rv; return rv;
} }
sra = sysfs_read(fd, 0, GET_VERSION); 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)) if (fstat(fd, &stb) != 0 && !S_ISBLK(stb.st_mode))
stb.st_rdev = 0; stb.st_rdev = 0;
@ -139,6 +140,8 @@ int Detail(char *dev, int brief, int export, int test, char *homehost)
if (st->sb) if (st->sb)
st->ss->free_super(st); st->ss->free_super(st);
if (subarray)
strcpy(st->subarray, subarray);
err = st->ss->load_super(st, fd2, NULL); err = st->ss->load_super(st, fd2, NULL);
close(fd2); close(fd2);
if (err) if (err)
@ -581,6 +584,7 @@ This is pretty boring
free(disks); free(disks);
out: out:
close(fd); close(fd);
free(subarray);
return rv; 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 nfd, fd2;
int d, nd; int d, nd;
struct supertype *st = NULL; struct supertype *st = NULL;
char *subarray = NULL;
if (ioctl(fd, GET_ARRAY_INFO, &info.array) < 0) { if (ioctl(fd, GET_ARRAY_INFO, &info.array) < 0) {
fprintf(stderr, Name ": cannot get array info for %s\n", devname); fprintf(stderr, Name ": cannot get array info for %s\n", devname);
return 1; 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) { if (info.array.level != -1) {
fprintf(stderr, Name ": can only add devices to linear arrays\n"); fprintf(stderr, Name ": can only add devices to linear arrays\n");
return 1; 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); nfd = open(newdev, O_RDWR|O_EXCL|O_DIRECT);
if (nfd < 0) { if (nfd < 0) {
fprintf(stderr, Name ": cannot open %s\n", newdev); fprintf(stderr, Name ": cannot open %s\n", newdev);
free(st);
return 1; return 1;
} }
fstat(nfd, &stb); fstat(nfd, &stb);
if ((stb.st_mode & S_IFMT) != S_IFBLK) { if ((stb.st_mode & S_IFMT) != S_IFBLK) {
fprintf(stderr, Name ": %s is not a block device!\n", newdev); fprintf(stderr, Name ": %s is not a block device!\n", newdev);
close(nfd); close(nfd);
free(st);
return 1; return 1;
} }
/* now check out all the devices and make sure we can read the superblock */ /* 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; mdu_disk_info_t disk;
char *dv; char *dv;
st->ss->free_super(st);
disk.number = d; disk.number = d;
if (ioctl(fd, GET_DISK_INFO, &disk) < 0) { if (ioctl(fd, GET_DISK_INFO, &disk) < 0) {
fprintf(stderr, Name ": cannot get device detail for device %d\n", fprintf(stderr, Name ": cannot get device detail for device %d\n",
d); d);
close(nfd);
free(st);
return 1; return 1;
} }
dv = map_dev(disk.major, disk.minor, 1); dv = map_dev(disk.major, disk.minor, 1);
if (!dv) { if (!dv) {
fprintf(stderr, Name ": cannot find device file for device %d\n", fprintf(stderr, Name ": cannot find device file for device %d\n",
d); d);
close(nfd);
free(st);
return 1; return 1;
} }
fd2 = dev_open(dv, O_RDWR); fd2 = dev_open(dv, O_RDWR);
if (!fd2) { if (!fd2) {
fprintf(stderr, Name ": cannot open device file %s\n", dv); fprintf(stderr, Name ": cannot open device file %s\n", dv);
close(nfd);
free(st);
return 1; return 1;
} }
st->ss->free_super(st);
if (st->ss->load_super(st, fd2, NULL)) { if (st->ss->load_super(st, fd2, NULL)) {
fprintf(stderr, Name ": cannot find super block on %s\n", dv); fprintf(stderr, Name ": cannot find super block on %s\n", dv);
close(nfd);
close(fd2); close(fd2);
free(st);
return 1; return 1;
} }
close(fd2); 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_bitmap_file_t bmf;
mdu_array_info_t array; mdu_array_info_t array;
struct supertype *st; struct supertype *st;
char *subarray = NULL;
int major = BITMAP_MAJOR_HI; int major = BITMAP_MAJOR_HI;
int vers = md_get_version(fd); int vers = md_get_version(fd);
unsigned long long bitmapsize, array_size; 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); devname);
return 1; return 1;
} }
if (strcmp(file, "none") == 0) {
fprintf(stderr, Name ": no bitmap found on %s\n", devname);
return 1;
}
if (array.level <= 0) { if (array.level <= 0) {
fprintf(stderr, Name ": Bitmaps not meaningful with level %s\n", fprintf(stderr, Name ": Bitmaps not meaningful with level %s\n",
map_num(pers, array.level)?:"of this array"); 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; bitmapsize = bitmapsize * array.raid_disks / ncopies;
} }
st = super_by_fd(fd); st = super_by_fd(fd, &subarray);
if (!st) { if (!st) {
fprintf(stderr, Name ": Cannot understand version %d.%d\n", fprintf(stderr, Name ": Cannot understand version %d.%d\n",
array.major_version, array.minor_version); array.major_version, array.minor_version);
return 1; return 1;
} }
if (strcmp(file, "none") == 0) { if (subarray) {
fprintf(stderr, Name ": no bitmap found on %s\n", devname); fprintf(stderr, Name ": Cannot add bitmaps to sub-arrays yet\n");
free(subarray);
free(st);
return 1; return 1;
} else if (strcmp(file, "internal") == 0) { }
if (strcmp(file, "internal") == 0) {
int d; int d;
if (st->ss->add_internal_bitmap == NULL) { if (st->ss->add_internal_bitmap == NULL) {
fprintf(stderr, Name ": Internal bitmaps not supported " 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; char *c;
int rv = 0; int rv = 0;
struct supertype *st; struct supertype *st;
char *subarray = NULL;
int nchunk, ochunk; int nchunk, ochunk;
int nlayout, olayout; 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 * layout/chunksize/raid_disks can be changed
* though the kernel may not support it all. * 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. * There are three possibilities.

View File

@ -349,6 +349,7 @@ int Manage_subdevs(char *devname, int fd,
int j, jnext = 0; int j, jnext = 0;
int tfd = -1; int tfd = -1;
struct supertype *st, *tst; struct supertype *st, *tst;
char *subarray = NULL;
int duuid[4]; int duuid[4];
int ouuid[4]; int ouuid[4];
int lfd = -1; int lfd = -1;
@ -369,7 +370,7 @@ int Manage_subdevs(char *devname, int fd,
if (array_size <= 0) if (array_size <= 0)
array_size = array.size * 2; array_size = array.size * 2;
tst = super_by_fd(fd); tst = super_by_fd(fd, &subarray);
if (!tst) { if (!tst) {
fprintf(stderr, Name ": unsupport array - version %d.%d\n", fprintf(stderr, Name ": unsupport array - version %d.%d\n",
array.major_version, array.minor_version); array.major_version, array.minor_version);
@ -548,7 +549,7 @@ int Manage_subdevs(char *devname, int fd,
return 1; return 1;
case 'a': case 'a':
/* add the device */ /* add the device */
if (tst->subarray[0]) { if (subarray) {
fprintf(stderr, Name ": Cannot add disks to a" fprintf(stderr, Name ": Cannot add disks to a"
" \'member\' array, perform this" " \'member\' array, perform this"
" operation on the parent container\n"); " operation on the parent container\n");
@ -879,7 +880,7 @@ int Manage_subdevs(char *devname, int fd,
case 'r': case 'r':
/* hot remove */ /* hot remove */
if (tst->subarray[0]) { if (subarray) {
fprintf(stderr, Name ": Cannot remove disks from a" fprintf(stderr, Name ": Cannot remove disks from a"
" \'member\' array, perform this" " \'member\' array, perform this"
" operation on the parent container\n"); " 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 }; enum guess_types { guess_any, guess_array, guess_partitions };
extern struct supertype *guess_super_type(int fd, enum guess_types guess_type); extern struct supertype *guess_super_type(int fd, enum guess_types guess_type);
static inline struct supertype *guess_super(int fd) { 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) #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; mdu_array_info_t array;
int vers; int vers;
@ -1086,13 +1086,10 @@ struct supertype *super_by_fd(int fd)
sysfs_free(sra); sysfs_free(sra);
if (st) { if (st) {
st->sb = NULL; st->sb = NULL;
if (subarray) { st->subarray[0] = 0;
strncpy(st->subarray, subarray, 32); *subarrayp = subarray;
st->subarray[31] = 0; } else
free(subarray); free(subarray);
} else
st->subarray[0] = 0;
}
return st; return st;
} }
#endif /* !defined(MDASSEMBLE) || defined(MDASSEMBLE) && defined(MDASSEMBLE_AUTO) */ #endif /* !defined(MDASSEMBLE) || defined(MDASSEMBLE) && defined(MDASSEMBLE_AUTO) */