Hi

Here I'm releasing the second version of the deviceless messages patch. I 
discussed it with Alasdair and we concluded to change the format of the 
message. If the device is "." (note that this name is rejected by the 
kernel, so no device with this name could exist), the message is 
considered deviceless.

You could send the deviceless message to the linear target with:
dmsetup message . 0 linear Hello

Mikulas


From: Mikulas Patocka <[email protected]>

The VDO code needs to perform some calculations before creating a device.
The calculations should be performed in the kernel, so that the same logic
is not duplicated in the kernel and in the userspace.

However, currently it is not possible to call a device mapper target
when no device exists.

This commit solves the problem by adding "deviceless" messages. If the 
message is directed to a device ".", the sector number is ignored and the 
first argument is the name of the target the message should be delivered 
to. The other arguments are passed to the target's deviceless_message 
method. The target can perform the requested calculations in this method 
and return the result back to userspace.

Signed-off-by: Mikulas Patocka <[email protected]>

---
 drivers/md/dm-ioctl.c         |   60 +++++++++++++++++++++++++++++++++---------
 include/linux/device-mapper.h |    4 ++
 2 files changed, 52 insertions(+), 12 deletions(-)

Index: linux-2.6/drivers/md/dm-ioctl.c
===================================================================
--- linux-2.6.orig/drivers/md/dm-ioctl.c        2026-05-12 15:40:22.000000000 
+0200
+++ linux-2.6/drivers/md/dm-ioctl.c     2026-05-13 14:52:23.000000000 +0200
@@ -1743,6 +1743,30 @@ 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;
+
+       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 +1812,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 +1831,25 @@ static int target_message(struct file *f
                goto out_argv;
        }
 
+       if (!strcmp(param->name, ".")) {
+               if (argc == 1) {
+                       DMERR("Empty message received.");
+                       r = -EINVAL;
+                       goto out_argv;
+               }
+               r = message_for_module(argv[0], argc - 1, argv + 1, result, 
maxlen);
+               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_argv;
+               goto out_md;
 
        table = dm_get_live_table(md, &srcu_idx);
        if (!table) {
@@ -1838,14 +1874,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 +1889,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-05-12 
15:40:22.000000000 +0200
+++ linux-2.6/include/linux/device-mapper.h     2026-05-12 15:40:22.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;


Reply via email to