Re: [RFC PATCH] dm: add deviceless messages
Matthew Sakai <[email protected]>
| Newsgroups | dev.linux.lists.dm-devel |
|---|---|
| Message-ID | <[email protected]> |
On 5/12/26 9:36 AM, Mikulas Patocka wrote: > 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 <[email protected]> I do wish that we could clean up the message interface. The sector number argument is completely meaningless for a deviceless message, so in theory we could distinguish this case by omitting the argument, e.g. "dmsetup message <target_type> <command>" and not require the special '%' notation, either. But that looks like it would require a lot more rearrangement of the message handling code. I agree this does what we need, so... Reviewed-by: Matthew Sakai <[email protected]> > --- > 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; >