Merging upstream version 4.3+20240723.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
9d4f96bc70
commit
aa881a3626
70 changed files with 1465 additions and 1206 deletions
169
Grow.c
169
Grow.c
|
@ -862,10 +862,7 @@ static void wait_reshape(struct mdinfo *sra)
|
|||
close(fd);
|
||||
}
|
||||
|
||||
static int reshape_super(struct supertype *st, unsigned long long size,
|
||||
int level, int layout, int chunksize, int raid_disks,
|
||||
int delta_disks, char *backup_file, char *dev,
|
||||
int direction, int verbose)
|
||||
static int reshape_super(struct supertype *st, struct shape *shape, struct context *c)
|
||||
{
|
||||
/* nothing extra to check in the native case */
|
||||
if (!st->ss->external)
|
||||
|
@ -876,9 +873,65 @@ static int reshape_super(struct supertype *st, unsigned long long size,
|
|||
return 1;
|
||||
}
|
||||
|
||||
return st->ss->reshape_super(st, size, level, layout, chunksize,
|
||||
raid_disks, delta_disks, backup_file, dev,
|
||||
direction, verbose);
|
||||
return st->ss->reshape_super(st, shape, c);
|
||||
}
|
||||
|
||||
/**
|
||||
* reshape_super_size() - Reshape array, size only.
|
||||
*
|
||||
* @st: supertype.
|
||||
* @devname: device name.
|
||||
* @size: component size.
|
||||
* @dir metadata changes direction
|
||||
* Returns: 0 on success, 1 otherwise.
|
||||
*
|
||||
* This function is solely used to change size of the volume.
|
||||
* Setting size is not valid for container.
|
||||
* Size is only change that can be rolled back, thus the @dir param.
|
||||
*/
|
||||
static int reshape_super_size(struct supertype *st, char *devname,
|
||||
unsigned long long size, change_dir_t direction,
|
||||
struct context *c)
|
||||
{
|
||||
struct shape shape = {0};
|
||||
|
||||
shape.level = UnSet;
|
||||
shape.layout = UnSet;
|
||||
shape.delta_disks = UnSet;
|
||||
shape.dev = devname;
|
||||
shape.size = size;
|
||||
shape.direction = direction;
|
||||
|
||||
return reshape_super(st, &shape, c);
|
||||
}
|
||||
|
||||
/**
|
||||
* reshape_super_non_size() - Reshape array, non size changes.
|
||||
*
|
||||
* @st: supertype.
|
||||
* @devname: device name.
|
||||
* @info: superblock info.
|
||||
* Returns: 0 on success, 1 otherwise.
|
||||
*
|
||||
* This function is used for any external array changes but size.
|
||||
* It handles both volumes and containers.
|
||||
* For changes other than size, rollback is not possible.
|
||||
*/
|
||||
static int reshape_super_non_size(struct supertype *st, char *devname,
|
||||
struct mdinfo *info, struct context *c)
|
||||
{
|
||||
struct shape shape = {0};
|
||||
/* Size already set to zero, not updating size */
|
||||
shape.level = info->new_level;
|
||||
shape.layout = info->new_layout;
|
||||
shape.chunk = info->new_chunk;
|
||||
shape.raiddisks = info->array.raid_disks;
|
||||
shape.delta_disks = info->delta_disks;
|
||||
shape.dev = devname;
|
||||
/* Rollback not possible for non size changes */
|
||||
shape.direction = APPLY_METADATA_CHANGES;
|
||||
|
||||
return reshape_super(st, &shape, c);
|
||||
}
|
||||
|
||||
static void sync_metadata(struct supertype *st)
|
||||
|
@ -1170,13 +1223,14 @@ int reshape_open_backup_file(char *backup_file,
|
|||
* way this will not notice, but it is better than
|
||||
* nothing.
|
||||
*/
|
||||
fstat(*fdlist, &stb);
|
||||
if (fstat(*fdlist, &stb) != 0)
|
||||
goto error;
|
||||
dev = stb.st_dev;
|
||||
fstat(fd, &stb);
|
||||
if (fstat(fd, &stb) != 0)
|
||||
goto error;
|
||||
if (stb.st_rdev == dev) {
|
||||
pr_err("backup file must NOT be on the array being reshaped.\n");
|
||||
close(*fdlist);
|
||||
return 0;
|
||||
goto error;
|
||||
}
|
||||
|
||||
memset(buf, 0, 512);
|
||||
|
@ -1202,6 +1256,9 @@ int reshape_open_backup_file(char *backup_file,
|
|||
}
|
||||
|
||||
return 1;
|
||||
error:
|
||||
close(*fdlist);
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned long compute_backup_blocks(int nchunk, int ochunk,
|
||||
|
@ -1764,9 +1821,8 @@ static int reshape_container(char *container, char *devname,
|
|||
int mdfd,
|
||||
struct supertype *st,
|
||||
struct mdinfo *info,
|
||||
int force,
|
||||
char *backup_file, int verbose,
|
||||
int forked, int restart, int freeze_reshape);
|
||||
struct context *c,
|
||||
int forked, int restart);
|
||||
|
||||
/**
|
||||
* prepare_external_reshape() - prepares update on external metadata if supported.
|
||||
|
@ -1982,9 +2038,8 @@ int Grow_reshape(char *devname, int fd,
|
|||
}
|
||||
|
||||
/* ========= set size =============== */
|
||||
if (s->size > 0 &&
|
||||
(s->size == MAX_SIZE || s->size != (unsigned)array.size)) {
|
||||
unsigned long long orig_size = get_component_size(fd)/2;
|
||||
if (s->size > 0 && (s->size == MAX_SIZE || s->size != (unsigned)array.size)) {
|
||||
unsigned long long orig_size = get_component_size(fd) / 2;
|
||||
unsigned long long min_csize;
|
||||
struct mdinfo *mdi;
|
||||
int raid0_takeover = 0;
|
||||
|
@ -2004,9 +2059,7 @@ int Grow_reshape(char *devname, int fd,
|
|||
goto release;
|
||||
}
|
||||
|
||||
if (reshape_super(st, s->size, UnSet, UnSet, 0, 0, UnSet, NULL,
|
||||
devname, APPLY_METADATA_CHANGES,
|
||||
c->verbose > 0)) {
|
||||
if (reshape_super_size(st, devname, s->size, APPLY_METADATA_CHANGES, c)) {
|
||||
rv = 1;
|
||||
goto release;
|
||||
}
|
||||
|
@ -2085,7 +2138,7 @@ int Grow_reshape(char *devname, int fd,
|
|||
if (!mdmon_running(st->container_devnm))
|
||||
start_mdmon(st->container_devnm);
|
||||
ping_monitor(container);
|
||||
if (mdmon_running(st->container_devnm) == false) {
|
||||
if (wait_for_mdmon(st->container_devnm) != MDADM_STATUS_SUCCESS) {
|
||||
pr_err("No mdmon found. Grow cannot continue.\n");
|
||||
goto release;
|
||||
}
|
||||
|
@ -2124,10 +2177,8 @@ size_change_error:
|
|||
int err = errno;
|
||||
|
||||
/* restore metadata */
|
||||
if (reshape_super(st, orig_size, UnSet, UnSet, 0, 0,
|
||||
UnSet, NULL, devname,
|
||||
ROLLBACK_METADATA_CHANGES,
|
||||
c->verbose) == 0)
|
||||
if (reshape_super_size(st, devname, orig_size,
|
||||
ROLLBACK_METADATA_CHANGES, c) == 0)
|
||||
sync_metadata(st);
|
||||
pr_err("Cannot set device size for %s: %s\n",
|
||||
devname, strerror(err));
|
||||
|
@ -2338,8 +2389,7 @@ size_change_error:
|
|||
*/
|
||||
close_fd(&fd);
|
||||
rv = reshape_container(container, devname, -1, st, &info,
|
||||
c->force, c->backup_file, c->verbose,
|
||||
0, 0, 0);
|
||||
c, 0, 0);
|
||||
frozen = 0;
|
||||
} else {
|
||||
/* get spare devices from external metadata
|
||||
|
@ -2356,13 +2406,9 @@ size_change_error:
|
|||
}
|
||||
|
||||
/* Impose these changes on a single array. First
|
||||
* check that the metadata is OK with the change. */
|
||||
|
||||
if (reshape_super(st, 0, info.new_level,
|
||||
info.new_layout, info.new_chunk,
|
||||
info.array.raid_disks, info.delta_disks,
|
||||
c->backup_file, devname,
|
||||
APPLY_METADATA_CHANGES, c->verbose)) {
|
||||
* check that the metadata is OK with the change.
|
||||
*/
|
||||
if (reshape_super_non_size(st, devname, &info, c)) {
|
||||
rv = 1;
|
||||
goto release;
|
||||
}
|
||||
|
@ -3176,7 +3222,8 @@ static int reshape_array(char *container, int fd, char *devname,
|
|||
if (!mdmon_running(container))
|
||||
start_mdmon(container);
|
||||
ping_monitor(container);
|
||||
if (mdmon_running(container) && st->update_tail == NULL)
|
||||
if (wait_for_mdmon(container) == MDADM_STATUS_SUCCESS &&
|
||||
!st->update_tail)
|
||||
st->update_tail = &st->updates;
|
||||
}
|
||||
}
|
||||
|
@ -3668,23 +3715,15 @@ int reshape_container(char *container, char *devname,
|
|||
int mdfd,
|
||||
struct supertype *st,
|
||||
struct mdinfo *info,
|
||||
int force,
|
||||
char *backup_file, int verbose,
|
||||
int forked, int restart, int freeze_reshape)
|
||||
struct context *c,
|
||||
int forked, int restart)
|
||||
{
|
||||
struct mdinfo *cc = NULL;
|
||||
int rv = restart;
|
||||
char last_devnm[32] = "";
|
||||
|
||||
/* component_size is not meaningful for a container,
|
||||
* so pass '0' meaning 'no change'
|
||||
*/
|
||||
if (!restart &&
|
||||
reshape_super(st, 0, info->new_level,
|
||||
info->new_layout, info->new_chunk,
|
||||
info->array.raid_disks, info->delta_disks,
|
||||
backup_file, devname, APPLY_METADATA_CHANGES,
|
||||
verbose)) {
|
||||
/* component_size is not meaningful for a container */
|
||||
if (!restart && reshape_super_non_size(st, devname, info, c)) {
|
||||
unfreeze(st);
|
||||
return 1;
|
||||
}
|
||||
|
@ -3695,7 +3734,7 @@ int reshape_container(char *container, char *devname,
|
|||
*/
|
||||
ping_monitor(container);
|
||||
|
||||
if (!forked && !freeze_reshape)
|
||||
if (!forked && !c->freeze_reshape)
|
||||
if (continue_via_systemd(container, GROW_SERVICE, NULL))
|
||||
return 0;
|
||||
|
||||
|
@ -3705,7 +3744,7 @@ int reshape_container(char *container, char *devname,
|
|||
unfreeze(st);
|
||||
return 1;
|
||||
default: /* parent */
|
||||
if (!freeze_reshape)
|
||||
if (!c->freeze_reshape)
|
||||
printf("%s: multi-array reshape continues in background\n", Name);
|
||||
return 0;
|
||||
case 0: /* child */
|
||||
|
@ -3802,12 +3841,12 @@ int reshape_container(char *container, char *devname,
|
|||
flush_mdmon(container);
|
||||
|
||||
rv = reshape_array(container, fd, adev, st,
|
||||
content, force, NULL, INVALID_SECTORS,
|
||||
backup_file, verbose, 1, restart,
|
||||
freeze_reshape);
|
||||
content, c->force, NULL, INVALID_SECTORS,
|
||||
c->backup_file, c->verbose, 1, restart,
|
||||
c->freeze_reshape);
|
||||
close(fd);
|
||||
|
||||
if (freeze_reshape) {
|
||||
if (c->freeze_reshape) {
|
||||
sysfs_free(cc);
|
||||
exit(0);
|
||||
}
|
||||
|
@ -4449,7 +4488,6 @@ int child_monitor(int afd, struct mdinfo *sra, struct reshape *reshape,
|
|||
*/
|
||||
char *buf;
|
||||
int degraded = -1;
|
||||
unsigned long long speed;
|
||||
unsigned long long suspend_point, array_size;
|
||||
unsigned long long backup_point, wait_point;
|
||||
unsigned long long reshape_completed;
|
||||
|
@ -4505,10 +4543,6 @@ int child_monitor(int afd, struct mdinfo *sra, struct reshape *reshape,
|
|||
if (posix_memalign((void**)&buf, 4096, disks * chunk))
|
||||
/* Don't start the 'reshape' */
|
||||
return 0;
|
||||
if (reshape->before.data_disks == reshape->after.data_disks) {
|
||||
sysfs_get_ll(sra, NULL, "sync_speed_min", &speed);
|
||||
sysfs_set_num(sra, NULL, "sync_speed_min", 200000);
|
||||
}
|
||||
|
||||
if (increasing) {
|
||||
array_size = sra->component_size * reshape->after.data_disks;
|
||||
|
@ -4641,8 +4675,6 @@ int child_monitor(int afd, struct mdinfo *sra, struct reshape *reshape,
|
|||
sysfs_set_num(sra, NULL, "suspend_lo", 0);
|
||||
sysfs_set_num(sra, NULL, "sync_min", 0);
|
||||
|
||||
if (reshape->before.data_disks == reshape->after.data_disks)
|
||||
sysfs_set_num(sra, NULL, "sync_speed_min", speed);
|
||||
free(buf);
|
||||
return done;
|
||||
}
|
||||
|
@ -4970,8 +5002,7 @@ int Grow_restart(struct supertype *st, struct mdinfo *info, int *fdlist,
|
|||
return 1;
|
||||
}
|
||||
|
||||
int Grow_continue_command(char *devname, int fd,
|
||||
char *backup_file, int verbose)
|
||||
int Grow_continue_command(char *devname, int fd, struct context *c)
|
||||
{
|
||||
int ret_val = 0;
|
||||
struct supertype *st = NULL;
|
||||
|
@ -5140,7 +5171,7 @@ int Grow_continue_command(char *devname, int fd,
|
|||
start_mdmon(container);
|
||||
ping_monitor(container);
|
||||
|
||||
if (mdmon_running(container) == false) {
|
||||
if (wait_for_mdmon(container) != MDADM_STATUS_SUCCESS) {
|
||||
pr_err("No mdmon found. Grow cannot continue.\n");
|
||||
ret_val = 1;
|
||||
goto Grow_continue_command_exit;
|
||||
|
@ -5157,7 +5188,7 @@ int Grow_continue_command(char *devname, int fd,
|
|||
|
||||
/* continue reshape
|
||||
*/
|
||||
ret_val = Grow_continue(fd, st, content, backup_file, 1, 0);
|
||||
ret_val = Grow_continue(fd, st, content, 1, c);
|
||||
|
||||
Grow_continue_command_exit:
|
||||
if (cfd > -1)
|
||||
|
@ -5171,7 +5202,7 @@ Grow_continue_command_exit:
|
|||
}
|
||||
|
||||
int Grow_continue(int mdfd, struct supertype *st, struct mdinfo *info,
|
||||
char *backup_file, int forked, int freeze_reshape)
|
||||
int forked, struct context *c)
|
||||
{
|
||||
int ret_val = 2;
|
||||
|
||||
|
@ -5187,14 +5218,12 @@ int Grow_continue(int mdfd, struct supertype *st, struct mdinfo *info,
|
|||
st->ss->load_container(st, cfd, st->container_devnm);
|
||||
close(cfd);
|
||||
ret_val = reshape_container(st->container_devnm, NULL, mdfd,
|
||||
st, info, 0, backup_file, 0,
|
||||
forked, 1 | info->reshape_active,
|
||||
freeze_reshape);
|
||||
st, info, c, forked, 1 | info->reshape_active);
|
||||
} else
|
||||
ret_val = reshape_array(NULL, mdfd, "array", st, info, 1,
|
||||
NULL, INVALID_SECTORS, backup_file,
|
||||
NULL, INVALID_SECTORS, c->backup_file,
|
||||
0, forked, 1 | info->reshape_active,
|
||||
freeze_reshape);
|
||||
c->freeze_reshape);
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue