summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2017-01-26 23:37:35 -0500
committerDan Williams <dan.j.williams@intel.com>2017-04-20 14:57:52 -0400
commitb0686260fecaa924d8eff2ace94bee70506bc308 (patch)
tree36193b32e9f64ee93c4dd02e29da9256e8930fb7
parentd8f07aee3f2fd959878bf614d4e984900018eb9e (diff)
dax: introduce dax_direct_access()
Replace bdev_direct_access() with dax_direct_access() that uses dax_device and dax_operations instead of a block_device and block_device_operations for dax. Once all consumers of the old api have been converted bdev_direct_access() will be deleted. Given that block device partitioning decisions can cause dax page alignment constraints to be violated this also introduces the bdev_dax_pgoff() helper. It handles calculating a logical pgoff relative to the dax_device and also checks for page alignment. Signed-off-by: Dan Williams <dan.j.williams@intel.com>
-rw-r--r--block/Kconfig1
-rw-r--r--drivers/dax/super.c39
-rw-r--r--fs/block_dev.c14
-rw-r--r--include/linux/blkdev.h1
-rw-r--r--include/linux/dax.h2
5 files changed, 57 insertions, 0 deletions
diff --git a/block/Kconfig b/block/Kconfig
index e9f780f815f5..93da7fc3f254 100644
--- a/block/Kconfig
+++ b/block/Kconfig
@@ -6,6 +6,7 @@ menuconfig BLOCK
6 default y 6 default y
7 select SBITMAP 7 select SBITMAP
8 select SRCU 8 select SRCU
9 select DAX
9 help 10 help
10 Provide block layer support for the kernel. 11 Provide block layer support for the kernel.
11 12
diff --git a/drivers/dax/super.c b/drivers/dax/super.c
index 1a58542ee8fd..465dcd7317d5 100644
--- a/drivers/dax/super.c
+++ b/drivers/dax/super.c
@@ -65,6 +65,45 @@ struct dax_device {
65 const struct dax_operations *ops; 65 const struct dax_operations *ops;
66}; 66};
67 67
68/**
69 * dax_direct_access() - translate a device pgoff to an absolute pfn
70 * @dax_dev: a dax_device instance representing the logical memory range
71 * @pgoff: offset in pages from the start of the device to translate
72 * @nr_pages: number of consecutive pages caller can handle relative to @pfn
73 * @kaddr: output parameter that returns a virtual address mapping of pfn
74 * @pfn: output parameter that returns an absolute pfn translation of @pgoff
75 *
76 * Return: negative errno if an error occurs, otherwise the number of
77 * pages accessible at the device relative @pgoff.
78 */
79long dax_direct_access(struct dax_device *dax_dev, pgoff_t pgoff, long nr_pages,
80 void **kaddr, pfn_t *pfn)
81{
82 long avail;
83
84 /*
85 * The device driver is allowed to sleep, in order to make the
86 * memory directly accessible.
87 */
88 might_sleep();
89
90 if (!dax_dev)
91 return -EOPNOTSUPP;
92
93 if (!dax_alive(dax_dev))
94 return -ENXIO;
95
96 if (nr_pages < 0)
97 return nr_pages;
98
99 avail = dax_dev->ops->direct_access(dax_dev, pgoff, nr_pages,
100 kaddr, pfn);
101 if (!avail)
102 return -ERANGE;
103 return min(avail, nr_pages);
104}
105EXPORT_SYMBOL_GPL(dax_direct_access);
106
68bool dax_alive(struct dax_device *dax_dev) 107bool dax_alive(struct dax_device *dax_dev)
69{ 108{
70 lockdep_assert_held(&dax_srcu); 109 lockdep_assert_held(&dax_srcu);
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 7f40ea2f0875..2f7885712575 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -18,6 +18,7 @@
18#include <linux/module.h> 18#include <linux/module.h>
19#include <linux/blkpg.h> 19#include <linux/blkpg.h>
20#include <linux/magic.h> 20#include <linux/magic.h>
21#include <linux/dax.h>
21#include <linux/buffer_head.h> 22#include <linux/buffer_head.h>
22#include <linux/swap.h> 23#include <linux/swap.h>
23#include <linux/pagevec.h> 24#include <linux/pagevec.h>
@@ -762,6 +763,19 @@ long bdev_direct_access(struct block_device *bdev, struct blk_dax_ctl *dax)
762} 763}
763EXPORT_SYMBOL_GPL(bdev_direct_access); 764EXPORT_SYMBOL_GPL(bdev_direct_access);
764 765
766int bdev_dax_pgoff(struct block_device *bdev, sector_t sector, size_t size,
767 pgoff_t *pgoff)
768{
769 phys_addr_t phys_off = (get_start_sect(bdev) + sector) * 512;
770
771 if (pgoff)
772 *pgoff = PHYS_PFN(phys_off);
773 if (phys_off % PAGE_SIZE || size % PAGE_SIZE)
774 return -EINVAL;
775 return 0;
776}
777EXPORT_SYMBOL(bdev_dax_pgoff);
778
765/** 779/**
766 * bdev_dax_supported() - Check if the device supports dax for filesystem 780 * bdev_dax_supported() - Check if the device supports dax for filesystem
767 * @sb: The superblock of the device 781 * @sb: The superblock of the device
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index f72708399b83..612c497d1461 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -1958,6 +1958,7 @@ extern int bdev_write_page(struct block_device *, sector_t, struct page *,
1958 struct writeback_control *); 1958 struct writeback_control *);
1959extern long bdev_direct_access(struct block_device *, struct blk_dax_ctl *); 1959extern long bdev_direct_access(struct block_device *, struct blk_dax_ctl *);
1960extern int bdev_dax_supported(struct super_block *, int); 1960extern int bdev_dax_supported(struct super_block *, int);
1961int bdev_dax_pgoff(struct block_device *, sector_t, size_t, pgoff_t *pgoff);
1961#else /* CONFIG_BLOCK */ 1962#else /* CONFIG_BLOCK */
1962 1963
1963struct block_device; 1964struct block_device;
diff --git a/include/linux/dax.h b/include/linux/dax.h
index 39a0312c45c3..7e62e280c11f 100644
--- a/include/linux/dax.h
+++ b/include/linux/dax.h
@@ -27,6 +27,8 @@ void put_dax(struct dax_device *dax_dev);
27bool dax_alive(struct dax_device *dax_dev); 27bool dax_alive(struct dax_device *dax_dev);
28void kill_dax(struct dax_device *dax_dev); 28void kill_dax(struct dax_device *dax_dev);
29void *dax_get_private(struct dax_device *dax_dev); 29void *dax_get_private(struct dax_device *dax_dev);
30long dax_direct_access(struct dax_device *dax_dev, pgoff_t pgoff, long nr_pages,
31 void **kaddr, pfn_t *pfn);
30 32
31/* 33/*
32 * We use lowest available bit in exceptional entry for locking, one bit for 34 * We use lowest available bit in exceptional entry for locking, one bit for