]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - Grow.c
Switch open_subarray to use the new load_container
[thirdparty/mdadm.git] / Grow.c
diff --git a/Grow.c b/Grow.c
index 78c3d4facba654aa3a676fda5f035a851ed496fb..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.
@@ -979,7 +1010,7 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
                        rv = 1;
                        break;
                }
-               nrdisks = array.nr_disks + sra->array.spare_disks;
+               nrdisks = array.raid_disks + sra->array.spare_disks;
                /* Now we need to open all these devices so we can read/write.
                 */
                fdlist = malloc((1+nrdisks) * sizeof(int));
@@ -1350,17 +1381,21 @@ int grow_backup(struct mdinfo *sra,
                        bsb.sb_csum2 = bsb_csum((char*)&bsb,
                                                ((char*)&bsb.sb_csum2)-((char*)&bsb));
 
+               rv = -1;
                if ((unsigned long long)lseek64(destfd[i], destoffsets[i] - 4096, 0)
                    != destoffsets[i] - 4096)
-                       rv = 1;
-               rv = rv ?: write(destfd[i], &bsb, 512);
+                       break;
+               if (write(destfd[i], &bsb, 512) != 512)
+                       break;
                if (destoffsets[i] > 4096) {
                        if ((unsigned long long)lseek64(destfd[i], destoffsets[i]+stripes*chunk*odata, 0) !=
                            destoffsets[i]+stripes*chunk*odata)
-                               rv = 1;
-                       rv = rv ?: write(destfd[i], &bsb, 512);
+                               break;
+                       if (write(destfd[i], &bsb, 512) != 512)
+                               break;
                }
                fsync(destfd[i]);
+               rv = 0;
        }
 
        return rv;
@@ -1431,8 +1466,10 @@ int wait_backup(struct mdinfo *sra,
                                                ((char*)&bsb.sb_csum2)-((char*)&bsb));
                if ((unsigned long long)lseek64(destfd[i], destoffsets[i]-4096, 0) !=
                    destoffsets[i]-4096)
-                       rv = 1;
-               rv = rv ?: write(destfd[i], &bsb, 512);
+                       rv = -1;
+               if (rv == 0 && 
+                   write(destfd[i], &bsb, 512) != 512)
+                       rv = -1;
                fsync(destfd[i]);
        }
        return rv;
@@ -1441,8 +1478,8 @@ int wait_backup(struct mdinfo *sra,
 static void fail(char *msg)
 {
        int rv;
-       rv = write(2, msg, strlen(msg));
-       rv |= write(2, "\n", 1);
+       rv = (write(2, msg, strlen(msg)) != (int)strlen(msg));
+       rv |= (write(2, "\n", 1) != 1);
        exit(rv ? 1 : 2);
 }
 
@@ -1722,7 +1759,7 @@ int Grow_restart(struct supertype *st, struct mdinfo *info, int *fdlist, int cnt
                        if (st->ss->load_super(st, fd, NULL))
                                continue;
 
-                       st->ss->getinfo_super(st, &dinfo);
+                       st->ss->getinfo_super(st, &dinfo, NULL);
                        st->ss->free_super(st);
 
                        if (lseek64(fd,
@@ -1840,7 +1877,7 @@ int Grow_restart(struct supertype *st, struct mdinfo *info, int *fdlist, int cnt
                        if (st->ss->load_super(st, fdlist[j], NULL))
                                /* FIXME should be this be an error */
                                continue;
-                       st->ss->getinfo_super(st, &dinfo);
+                       st->ss->getinfo_super(st, &dinfo, NULL);
                        st->ss->free_super(st);
                        offsets[j] = dinfo.data_offset * 512;
                }
@@ -1902,7 +1939,7 @@ int Grow_restart(struct supertype *st, struct mdinfo *info, int *fdlist, int cnt
                        if (fdlist[j] < 0) continue;
                        if (st->ss->load_super(st, fdlist[j], NULL))
                                continue;
-                       st->ss->getinfo_super(st, &dinfo);
+                       st->ss->getinfo_super(st, &dinfo, NULL);
                        dinfo.reshape_progress = info->reshape_progress;
                        st->ss->update_super(st, &dinfo,
                                             "_reshape_progress",