[PATCH v3 08/11] dm: Introduce ->rmap() to find bdev offset

From: Shiyang Ruan
Date: Mon Feb 08 2021 - 06:25:27 EST


Pmem device could be a target of mapped device. In order to obtain
superblock on the mapped device, we introduce this to translate offset
from target device to md device.

Currently, we implement it on linear target, which is easy to do the
translation. Other targets will be supported in the future. However,
some targets may not support it because of the non-linear mapping.

Signed-off-by: Shiyang Ruan <ruansy.fnst@xxxxxxxxxxxxxx>
---
drivers/md/dm-linear.c | 20 ++++++++++++++++++++
include/linux/device-mapper.h | 5 +++++
2 files changed, 25 insertions(+)

diff --git a/drivers/md/dm-linear.c b/drivers/md/dm-linear.c
index 00774b5d7668..90fdb4700afd 100644
--- a/drivers/md/dm-linear.c
+++ b/drivers/md/dm-linear.c
@@ -5,6 +5,7 @@
*/

#include "dm.h"
+#include "dm-core.h"
#include <linux/module.h>
#include <linux/init.h>
#include <linux/blkdev.h>
@@ -119,6 +120,24 @@ static void linear_status(struct dm_target *ti, status_type_t type,
}
}

+static int linear_rmap(struct dm_target *ti, sector_t offset,
+ rmap_callout_fn fn, void *data)
+{
+ struct linear_c *lc = (struct linear_c *) ti->private;
+ struct mapped_device *md = ti->table->md;
+ struct block_device *bdev;
+ sector_t disk_sect = offset - dm_target_offset(ti, lc->start);
+ int rc = -ENODEV;
+
+ bdev = bdget_disk_sector(md->disk, offset);
+ if (!bdev)
+ return rc;
+
+ rc = fn(ti, bdev, disk_sect, data);
+ bdput(bdev);
+ return rc;
+}
+
static int linear_prepare_ioctl(struct dm_target *ti, struct block_device **bdev)
{
struct linear_c *lc = (struct linear_c *) ti->private;
@@ -238,6 +257,7 @@ static struct target_type linear_target = {
.ctr = linear_ctr,
.dtr = linear_dtr,
.map = linear_map,
+ .rmap = linear_rmap,
.status = linear_status,
.prepare_ioctl = linear_prepare_ioctl,
.iterate_devices = linear_iterate_devices,
diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h
index 61a66fb8ebb3..c5cd1009a08d 100644
--- a/include/linux/device-mapper.h
+++ b/include/linux/device-mapper.h
@@ -58,6 +58,10 @@ typedef void (*dm_dtr_fn) (struct dm_target *ti);
* = 2: The target wants to push back the io
*/
typedef int (*dm_map_fn) (struct dm_target *ti, struct bio *bio);
+typedef int (*rmap_callout_fn) (struct dm_target *ti, struct block_device *bdev,
+ sector_t sect, void *data);
+typedef int (*dm_rmap_fn) (struct dm_target *ti, sector_t offset,
+ rmap_callout_fn fn, void *data);
typedef int (*dm_clone_and_map_request_fn) (struct dm_target *ti,
struct request *rq,
union map_info *map_context,
@@ -175,6 +179,7 @@ struct target_type {
dm_ctr_fn ctr;
dm_dtr_fn dtr;
dm_map_fn map;
+ dm_rmap_fn rmap;
dm_clone_and_map_request_fn clone_and_map_rq;
dm_release_clone_request_fn release_clone_rq;
dm_endio_fn end_io;
--
2.30.0