Skip to content
Permalink
Browse files
dm: new ioctl DM_DEV_REMAP_CMD
New ioctl DM_DEV_REMAP_CMD allow to remap bio requests
from regular block device to dm device.

Signed-off-by: Sergei Shtepa <sergei.shtepa@veeam.com>
  • Loading branch information
SergeiShtepa authored and intel-lab-lkp committed Feb 9, 2021
1 parent 49860be commit 2dbb264e739c9f95b90e4ea2a0cdb5d874628746
Show file tree
Hide file tree
Showing 4 changed files with 433 additions and 12 deletions.
@@ -13,6 +13,7 @@
#include <linux/ktime.h>
#include <linux/genhd.h>
#include <linux/blk-mq.h>
#include <linux/rbtree.h>

#include <trace/events/block.h>

@@ -109,6 +110,9 @@ struct mapped_device {
bool init_tio_pdu:1;

struct srcu_struct io_barrier;

/* interposer device for remap */
struct dm_interposed_dev *ip_dev;
};

void disable_discard(struct mapped_device *md);
@@ -164,6 +168,22 @@ struct dm_table {
struct dm_md_mempools *mempools;
};

struct dm_rb_range {
struct rb_node node;
sector_t start; /* start sector of rb node */
sector_t last; /* end sector of rb node */
sector_t _subtree_last; /* highest sector in subtree of rb node */
};

void dm_rb_insert(struct dm_rb_range *node, struct rb_root_cached *root);
void dm_rb_remove(struct dm_rb_range *node, struct rb_root_cached *root);

struct dm_rb_range *dm_rb_iter_first(struct rb_root_cached *root, sector_t start, sector_t last);
struct dm_rb_range *dm_rb_iter_next(struct dm_rb_range *node, sector_t start, sector_t last);

int dm_remap_install(struct mapped_device *md, const char *donor_device_name);
int dm_remap_uninstall(struct mapped_device *md);

static inline struct completion *dm_get_completion_from_kobject(struct kobject *kobj)
{
return &container_of(kobj, struct dm_kobject_holder, kobj)->completion;
@@ -1649,6 +1649,40 @@ static int target_message(struct file *filp, struct dm_ioctl *param, size_t para
return r;
}

static inline int dev_remap_start(struct mapped_device *md, uint8_t *params)
{
char *donor_device_name = (char *)params;

return dm_remap_install(md, donor_device_name);
}
static int dev_remap_finish(struct mapped_device *md)
{
return dm_remap_uninstall(md);
}

static int dev_remap(struct file *filp, struct dm_ioctl *param, size_t param_size)
{
int ret = 0;
struct mapped_device *md;
struct dm_remap_param *remap_param = (void *)(param) + param->data_start;

md = find_device(param);
if (!md)
return -ENXIO;

if (remap_param->cmd == REMAP_START_CMD)
ret = dev_remap_start(md, remap_param->params);
else if (remap_param->cmd == REMAP_FINISH_CMD)
ret = dev_remap_finish(md);
else {
DMWARN("Invalid remap command, %d", remap_param->cmd);
ret = -EINVAL;
}

dm_put(md);
return ret;
}

/*
* The ioctl parameter block consists of two parts, a dm_ioctl struct
* followed by a data buffer. This flag is set if the second part,
@@ -1691,6 +1725,7 @@ static ioctl_fn lookup_ioctl(unsigned int cmd, int *ioctl_flags)
{DM_DEV_SET_GEOMETRY_CMD, 0, dev_set_geometry},
{DM_DEV_ARM_POLL, IOCTL_FLAGS_NO_PARAMS, dev_arm_poll},
{DM_GET_TARGET_VERSION, 0, get_target_version},
{DM_DEV_REMAP_CMD, 0, dev_remap},
};

if (unlikely(cmd >= ARRAY_SIZE(_ioctls)))

0 comments on commit 2dbb264

Please sign in to comment.