From 0acda7053df653022e46fa3b7caf1f4d4ba31a66 Mon Sep 17 00:00:00 2001 From: Mateusz Kusiak Date: Mon, 29 Apr 2024 15:07:14 +0200 Subject: [PATCH 53/69] mdadm: use struct context in reshape_super() reshape_super() takes too many arguments. Change passing params in favor of single struct. Add devname pointer and change direction members to struct shape and use it for reshape_super(). Create reshape_array_size() and reshape_array_non_size() to handle reshape_super() calls. Signed-off-by: Mateusz Kusiak Signed-off-by: Mariusz Tkaczyk --- Grow.c | 93 +++++++++++++++++++++++++++++++++++++-------------- mdadm.h | 18 +++++----- super-intel.c | 43 +++++++++++++++--------- 3 files changed, 105 insertions(+), 49 deletions(-) diff --git a/Grow.c b/Grow.c index f477b438..87ed9214 100644 --- a/Grow.c +++ b/Grow.c @@ -862,9 +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 *dev, int direction, struct context *c) +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) @@ -875,8 +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, dev, direction, c); + 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) @@ -1979,9 +2034,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; @@ -2001,8 +2055,7 @@ int Grow_reshape(char *devname, int fd, goto release; } - if (reshape_super(st, s->size, UnSet, UnSet, 0, 0, UnSet, - devname, APPLY_METADATA_CHANGES, c)) { + if (reshape_super_size(st, devname, s->size, APPLY_METADATA_CHANGES, c)) { rv = 1; goto release; } @@ -2120,8 +2173,8 @@ size_change_error: int err = errno; /* restore metadata */ - if (reshape_super(st, orig_size, UnSet, UnSet, 0, 0, UnSet, - devname, ROLLBACK_METADATA_CHANGES, c) == 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)); @@ -2351,11 +2404,7 @@ 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, - devname, APPLY_METADATA_CHANGES, c)) { + if (reshape_super_non_size(st, devname, &info, c)) { rv = 1; goto release; } @@ -3668,14 +3717,8 @@ int reshape_container(char *container, char *devname, 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, - devname, APPLY_METADATA_CHANGES, c)) { + /* component_size is not meaningful for a container */ + if (!restart && reshape_super_non_size(st, devname, info, c)) { unfreeze(st); return 1; } diff --git a/mdadm.h b/mdadm.h index 0ade4beb..2ff3e463 100644 --- a/mdadm.h +++ b/mdadm.h @@ -594,6 +594,11 @@ enum flag_mode { FlagDefault, FlagSet, FlagClear, }; +typedef enum { + ROLLBACK_METADATA_CHANGES, + APPLY_METADATA_CHANGES +} change_dir_t; + /* structures read from config file */ /* List of mddevice names and identifiers * Identifiers can be: @@ -667,7 +672,9 @@ struct context { }; struct shape { + char *dev; int raiddisks; + int delta_disks; int sparedisks; int journaldisks; int level; @@ -682,6 +689,7 @@ struct shape { unsigned long long size; unsigned long long data_offset; int consistency_policy; + change_dir_t direction; }; /* List of device names - wildcards expanded */ @@ -1229,14 +1237,8 @@ extern struct superswitch { * initialized to indicate if reshape is being performed at the * container or subarray level */ -#define APPLY_METADATA_CHANGES 1 -#define ROLLBACK_METADATA_CHANGES 0 - - int (*reshape_super)(struct supertype *st, - unsigned long long size, int level, - int layout, int chunksize, int raid_disks, - int delta_disks, char *dev, int direction, - struct context *c); + + int (*reshape_super)(struct supertype *st, struct shape *shape, struct context *c); int (*manage_reshape)( /* optional */ int afd, struct mdinfo *sra, struct reshape *reshape, struct supertype *st, unsigned long blocks, diff --git a/super-intel.c b/super-intel.c index 417da267..1a8a7b12 100644 --- a/super-intel.c +++ b/super-intel.c @@ -12152,26 +12152,37 @@ exit: return ret_val; } -static int imsm_reshape_super(struct supertype *st, unsigned long long size, - int level, int layout, int chunksize, int raid_disks, - int delta_disks, char *dev, int direction, struct context *c) +/** + * shape_to_geo() - fill geo_params from shape. + * + * @shape: array details. + * @geo: new geometry params. + * Returns: 0 on success, 1 otherwise. + */ +static void shape_to_geo(struct shape *shape, struct geo_params *geo) +{ + assert(shape); + assert(geo); + + geo->dev_name = shape->dev; + geo->size = shape->size; + geo->level = shape->level; + geo->layout = shape->layout; + geo->chunksize = shape->chunk; + geo->raid_disks = shape->raiddisks; +} + +static int imsm_reshape_super(struct supertype *st, struct shape *shape, struct context *c) { int ret_val = 1; - struct geo_params geo; + struct geo_params geo = {0}; dprintf("(enter)\n"); - memset(&geo, 0, sizeof(struct geo_params)); - - geo.dev_name = dev; + shape_to_geo(shape, &geo); strcpy(geo.devnm, st->devnm); - geo.size = size; - geo.level = level; - geo.layout = layout; - geo.chunksize = chunksize; - geo.raid_disks = raid_disks; - if (delta_disks != UnSet) - geo.raid_disks += delta_disks; + if (shape->delta_disks != UnSet) + geo.raid_disks += shape->delta_disks; dprintf("for level : %i\n", geo.level); dprintf("for raid_disks : %i\n", geo.raid_disks); @@ -12182,7 +12193,7 @@ static int imsm_reshape_super(struct supertype *st, unsigned long long size, int old_raid_disks = 0; if (imsm_reshape_is_allowed_on_container( - st, &geo, &old_raid_disks, direction)) { + st, &geo, &old_raid_disks, shape->direction)) { struct imsm_update_reshape *u = NULL; int len; @@ -12236,7 +12247,7 @@ static int imsm_reshape_super(struct supertype *st, unsigned long long size, goto exit_imsm_reshape_super; } super->current_vol = dev->index; - change = imsm_analyze_change(st, &geo, direction); + change = imsm_analyze_change(st, &geo, shape->direction); switch (change) { case CH_TAKEOVER: ret_val = imsm_takeover(st, &geo); -- 2.41.0