diff options
author | Dan Williams <dan.j.williams@intel.com> | 2017-01-26 23:37:35 -0500 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2017-04-20 14:57:52 -0400 |
commit | b0686260fecaa924d8eff2ace94bee70506bc308 (patch) | |
tree | 36193b32e9f64ee93c4dd02e29da9256e8930fb7 /drivers/dax | |
parent | d8f07aee3f2fd959878bf614d4e984900018eb9e (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>
Diffstat (limited to 'drivers/dax')
-rw-r--r-- | drivers/dax/super.c | 39 |
1 files changed, 39 insertions, 0 deletions
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 | */ | ||
79 | long 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 | } | ||
105 | EXPORT_SYMBOL_GPL(dax_direct_access); | ||
106 | |||
68 | bool dax_alive(struct dax_device *dax_dev) | 107 | bool dax_alive(struct dax_device *dax_dev) |
69 | { | 108 | { |
70 | lockdep_assert_held(&dax_srcu); | 109 | lockdep_assert_held(&dax_srcu); |