Re: [PATCH v2] md: Allow setting persistent superblock version for md= command line

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 2025-08-25 13:58, Paul Menzel wrote:
Dear Jeremias,


Thank you very much for your patch, and welcome to the Linux kernel community!

Am 25.08.25 um 13:34 schrieb Jeremias Stotter:
This allows for setting a superblock version on the kernel command line to be able to assemble version >=1.0 arrays. It can optionally be set like this:

Could you start by describing the problem. I am using several systems, where arrays with version ≥ can be assembled. What am I missing?


md=vX.X,...

This will set the version of the array before assembly so it can be assembled
correctly.

Also updated docs accordingly.

v2: Use pr_warn instead of printk

Signed-off-by: Jeremias Stotter <jeremias@xxxxxxxx>
---
  Documentation/admin-guide/md.rst |  8 +++++
drivers/md/md-autodetect.c | 61 ++++++++++++++++++++++++++++++--
  2 files changed, 67 insertions(+), 2 deletions(-)

diff --git a/Documentation/admin-guide/md.rst b/Documentation/admin-guide/md.rst
index 4ff2cc291d18..7b904d73ace0 100644
--- a/Documentation/admin-guide/md.rst
+++ b/Documentation/admin-guide/md.rst
@@ -23,6 +23,14 @@ or, to assemble a partitionable array::
      md=d<md device no.>,dev0,dev1,...,devn
+if you are using superblock versions greater than 0, use the following::
+
+  md=v<superblock version no.>,<md device no.>,dev0,dev1,...,devn
+
+for example, for a raid array with superblock version 1.2 it could look like this::
+
+  md=v1.2,0,/dev/sda1,/dev/sdb1
+

Why not keep the pattern of the other options to specify <md device no.> first?

  ``md device no.``
  +++++++++++++++++
  diff --git a/drivers/md/md-autodetect.c b/drivers/md/md-autodetect.c
index 4b80165afd23..4c4775c33963 100644
--- a/drivers/md/md-autodetect.c
+++ b/drivers/md/md-autodetect.c
@@ -32,6 +32,8 @@ static struct md_setup_args {
  	int partitioned;
  	int level;
  	int chunk;
+	int major_version;
+	int minor_version;
  	char *device_names;
  } md_setup_args[256] __initdata;
  @@ -56,6 +58,9 @@ static int md_setup_ents __initdata;
   * 2001-06-03: Dave Cinege <dcinege@xxxxxxxxxxxxx>
* Shifted name_to_kdev_t() and related operations to md_set_drive()
   *		for later execution. Rewrote section to make devfs compatible.
+ * 2025-08-24: Jeremias Stotter <jeremias@xxxxxxxx>
+ *              Allow setting of the superblock version:
+ *              md=vX.X,...

I believe since git (and BitKeeper before) being used, these headers are not updated any more.

   */
  static int __init md_setup(char *str)
  {
@@ -63,6 +68,49 @@ static int __init md_setup(char *str)
  	char *pername = "";
  	char *str1;
  	int ent;
+	int major_i = 0, minor_i = 0;
+
+	if (*str == 'v') {
+		char *version = ++str;
+		char *version_end = strchr(str, ',');
+
+		if (!version_end) {
+ pr_warn("md: Version (%s) has been specified wrong, no ',' found, use like this: md=vX.X,...\n",

s/wrong/incorrectly/?

Or wrong*ly*. Same below.

+				version);
+			return 0;
+		}
+		*version_end = '\0';
+		str = version_end + 1;
+
+		char *separator = strchr(version, '.');
+
+		if (!separator) {
+ pr_warn("md: Version (%s) has been specified wrong, no '.' to separate major and minor version found, use like this: md=vX.X,...\n",
+				version);
+			return 0;
+		}
+		*separator = '\0';
+		char *minor_s = separator + 1;
+
+		int ret = kstrtoint(version, 10, &major_i);
+
+		if (ret != 0) {
+ pr_warn("md: Version has been specified wrong, couldn't convert major '%s' to number, use like this: md=vX.X,...\n",
+				version);
+			return 0;
+		}
+		if (major_i != 0 && major_i != 1) {
+			pr_warn("md: Major version %d is not valid, use 0 or 1\n",
+				major_i);
+			return 0;
+		}
+		ret = kstrtoint(minor_s, 10, &minor_i);
+		if (ret != 0) {
+ pr_warn("md: Version has been specified wrong, couldn't convert minor '%s' to number, use like this: md=vX.X,...\n",
+				minor_s);
+			return 0;
+		}
+	}
    	if (*str == 'd') {
  		partitioned = 1;
@@ -116,6 +164,8 @@ static int __init md_setup(char *str)
  	md_setup_args[ent].device_names = str;
  	md_setup_args[ent].partitioned = partitioned;
  	md_setup_args[ent].minor = minor;
+	md_setup_args[ent].minor_version = minor_i;
+	md_setup_args[ent].major_version = major_i;
    	return 1;
  }
@@ -200,6 +250,9 @@ static void __init md_setup_drive(struct md_setup_args *args)
    	err = md_set_array_info(mddev, &ainfo);
  +	mddev->major_version = args->major_version;
+	mddev->minor_version = args->minor_version;
+
  	for (i = 0; i <= MD_SB_DISKS && devices[i]; i++) {
  		struct mdu_disk_info_s dinfo = {
  			.major	= MAJOR(devices[i]),
@@ -273,11 +326,15 @@ void __init md_run_setup(void)
  {
  	int ent;
  +	/*
+	 * Assemble manually defined raids first
+	 */
+	for (ent = 0; ent < md_setup_ents; ent++)
+		md_setup_drive(&md_setup_args[ent]);
+
  	if (raid_noautodetect)
printk(KERN_INFO "md: Skipping autodetection of RAID arrays. (raid=autodetect will force)\n");
  	else
  		autodetect_raid();
  -	for (ent = 0; ent < md_setup_ents; ent++)
-		md_setup_drive(&md_setup_args[ent]);
  }


Kind regards,

Paul
Hello Paul,

thanks for the feedback! This is my first patch, please excuse me for not being familiar with the kernel development process yet. This is relevant, for example, when using an array with version 1.2 as root. When assembling an array without an initrd that is version 1.2 for example, you get an invalid version 0.0 superblock error as the kernel tries to assemble the array with that version. There is no way right now to specify the superblock version from the kernel command line alone, so the array is just never assembled. Or am I missing something?

I will be sending you a patch taking into account your other concerns.

Kind regards,

Jeremias




[Index of Archives]     [Linux RAID Wiki]     [ATA RAID]     [Linux SCSI Target Infrastructure]     [Linux Block]     [Linux IDE]     [Linux SCSI]     [Linux Hams]     [Device Mapper]     [Device Mapper Cryptographics]     [Kernel]     [Linux Admin]     [Linux Net]     [GFS]     [RPM]     [git]     [Yosemite Forum]


  Powered by Linux