[dm-devel] [PATCH 02/13] block, dax: introduce dax_operations

Dan Williams dan.j.williams at intel.com
Fri Jan 20 03:50:24 UTC 2017


Prepare for the removal of memcpy_to_pmem() and copy_from_iter_pmem() by
introducing dax_ops. This allows for driver specific overrides for the
routines that transfer data to a dax capable block device.

Cc: <dm-devel at redhat.com>
Cc: Jan Kara <jack at suse.cz>
Cc: Jens Axboe <axboe at fb.com>
Cc: Jeff Moyer <jmoyer at redhat.com>
Cc: Christoph Hellwig <hch at lst.de>
Cc: Toshi Kani <toshi.kani at hpe.com>
Cc: Mike Snitzer <snitzer at redhat.com>
Cc: Matthew Wilcox <mawilcox at microsoft.com>
Cc: Ross Zwisler <ross.zwisler at linux.intel.com>
Signed-off-by: Dan Williams <dan.j.williams at intel.com>
---
 arch/powerpc/sysdev/axonram.c |    6 +++++-
 drivers/block/brd.c           |    6 +++++-
 drivers/md/dm.c               |    6 +++++-
 drivers/nvdimm/pmem.c         |    6 +++++-
 drivers/s390/block/dcssblk.c  |    6 +++++-
 fs/block_dev.c                |    6 ++++--
 include/linux/blkdev.h        |    8 ++++++--
 7 files changed, 35 insertions(+), 9 deletions(-)

diff --git a/arch/powerpc/sysdev/axonram.c b/arch/powerpc/sysdev/axonram.c
index ada29eaed6e2..d4f318e7e6f3 100644
--- a/arch/powerpc/sysdev/axonram.c
+++ b/arch/powerpc/sysdev/axonram.c
@@ -153,9 +153,13 @@ axon_ram_direct_access(struct block_device *device, sector_t sector,
 	return bank->size - offset;
 }
 
+static const struct dax_operations axon_ram_dax_ops = {
+	.direct_access	= axon_ram_direct_access,
+};
+
 static const struct block_device_operations axon_ram_devops = {
 	.owner		= THIS_MODULE,
-	.direct_access	= axon_ram_direct_access
+	.dax_ops	= &axon_ram_dax_ops,
 };
 
 /**
diff --git a/drivers/block/brd.c b/drivers/block/brd.c
index 3adc32a3153b..9d06e5da2ab2 100644
--- a/drivers/block/brd.c
+++ b/drivers/block/brd.c
@@ -395,10 +395,14 @@ static long brd_direct_access(struct block_device *bdev, sector_t sector,
 #define brd_direct_access NULL
 #endif
 
+static const struct dax_operations brd_dax_ops = {
+	.direct_access = 	brd_direct_access,
+};
+
 static const struct block_device_operations brd_fops = {
 	.owner =		THIS_MODULE,
 	.rw_page =		brd_rw_page,
-	.direct_access =	brd_direct_access,
+	.dax_ops =		&brd_dax_ops,
 };
 
 /*
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index 3086da5664f3..87920a379d20 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -2725,13 +2725,17 @@ static const struct pr_ops dm_pr_ops = {
 	.pr_clear	= dm_pr_clear,
 };
 
+static const struct dax_operations dm_dax_ops = {
+	.direct_access = dm_blk_direct_access,
+};
+
 static const struct block_device_operations dm_blk_dops = {
 	.open = dm_blk_open,
 	.release = dm_blk_close,
 	.ioctl = dm_blk_ioctl,
-	.direct_access = dm_blk_direct_access,
 	.getgeo = dm_blk_getgeo,
 	.pr_ops = &dm_pr_ops,
+	.dax_ops = &dm_dax_ops,
 	.owner = THIS_MODULE
 };
 
diff --git a/drivers/nvdimm/pmem.c b/drivers/nvdimm/pmem.c
index 0d7779384a9f..6e5442174245 100644
--- a/drivers/nvdimm/pmem.c
+++ b/drivers/nvdimm/pmem.c
@@ -217,11 +217,15 @@ __weak long pmem_direct_access(struct block_device *bdev, sector_t sector,
 	return pmem->size - pmem->pfn_pad - offset;
 }
 
+static const struct dax_operations pmem_dax_ops = {
+	.direct_access = pmem_direct_access,
+};
+
 static const struct block_device_operations pmem_fops = {
 	.owner =		THIS_MODULE,
 	.rw_page =		pmem_rw_page,
-	.direct_access =	pmem_direct_access,
 	.revalidate_disk =	nvdimm_revalidate_disk,
+	.dax_ops =		&pmem_dax_ops,
 };
 
 static void pmem_release_queue(void *q)
diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c
index 9d66b4fb174b..6acebe4a47f3 100644
--- a/drivers/s390/block/dcssblk.c
+++ b/drivers/s390/block/dcssblk.c
@@ -36,11 +36,15 @@ static long dcssblk_direct_access(struct block_device *bdev, sector_t secnum,
 static char dcssblk_segments[DCSSBLK_PARM_LEN] = "\0";
 
 static int dcssblk_major;
+
+static const struct dax_operations dcssblk_dax_ops = {
+	.direct_access 	= dcssblk_direct_access,
+};
+
 static const struct block_device_operations dcssblk_devops = {
 	.owner   	= THIS_MODULE,
 	.open    	= dcssblk_open,
 	.release 	= dcssblk_release,
-	.direct_access 	= dcssblk_direct_access,
 };
 
 struct dcssblk_dev_info {
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 5db5d1340d69..1acfc7d25768 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -736,6 +736,7 @@ long bdev_direct_access(struct block_device *bdev, struct blk_dax_ctl *dax)
 	sector_t sector = dax->sector;
 	long avail, size = dax->size;
 	const struct block_device_operations *ops = bdev->bd_disk->fops;
+	const struct dax_operations *dax_ops = ops->dax_ops;
 
 	/*
 	 * The device driver is allowed to sleep, in order to make the
@@ -745,7 +746,8 @@ long bdev_direct_access(struct block_device *bdev, struct blk_dax_ctl *dax)
 
 	if (size < 0)
 		return size;
-	if (!blk_queue_dax(bdev_get_queue(bdev)) || !ops->direct_access)
+	if (!blk_queue_dax(bdev_get_queue(bdev)) || !dax_ops
+			|| !dax_ops->direct_access)
 		return -EOPNOTSUPP;
 	if ((sector + DIV_ROUND_UP(size, 512)) >
 					part_nr_sects_read(bdev->bd_part))
@@ -753,7 +755,7 @@ long bdev_direct_access(struct block_device *bdev, struct blk_dax_ctl *dax)
 	sector += get_start_sect(bdev);
 	if (sector % (PAGE_SIZE / 512))
 		return -EINVAL;
-	avail = ops->direct_access(bdev, sector, &dax->addr, &dax->pfn, size);
+	avail = dax_ops->direct_access(bdev, sector, &dax->addr, &dax->pfn, size);
 	if (!avail)
 		return -ERANGE;
 	if (avail > 0 && avail & ~PAGE_MASK)
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 83695641bd5e..8afce34823f5 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -1863,14 +1863,17 @@ struct blk_dax_ctl {
 	pfn_t pfn;
 };
 
+struct dax_operations {
+	long (*direct_access)(struct block_device *, sector_t, void **, pfn_t *,
+			long);
+};
+
 struct block_device_operations {
 	int (*open) (struct block_device *, fmode_t);
 	void (*release) (struct gendisk *, fmode_t);
 	int (*rw_page)(struct block_device *, sector_t, struct page *, bool);
 	int (*ioctl) (struct block_device *, fmode_t, unsigned, unsigned long);
 	int (*compat_ioctl) (struct block_device *, fmode_t, unsigned, unsigned long);
-	long (*direct_access)(struct block_device *, sector_t, void **, pfn_t *,
-			long);
 	unsigned int (*check_events) (struct gendisk *disk,
 				      unsigned int clearing);
 	/* ->media_changed() is DEPRECATED, use ->check_events() instead */
@@ -1882,6 +1885,7 @@ struct block_device_operations {
 	void (*swap_slot_free_notify) (struct block_device *, unsigned long);
 	struct module *owner;
 	const struct pr_ops *pr_ops;
+	const struct dax_operations *dax_ops;
 };
 
 extern int __blkdev_driver_ioctl(struct block_device *, fmode_t, unsigned int,




More information about the dm-devel mailing list