|
|
c0f891 |
From 7211116c295ba1f9e1fcbdc2dd2d3762855062e1 Mon Sep 17 00:00:00 2001
|
|
|
c0f891 |
From: Mateusz Kusiak <mateusz.kusiak@intel.com>
|
|
|
c0f891 |
Date: Thu, 28 Jul 2022 20:20:53 +0800
|
|
|
c0f891 |
Subject: [PATCH 51/52] Grow: Split Grow_reshape into helper function
|
|
|
c0f891 |
|
|
|
c0f891 |
Grow_reshape should be split into helper functions given its size.
|
|
|
c0f891 |
- Add helper function for preparing reshape on external metadata.
|
|
|
c0f891 |
- Close cfd file descriptor.
|
|
|
c0f891 |
|
|
|
c0f891 |
Signed-off-by: Mateusz Kusiak <mateusz.kusiak@intel.com>
|
|
|
c0f891 |
Acked-by: Coly Li <colyli@suse.de>
|
|
|
c0f891 |
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
|
|
|
c0f891 |
---
|
|
|
c0f891 |
Grow.c | 125 ++++++++++++++++++++++++++++++--------------------------
|
|
|
c0f891 |
mdadm.h | 1 +
|
|
|
c0f891 |
util.c | 14 +++++++
|
|
|
c0f891 |
3 files changed, 81 insertions(+), 59 deletions(-)
|
|
|
c0f891 |
|
|
|
c0f891 |
diff --git a/Grow.c b/Grow.c
|
|
|
c0f891 |
index 868bdc3a..0f07a894 100644
|
|
|
c0f891 |
--- a/Grow.c
|
|
|
c0f891 |
+++ b/Grow.c
|
|
|
c0f891 |
@@ -1773,6 +1773,65 @@ static int reshape_container(char *container, char *devname,
|
|
|
c0f891 |
char *backup_file, int verbose,
|
|
|
c0f891 |
int forked, int restart, int freeze_reshape);
|
|
|
c0f891 |
|
|
|
c0f891 |
+/**
|
|
|
c0f891 |
+ * prepare_external_reshape() - prepares update on external metadata if supported.
|
|
|
c0f891 |
+ * @devname: Device name.
|
|
|
c0f891 |
+ * @subarray: Subarray.
|
|
|
c0f891 |
+ * @st: Supertype.
|
|
|
c0f891 |
+ * @container: Container.
|
|
|
c0f891 |
+ * @cfd: Container file descriptor.
|
|
|
c0f891 |
+ *
|
|
|
c0f891 |
+ * Function checks that the requested reshape is supported on external metadata,
|
|
|
c0f891 |
+ * and performs an initial check that the container holds the pre-requisite
|
|
|
c0f891 |
+ * spare devices (mdmon owns final validation).
|
|
|
c0f891 |
+ *
|
|
|
c0f891 |
+ * Return: 0 on success, else 1
|
|
|
c0f891 |
+ */
|
|
|
c0f891 |
+static int prepare_external_reshape(char *devname, char *subarray,
|
|
|
c0f891 |
+ struct supertype *st, char *container,
|
|
|
c0f891 |
+ const int cfd)
|
|
|
c0f891 |
+{
|
|
|
c0f891 |
+ struct mdinfo *cc = NULL;
|
|
|
c0f891 |
+ struct mdinfo *content = NULL;
|
|
|
c0f891 |
+
|
|
|
c0f891 |
+ if (st->ss->load_container(st, cfd, NULL)) {
|
|
|
c0f891 |
+ pr_err("Cannot read superblock for %s\n", devname);
|
|
|
c0f891 |
+ return 1;
|
|
|
c0f891 |
+ }
|
|
|
c0f891 |
+
|
|
|
c0f891 |
+ if (!st->ss->container_content)
|
|
|
c0f891 |
+ return 1;
|
|
|
c0f891 |
+
|
|
|
c0f891 |
+ cc = st->ss->container_content(st, subarray);
|
|
|
c0f891 |
+ for (content = cc; content ; content = content->next) {
|
|
|
c0f891 |
+ /*
|
|
|
c0f891 |
+ * check if reshape is allowed based on metadata
|
|
|
c0f891 |
+ * indications stored in content.array.status
|
|
|
c0f891 |
+ */
|
|
|
c0f891 |
+ if (is_bit_set(&content->array.state, MD_SB_BLOCK_VOLUME) ||
|
|
|
c0f891 |
+ is_bit_set(&content->array.state, MD_SB_BLOCK_CONTAINER_RESHAPE)) {
|
|
|
c0f891 |
+ pr_err("Cannot reshape arrays in container with unsupported metadata: %s(%s)\n",
|
|
|
c0f891 |
+ devname, container);
|
|
|
c0f891 |
+ goto error;
|
|
|
c0f891 |
+ }
|
|
|
c0f891 |
+ if (content->consistency_policy == CONSISTENCY_POLICY_PPL) {
|
|
|
c0f891 |
+ pr_err("Operation not supported when ppl consistency policy is enabled\n");
|
|
|
c0f891 |
+ goto error;
|
|
|
c0f891 |
+ }
|
|
|
c0f891 |
+ if (content->consistency_policy == CONSISTENCY_POLICY_BITMAP) {
|
|
|
c0f891 |
+ pr_err("Operation not supported when write-intent bitmap consistency policy is enabled\n");
|
|
|
c0f891 |
+ goto error;
|
|
|
c0f891 |
+ }
|
|
|
c0f891 |
+ }
|
|
|
c0f891 |
+ sysfs_free(cc);
|
|
|
c0f891 |
+ if (mdmon_running(container))
|
|
|
c0f891 |
+ st->update_tail = &st->updates;
|
|
|
c0f891 |
+ return 0;
|
|
|
c0f891 |
+error:
|
|
|
c0f891 |
+ sysfs_free(cc);
|
|
|
c0f891 |
+ return 1;
|
|
|
c0f891 |
+}
|
|
|
c0f891 |
+
|
|
|
c0f891 |
int Grow_reshape(char *devname, int fd,
|
|
|
c0f891 |
struct mddev_dev *devlist,
|
|
|
c0f891 |
struct context *c, struct shape *s)
|
|
|
c0f891 |
@@ -1799,7 +1858,7 @@ int Grow_reshape(char *devname, int fd,
|
|
|
c0f891 |
struct supertype *st;
|
|
|
c0f891 |
char *subarray = NULL;
|
|
|
c0f891 |
|
|
|
c0f891 |
- int frozen;
|
|
|
c0f891 |
+ int frozen = 0;
|
|
|
c0f891 |
int changed = 0;
|
|
|
c0f891 |
char *container = NULL;
|
|
|
c0f891 |
int cfd = -1;
|
|
|
c0f891 |
@@ -1808,7 +1867,7 @@ int Grow_reshape(char *devname, int fd,
|
|
|
c0f891 |
int added_disks;
|
|
|
c0f891 |
|
|
|
c0f891 |
struct mdinfo info;
|
|
|
c0f891 |
- struct mdinfo *sra;
|
|
|
c0f891 |
+ struct mdinfo *sra = NULL;
|
|
|
c0f891 |
|
|
|
c0f891 |
if (md_get_array_info(fd, &array) < 0) {
|
|
|
c0f891 |
pr_err("%s is not an active md array - aborting\n",
|
|
|
c0f891 |
@@ -1865,13 +1924,7 @@ int Grow_reshape(char *devname, int fd,
|
|
|
c0f891 |
}
|
|
|
c0f891 |
}
|
|
|
c0f891 |
|
|
|
c0f891 |
- /* in the external case we need to check that the requested reshape is
|
|
|
c0f891 |
- * supported, and perform an initial check that the container holds the
|
|
|
c0f891 |
- * pre-requisite spare devices (mdmon owns final validation)
|
|
|
c0f891 |
- */
|
|
|
c0f891 |
if (st->ss->external) {
|
|
|
c0f891 |
- int retval;
|
|
|
c0f891 |
-
|
|
|
c0f891 |
if (subarray) {
|
|
|
c0f891 |
container = st->container_devnm;
|
|
|
c0f891 |
cfd = open_dev_excl(st->container_devnm);
|
|
|
c0f891 |
@@ -1887,13 +1940,12 @@ int Grow_reshape(char *devname, int fd,
|
|
|
c0f891 |
return 1;
|
|
|
c0f891 |
}
|
|
|
c0f891 |
|
|
|
c0f891 |
- retval = st->ss->load_container(st, cfd, NULL);
|
|
|
c0f891 |
-
|
|
|
c0f891 |
- if (retval) {
|
|
|
c0f891 |
- pr_err("Cannot read superblock for %s\n", devname);
|
|
|
c0f891 |
- close(cfd);
|
|
|
c0f891 |
+ rv = prepare_external_reshape(devname, subarray, st,
|
|
|
c0f891 |
+ container, cfd);
|
|
|
c0f891 |
+ if (rv > 0) {
|
|
|
c0f891 |
free(subarray);
|
|
|
c0f891 |
- return 1;
|
|
|
c0f891 |
+ close(cfd);
|
|
|
c0f891 |
+ goto release;
|
|
|
c0f891 |
}
|
|
|
c0f891 |
|
|
|
c0f891 |
if (s->raiddisks && subarray) {
|
|
|
c0f891 |
@@ -1902,51 +1954,6 @@ int Grow_reshape(char *devname, int fd,
|
|
|
c0f891 |
free(subarray);
|
|
|
c0f891 |
return 1;
|
|
|
c0f891 |
}
|
|
|
c0f891 |
-
|
|
|
c0f891 |
- /* check if operation is supported for metadata handler */
|
|
|
c0f891 |
- if (st->ss->container_content) {
|
|
|
c0f891 |
- struct mdinfo *cc = NULL;
|
|
|
c0f891 |
- struct mdinfo *content = NULL;
|
|
|
c0f891 |
-
|
|
|
c0f891 |
- cc = st->ss->container_content(st, subarray);
|
|
|
c0f891 |
- for (content = cc; content ; content = content->next) {
|
|
|
c0f891 |
- int allow_reshape = 1;
|
|
|
c0f891 |
-
|
|
|
c0f891 |
- /* check if reshape is allowed based on metadata
|
|
|
c0f891 |
- * indications stored in content.array.status
|
|
|
c0f891 |
- */
|
|
|
c0f891 |
- if (content->array.state &
|
|
|
c0f891 |
- (1 << MD_SB_BLOCK_VOLUME))
|
|
|
c0f891 |
- allow_reshape = 0;
|
|
|
c0f891 |
- if (content->array.state &
|
|
|
c0f891 |
- (1 << MD_SB_BLOCK_CONTAINER_RESHAPE))
|
|
|
c0f891 |
- allow_reshape = 0;
|
|
|
c0f891 |
- if (!allow_reshape) {
|
|
|
c0f891 |
- pr_err("cannot reshape arrays in container with unsupported metadata: %s(%s)\n",
|
|
|
c0f891 |
- devname, container);
|
|
|
c0f891 |
- sysfs_free(cc);
|
|
|
c0f891 |
- free(subarray);
|
|
|
c0f891 |
- return 1;
|
|
|
c0f891 |
- }
|
|
|
c0f891 |
- if (content->consistency_policy ==
|
|
|
c0f891 |
- CONSISTENCY_POLICY_PPL) {
|
|
|
c0f891 |
- pr_err("Operation not supported when ppl consistency policy is enabled\n");
|
|
|
c0f891 |
- sysfs_free(cc);
|
|
|
c0f891 |
- free(subarray);
|
|
|
c0f891 |
- return 1;
|
|
|
c0f891 |
- }
|
|
|
c0f891 |
- if (content->consistency_policy ==
|
|
|
c0f891 |
- CONSISTENCY_POLICY_BITMAP) {
|
|
|
c0f891 |
- pr_err("Operation not supported when write-intent bitmap is enabled\n");
|
|
|
c0f891 |
- sysfs_free(cc);
|
|
|
c0f891 |
- free(subarray);
|
|
|
c0f891 |
- return 1;
|
|
|
c0f891 |
- }
|
|
|
c0f891 |
- }
|
|
|
c0f891 |
- sysfs_free(cc);
|
|
|
c0f891 |
- }
|
|
|
c0f891 |
- if (mdmon_running(container))
|
|
|
c0f891 |
- st->update_tail = &st->updates;
|
|
|
c0f891 |
}
|
|
|
c0f891 |
|
|
|
c0f891 |
added_disks = 0;
|
|
|
c0f891 |
diff --git a/mdadm.h b/mdadm.h
|
|
|
c0f891 |
index 8208b81e..941a5f38 100644
|
|
|
c0f891 |
--- a/mdadm.h
|
|
|
c0f891 |
+++ b/mdadm.h
|
|
|
c0f891 |
@@ -1539,6 +1539,7 @@ extern int stat_is_blkdev(char *devname, dev_t *rdev);
|
|
|
c0f891 |
extern bool is_dev_alive(char *path);
|
|
|
c0f891 |
extern int get_mdp_major(void);
|
|
|
c0f891 |
extern int get_maj_min(char *dev, int *major, int *minor);
|
|
|
c0f891 |
+extern bool is_bit_set(int *val, unsigned char index);
|
|
|
c0f891 |
extern int dev_open(char *dev, int flags);
|
|
|
c0f891 |
extern int open_dev(char *devnm);
|
|
|
c0f891 |
extern void reopen_mddev(int mdfd);
|
|
|
c0f891 |
diff --git a/util.c b/util.c
|
|
|
c0f891 |
index ca48d976..26ffdcea 100644
|
|
|
c0f891 |
--- a/util.c
|
|
|
c0f891 |
+++ b/util.c
|
|
|
c0f891 |
@@ -1027,6 +1027,20 @@ int get_maj_min(char *dev, int *major, int *minor)
|
|
|
c0f891 |
*e == 0);
|
|
|
c0f891 |
}
|
|
|
c0f891 |
|
|
|
c0f891 |
+/**
|
|
|
c0f891 |
+ * is_bit_set() - get bit value by index.
|
|
|
c0f891 |
+ * @val: value.
|
|
|
c0f891 |
+ * @index: index of the bit (LSB numbering).
|
|
|
c0f891 |
+ *
|
|
|
c0f891 |
+ * Return: bit value.
|
|
|
c0f891 |
+ */
|
|
|
c0f891 |
+bool is_bit_set(int *val, unsigned char index)
|
|
|
c0f891 |
+{
|
|
|
c0f891 |
+ if ((*val) & (1 << index))
|
|
|
c0f891 |
+ return true;
|
|
|
c0f891 |
+ return false;
|
|
|
c0f891 |
+}
|
|
|
c0f891 |
+
|
|
|
c0f891 |
int dev_open(char *dev, int flags)
|
|
|
c0f891 |
{
|
|
|
c0f891 |
/* like 'open', but if 'dev' matches %d:%d, create a temp
|
|
|
c0f891 |
--
|
|
|
c0f891 |
2.31.1
|
|
|
c0f891 |
|