Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions Documentation/admin-guide/md.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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

``md device no.``
+++++++++++++++++

Expand Down
66 changes: 64 additions & 2 deletions drivers/md/md-autodetect.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
int partitioned;
int level;
int chunk;
int major_version;
int minor_version;
char *device_names;
} md_setup_args[256] __initdata;

Expand All @@ -56,13 +58,64 @@
* 2001-06-03: Dave Cinege <[email protected]>
* 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 <[email protected]>
* Allow setting of the superblock version:
* md=vX.X,...
*/
static int __init md_setup(char *str)
{
int minor, level, factor, fault, partitioned = 0;
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) {
printk(KERN_WARNING

Check failure on line 78 in drivers/md/md-autodetect.c

View workflow job for this annotation

GitHub Actions / per-patch-testing

WARNING: Prefer [subsystem eg: netdev]_warn([subsystem]dev, ... then dev_warn(dev, ... then pr_warn(... to printk(KERN_WARNING ...
"md: Version (%s) has been specified wrong, no ',' found, use like this: md=vX.X,...\n",
version);
return 0;
}
*version_end = '\0';
str = version_end + 1;

char *separator = strchr(version, '.');

if (!separator) {
printk(KERN_WARNING

Check failure on line 89 in drivers/md/md-autodetect.c

View workflow job for this annotation

GitHub Actions / per-patch-testing

WARNING: Prefer [subsystem eg: netdev]_warn([subsystem]dev, ... then dev_warn(dev, ... then pr_warn(... to printk(KERN_WARNING ...
"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) {
printk(KERN_WARNING

Check failure on line 100 in drivers/md/md-autodetect.c

View workflow job for this annotation

GitHub Actions / per-patch-testing

WARNING: Prefer [subsystem eg: netdev]_warn([subsystem]dev, ... then dev_warn(dev, ... then pr_warn(... to printk(KERN_WARNING ...
"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) {
printk(KERN_WARNING

Check failure on line 106 in drivers/md/md-autodetect.c

View workflow job for this annotation

GitHub Actions / per-patch-testing

WARNING: Prefer [subsystem eg: netdev]_warn([subsystem]dev, ... then dev_warn(dev, ... then pr_warn(... to printk(KERN_WARNING ...
"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) {
printk(KERN_WARNING

Check failure on line 113 in drivers/md/md-autodetect.c

View workflow job for this annotation

GitHub Actions / per-patch-testing

WARNING: Prefer [subsystem eg: netdev]_warn([subsystem]dev, ... then dev_warn(dev, ... then pr_warn(... to printk(KERN_WARNING ...
"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;
Expand Down Expand Up @@ -116,6 +169,8 @@
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;
}
Expand Down Expand Up @@ -200,6 +255,9 @@

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]),
Expand Down Expand Up @@ -273,11 +331,15 @@
{
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]);
}