All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH] dm: add deviceless messages
@ 2026-05-12 13:36 Mikulas Patocka
  2026-05-12 13:39 ` Mikulas Patocka
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Mikulas Patocka @ 2026-05-12 13:36 UTC (permalink / raw)
  To: Alasdair Kergon, Mike Snitzer, Benjamin Marzinski, Bruce Johnston,
	Matthew Sakai
  Cc: dm-devel

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 starts with '%', the name is a name of a target, not a name of a 
device. The message will be directed to the target by calling the 
"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 <mpatocka@redhat.com>

---
 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;


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2026-05-13 10:37 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-12 13:36 [RFC PATCH] dm: add deviceless messages Mikulas Patocka
2026-05-12 13:39 ` Mikulas Patocka
2026-05-12 17:31 ` Benjamin Marzinski
2026-05-12 19:26 ` Matthew Sakai
2026-05-13 10:37   ` Mikulas Patocka

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.