From 4725bc31fb3d7fc207671e851617852dc8034cd5 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Mon, 22 Nov 2010 19:35:25 +1100 Subject: [PATCH] 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 --- Detail.c | 6 +++++- Grow.c | 53 ++++++++++++++++++++++++++++++++++++++++++----------- Manage.c | 7 ++++--- mdadm.h | 2 +- util.c | 13 +++++-------- 5 files changed, 57 insertions(+), 24 deletions(-) diff --git a/Detail.c b/Detail.c index eb51a3ec..0cc1bcf6 100644 --- a/Detail.c +++ b/Detail.c @@ -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; } diff --git a/Grow.c b/Grow.c index 800dbb55..a33a2802 100644 --- a/Grow.c +++ b/Grow.c @@ -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 (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 (info.array.level != -1) { - fprintf(stderr, Name ": can only add devices to linear arrays\n"); - 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. diff --git a/Manage.c b/Manage.c index c3322f4d..1ce4aa63 100644 --- a/Manage.c +++ b/Manage.c @@ -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"); diff --git a/mdadm.h b/mdadm.h index 9ca3223a..deff9482 100644 --- a/mdadm.h +++ b/mdadm.h @@ -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) { diff --git a/util.c b/util.c index b965c8d7..66c7f0b9 100644 --- a/util.c +++ b/util.c @@ -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) */ -- 2.39.2