summaryrefslogtreecommitdiffstats
path: root/drivers/dax
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-05-12 18:43:10 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2017-05-12 18:43:10 -0400
commit0fcc3ab23d7395f58e8ab0834e7913e2e4314a83 (patch)
treeebd4745696ad330e2da6873cea158d9d56aa661d /drivers/dax
parentdeac8429d62ca19c1571853e2a18f60e760ee04c (diff)
parente84b83b9ee2187817cf895471675f1ccdf64cd53 (diff)
Merge branch 'libnvdimm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm
Pull libnvdimm fixes from Dan Williams: "Incremental fixes and a small feature addition on top of the main libnvdimm 4.12 pull request: - Geert noticed that tinyconfig was bloated by BLOCK selecting DAX. The size regression is fixed by moving all dax helpers into the dax-core and only specifying "select DAX" for FS_DAX and dax-capable drivers. He also asked for clarification of the NR_DEV_DAX config option which, on closer look, does not need to be a config option at all. Mike also throws in a DEV_DAX_PMEM fixup for good measure. - Ben's attention to detail on -stable patch submissions caught a case where the recent fixes to arch_copy_from_iter_pmem() missed a condition where we strand dirty data in the cache. This is tagged for -stable and will also be included in the rework of the pmem api to a proposed {memcpy,copy_user}_flushcache() interface for 4.13. - Vishal adds a feature that missed the initial pull due to pending review feedback. It allows the kernel to clear media errors when initializing a BTT (atomic sector update driver) instance on a pmem namespace. - Ross noticed that the dax_device + dax_operations conversion broke __dax_zero_page_range(). The nvdimm unit tests fail to check this path, but xfstests immediately trips over it. No excuse for missing this before submitting the 4.12 pull request. These all pass the nvdimm unit tests and an xfstests spot check. The set has received a build success notification from the kbuild robot" * 'libnvdimm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm: filesystem-dax: fix broken __dax_zero_page_range() conversion libnvdimm, btt: ensure that initializing metadata clears poison libnvdimm: add an atomic vs process context flag to rw_bytes x86, pmem: Fix cache flushing for iovec write < 8 bytes device-dax: kill NR_DEV_DAX block, dax: move "select DAX" from BLOCK to FS_DAX device-dax: Tell kbuild DEV_DAX_PMEM depends on DEV_DAX
Diffstat (limited to 'drivers/dax')
-rw-r--r--drivers/dax/Kconfig7
-rw-r--r--drivers/dax/super.c81
2 files changed, 74 insertions, 14 deletions
diff --git a/drivers/dax/Kconfig b/drivers/dax/Kconfig
index b7053eafd88e..b79aa8f7a497 100644
--- a/drivers/dax/Kconfig
+++ b/drivers/dax/Kconfig
@@ -19,7 +19,7 @@ config DEV_DAX
19 19
20config DEV_DAX_PMEM 20config DEV_DAX_PMEM
21 tristate "PMEM DAX: direct access to persistent memory" 21 tristate "PMEM DAX: direct access to persistent memory"
22 depends on LIBNVDIMM && NVDIMM_DAX 22 depends on LIBNVDIMM && NVDIMM_DAX && DEV_DAX
23 default DEV_DAX 23 default DEV_DAX
24 help 24 help
25 Support raw access to persistent memory. Note that this 25 Support raw access to persistent memory. Note that this
@@ -28,9 +28,4 @@ config DEV_DAX_PMEM
28 28
29 Say Y if unsure 29 Say Y if unsure
30 30
31config NR_DEV_DAX
32 int "Maximum number of Device-DAX instances"
33 default 32768
34 range 256 2147483647
35
36endif 31endif
diff --git a/drivers/dax/super.c b/drivers/dax/super.c
index 465dcd7317d5..ebf43f531ada 100644
--- a/drivers/dax/super.c
+++ b/drivers/dax/super.c
@@ -14,16 +14,13 @@
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/mount.h> 15#include <linux/mount.h>
16#include <linux/magic.h> 16#include <linux/magic.h>
17#include <linux/genhd.h>
17#include <linux/cdev.h> 18#include <linux/cdev.h>
18#include <linux/hash.h> 19#include <linux/hash.h>
19#include <linux/slab.h> 20#include <linux/slab.h>
20#include <linux/dax.h> 21#include <linux/dax.h>
21#include <linux/fs.h> 22#include <linux/fs.h>
22 23
23static int nr_dax = CONFIG_NR_DEV_DAX;
24module_param(nr_dax, int, S_IRUGO);
25MODULE_PARM_DESC(nr_dax, "max number of dax device instances");
26
27static dev_t dax_devt; 24static dev_t dax_devt;
28DEFINE_STATIC_SRCU(dax_srcu); 25DEFINE_STATIC_SRCU(dax_srcu);
29static struct vfsmount *dax_mnt; 26static struct vfsmount *dax_mnt;
@@ -47,6 +44,75 @@ void dax_read_unlock(int id)
47} 44}
48EXPORT_SYMBOL_GPL(dax_read_unlock); 45EXPORT_SYMBOL_GPL(dax_read_unlock);
49 46
47int bdev_dax_pgoff(struct block_device *bdev, sector_t sector, size_t size,
48 pgoff_t *pgoff)
49{
50 phys_addr_t phys_off = (get_start_sect(bdev) + sector) * 512;
51
52 if (pgoff)
53 *pgoff = PHYS_PFN(phys_off);
54 if (phys_off % PAGE_SIZE || size % PAGE_SIZE)
55 return -EINVAL;
56 return 0;
57}
58EXPORT_SYMBOL(bdev_dax_pgoff);
59
60/**
61 * __bdev_dax_supported() - Check if the device supports dax for filesystem
62 * @sb: The superblock of the device
63 * @blocksize: The block size of the device
64 *
65 * This is a library function for filesystems to check if the block device
66 * can be mounted with dax option.
67 *
68 * Return: negative errno if unsupported, 0 if supported.
69 */
70int __bdev_dax_supported(struct super_block *sb, int blocksize)
71{
72 struct block_device *bdev = sb->s_bdev;
73 struct dax_device *dax_dev;
74 pgoff_t pgoff;
75 int err, id;
76 void *kaddr;
77 pfn_t pfn;
78 long len;
79
80 if (blocksize != PAGE_SIZE) {
81 pr_err("VFS (%s): error: unsupported blocksize for dax\n",
82 sb->s_id);
83 return -EINVAL;
84 }
85
86 err = bdev_dax_pgoff(bdev, 0, PAGE_SIZE, &pgoff);
87 if (err) {
88 pr_err("VFS (%s): error: unaligned partition for dax\n",
89 sb->s_id);
90 return err;
91 }
92
93 dax_dev = dax_get_by_host(bdev->bd_disk->disk_name);
94 if (!dax_dev) {
95 pr_err("VFS (%s): error: device does not support dax\n",
96 sb->s_id);
97 return -EOPNOTSUPP;
98 }
99
100 id = dax_read_lock();
101 len = dax_direct_access(dax_dev, pgoff, 1, &kaddr, &pfn);
102 dax_read_unlock(id);
103
104 put_dax(dax_dev);
105
106 if (len < 1) {
107 pr_err("VFS (%s): error: dax access failed (%ld)",
108 sb->s_id, len);
109 return len < 0 ? len : -EIO;
110 }
111
112 return 0;
113}
114EXPORT_SYMBOL_GPL(__bdev_dax_supported);
115
50/** 116/**
51 * struct dax_device - anchor object for dax services 117 * struct dax_device - anchor object for dax services
52 * @inode: core vfs 118 * @inode: core vfs
@@ -261,7 +327,7 @@ struct dax_device *alloc_dax(void *private, const char *__host,
261 if (__host && !host) 327 if (__host && !host)
262 return NULL; 328 return NULL;
263 329
264 minor = ida_simple_get(&dax_minor_ida, 0, nr_dax, GFP_KERNEL); 330 minor = ida_simple_get(&dax_minor_ida, 0, MINORMASK+1, GFP_KERNEL);
265 if (minor < 0) 331 if (minor < 0)
266 goto err_minor; 332 goto err_minor;
267 333
@@ -405,8 +471,7 @@ static int __init dax_fs_init(void)
405 if (rc) 471 if (rc)
406 return rc; 472 return rc;
407 473
408 nr_dax = max(nr_dax, 256); 474 rc = alloc_chrdev_region(&dax_devt, 0, MINORMASK+1, "dax");
409 rc = alloc_chrdev_region(&dax_devt, 0, nr_dax, "dax");
410 if (rc) 475 if (rc)
411 __dax_fs_exit(); 476 __dax_fs_exit();
412 return rc; 477 return rc;
@@ -414,7 +479,7 @@ static int __init dax_fs_init(void)
414 479
415static void __exit dax_fs_exit(void) 480static void __exit dax_fs_exit(void)
416{ 481{
417 unregister_chrdev_region(dax_devt, nr_dax); 482 unregister_chrdev_region(dax_devt, MINORMASK+1);
418 ida_destroy(&dax_minor_ida); 483 ida_destroy(&dax_minor_ida);
419 __dax_fs_exit(); 484 __dax_fs_exit();
420} 485}