]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
mdadm: use struct context in reshape_super()
authorMateusz Kusiak <mateusz.kusiak@intel.com>
Mon, 29 Apr 2024 13:07:14 +0000 (15:07 +0200)
committerMariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Mon, 6 May 2024 23:49:37 +0000 (01:49 +0200)
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
mdadm.h
super-intel.c

diff --git a/Grow.c b/Grow.c
index f477b438e810bf1d37d3fe9f4812150ec41fff72..87ed9214ef0249d9dbc851f9afa7cf0183f95dcb 100644 (file)
--- 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 0ade4bebc400e2b9f74d1540a01d708518003d48..2ff3e46383cde40e15542799a615956e62fe83ed 100644 (file)
--- 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,
index 417da26725040c8f771318284092766351385f8e..1a8a7b12502520c65b337f5423aa0aa8c246a8dd 100644 (file)
@@ -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);