[RFC PATCH v2 1/4] md: add uapi definitions for the md control device

From: Abd-Alrhman Masalkhi

Date: Thu Oct 01 2026 - 09:13:20 EST


Add the ioctl commands and structures for /dev/md-control, a misc device
that manages md arrays without opening the md block device. The device
itself is added in the next patch.

Every command except MD_RAID_VERSION takes a struct mdu_ioctl, which
names the array by name, UUID or device number, carries a flags field,
and points to the command's payload. The commands mirror the existing
block device ioctls and use the MD_MAJOR ioctl type, with numbers
starting at 0x40, grouped like the old ones: status at 0x40,
configuration at 0x50 and usage at 0x60.

The payload structures are new versions of the old ones with fixed-size
types and explicit padding, so they have the same layout on 32-bit and
64-bit systems. Fields that overflow in the old structures are 64-bit
now: size, ctime and utime in struct mdu_array_info64.
struct mdu_array_info64 also reports the number of journal disks.

STOP_ARRAY_RO has no separate command: MD_STOP_ARRAY with MD_RO_FLAG
set switches the array to read-only mode instead of stopping it.

Signed-off-by: Abd-Alrhman Masalkhi <abd.masalkhi@xxxxxxxxx>
---
include/uapi/linux/raid/md_u.h | 119 +++++++++++++++++++++++++++++++++
1 file changed, 119 insertions(+)

diff --git a/include/uapi/linux/raid/md_u.h b/include/uapi/linux/raid/md_u.h
index a893010735fb..adc62b5e50ec 100644
--- a/include/uapi/linux/raid/md_u.h
+++ b/include/uapi/linux/raid/md_u.h
@@ -12,6 +12,8 @@
#ifndef _UAPI_MD_U_H
#define _UAPI_MD_U_H

+#include <linux/types.h>
+
/*
* Different major versions are not compatible.
* Different minor versions are only downward compatible.
@@ -30,6 +32,10 @@
*/
#define MD_PATCHLEVEL_VERSION 3

+#define MD_NAME_LEN 32
+#define MD_UUID_LEN 16
+#define MD_CTL_NODE "md-control"
+
/* ioctls */

/* status */
@@ -61,6 +67,29 @@
#define RESTART_ARRAY_RW _IO (MD_MAJOR, 0x34)
#define CLUSTERED_DISK_NACK _IO (MD_MAJOR, 0x35)

+/* ioctl commands for the MD misc control driver */
+/* status */
+#define MD_RAID_VERSION _IOR(MD_MAJOR, 0x40, struct mdu_version64)
+#define MD_GET_ARRAY_INFO _IOWR(MD_MAJOR, 0x41, struct mdu_ioctl)
+#define MD_GET_DISK_INFO _IOWR(MD_MAJOR, 0x42, struct mdu_ioctl)
+#define MD_RAID_AUTORUN _IOWR(MD_MAJOR, 0x43, struct mdu_ioctl)
+#define MD_GET_BITMAP_FILE _IOWR(MD_MAJOR, 0x44, struct mdu_ioctl)
+
+/* configuration */
+#define MD_ADD_NEW_DISK _IOWR(MD_MAJOR, 0x50, struct mdu_ioctl)
+#define MD_HOT_ADD_DISK _IOWR(MD_MAJOR, 0x51, struct mdu_ioctl)
+#define MD_HOT_REMOVE_DISK _IOWR(MD_MAJOR, 0x52, struct mdu_ioctl)
+#define MD_SET_ARRAY_INFO _IOWR(MD_MAJOR, 0x53, struct mdu_ioctl)
+#define MD_SET_DISK_INFO _IOWR(MD_MAJOR, 0x54, struct mdu_ioctl)
+#define MD_SET_DISK_FAULTY _IOWR(MD_MAJOR, 0x55, struct mdu_ioctl)
+#define MD_SET_BITMAP_FILE _IOWR(MD_MAJOR, 0x56, struct mdu_ioctl)
+
+/* usage */
+#define MD_RUN_ARRAY _IOWR(MD_MAJOR, 0x60, struct mdu_ioctl)
+#define MD_STOP_ARRAY _IOWR(MD_MAJOR, 0x61, struct mdu_ioctl)
+#define MD_RESTART_ARRAY_RW _IOWR(MD_MAJOR, 0x62, struct mdu_ioctl)
+#define MD_CLUSTERED_DISK_NACK _IOWR(MD_MAJOR, 0x63, struct mdu_ioctl)
+
/* 63 partitions with the alternate major number (mdp) */
#define MdpMinorShift 6

@@ -146,4 +175,94 @@ typedef struct mdu_param_s
int max_fault; /* unused for now */
} mdu_param_t;

+/* structures for the MD misc control driver */
+struct mdu_version64 {
+ __u32 major;
+ __u32 minor;
+ __u32 patchlevel;
+ __u32 padding;
+};
+
+struct mdu_array_info64 {
+ /*
+ * Generic constant information
+ */
+ __u32 major_version;
+ __u32 minor_version;
+ __u32 patch_version;
+ __s32 level;
+
+ __u64 ctime;
+ __s64 size;
+
+ __u32 nr_disks;
+ __u32 raid_disks;
+ __u32 md_minor;
+ __u32 not_persistent;
+
+ /*
+ * Generic state information
+ */
+ __u64 utime; /* 0 Superblock update time */
+
+ __u32 state; /* 1 State bits (clean, ...) */
+ __u32 active_disks; /* 2 Number of currently active disks */
+ __u32 working_disks; /* 3 Number of working disks */
+ __u32 failed_disks; /* 4 Number of failed disks */
+ __u32 spare_disks; /* 5 Number of spare disks */
+ __u32 journal_disks; /* 6 Number of disks used for journaling */
+
+ /*
+ * Personality information
+ */
+ __s32 layout; /* 0 the array's physical layout */
+ __u32 chunk_size; /* 1 chunk size in bytes */
+
+};
+
+struct mdu_disk_info64 {
+ /*
+ * configuration/status of one particular disk
+ */
+ __u32 state;
+ __u32 major;
+ __u32 minor;
+ __u32 padding;
+
+ __s32 number;
+ __s32 raid_disk;
+};
+
+struct mdu_bitmap_file64 {
+ char pathname[4096];
+};
+
+struct mdu_param64 {
+ __s32 personality; /* 1,2,3,4 */
+ __u32 max_fault; /* unused for now */
+ __u32 chunk_size; /* in bytes */
+ __u32 padding;
+};
+
+struct mdu_ioctl {
+ char name[MD_NAME_LEN];
+ char uuid[MD_UUID_LEN];
+ __u64 dev;
+ __u32 flags;
+ __u32 padding;
+ union {
+ __u64 array;
+ __u64 disk;
+ __u64 param;
+ __u64 bitmap_file;
+ __u64 arg;
+ };
+};
+
+/*
+ * If set, MD_STOP_ARRAY will switch the array to read-only mode instead
+ * of fully stopping it.
+ */
+#define MD_RO_FLAG (1u << 0)
+
#endif /* _UAPI_MD_U_H */
--
2.43.0