aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2017-05-08 13:55:27 -0400
committerDan Williams <dan.j.williams@intel.com>2017-05-08 13:55:27 -0400
commitef51042472f55b325fd7f2b26a2e29fd89757234 (patch)
treead814d3a1537f69b6ca54c0417260324e8f1a6eb
parent74d71a01abef37f71d914f2105a4cb8712a2beb8 (diff)
block, dax: move "select DAX" from BLOCK to FS_DAX
For configurations that do not enable DAX filesystems or drivers, do not require the DAX core to be built. Given that the 'direct_access' method has been removed from 'block_device_operations', we can also go ahead and remove the block-related dax helper functions from fs/block_dev.c to drivers/dax/super.c. This keeps dax details out of the block layer and lets the DAX core be built as a module in the FS_DAX=n case. Filesystems need to include dax.h to call bdev_dax_supported(). Cc: linux-xfs@vger.kernel.org Cc: Jens Axboe <axboe@kernel.dk> Cc: "Theodore Ts'o" <tytso@mit.edu> Cc: Matthew Wilcox <mawilcox@microsoft.com> Cc: Alexander Viro <viro@zeniv.linux.org.uk> Cc: "Darrick J. Wong" <darrick.wong@oracle.com> Cc: Ross Zwisler <ross.zwisler@linux.intel.com> Reviewed-by: Jan Kara <jack@suse.com> Reported-by: Geert Uytterhoeven <geert@linux-m68k.org> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
-rw-r--r--block/Kconfig1
-rw-r--r--drivers/dax/super.c70
-rw-r--r--fs/Kconfig1
-rw-r--r--fs/block_dev.c66
-rw-r--r--fs/ext2/super.c1
-rw-r--r--fs/ext4/super.c1
-rw-r--r--fs/xfs/xfs_super.c1
-rw-r--r--include/linux/blkdev.h2
-rw-r--r--include/linux/dax.h30
9 files changed, 102 insertions, 71 deletions
diff --git a/block/Kconfig b/block/Kconfig
index 93da7fc3f254..e9f780f815f5 100644
--- a/block/Kconfig
+++ b/block/Kconfig
@@ -6,7 +6,6 @@ menuconfig BLOCK
6 default y 6 default y
7 select SBITMAP 7 select SBITMAP
8 select SRCU 8 select SRCU
9 select DAX
10 help 9 help
11 Provide block layer support for the kernel. 10 Provide block layer support for the kernel.
12 11
diff --git a/drivers/dax/super.c b/drivers/dax/super.c
index 465dcd7317d5..e8998d15f3cd 100644
--- a/drivers/dax/super.c
+++ b/drivers/dax/super.c
@@ -14,6 +14,7 @@
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>
@@ -47,6 +48,75 @@ void dax_read_unlock(int id)
47} 48}
48EXPORT_SYMBOL_GPL(dax_read_unlock); 49EXPORT_SYMBOL_GPL(dax_read_unlock);
49 50
51int bdev_dax_pgoff(struct block_device *bdev, sector_t sector, size_t size,
52 pgoff_t *pgoff)
53{
54 phys_addr_t phys_off = (get_start_sect(bdev) + sector) * 512;
55
56 if (pgoff)
57 *pgoff = PHYS_PFN(phys_off);
58 if (phys_off % PAGE_SIZE || size % PAGE_SIZE)
59 return -EINVAL;
60 return 0;
61}
62EXPORT_SYMBOL(bdev_dax_pgoff);
63
64/**
65 * __bdev_dax_supported() - Check if the device supports dax for filesystem
66 * @sb: The superblock of the device
67 * @blocksize: The block size of the device
68 *
69 * This is a library function for filesystems to check if the block device
70 * can be mounted with dax option.
71 *
72 * Return: negative errno if unsupported, 0 if supported.
73 */
74int __bdev_dax_supported(struct super_block *sb, int blocksize)
75{
76 struct block_device *bdev = sb->s_bdev;
77 struct dax_device *dax_dev;
78 pgoff_t pgoff;
79 int err, id;
80 void *kaddr;
81 pfn_t pfn;
82 long len;
83
84 if (blocksize != PAGE_SIZE) {
85 pr_err("VFS (%s): error: unsupported blocksize for dax\n",
86 sb->s_id);
87 return -EINVAL;
88 }
89
90 err = bdev_dax_pgoff(bdev, 0, PAGE_SIZE, &pgoff);
91 if (err) {
92 pr_err("VFS (%s): error: unaligned partition for dax\n",
93 sb->s_id);
94 return err;
95 }
96
97 dax_dev = dax_get_by_host(bdev->bd_disk->disk_name);
98 if (!dax_dev) {
99 pr_err("VFS (%s): error: device does not support dax\n",
100 sb->s_id);
101 return -EOPNOTSUPP;
102 }
103
104 id = dax_read_lock();
105 len = dax_direct_access(dax_dev, pgoff, 1, &kaddr, &pfn);
106 dax_read_unlock(id);
107
108 put_dax(dax_dev);
109
110 if (len < 1) {
111 pr_err("VFS (%s): error: dax access failed (%ld)",
112 sb->s_id, len);
113 return len < 0 ? len : -EIO;
114 }
115
116 return 0;
117}
118EXPORT_SYMBOL_GPL(__bdev_dax_supported);
119
50/** 120/**
51 * struct dax_device - anchor object for dax services 121 * struct dax_device - anchor object for dax services
52 * @inode: core vfs 122 * @inode: core vfs
diff --git a/fs/Kconfig b/fs/Kconfig
index 83eab52fb3f6..b0e42b6a96b9 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -39,6 +39,7 @@ config FS_DAX
39 depends on MMU 39 depends on MMU
40 depends on !(ARM || MIPS || SPARC) 40 depends on !(ARM || MIPS || SPARC)
41 select FS_IOMAP 41 select FS_IOMAP
42 select DAX
42 help 43 help
43 Direct Access (DAX) can be used on memory-backed block devices. 44 Direct Access (DAX) can be used on memory-backed block devices.
44 If the block device supports DAX and the filesystem supports DAX, 45 If the block device supports DAX and the filesystem supports DAX,
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 666367e13711..3096ecd48304 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -718,72 +718,6 @@ int bdev_write_page(struct block_device *bdev, sector_t sector,
718} 718}
719EXPORT_SYMBOL_GPL(bdev_write_page); 719EXPORT_SYMBOL_GPL(bdev_write_page);
720 720
721int bdev_dax_pgoff(struct block_device *bdev, sector_t sector, size_t size,
722 pgoff_t *pgoff)
723{
724 phys_addr_t phys_off = (get_start_sect(bdev) + sector) * 512;
725
726 if (pgoff)
727 *pgoff = PHYS_PFN(phys_off);
728 if (phys_off % PAGE_SIZE || size % PAGE_SIZE)
729 return -EINVAL;
730 return 0;
731}
732EXPORT_SYMBOL(bdev_dax_pgoff);
733
734/**
735 * bdev_dax_supported() - Check if the device supports dax for filesystem
736 * @sb: The superblock of the device
737 * @blocksize: The block size of the device
738 *
739 * This is a library function for filesystems to check if the block device
740 * can be mounted with dax option.
741 *
742 * Return: negative errno if unsupported, 0 if supported.
743 */
744int bdev_dax_supported(struct super_block *sb, int blocksize)
745{
746 struct block_device *bdev = sb->s_bdev;
747 struct dax_device *dax_dev;
748 pgoff_t pgoff;
749 int err, id;
750 void *kaddr;
751 pfn_t pfn;
752 long len;
753
754 if (blocksize != PAGE_SIZE) {
755 vfs_msg(sb, KERN_ERR, "error: unsupported blocksize for dax");
756 return -EINVAL;
757 }
758
759 err = bdev_dax_pgoff(bdev, 0, PAGE_SIZE, &pgoff);
760 if (err) {
761 vfs_msg(sb, KERN_ERR, "error: unaligned partition for dax");
762 return err;
763 }
764
765 dax_dev = dax_get_by_host(bdev->bd_disk->disk_name);
766 if (!dax_dev) {
767 vfs_msg(sb, KERN_ERR, "error: device does not support dax");
768 return -EOPNOTSUPP;
769 }
770
771 id = dax_read_lock();
772 len = dax_direct_access(dax_dev, pgoff, 1, &kaddr, &pfn);
773 dax_read_unlock(id);
774
775 put_dax(dax_dev);
776
777 if (len < 1) {
778 vfs_msg(sb, KERN_ERR,
779 "error: dax access failed (%ld)", len);
780 return len < 0 ? len : -EIO;
781 }
782
783 return 0;
784}
785EXPORT_SYMBOL_GPL(bdev_dax_supported);
786
787/* 721/*
788 * pseudo-fs 722 * pseudo-fs
789 */ 723 */
diff --git a/fs/ext2/super.c b/fs/ext2/super.c
index 9e25a71fe1a2..d07773b81da9 100644
--- a/fs/ext2/super.c
+++ b/fs/ext2/super.c
@@ -32,6 +32,7 @@
32#include <linux/log2.h> 32#include <linux/log2.h>
33#include <linux/quotaops.h> 33#include <linux/quotaops.h>
34#include <linux/uaccess.h> 34#include <linux/uaccess.h>
35#include <linux/dax.h>
35#include "ext2.h" 36#include "ext2.h"
36#include "xattr.h" 37#include "xattr.h"
37#include "acl.h" 38#include "acl.h"
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index a9448db1cf7e..bf6bb8997124 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -37,6 +37,7 @@
37#include <linux/ctype.h> 37#include <linux/ctype.h>
38#include <linux/log2.h> 38#include <linux/log2.h>
39#include <linux/crc16.h> 39#include <linux/crc16.h>
40#include <linux/dax.h>
40#include <linux/cleancache.h> 41#include <linux/cleancache.h>
41#include <linux/uaccess.h> 42#include <linux/uaccess.h>
42 43
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index 685c042a120f..f5c58d6dcafb 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -52,6 +52,7 @@
52#include "xfs_reflink.h" 52#include "xfs_reflink.h"
53 53
54#include <linux/namei.h> 54#include <linux/namei.h>
55#include <linux/dax.h>
55#include <linux/init.h> 56#include <linux/init.h>
56#include <linux/slab.h> 57#include <linux/slab.h>
57#include <linux/mount.h> 58#include <linux/mount.h>
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 848f87eb1905..e4d9899755a7 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -1940,8 +1940,6 @@ extern int __blkdev_driver_ioctl(struct block_device *, fmode_t, unsigned int,
1940extern int bdev_read_page(struct block_device *, sector_t, struct page *); 1940extern int bdev_read_page(struct block_device *, sector_t, struct page *);
1941extern int bdev_write_page(struct block_device *, sector_t, struct page *, 1941extern int bdev_write_page(struct block_device *, sector_t, struct page *,
1942 struct writeback_control *); 1942 struct writeback_control *);
1943extern int bdev_dax_supported(struct super_block *, int);
1944int bdev_dax_pgoff(struct block_device *, sector_t, size_t, pgoff_t *pgoff);
1945#else /* CONFIG_BLOCK */ 1943#else /* CONFIG_BLOCK */
1946 1944
1947struct block_device; 1945struct block_device;
diff --git a/include/linux/dax.h b/include/linux/dax.h
index d3158e74a59e..7fdf1d710042 100644
--- a/include/linux/dax.h
+++ b/include/linux/dax.h
@@ -18,12 +18,38 @@ struct dax_operations {
18 void **, pfn_t *); 18 void **, pfn_t *);
19}; 19};
20 20
21int bdev_dax_pgoff(struct block_device *, sector_t, size_t, pgoff_t *pgoff);
22#if IS_ENABLED(CONFIG_FS_DAX)
23int __bdev_dax_supported(struct super_block *sb, int blocksize);
24static inline int bdev_dax_supported(struct super_block *sb, int blocksize)
25{
26 return __bdev_dax_supported(sb, blocksize);
27}
28#else
29static inline int bdev_dax_supported(struct super_block *sb, int blocksize)
30{
31 return -EOPNOTSUPP;
32}
33#endif
34
35#if IS_ENABLED(CONFIG_DAX)
36struct dax_device *dax_get_by_host(const char *host);
37void put_dax(struct dax_device *dax_dev);
38#else
39static inline struct dax_device *dax_get_by_host(const char *host)
40{
41 return NULL;
42}
43
44static inline void put_dax(struct dax_device *dax_dev)
45{
46}
47#endif
48
21int dax_read_lock(void); 49int dax_read_lock(void);
22void dax_read_unlock(int id); 50void dax_read_unlock(int id);
23struct dax_device *dax_get_by_host(const char *host);
24struct dax_device *alloc_dax(void *private, const char *host, 51struct dax_device *alloc_dax(void *private, const char *host,
25 const struct dax_operations *ops); 52 const struct dax_operations *ops);
26void put_dax(struct dax_device *dax_dev);
27bool dax_alive(struct dax_device *dax_dev); 53bool dax_alive(struct dax_device *dax_dev);
28void kill_dax(struct dax_device *dax_dev); 54void kill_dax(struct dax_device *dax_dev);
29void *dax_get_private(struct dax_device *dax_dev); 55void *dax_get_private(struct dax_device *dax_dev);