]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - Grow.c
Grow: Allow for component_size not being set for RAID0 arrays.
[thirdparty/mdadm.git] / Grow.c
diff --git a/Grow.c b/Grow.c
index ecbc837e7013f10882761c80d98affead9c79e75..812c1da9e997c3c0f3dda704f98e55e7e5f8ecdf 100644 (file)
--- a/Grow.c
+++ b/Grow.c
@@ -1506,7 +1506,10 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
        info.component_size = size*2;
        info.new_level = level;
        info.new_chunk = chunksize * 1024;
-       if (raid_disks)
+       if (info.array.level == LEVEL_CONTAINER) {
+               info.delta_disks = UnSet;
+               info.array.raid_disks = raid_disks;
+       } else if (raid_disks)
                info.delta_disks = raid_disks - info.array.raid_disks;
        else
                info.delta_disks = UnSet;
@@ -1646,22 +1649,40 @@ static int reshape_array(char *container, int fd, char *devname,
        int done;
        struct mdinfo *sra = NULL;
 
-       msg = analyse_change(info, &reshape);
+       /* when reshaping a RAID0, the component_size might be zero.
+        * So try to fix that up.
+        */
+       if (ioctl(fd, GET_ARRAY_INFO, &array) != 0) {
+               dprintf("Cannot get array information.\n");
+               goto release;
+       }
+       if (array.level == 0 && info->component_size == 0) {
+               get_dev_size(fd, NULL, &array_size);
+               info->component_size = array_size / array.raid_disks;
+       }
+
+       if (info->reshape_active) {
+               int new_level = info->new_level;
+               info->new_level = UnSet;
+               msg = analyse_change(info, &reshape);
+               info->new_level = new_level;
+               if (!restart)
+                       /* Make sure the array isn't read-only */
+                       ioctl(fd, RESTART_ARRAY_RW, 0);
+       } else
+               msg = analyse_change(info, &reshape);
        if (msg) {
                fprintf(stderr, Name ": %s\n", msg);
                goto release;
        }
-       if (reshape.level != info->array.level ||
-           reshape.before.layout != info->array.layout ||
-           reshape.before.data_disks + reshape.parity != info->array.raid_disks) {
+       if (restart &&
+           (reshape.level != info->array.level ||
+            reshape.before.layout != info->array.layout ||
+            reshape.before.data_disks + reshape.parity != info->array.raid_disks)) {
                fprintf(stderr, Name ": reshape info is not in native format -"
                        " cannot continue.\n");
                goto release;
        }
-       if (ioctl(fd, GET_ARRAY_INFO, &array) != 0) {
-               dprintf("Cannot get array information.\n");
-               goto release;
-       }
 
        if (restart) {
                /* reshape already started. just skip to monitoring the reshape */
@@ -3360,10 +3381,22 @@ int Grow_continue(int mdfd, struct supertype *st, struct mdinfo *info,
                fmt_devname(buf, st->container_dev);
                container = buf;
                freeze(st);
-               if (info->reshape_active == 2)
+
+               if (!mdmon_running(st->container_dev))
+                       start_mdmon(st->container_dev);
+               ping_monitor(devnum2devname(st->container_dev));
+
+
+               if (info->reshape_active == 2) {
+                       int cfd = open_dev(st->container_dev);
+                       if (cfd < 0)
+                               return 1;
+                       st->ss->load_container(st, cfd, container);
+                       close(cfd);
                        return reshape_container(container, NULL,
                                                 st, info, 0, backup_file,
                                                 0, 1);
+               }
        }
        return reshape_array(container, mdfd, "array", st, info, 1,
                             backup_file, 0, 0, 1);