]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - Manage.c
fix load_super/free_super mismatch in util.c
[thirdparty/mdadm.git] / Manage.c
index 09d397b7c9fc98535aedbbb9ed8fca28bc116954..1fb8468981886342d76f9786a8ff90a203f27c47 100644 (file)
--- a/Manage.c
+++ b/Manage.c
@@ -188,6 +188,7 @@ int Manage_subdevs(char *devname, int fd,
         */
        mdu_array_info_t array;
        mdu_disk_info_t disc;
+       unsigned long long array_size;
        mddev_dev_t dv, next = NULL;
        struct stat stb;
        int j, jnext = 0;
@@ -202,8 +203,15 @@ int Manage_subdevs(char *devname, int fd,
                return 1;
        }
 
-       tst = super_by_version(array.major_version,
-                              array.minor_version);
+       /* array.size is only 32 bit and may be truncated.
+        * So read from sysfs if possible, and record number of sectors
+        */
+
+       array_size = get_component_size(fd);
+       if (array_size <= 0)
+               array_size = array.size * 2;
+
+       tst = super_by_fd(fd);
        if (!tst) {
                fprintf(stderr, Name ": unsupport array - version %d.%d\n",
                        array.major_version, array.minor_version);
@@ -308,8 +316,7 @@ int Manage_subdevs(char *devname, int fd,
                        }
                        remove_partitions(tfd);
 
-                       st = super_by_version(array.major_version,
-                                             array.minor_version);
+                       st = dup_super(tst);
 
                        if (array.not_persistent==0)
                                st->ss->load_super(st, tfd, NULL);
@@ -339,7 +346,7 @@ int Manage_subdevs(char *devname, int fd,
 
                                /* Make sure device is large enough */
                                if (tst->ss->avail_size(tst, ldsize/512) <
-                                   array.size) {
+                                   array_size) {
                                        fprintf(stderr, Name ": %s not large enough to join array\n",
                                                dv->devname);
                                        return 1;
@@ -414,7 +421,7 @@ int Manage_subdevs(char *devname, int fd,
                                /* non-persistent. Must ensure that new drive
                                 * is at least array.size big.
                                 */
-                               if (ldsize/512 < array.size) {
+                               if (ldsize/512 < array_size) {
                                        fprintf(stderr, Name ": %s not large enough to join array\n",
                                                dv->devname);
                                        return 1;