diff options
author | NeilBrown <neilb@suse.de> | 2011-03-08 17:36:40 +1100 |
---|---|---|
committer | NeilBrown <neilb@suse.de> | 2011-03-08 17:36:40 +1100 |
commit | 493f5dd6b249da3b92822f9e8ee0f20b17b131ce (patch) | |
tree | fcfed0ab3a235d0958c626b842dc7ba875f45b93 /Grow.c | |
parent | 04fa95230951582a4c5e8f022627d8baebd51af2 (diff) |
Allow Grow_continue for whole container as well as single array.
Some grow operations must be applied to a whole container. These
are performed one array at a time, so only one array appears to
be reshaping.
When re-assembling such an array, we need to make sure that
when the reshape finished, we move on to the next array.
So require metadata to set ->reshape_active = 2 in that case,
and use reshape_container to complete the reshape.
Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'Grow.c')
-rw-r--r-- | Grow.c | 27 |
1 files changed, 19 insertions, 8 deletions
@@ -1271,12 +1271,12 @@ static int reshape_array(char *container, int fd, char *devname, struct supertype *st, struct mdinfo *info, int force, char *backup_file, int quiet, int forked, int restart); -static int reshape_container(char *container, int cfd, char *devname, +static int reshape_container(char *container, char *devname, struct supertype *st, struct mdinfo *info, int force, char *backup_file, - int quiet); + int quiet, int restart); int Grow_reshape(char *devname, int fd, int quiet, char *backup_file, long long size, @@ -1578,8 +1578,8 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file, * number of devices (On-Line Capacity Expansion) must be * performed at the level of the container */ - rv = reshape_container(container, fd, devname, st, &info, - force, backup_file, quiet); + rv = reshape_container(container, devname, st, &info, + force, backup_file, quiet, 0); frozen = 0; } else { /* get spare devices from external metadata @@ -2135,19 +2135,20 @@ release: return 1; } -int reshape_container(char *container, int cfd, char *devname, +int reshape_container(char *container, char *devname, struct supertype *st, struct mdinfo *info, int force, char *backup_file, - int quiet) + int quiet, int restart) { struct mdinfo *cc = NULL; /* component_size is not meaningful for a container, * so pass '-1' meaning 'no change' */ - if (reshape_super(st, -1, info->new_level, + if (!restart && + reshape_super(st, -1, info->new_level, info->new_layout, info->new_chunk, info->array.raid_disks, info->delta_disks, backup_file, devname, quiet)) { @@ -2180,6 +2181,10 @@ int reshape_container(char *container, int cfd, char *devname, * reshape it. reshape_array() will re-read the metadata * so the next time through a different array should be * ready for reshape. + * It is possible that the 'different' array will not + * be assembled yet. In that case we simple exit. + * When it is assembled, the mdadm which assembles it + * will take over the reshape. */ struct mdinfo *content; int rv; @@ -2219,8 +2224,9 @@ int reshape_container(char *container, int cfd, char *devname, rv = reshape_array(container, fd, adev, st, content, force, - backup_file, quiet, 1, 0); + backup_file, quiet, 1, restart); close(fd); + restart = 0; if (rv) break; } @@ -3334,6 +3340,11 @@ int Grow_continue(int mdfd, struct supertype *st, struct mdinfo *info, if (st->ss->external) { fmt_devname(buf, st->container_dev); container = buf; + freeze(st); + if (info->reshape_active == 2) + 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); |