You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
297 lines
9.1 KiB
297 lines
9.1 KiB
From 0acda7053df653022e46fa3b7caf1f4d4ba31a66 Mon Sep 17 00:00:00 2001
|
|
From: Mateusz Kusiak <mateusz.kusiak@intel.com>
|
|
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 <mateusz.kusiak@intel.com>
|
|
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
|
---
|
|
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
|
|
|