[PATCH 1/1] dm: adds an IOCTL to work with device-filters

From: Sergei Shtepa
Date: Thu Mar 04 2021 - 12:15:33 EST


The four simplest IOCTL's allow to create new filters, remove them
and pass control commands specific to each target.

Signed-off-by: Sergei Shtepa <sergei.shtepa@xxxxxxxxx>
---
drivers/md/Makefile | 2 +-
drivers/md/dm-ioctl.c | 22 ++++++++++++++++++++++
drivers/md/flt-ctl.c | 25 +++++++++++++++++++++++++
drivers/md/flt-ctl.h | 10 ++++++++++
include/uapi/linux/dm-ioctl.h | 18 ++++++++++++++++--
5 files changed, 74 insertions(+), 3 deletions(-)
create mode 100644 drivers/md/flt-ctl.c
create mode 100644 drivers/md/flt-ctl.h

diff --git a/drivers/md/Makefile b/drivers/md/Makefile
index bd5b38bee82e..1b650950adc1 100644
--- a/drivers/md/Makefile
+++ b/drivers/md/Makefile
@@ -5,7 +5,7 @@

dm-mod-y += dm.o dm-table.o dm-target.o dm-linear.o dm-stripe.o \
dm-ioctl.o dm-io.o dm-kcopyd.o dm-sysfs.o dm-stats.o \
- dm-rq.o dm-interposer.o
+ dm-rq.o dm-interposer.o flt-ctl.o
dm-multipath-y += dm-path-selector.o dm-mpath.o
dm-historical-service-time-y += dm-ps-historical-service-time.o
dm-io-affinity-y += dm-ps-io-affinity.o
diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c
index 2bcb316144a1..f5f0c9377752 100644
--- a/drivers/md/dm-ioctl.c
+++ b/drivers/md/dm-ioctl.c
@@ -6,6 +6,7 @@
*/

#include "dm-core.h"
+#include "flt-control.h"

#include <linux/module.h>
#include <linux/vmalloc.h>
@@ -1700,6 +1701,27 @@ static ioctl_fn lookup_ioctl(unsigned int cmd, int *ioctl_flags)
{DM_GET_TARGET_VERSION, 0, get_target_version},
};

+ static const struct {
+ int cmd;
+ int flags;
+ ioctl_fn fn;
+ } _flt_ioctls[] = {
+ {FLT_REMOVE_ALL_CMD, IOCTL_FLAGS_NO_PARAMS | IOCTL_FLAGS_ISSUE_GLOBAL_EVENT, filter_remove_all},
+ {FLT_CREATE_CMD, IOCTL_FLAGS_NO_PARAMS | IOCTL_FLAGS_ISSUE_GLOBAL_EVENT, filter_create},
+ {FLT_REMOVE_CMD, IOCTL_FLAGS_NO_PARAMS | IOCTL_FLAGS_ISSUE_GLOBAL_EVENT, filter_remove},
+ {FLT_CONTROL_CMD, 0, filter_control},
+ };
+
+ if (cmd >= DM_FILTER_CMD) {
+ cmd -= DM_FILTER_CMD;
+
+ if (unlikely(cmd >= ARRAY_SIZE(_flt_ioctls)))
+ return NULL;
+
+ *ioctl_flags = _flt_ioctls[cmd].flags;
+ return _flt_ioctls[cmd].fn;
+ }
+
if (unlikely(cmd >= ARRAY_SIZE(_ioctls)))
return NULL;

diff --git a/drivers/md/flt-ctl.c b/drivers/md/flt-ctl.c
new file mode 100644
index 000000000000..aadf04be1438
--- /dev/null
+++ b/drivers/md/flt-ctl.c
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/dm-ioctl.h>
+
+#include "flt-ctl.h"
+
+int filter_remove_all(struct file *filp, struct dm_ioctl *param, size_t param_size)
+{
+ return 0;
+};
+int filter_create(struct file *filp, struct dm_ioctl *param, size_t param_size)
+{
+ return 0;
+};
+int filter_remove(struct file *filp, struct dm_ioctl *param, size_t param_size)
+{
+ return 0;
+};
+int filter_control(struct file *filp, struct dm_ioctl *param, size_t param_size)
+{
+ return 0;
+};
+
diff --git a/drivers/md/flt-ctl.h b/drivers/md/flt-ctl.h
new file mode 100644
index 000000000000..61a80184abae
--- /dev/null
+++ b/drivers/md/flt-ctl.h
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: LGPL-2.0+ WITH Linux-syscall-note */
+#ifndef FLT_CTL_H
+#define FLT_CTL_H
+
+int filter_remove_all(struct file *filp, struct dm_ioctl *param, size_t param_size);
+int filter_create(struct file *filp, struct dm_ioctl *param, size_t param_size);
+int filter_remove(struct file *filp, struct dm_ioctl *param, size_t param_size);
+int filter_control(struct file *filp, struct dm_ioctl *param, size_t param_size);
+
+#endif
diff --git a/include/uapi/linux/dm-ioctl.h b/include/uapi/linux/dm-ioctl.h
index e942e7d7c594..012e16761ba9 100644
--- a/include/uapi/linux/dm-ioctl.h
+++ b/include/uapi/linux/dm-ioctl.h
@@ -16,6 +16,7 @@
#define DM_MAX_TYPE_NAME 16
#define DM_NAME_LEN 128
#define DM_UUID_LEN 129
+#define DM_FILTER_CMD 128 /* First filters command */

/*
* A traditional ioctl interface for the device mapper.
@@ -244,6 +245,14 @@ enum {
DM_DEV_SET_GEOMETRY_CMD,
DM_DEV_ARM_POLL_CMD,
DM_GET_TARGET_VERSION_CMD,
+
+ /* Reserved space for additional DM ioctl */
+
+ /* Filters commands */
+ FLT_REMOVE_ALL_CMD = DM_FILTER_CMD, /* Cleanup all filters */
+ FLT_CREATE_CMD, /* Create new filter */
+ FLT_REMOVE_CMD, /* Remove filter */
+ FLT_CONTROL_CMD, /* Send a filter-specific command */
};

#define DM_IOCTL 0xfd
@@ -271,10 +280,15 @@ enum {
#define DM_TARGET_MSG _IOWR(DM_IOCTL, DM_TARGET_MSG_CMD, struct dm_ioctl)
#define DM_DEV_SET_GEOMETRY _IOWR(DM_IOCTL, DM_DEV_SET_GEOMETRY_CMD, struct dm_ioctl)

+#define FLT_REMOVE_ALL _IOWR(DM_IOCTL, FLT_REMOVE_ALL_CMD, struct dm_ioctl)
+#define FLT_CREATE _IOWR(DM_IOCTL, FLT_CREATE_CMD, struct dm_ioctl)
+#define FLT_REMOVE _IOWR(DM_IOCTL, FLT_REMOVE_CMD, struct dm_ioctl)
+#define FLT_CONTROL _IOWR(DM_IOCTL, FLT_CONTROL_CMD, struct dm_ioctl)
+
#define DM_VERSION_MAJOR 4
-#define DM_VERSION_MINOR 43
+#define DM_VERSION_MINOR 44
#define DM_VERSION_PATCHLEVEL 0
-#define DM_VERSION_EXTRA "-ioctl (2020-10-01)"
+#define DM_VERSION_EXTRA "-ioctl (2021-03-03)"

/* Status bits */
#define DM_READONLY_FLAG (1 << 0) /* In/Out */
--
2.20.1