summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukasz Florczak <lukasz.florczak@linux.intel.com>2022-06-15 14:28:39 +0200
committerJes Sorensen <jsorensen@fb.com>2022-06-24 14:09:38 -0400
commit70f1ff4291b0388adca1f4c91918ce1175e8b360 (patch)
treec15f74eefd9c8477b7bf51b62068a0da90cae212
parent9a7df595bbe360132cb37c8b39aa1fd9ac24b43f (diff)
downloadmdadm-70f1ff4291b0388adca1f4c91918ce1175e8b360.tar.gz
mdadm: block update=ppl for non raid456 levels
Option ppl should be used only for raid levels 4, 5 and 6. Cancel update for other levels. Applied globally for imsm and ddf format. Additionally introduce is_level456() helper function. Signed-off-by: Lukasz Florczak <lukasz.florczak@linux.intel.com> Signed-off-by: Jes Sorensen <jsorensen@fb.com>
-rw-r--r--Assemble.c11
-rw-r--r--Grow.c2
-rw-r--r--Manage.c14
-rw-r--r--mdadm.h11
-rw-r--r--super0.c2
-rw-r--r--super1.c3
6 files changed, 31 insertions, 12 deletions
diff --git a/Assemble.c b/Assemble.c
index 4b21356..6df6bfb 100644
--- a/Assemble.c
+++ b/Assemble.c
@@ -906,8 +906,7 @@ static int force_array(struct mdinfo *content,
* devices in RAID4 or last devices in RAID4/5/6.
*/
delta = devices[j].i.delta_disks;
- if (devices[j].i.array.level >= 4 &&
- devices[j].i.array.level <= 6 &&
+ if (is_level456(devices[j].i.array.level) &&
i/2 >= content->array.raid_disks - delta)
/* OK */;
else if (devices[j].i.array.level == 4 &&
@@ -1226,8 +1225,7 @@ static int start_array(int mdfd,
fprintf(stderr, ".\n");
}
if (content->reshape_active &&
- content->array.level >= 4 &&
- content->array.level <= 6) {
+ is_level456(content->array.level)) {
/* might need to increase the size
* of the stripe cache - default is 256
*/
@@ -1974,7 +1972,8 @@ int assemble_container_content(struct supertype *st, int mdfd,
int start_reshape;
char *avail;
int err;
- int is_raid456, is_clean, all_disks;
+ int is_clean, all_disks;
+ bool is_raid456;
if (sysfs_init(content, mdfd, NULL)) {
pr_err("Unable to initialize sysfs\n");
@@ -2107,7 +2106,7 @@ int assemble_container_content(struct supertype *st, int mdfd,
content->array.state |= 1;
}
- is_raid456 = (content->array.level >= 4 && content->array.level <= 6);
+ is_raid456 = is_level456(content->array.level);
is_clean = content->array.state & 1;
if (enough(content->array.level, content->array.raid_disks,
diff --git a/Grow.c b/Grow.c
index f6efbc4..8c520d4 100644
--- a/Grow.c
+++ b/Grow.c
@@ -2944,7 +2944,7 @@ static int impose_level(int fd, int level, char *devname, int verbose)
}
md_get_array_info(fd, &array);
- if (level == 0 && (array.level >= 4 && array.level <= 6)) {
+ if (level == 0 && is_level456(array.level)) {
/* To convert to RAID0 we need to fail and
* remove any non-data devices. */
int found = 0;
diff --git a/Manage.c b/Manage.c
index f789e0c..e5e6abe 100644
--- a/Manage.c
+++ b/Manage.c
@@ -307,7 +307,7 @@ int Manage_stop(char *devname, int fd, int verbose, int will_retry)
* - unfreeze reshape
* - wait on 'sync_completed' for that point to be reached.
*/
- if (mdi && (mdi->array.level >= 4 && mdi->array.level <= 6) &&
+ if (mdi && is_level456(mdi->array.level) &&
sysfs_attribute_available(mdi, NULL, "sync_action") &&
sysfs_attribute_available(mdi, NULL, "reshape_direction") &&
sysfs_get_str(mdi, NULL, "sync_action", buf, 20) > 0 &&
@@ -1679,6 +1679,7 @@ int Update_subarray(char *dev, char *subarray, char *update, struct mddev_ident
{
struct supertype supertype, *st = &supertype;
int fd, rv = 2;
+ struct mdinfo *info = NULL;
memset(st, 0, sizeof(*st));
@@ -1696,6 +1697,13 @@ int Update_subarray(char *dev, char *subarray, char *update, struct mddev_ident
if (mdmon_running(st->devnm))
st->update_tail = &st->updates;
+ info = st->ss->container_content(st, subarray);
+
+ if (strncmp(update, "ppl", 3) == 0 && !is_level456(info->array.level)) {
+ pr_err("RWH policy ppl is supported only for raid4, raid5 and raid6.\n");
+ goto free_super;
+ }
+
rv = st->ss->update_subarray(st, subarray, update, ident);
if (rv) {
@@ -1711,7 +1719,9 @@ int Update_subarray(char *dev, char *subarray, char *update, struct mddev_ident
pr_err("Updated subarray-%s name from %s, UUIDs may have changed\n",
subarray, dev);
- free_super:
+free_super:
+ if (info)
+ free(info);
st->ss->free_super(st);
close(fd);
diff --git a/mdadm.h b/mdadm.h
index d53df16..974415b 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -797,6 +797,17 @@ static inline int is_fd_valid(int fd)
}
/**
+ * is_level456() - check whether given level is between inclusive 4 and 6.
+ * @level: level to check.
+ *
+ * Return: true if condition is met, false otherwise
+ */
+static inline bool is_level456(int level)
+{
+ return (level >= 4 && level <= 6);
+}
+
+/**
* close_fd() - verify, close and unset file descriptor.
* @fd: pointer to file descriptor.
*
diff --git a/super0.c b/super0.c
index 61c9ec1..37f595e 100644
--- a/super0.c
+++ b/super0.c
@@ -683,7 +683,7 @@ static int update_super0(struct supertype *st, struct mdinfo *info,
int parity = sb->level == 6 ? 2 : 1;
rv = 0;
- if (sb->level >= 4 && sb->level <= 6 &&
+ if (is_level456(sb->level) &&
sb->reshape_position % (
sb->new_chunk/512 *
(sb->raid_disks - sb->delta_disks - parity))) {
diff --git a/super1.c b/super1.c
index 3a0c69f..71af860 100644
--- a/super1.c
+++ b/super1.c
@@ -1530,8 +1530,7 @@ static int update_super1(struct supertype *st, struct mdinfo *info,
* So we reject a revert-reshape unless the
* alignment is good.
*/
- if (__le32_to_cpu(sb->level) >= 4 &&
- __le32_to_cpu(sb->level) <= 6) {
+ if (is_level456(__le32_to_cpu(sb->level))) {
reshape_sectors =
__le64_to_cpu(sb->reshape_position);
reshape_chunk = __le32_to_cpu(sb->new_chunk);