From d1447022d4a273a6bd9eeb403f9711561c9ad8f6 Mon Sep 17 00:00:00 2001 From: Mariusz Tkaczyk Date: Fri, 3 Jul 2026 09:30:28 +0200 Subject: [PATCH] mdadm: Add define for magic +9 in version string To have it better understandable add definitions for that. Definition is placed in md_common.h because it is corresponding to both mdstat and sysfs implementations. Probably more shared properties will be defined in the future. The MD_EXTERNAL_PREFIX_LEN and MD_VERSION_BLOCKED_IDX are the same but are defined for different purpose. One is specyfing size of string but the second is specyfing index in the array. Also, replaces magic "external" used in code. No functional changes intended. Signed-off-by: Mariusz Tkaczyk --- Assemble.c | 2 +- Detail.c | 8 ++++---- Grow.c | 2 +- Manage.c | 15 ++++++++------- md_common.h | 29 +++++++++++++++++++++++++++++ mdmonitor.c | 9 +++++---- mdstat.c | 10 +++++----- mdstat.h | 5 ++++- msg.c | 4 ++-- super-intel.c | 7 ++++--- sysfs.c | 12 +++++++----- util.c | 3 ++- 12 files changed, 72 insertions(+), 34 deletions(-) create mode 100644 md_common.h diff --git a/Assemble.c b/Assemble.c index 7594e8f7..fa5ad07e 100644 --- a/Assemble.c +++ b/Assemble.c @@ -121,7 +121,7 @@ static int is_member_busy(char *metadata_version) continue; /* Skip first char - it can be '/' or '-' */ - if (strcmp(&ent->metadata_version[10], metadata_version + 1) == 0) { + if (strcmp(&ent->metadata_version[MD_VER_EXT_LEN + 1], metadata_version + 1) == 0) { busy = 1; break; } diff --git a/Detail.c b/Detail.c index 5d3d5c56..d9924b03 100644 --- a/Detail.c +++ b/Detail.c @@ -684,10 +684,10 @@ int Detail(char *dev, struct context *c) de->d_name); if (load_sys(path, vbuf, sizeof(vbuf)) < 0) continue; - if (strncmp(vbuf, "external:", 9) || - !is_subarray(vbuf + 9) || - strncmp(vbuf + 10, sra->sys_name, nlen) || - vbuf[10 + nlen] != '/') + if (strncmp(vbuf, MD_VER_EXT, MD_VER_EXT_LEN) || + !is_subarray(vbuf + MD_VER_EXT_LEN) || + strncmp(vbuf + MD_VER_EXT_LEN + 1, sra->sys_name, nlen) || + vbuf[MD_VER_EXT_LEN + 1 + nlen] != '/') continue; devid = devnm2devid(de->d_name); printf(" %s", diff --git a/Grow.c b/Grow.c index 8bcb7d4d..f28abfee 100644 --- a/Grow.c +++ b/Grow.c @@ -697,7 +697,7 @@ static int check_idle(struct supertype *st) if (!is_container_member(e, container)) continue; /* frozen array is not idle*/ - if (e->percent >= 0 || e->metadata_version[9] == '-') { + if (e->percent >= 0 || e->metadata_version[MD_VER_BLOCKED_IDX] == '-') { is_idle = 0; break; } diff --git a/Manage.c b/Manage.c index 18ebe67a..539c05e8 100644 --- a/Manage.c +++ b/Manage.c @@ -49,12 +49,12 @@ int Manage_ro(char *devname, int fd, int readonly) mdi->array.major_version == -1 && is_subarray(mdi->text_version)) { char vers[64]; - strcpy(vers, "external:"); + strcpy(vers, MD_VER_EXT); strcat(vers, mdi->text_version); if (readonly > 0) { int rv; /* We set readonly ourselves. */ - vers[9] = '-'; + vers[MD_VER_BLOCKED_IDX] = '-'; sysfs_set_str(mdi, NULL, "metadata_version", vers); close_fd(&fd); @@ -64,7 +64,7 @@ int Manage_ro(char *devname, int fd, int readonly) pr_err("failed to set readonly for %s: %s\n", devname, strerror(errno)); - vers[9] = mdi->text_version[0]; + vers[MD_VER_BLOCKED_IDX] = mdi->text_version[0]; sysfs_set_str(mdi, NULL, "metadata_version", vers); rv = 1; goto out; @@ -72,13 +72,13 @@ int Manage_ro(char *devname, int fd, int readonly) } else { char *cp; /* We cannot set read/write - must signal mdmon */ - vers[9] = '/'; + vers[MD_VER_BLOCKED_IDX] = '/'; sysfs_set_str(mdi, NULL, "metadata_version", vers); - cp = strchr(vers+10, '/'); + cp = strchr(vers + MD_VER_BLOCKED_IDX + 1, '/'); if (cp) *cp = 0; - ping_monitor(vers+10); + ping_monitor(vers + MD_VER_BLOCKED_IDX + 1); if (mdi->array.level <= 0) sysfs_set_str(mdi, NULL, "array_state", "active"); } @@ -279,7 +279,8 @@ int Manage_stop(char *devname, int fd, int verbose, int will_retry) mds = mdstat_read(0, 0); for (m = mds; m; m = m->next) if (is_mdstat_ent_external(m) && - metadata_container_matches(m->metadata_version + 9, devnm)) { + metadata_container_matches(m->metadata_version + MD_VER_EXT_LEN, + devnm)) { if (verbose >= 0) pr_err("Cannot stop container %s: member %s still active\n", devname, m->devnm); diff --git a/md_common.h b/md_common.h new file mode 100644 index 00000000..7e0c5d7d --- /dev/null +++ b/md_common.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +/* + * md_common - constants shared between md driver abstractions. + */ + +#ifndef MD_COMMON_H +#define MD_COMMON_H + +/* + * Prefix used by the md driver version to mark an externally-managed array or + * container. The full form is: + * + * "external:" [/-] containername [/subarray] + * + * The '/' or '-' separator distinguishes normal read-write arrays from those + * that mdmon must not reconfigure (read-only, reshaping, etc.). + */ +#define MD_EXT "external" /* The external keyword used in various contexts */ + +#define MD_VER_EXT "external:" /* The "external:" version const prefix */ +#define MD_VER_EXT_LEN (sizeof(MD_VER_EXT) - 1) /* Length of external prefix */ + +/* Index of the character that blocks the version. + * It is the one after the prefix so the array index is MD_VER_EXT_LEN + */ +#define MD_VER_BLOCKED_IDX (MD_VER_EXT_LEN) + +#endif diff --git a/mdmonitor.c b/mdmonitor.c index d26d80de..b06fa46a 100644 --- a/mdmonitor.c +++ b/mdmonitor.c @@ -893,7 +893,8 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, if (is_mdstat_ent_subarray(mse)) { char *sl; - snprintf(st->parent_devnm, MD_NAME_MAX, "%s", mse->metadata_version + 10); + snprintf(st->parent_devnm, MD_NAME_MAX, "%s", + mse->metadata_version + MD_VER_EXT_LEN + 1); sl = strchr(st->parent_devnm, '/'); if (sl) *sl = 0; @@ -1006,7 +1007,7 @@ static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist) char *sl; snprintf(st->parent_devnm, MD_NAME_MAX, "%s", - mse->metadata_version + 10); + mse->metadata_version + MD_VER_EXT_LEN + 1); sl = strchr(st->parent_devnm, '/'); if (sl) *sl = 0; @@ -1307,8 +1308,8 @@ int Wait(char *dev) } if (!e || e->percent == RESYNC_NONE) { if (e && is_mdstat_ent_external(e)) { - if (is_subarray(&e->metadata_version[9])) - ping_monitor(&e->metadata_version[9]); + if (is_subarray(&e->metadata_version[MD_VER_EXT_LEN])) + ping_monitor(&e->metadata_version[MD_VER_EXT_LEN]); else ping_monitor(devnm); } diff --git a/mdstat.c b/mdstat.c index 58376558..f7f89ea8 100644 --- a/mdstat.c +++ b/mdstat.c @@ -156,14 +156,14 @@ bool is_mdstat_ent_external(struct mdstat_ent *ent) if (!ent->metadata_version) return false; - if (strncmp(ent->metadata_version, "external:", 9) == 0) + if (strncmp(ent->metadata_version, MD_VER_EXT, MD_VER_EXT_LEN) == 0) return true; return false; } bool is_mdstat_ent_subarray(struct mdstat_ent *ent) { - if (is_mdstat_ent_external(ent) && is_subarray(ent->metadata_version + 9)) + if (is_mdstat_ent_external(ent) && is_subarray(ent->metadata_version + MD_VER_EXT_LEN)) return true; return false; } @@ -171,7 +171,7 @@ bool is_mdstat_ent_subarray(struct mdstat_ent *ent) bool is_container_member(struct mdstat_ent *mdstat, char *container) { if (is_mdstat_ent_external(mdstat) && - metadata_container_matches(mdstat->metadata_version + 9, container)) + metadata_container_matches(mdstat->metadata_version + MD_VER_EXT_LEN, container)) return true; return false; @@ -509,9 +509,9 @@ struct mdstat_ent *mdstat_by_subdev(char *subdev, char *container) if (!is_mdstat_ent_external(ent)) continue; - if (!metadata_container_matches(ent->metadata_version + 9, container)) + if (!metadata_container_matches(ent->metadata_version + MD_VER_EXT_LEN, container)) continue; - if (!metadata_subdev_matches(ent->metadata_version + 9, subdev)) + if (!metadata_subdev_matches(ent->metadata_version + MD_VER_EXT_LEN, subdev)) continue; break; diff --git a/mdstat.h b/mdstat.h index 76827c5c..227a68b2 100644 --- a/mdstat.h +++ b/mdstat.h @@ -7,6 +7,8 @@ #include #include +#include "md_common.h" + struct mdstat_ent { char devnm[32]; @@ -46,7 +48,8 @@ int is_subarray_active(char *subarray, char *container); static inline char *to_subarray(struct mdstat_ent *ent, char *container) { - return &ent->metadata_version[10+strlen(container)+1]; + /* Skip: "external:" prefix, [/-] separator, container name, '/'. */ + return &ent->metadata_version[MD_VER_EXT_LEN + 1 + strlen(container) + 1]; } #endif diff --git a/msg.c b/msg.c index 313cb7c4..19e59186 100644 --- a/msg.c +++ b/msg.c @@ -252,7 +252,7 @@ int unblock_subarray(struct mdinfo *sra, const int unfreeze) int rc = 0; if (sra) { - sprintf(buf, "external:%s\n", sra->text_version); + sprintf(buf, MD_VER_EXT "%s\n", sra->text_version); buf[9] = '/'; } else buf[9] = '-'; @@ -271,7 +271,7 @@ int block_subarray(struct mdinfo *sra) char buf[64]; int rc = 0; - sprintf(buf, "external:%s\n", sra->text_version); + sprintf(buf, MD_VER_EXT "%s\n", sra->text_version); buf[9] = '-'; if (sysfs_set_str(sra, NULL, "metadata_version", buf)) rc = -1; diff --git a/super-intel.c b/super-intel.c index 5e44dc46..dd268d23 100644 --- a/super-intel.c +++ b/super-intel.c @@ -7083,8 +7083,9 @@ active_arrays_by_format(char *name, char* hba, struct md_list **devlist, int found; for (memb = mdstat ; memb ; memb = memb->next) { - if (is_mdstat_ent_external(memb) && !is_subarray(memb->metadata_version + 9) && - strcmp(&memb->metadata_version[9], name) == 0 && memb->members) { + if (is_mdstat_ent_external(memb) && + !is_subarray(memb->metadata_version + MD_VER_EXT_LEN) && + strcmp(&memb->metadata_version[MD_VER_EXT_LEN], name) == 0 && memb->members) { struct dev_member *dev = memb->members; int fd = -1; @@ -13191,7 +13192,7 @@ static int set_bitmap_sysfs(struct mdinfo *info, unsigned long long chunksize, * related to the device's first lba (in opposition to the "internal" case * when this value is related to the beginning of the superblock). */ - if (sysfs_set_str(info, NULL, "bitmap/metadata", "external")) { + if (sysfs_set_str(info, NULL, "bitmap/metadata", MD_EXT)) { dprintf("failed to set bitmap/metadata\n"); return -1; } diff --git a/sysfs.c b/sysfs.c index 7589e944..96bfd5a7 100644 --- a/sysfs.c +++ b/sysfs.c @@ -24,6 +24,7 @@ */ #include "mdadm.h" +#include "md_common.h" #include "dlink.h" #include "xmalloc.h" @@ -293,10 +294,10 @@ struct mdinfo *sysfs_read(int fd, char *devnm, unsigned long options) sra->array.major_version = sra->array.minor_version = -1; strcpy(sra->text_version, ""); - } else if (strncmp(buf, "external:", 9) == 0) { + } else if (strncmp(buf, MD_VER_EXT, MD_VER_EXT_LEN) == 0) { sra->array.major_version = -1; sra->array.minor_version = -2; - strcpy(sra->text_version, buf+9); + strcpy(sra->text_version, buf + MD_VER_EXT_LEN); sra->text_version[sizeof(sra->text_version) - 1] = '\0'; } else { sscanf(buf, "%d.%d", @@ -809,7 +810,7 @@ int sysfs_set_array(struct mdinfo *info) info->array.minor_version == -2) { char buf[SYSFS_MAX_BUF_SIZE]; - strcat(strcpy(ver, "external:"), info->text_version); + strcat(strcpy(ver, MD_VER_EXT), info->text_version); /* meta version might already be set if we are setting * new geometry for a reshape. In that case we don't @@ -819,8 +820,9 @@ int sysfs_set_array(struct mdinfo *info) */ if (sysfs_get_str(info, NULL, "metadata_version", buf, sizeof(buf)) > 0) - if (strlen(buf) >= 9 && buf[9] == '-') - ver[9] = '-'; + if (strlen(buf) >= MD_VER_BLOCKED_IDX && + buf[MD_VER_BLOCKED_IDX] == '-') + ver[MD_VER_BLOCKED_IDX] = '-'; if (sysfs_set_str(info, NULL, "metadata_version", ver) < 0) { pr_err("This kernel does not support external metadata.\n"); diff --git a/util.c b/util.c index 4e05a4cf..3bd4829a 100644 --- a/util.c +++ b/util.c @@ -23,6 +23,7 @@ */ #include "mdadm.h" +#include "md_common.h" #include "md_p.h" #include "xmalloc.h" @@ -1559,7 +1560,7 @@ int open_container(int fd) if (n <= 0 || (unsigned)n >= sizeof(buf)) continue; buf[n] = 0; - if (strncmp(buf, "external", 8) != 0 || + if (strncmp(buf, MD_EXT, strlen(MD_EXT)) != 0 || n < 10 || buf[9] == '/') continue; -- 2.47.3