]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
Change way that reshaping arrays with external-metadata are assembled.
authorNeilBrown <neilb@suse.de>
Tue, 8 Mar 2011 05:10:29 +0000 (16:10 +1100)
committerNeilBrown <neilb@suse.de>
Tue, 8 Mar 2011 05:10:29 +0000 (16:10 +1100)
Now that the external metadata handler must provide an md-compatible
old/new geometry, sys_set_array can do all of the array set-up for
an array that is undergoing reshape.
That leave less for reshape_array to do.

Also clean up how reshape_array tells if the reshape has started or
not.
Don't use ->reshape_active as that doesn't tell us anything consistent
at this stage, only use the 'restart' flag passed in.

Signed-off-by: NeilBrown <neilb@suse.de>
Grow.c
sysfs.c

diff --git a/Grow.c b/Grow.c
index e321a391d4754d1e9e699f728085c758d2413ff4..848a06290cedb9fc9b7e168bff451536ad3c5f58 100644 (file)
--- a/Grow.c
+++ b/Grow.c
@@ -1647,6 +1647,13 @@ static int reshape_array(char *container, int fd, char *devname,
                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) {
+               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;
@@ -1928,7 +1935,7 @@ started:
 
        sra->new_chunk = info->new_chunk;
 
-       if (info->reshape_active)
+       if (restart)
                sra->reshape_progress = info->reshape_progress;
        else {
                sra->reshape_progress = 0;
@@ -1944,7 +1951,7 @@ started:
                /* use SET_ARRAY_INFO but only if reshape hasn't started */
                ioctl(fd, GET_ARRAY_INFO, &array);
                array.raid_disks = reshape.after.data_disks + reshape.parity;
-               if (!info->reshape_active &&
+               if (!restart &&
                    ioctl(fd, SET_ARRAY_INFO, &array) != 0) {
                        int err = errno;
 
@@ -1960,17 +1967,9 @@ started:
 
                        goto release;
                }
-       } else if (info->reshape_active && !st->ss->external) {
-               /* We don't need to set anything here for internal
-                * metadata, and for kernels before 2.6.38 we can
-                * fail if we try.
-                */
-       } else {
+       } else if (!restart) {
                /* set them all just in case some old 'new_*' value
                 * persists from some earlier problem.
-                * We even set them when restarting in the middle.  They will
-                * already be set in that case so this will be a no-op,
-                * but it is hard to tell the difference.
                 */
                int err = 0;
                if (sysfs_set_num(sra, NULL, "chunk_size", info->new_chunk) < 0)
@@ -1995,9 +1994,11 @@ started:
                }
        }
 
-       err = start_reshape(sra, (info->reshape_active && !st->ss->external));
+       err = start_reshape(sra, restart);
        if (err) {
-               fprintf(stderr, Name ": Cannot start reshape for %s\n",
+               fprintf(stderr, 
+                       Name ": Cannot %s reshape for %s\n",
+                       restart ? "continue" : "start",
                        devname);
                goto release;
        }
@@ -3327,16 +3328,13 @@ int Grow_continue(int mdfd, struct supertype *st, struct mdinfo *info,
        char *container = NULL;
        int err;
 
-       if (!st->ss->external) {
-               err = sysfs_set_str(info, NULL, "array_state", "readonly");
-               if (err)
-                       return err;
-       } else {
+       err = sysfs_set_str(info, NULL, "array_state", "readonly");
+       if (err)
+               return err;
+       if (st->ss->external) {
                fmt_devname(buf, st->container_dev);
                container = buf;
        }
        return reshape_array(container, mdfd, "array", st, info, 1,
                             backup_file, 0, 0, 1);
 }
-
-
diff --git a/sysfs.c b/sysfs.c
index 883a834871694385e978758a463f37197747c209..a7dfcc2966b5eca585d504338a267fc521ad6486 100644 (file)
--- a/sysfs.c
+++ b/sysfs.c
@@ -574,8 +574,11 @@ int sysfs_set_array(struct mdinfo *info, int vers)
                rv |= sysfs_set_num(info, NULL, "reshape_position",
                                    info->reshape_progress);
                rv |= sysfs_set_num(info, NULL, "chunk_size", info->new_chunk);
-               /* Don't set layout or raid_disks here as they require some
-                * analysis and are set by reshape_array 
+               rv |= sysfs_set_num(info, NULL, "layout", info->new_layout);
+               rv |= sysfs_set_num(info, NULL, "raid_disks",
+                                   info->array.raid_disks + info->delta_disks);
+               /* We don't set 'new_level' here.  That can only happen
+                * once the reshape completes.
                 */
        }
        return rv;