FIX: get updated information from metadata
Metadata is not modified by metadata preparation handler. It has to be read again from array. There is 2 read required: 1. before 'for' entry to get updated information after reshape_super() call 2. inside 'for' loop to get updated information for every processed array (it can happen /i.e. imsm case/ that container operation is a set of array operations and information in metadata is changed after every loop). Signed-off-by: Adam Kwolek <adam.kwolek@intel.com> Signed-off-by: NeilBrown <neilb@suse.de>
This commit is contained in:
parent
d677e0b8ec
commit
1bb174ba0b
68
Grow.c
68
Grow.c
|
@ -2040,6 +2040,21 @@ static int reshape_array(char *container, int fd, char *devname,
|
||||||
|
|
||||||
|
|
||||||
release:
|
release:
|
||||||
|
if (rv) {
|
||||||
|
unfreeze(st, frozen);
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
if (container)
|
||||||
|
ping_monitor(container);
|
||||||
|
if (st->ss->external) {
|
||||||
|
/* Re-load the metadata as much could have changed */
|
||||||
|
int cfd = open_dev(st->container_dev);
|
||||||
|
if (cfd >= 0) {
|
||||||
|
st->ss->free_super(st);
|
||||||
|
st->ss->load_container(st, cfd, container);
|
||||||
|
close(cfd);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (rv && orig_level != UnSet && sra) {
|
if (rv && orig_level != UnSet && sra) {
|
||||||
c = map_num(pers, orig_level);
|
c = map_num(pers, orig_level);
|
||||||
if (c && sysfs_set_str(sra, NULL, "level", c) == 0)
|
if (c && sysfs_set_str(sra, NULL, "level", c) == 0)
|
||||||
|
@ -2056,7 +2071,8 @@ int reshape_container(char *container, int cfd, char *devname,
|
||||||
char *backup_file,
|
char *backup_file,
|
||||||
int quiet)
|
int quiet)
|
||||||
{
|
{
|
||||||
struct mdinfo *cc;
|
struct mdinfo *cc = NULL;
|
||||||
|
|
||||||
if (reshape_super(st, info->component_size, info->new_level,
|
if (reshape_super(st, info->component_size, info->new_level,
|
||||||
info->new_layout, info->new_chunk,
|
info->new_layout, info->new_chunk,
|
||||||
info->array.raid_disks + info->delta_disks,
|
info->array.raid_disks + info->delta_disks,
|
||||||
|
@ -2065,10 +2081,9 @@ int reshape_container(char *container, int cfd, char *devname,
|
||||||
|
|
||||||
sync_metadata(st);
|
sync_metadata(st);
|
||||||
|
|
||||||
cc = st->ss->container_content(st, NULL);
|
/* ping monitor to be sure that update is on disk
|
||||||
|
*/
|
||||||
if (!cc)
|
ping_monitor(container);
|
||||||
return 1;
|
|
||||||
|
|
||||||
switch (fork()) {
|
switch (fork()) {
|
||||||
case -1: /* error */
|
case -1: /* error */
|
||||||
|
@ -2081,21 +2096,39 @@ int reshape_container(char *container, int cfd, char *devname,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* For each member array, we need to perform the reshape */
|
while(1) {
|
||||||
for (; cc; cc = cc->next) {
|
/* For each member array with reshape_active,
|
||||||
|
* we need to perform the reshape.
|
||||||
|
* We pick the first array that needs reshaping and
|
||||||
|
* reshape it. reshape_array() will re-read the metadata
|
||||||
|
* so the next time through a different array should be
|
||||||
|
* ready for reshape.
|
||||||
|
*/
|
||||||
|
struct mdinfo *content;
|
||||||
int rv;
|
int rv;
|
||||||
int fd;
|
int fd;
|
||||||
struct mdstat_ent *mdstat;
|
struct mdstat_ent *mdstat;
|
||||||
char *subarray = strchr(cc->text_version+1, '/')+1;
|
|
||||||
char *adev;
|
char *adev;
|
||||||
|
|
||||||
if (!cc->reshape_active)
|
sysfs_free(cc);
|
||||||
continue;
|
|
||||||
|
|
||||||
mdstat = mdstat_by_subdev(subarray, devname2devnum(container));
|
cc = st->ss->container_content(st, NULL);
|
||||||
|
|
||||||
|
for (content = cc; content ; content = content->next) {
|
||||||
|
char *subarray;
|
||||||
|
if (!content->reshape_active)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
subarray = strchr(content->text_version+1, '/')+1;
|
||||||
|
mdstat = mdstat_by_subdev(subarray,
|
||||||
|
devname2devnum(container));
|
||||||
|
if (!mdstat)
|
||||||
|
continue;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!content)
|
||||||
|
break;
|
||||||
|
|
||||||
if (!mdstat)
|
|
||||||
continue;
|
|
||||||
fd = open_dev_excl(mdstat->devnum);
|
fd = open_dev_excl(mdstat->devnum);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
break;
|
break;
|
||||||
|
@ -2103,15 +2136,18 @@ int reshape_container(char *container, int cfd, char *devname,
|
||||||
dev2minor(mdstat->devnum),
|
dev2minor(mdstat->devnum),
|
||||||
0);
|
0);
|
||||||
if (!adev)
|
if (!adev)
|
||||||
adev = cc->text_version;
|
adev = content->text_version;
|
||||||
|
|
||||||
sysfs_init(cc, fd, mdstat->devnum);
|
sysfs_init(content, fd, mdstat->devnum);
|
||||||
rv = reshape_array(container, fd, adev, st, cc, force,
|
|
||||||
|
rv = reshape_array(container, fd, adev, st,
|
||||||
|
content, force,
|
||||||
backup_file, quiet, 1);
|
backup_file, quiet, 1);
|
||||||
close(fd);
|
close(fd);
|
||||||
if (rv)
|
if (rv)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
sysfs_free(cc);
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue