Fix some issues with setting 'new' state of a reshape
- when reshaping a container, ->reshape_active is already set even though it isn't really active yet, so we need to set the new geometry even when reshape_active is set. This is safe. - When restarting a reshape, make sure the reshape_position is set appropriately when external metadata is used. Signed-off-by: NeilBrown <neilb@suse.de>
This commit is contained in:
parent
1cc7f4feb9
commit
f897078e8b
25
Grow.c
25
Grow.c
|
@ -1868,19 +1868,23 @@ started:
|
|||
|
||||
sra->new_chunk = info->new_chunk;
|
||||
|
||||
sra->reshape_progress = 0;
|
||||
if (reshape.after.data_disks < reshape.before.data_disks)
|
||||
/* start from the end of the new array */
|
||||
sra->reshape_progress = (sra->component_size
|
||||
* reshape.after.data_disks);
|
||||
|
||||
if (info->reshape_active)
|
||||
sra->reshape_progress = info->reshape_progress;
|
||||
else if (info->array.chunk_size == info->new_chunk &&
|
||||
else {
|
||||
sra->reshape_progress = 0;
|
||||
if (reshape.after.data_disks < reshape.before.data_disks)
|
||||
/* start from the end of the new array */
|
||||
sra->reshape_progress = (sra->component_size
|
||||
* reshape.after.data_disks);
|
||||
}
|
||||
|
||||
if (info->array.chunk_size == info->new_chunk &&
|
||||
reshape.before.layout == reshape.after.layout &&
|
||||
st->ss->external == 0) {
|
||||
/* use SET_ARRAY_INFO but only if reshape hasn't started */
|
||||
array.raid_disks = reshape.after.data_disks + reshape.parity;
|
||||
if (ioctl(fd, SET_ARRAY_INFO, &array) != 0) {
|
||||
if (!info->reshape_active &&
|
||||
ioctl(fd, SET_ARRAY_INFO, &array) != 0) {
|
||||
int err = errno;
|
||||
|
||||
fprintf(stderr,
|
||||
|
@ -1897,7 +1901,10 @@ started:
|
|||
}
|
||||
} else {
|
||||
/* set them all just in case some old 'new_*' value
|
||||
* persists from some earlier problem
|
||||
* 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)
|
||||
|
|
9
sysfs.c
9
sysfs.c
|
@ -569,6 +569,15 @@ int sysfs_set_array(struct mdinfo *info, int vers)
|
|||
|
||||
if (info->array.level > 0)
|
||||
rv |= sysfs_set_num(info, NULL, "resync_start", info->resync_start);
|
||||
|
||||
if (info->reshape_active) {
|
||||
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
|
||||
*/
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue