]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
Grow: Split Grow_reshape into helper function
authorMateusz Kusiak <mateusz.kusiak@intel.com>
Thu, 28 Jul 2022 12:20:53 +0000 (20:20 +0800)
committerJes Sorensen <jsorensen@fb.com>
Wed, 24 Aug 2022 15:53:40 +0000 (11:53 -0400)
Grow_reshape should be split into helper functions given its size.
- Add helper function for preparing reshape on external metadata.
- Close cfd file descriptor.

Signed-off-by: Mateusz Kusiak <mateusz.kusiak@intel.com>
Acked-by: Coly Li <colyli@suse.de>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
Grow.c
mdadm.h
util.c

diff --git a/Grow.c b/Grow.c
index 868bdc3a3be4fe8134a342d0dbcd43b52136015c..0f07a89435af4d54c3293da19b6707edbded8790 100644 (file)
--- a/Grow.c
+++ b/Grow.c
@@ -1773,6 +1773,65 @@ static int reshape_container(char *container, char *devname,
                             char *backup_file, int verbose,
                             int forked, int restart, int freeze_reshape);
 
+/**
+ * prepare_external_reshape() - prepares update on external metadata if supported.
+ * @devname: Device name.
+ * @subarray: Subarray.
+ * @st: Supertype.
+ * @container: Container.
+ * @cfd: Container file descriptor.
+ *
+ * Function checks that the requested reshape is supported on external metadata,
+ * and performs an initial check that the container holds the pre-requisite
+ * spare devices (mdmon owns final validation).
+ *
+ * Return: 0 on success, else 1
+ */
+static int prepare_external_reshape(char *devname, char *subarray,
+                                   struct supertype *st, char *container,
+                                   const int cfd)
+{
+       struct mdinfo *cc = NULL;
+       struct mdinfo *content = NULL;
+
+       if (st->ss->load_container(st, cfd, NULL)) {
+               pr_err("Cannot read superblock for %s\n", devname);
+               return 1;
+       }
+
+       if (!st->ss->container_content)
+               return 1;
+
+       cc = st->ss->container_content(st, subarray);
+       for (content = cc; content ; content = content->next) {
+               /*
+                * check if reshape is allowed based on metadata
+                * indications stored in content.array.status
+                */
+               if (is_bit_set(&content->array.state, MD_SB_BLOCK_VOLUME) ||
+                   is_bit_set(&content->array.state, MD_SB_BLOCK_CONTAINER_RESHAPE)) {
+                       pr_err("Cannot reshape arrays in container with unsupported metadata: %s(%s)\n",
+                              devname, container);
+                       goto error;
+               }
+               if (content->consistency_policy == CONSISTENCY_POLICY_PPL) {
+                       pr_err("Operation not supported when ppl consistency policy is enabled\n");
+                       goto error;
+               }
+               if (content->consistency_policy == CONSISTENCY_POLICY_BITMAP) {
+                       pr_err("Operation not supported when write-intent bitmap consistency policy is enabled\n");
+                       goto error;
+               }
+       }
+       sysfs_free(cc);
+       if (mdmon_running(container))
+               st->update_tail = &st->updates;
+       return 0;
+error:
+       sysfs_free(cc);
+       return 1;
+}
+
 int Grow_reshape(char *devname, int fd,
                 struct mddev_dev *devlist,
                 struct context *c, struct shape *s)
@@ -1799,7 +1858,7 @@ int Grow_reshape(char *devname, int fd,
        struct supertype *st;
        char *subarray = NULL;
 
-       int frozen;
+       int frozen = 0;
        int changed = 0;
        char *container = NULL;
        int cfd = -1;
@@ -1808,7 +1867,7 @@ int Grow_reshape(char *devname, int fd,
        int added_disks;
 
        struct mdinfo info;
-       struct mdinfo *sra;
+       struct mdinfo *sra = NULL;
 
        if (md_get_array_info(fd, &array) < 0) {
                pr_err("%s is not an active md array - aborting\n",
@@ -1865,13 +1924,7 @@ int Grow_reshape(char *devname, int fd,
                }
        }
 
-       /* in the external case we need to check that the requested reshape is
-        * supported, and perform an initial check that the container holds the
-        * pre-requisite spare devices (mdmon owns final validation)
-        */
        if (st->ss->external) {
-               int retval;
-
                if (subarray) {
                        container = st->container_devnm;
                        cfd = open_dev_excl(st->container_devnm);
@@ -1887,13 +1940,12 @@ int Grow_reshape(char *devname, int fd,
                        return 1;
                }
 
-               retval = st->ss->load_container(st, cfd, NULL);
-
-               if (retval) {
-                       pr_err("Cannot read superblock for %s\n", devname);
-                       close(cfd);
+               rv = prepare_external_reshape(devname, subarray, st,
+                                             container, cfd);
+               if (rv > 0) {
                        free(subarray);
-                       return 1;
+                       close(cfd);
+                       goto release;
                }
 
                if (s->raiddisks && subarray) {
@@ -1902,51 +1954,6 @@ int Grow_reshape(char *devname, int fd,
                        free(subarray);
                        return 1;
                }
-
-               /* check if operation is supported for metadata handler */
-               if (st->ss->container_content) {
-                       struct mdinfo *cc = NULL;
-                       struct mdinfo *content = NULL;
-
-                       cc = st->ss->container_content(st, subarray);
-                       for (content = cc; content ; content = content->next) {
-                               int allow_reshape = 1;
-
-                               /* check if reshape is allowed based on metadata
-                                * indications stored in content.array.status
-                                */
-                               if (content->array.state &
-                                   (1 << MD_SB_BLOCK_VOLUME))
-                                       allow_reshape = 0;
-                               if (content->array.state &
-                                   (1 << MD_SB_BLOCK_CONTAINER_RESHAPE))
-                                       allow_reshape = 0;
-                               if (!allow_reshape) {
-                                       pr_err("cannot reshape arrays in container with unsupported metadata: %s(%s)\n",
-                                              devname, container);
-                                       sysfs_free(cc);
-                                       free(subarray);
-                                       return 1;
-                               }
-                               if (content->consistency_policy ==
-                                   CONSISTENCY_POLICY_PPL) {
-                                       pr_err("Operation not supported when ppl consistency policy is enabled\n");
-                                       sysfs_free(cc);
-                                       free(subarray);
-                                       return 1;
-                               }
-                               if (content->consistency_policy ==
-                                   CONSISTENCY_POLICY_BITMAP) {
-                                       pr_err("Operation not supported when write-intent bitmap is enabled\n");
-                                       sysfs_free(cc);
-                                       free(subarray);
-                                       return 1;
-                               }
-                       }
-                       sysfs_free(cc);
-               }
-               if (mdmon_running(container))
-                       st->update_tail = &st->updates;
        }
 
        added_disks = 0;
diff --git a/mdadm.h b/mdadm.h
index 8208b81e8d1e8616256b1506f8af4341311a2a63..941a5f3823a01b5d506c790be1c2dfb810501272 100644 (file)
--- a/mdadm.h
+++ b/mdadm.h
@@ -1539,6 +1539,7 @@ extern int stat_is_blkdev(char *devname, dev_t *rdev);
 extern bool is_dev_alive(char *path);
 extern int get_mdp_major(void);
 extern int get_maj_min(char *dev, int *major, int *minor);
+extern bool is_bit_set(int *val, unsigned char index);
 extern int dev_open(char *dev, int flags);
 extern int open_dev(char *devnm);
 extern void reopen_mddev(int mdfd);
diff --git a/util.c b/util.c
index ca48d976e9f5b368453c65ce1718efc70e96f3bd..26ffdceabcdc0fbd3728d3975180452f02286017 100644 (file)
--- a/util.c
+++ b/util.c
@@ -1027,6 +1027,20 @@ int get_maj_min(char *dev, int *major, int *minor)
                *e == 0);
 }
 
+/**
+ * is_bit_set() - get bit value by index.
+ * @val: value.
+ * @index: index of the bit (LSB numbering).
+ *
+ * Return: bit value.
+ */
+bool is_bit_set(int *val, unsigned char index)
+{
+       if ((*val) & (1 << index))
+               return true;
+       return false;
+}
+
 int dev_open(char *dev, int flags)
 {
        /* like 'open', but if 'dev' matches %d:%d, create a temp