]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
super_by_fd: return subarray info explicitly.
authorNeilBrown <neilb@suse.de>
Mon, 22 Nov 2010 08:35:25 +0000 (19:35 +1100)
committerNeilBrown <neilb@suse.de>
Mon, 22 Nov 2010 08:35:25 +0000 (19:35 +1100)
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>
Detail.c
Grow.c
Manage.c
mdadm.h
util.c

index eb51a3ecee279a328c5c0fb8d42ab00601ece2e9..0cc1bcf6637bdd8a15ac23c6dfbce5cad480dc05 100644 (file)
--- 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 800dbb55e29138ac8fe4f3e80d220ae6a1ea38aa..a33a2802ea3b716fd229f020d98537762e456f5a 100644 (file)
--- 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.
index c3322f4d322be56113cdfc588e51494d1e9ee26b..1ce4aa63521c7935cab8182c6d023110b12d49bd 100644 (file)
--- 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 9ca3223a79e5802c044d939372cecdad0ff93db2..deff94827dee2b456424702a69d9123d2f4c3422 100644 (file)
--- 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 b965c8d7883ddae9d8f7ec66a978fcf7374f59ed..66c7f0b9d6ddfa5f26ccc3bc77d13a481c72fbac 100644 (file)
--- 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) */