2021-03-04 18:50:32

by Sergei Shtepa

[permalink] [raw]
Subject: [PATCH 0/1] device filter

Hi all.

I would like to discuss the idea of further extending the functionality
of device mapper and suggest the concept of device filters (DF).

The DM creates new block devices based on existing ones.
DF will not create new devices. Using blk_interposer, DF will intercept
bio requests, perform additional processing, and then pass (or skip)
the original request.

By analogy with the way DM implements various mapping algorithms through
additional modules, so DF will be the basis for the work of modules that
implement their own filtering algorithm.

Based on DF, it will be possible to create solutions for live migration,
continius data protection, and implement the backup on write algorithm.
For security systems, it will be possible to implement algorithms for
checking accesses to a block device.

Installing and removing such filters does not require changing
the configuration of the user's infrastructure or rebooting.
Connecting and disconnecting is possible "on the fly" using
blk-interposer.

In this patch, I propose to consider additional IOCTL for the dm-mod
module. The new IOCTL looks like a good starting point for developing
device filters.

It is technically possible to create a DF independently of the DM.
However, I think that DF can use a significant part of the code already
existing in the DM without creating duplication.

I look forward to your feedback on device filter.

Sergei Shtepa (1):
dm: adds an IOCTL to work with device-filters

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

--
2.20.1


2021-03-04 18:51:05

by Sergei Shtepa

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

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 <[email protected]>
---
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