From 20a40eca4b40068f6a45b9eab67320bd5de56f11 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Tue, 8 Mar 2011 16:10:29 +1100 Subject: [PATCH] Change way that reshaping arrays with external-metadata are assembled. 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 --- Grow.c | 38 ++++++++++++++++++-------------------- sysfs.c | 7 +++++-- 2 files changed, 23 insertions(+), 22 deletions(-) diff --git a/Grow.c b/Grow.c index e321a391..848a0629 100644 --- 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 883a8348..a7dfcc29 100644 --- 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; -- 2.39.2