---
drivers/md/dm-ioctl.c | 57
+++++++++++++++++++++++++++++++++---------
include/linux/device-mapper.h | 4 ++
2 files changed, 49 insertions(+), 12 deletions(-)
Index: linux-2.6/drivers/md/dm-ioctl.c
===================================================================
--- linux-2.6.orig/drivers/md/dm-ioctl.c 2026-05-06 22:15:36.000000000
+0200
+++ linux-2.6/drivers/md/dm-ioctl.c 2026-05-11 12:53:37.000000000 +0200
@@ -1743,6 +1743,33 @@ static int table_status(struct file *fil
return 0;
}
+static int message_for_module(const char *target_name, unsigned int argc, char **argv,
+ char *result, unsigned int maxlen)
+{
+ struct target_type *tt;
+ int r;
+
+ if (**argv != '%')
+ return 2;
+
+ tt = dm_get_target_type(target_name);
+ if (!tt) {
+ DMERR("unknown target name %s", target_name);
+ return -EINVAL;
+ }
+
+ if (!tt->deviceless_message) {
+ DMERR("target %s doesn't support deviceless messages",
target_name);
+ r = -EINVAL;
+ } else {
+ r = tt->deviceless_message(argc, argv, result, maxlen);
+ }
+
+ dm_put_target_type(tt);
+
+ return r;
+}
+
/*
* Process device-mapper dependent messages. Messages prefixed with '@'
* are processed by the DM core. All others are delivered to the target.
@@ -1788,10 +1815,6 @@ static int target_message(struct file *f
char *result = get_result_buffer(param, param_size, &maxlen);
int srcu_idx;
- md = find_device(param);
- if (!md)
- return -ENXIO;
-
if (tmsg < (struct dm_target_msg *) param->data ||
invalid_str(tmsg->message, (void *) param + param_size)) {
DMERR("Invalid target message parameters.");
@@ -1811,9 +1834,19 @@ static int target_message(struct file *f
goto out_argv;
}
- r = message_for_md(md, argc, argv, result, maxlen);
+ r = message_for_module(param->name, argc, argv, result, maxlen);
if (r <= 1)
+ goto out_deviceless;
+
+ md = find_device(param);
+ if (!md) {
+ r = -ENXIO;
goto out_argv;
+ }
+
+ r = message_for_md(md, argc, argv, result, maxlen);
+ if (r <= 1)
+ goto out_md;
table = dm_get_live_table(md, &srcu_idx);
if (!table) {
@@ -1838,14 +1871,13 @@ static int target_message(struct file *f
r = -EINVAL;
}
- out_table:
+out_table:
dm_put_live_table(md, srcu_idx);
- out_argv:
- kfree(argv);
- out:
+out_md:
if (r >= 0)
__dev_status(md, param);
-
+ dm_put(md);
+out_deviceless:
if (r == 1) {
param->flags |= DM_DATA_OUT_FLAG;
if (dm_message_test_buffer_overflow(result, maxlen))
@@ -1854,8 +1886,9 @@ static int target_message(struct file *f
param->data_size = param->data_start + strlen(result) +
1;
r = 0;
}
-
- dm_put(md);
+out_argv:
+ kfree(argv);
+out:
return r;
}
Index: linux-2.6/include/linux/device-mapper.h
===================================================================
--- linux-2.6.orig/include/linux/device-mapper.h 2026-04-27
19:06:34.000000000 +0200
+++ linux-2.6/include/linux/device-mapper.h 2026-05-11 12:45:45.000000000
+0200
@@ -93,6 +93,9 @@ typedef void (*dm_status_fn) (struct dm_
typedef int (*dm_message_fn) (struct dm_target *ti, unsigned int argc, char
**argv,
char *result, unsigned int maxlen);
+typedef int (*dm_deviceless_message_fn) (unsigned int argc, char **argv,
+ char *result, unsigned int maxlen);
+
/*
* Called with *forward == true. If it remains true, the ioctl should be
* forwarded to bdev. If it is reset to false, the target already fully
handled
@@ -214,6 +217,7 @@ struct target_type {
dm_resume_fn resume;
dm_status_fn status;
dm_message_fn message;
+ dm_deviceless_message_fn deviceless_message;
dm_prepare_ioctl_fn prepare_ioctl;
dm_report_zones_fn report_zones;
dm_busy_fn busy;