diff options
author | Dan Williams <dan.j.williams@intel.com> | 2017-05-08 13:55:27 -0400 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2017-05-08 13:55:27 -0400 |
commit | ef51042472f55b325fd7f2b26a2e29fd89757234 (patch) | |
tree | ad814d3a1537f69b6ca54c0417260324e8f1a6eb | |
parent | 74d71a01abef37f71d914f2105a4cb8712a2beb8 (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/Kconfig | 1 | ||||
-rw-r--r-- | drivers/dax/super.c | 70 | ||||
-rw-r--r-- | fs/Kconfig | 1 | ||||
-rw-r--r-- | fs/block_dev.c | 66 | ||||
-rw-r--r-- | fs/ext2/super.c | 1 | ||||
-rw-r--r-- | fs/ext4/super.c | 1 | ||||
-rw-r--r-- | fs/xfs/xfs_super.c | 1 | ||||
-rw-r--r-- | include/linux/blkdev.h | 2 | ||||
-rw-r--r-- | include/linux/dax.h | 30 |
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 | } |
48 | EXPORT_SYMBOL_GPL(dax_read_unlock); | 49 | EXPORT_SYMBOL_GPL(dax_read_unlock); |
49 | 50 | ||
51 | int 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 | } | ||
62 | EXPORT_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 | */ | ||
74 | int __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 | } | ||
118 | EXPORT_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 | } |
719 | EXPORT_SYMBOL_GPL(bdev_write_page); | 719 | EXPORT_SYMBOL_GPL(bdev_write_page); |
720 | 720 | ||
721 | int 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 | } | ||
732 | EXPORT_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 | */ | ||
744 | int 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 | } | ||
785 | EXPORT_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, | |||
1940 | extern int bdev_read_page(struct block_device *, sector_t, struct page *); | 1940 | extern int bdev_read_page(struct block_device *, sector_t, struct page *); |
1941 | extern int bdev_write_page(struct block_device *, sector_t, struct page *, | 1941 | extern int bdev_write_page(struct block_device *, sector_t, struct page *, |
1942 | struct writeback_control *); | 1942 | struct writeback_control *); |
1943 | extern int bdev_dax_supported(struct super_block *, int); | ||
1944 | int bdev_dax_pgoff(struct block_device *, sector_t, size_t, pgoff_t *pgoff); | ||
1945 | #else /* CONFIG_BLOCK */ | 1943 | #else /* CONFIG_BLOCK */ |
1946 | 1944 | ||
1947 | struct block_device; | 1945 | struct 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 | ||
21 | int bdev_dax_pgoff(struct block_device *, sector_t, size_t, pgoff_t *pgoff); | ||
22 | #if IS_ENABLED(CONFIG_FS_DAX) | ||
23 | int __bdev_dax_supported(struct super_block *sb, int blocksize); | ||
24 | static inline int bdev_dax_supported(struct super_block *sb, int blocksize) | ||
25 | { | ||
26 | return __bdev_dax_supported(sb, blocksize); | ||
27 | } | ||
28 | #else | ||
29 | static 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) | ||
36 | struct dax_device *dax_get_by_host(const char *host); | ||
37 | void put_dax(struct dax_device *dax_dev); | ||
38 | #else | ||
39 | static inline struct dax_device *dax_get_by_host(const char *host) | ||
40 | { | ||
41 | return NULL; | ||
42 | } | ||
43 | |||
44 | static inline void put_dax(struct dax_device *dax_dev) | ||
45 | { | ||
46 | } | ||
47 | #endif | ||
48 | |||
21 | int dax_read_lock(void); | 49 | int dax_read_lock(void); |
22 | void dax_read_unlock(int id); | 50 | void dax_read_unlock(int id); |
23 | struct dax_device *dax_get_by_host(const char *host); | ||
24 | struct dax_device *alloc_dax(void *private, const char *host, | 51 | struct dax_device *alloc_dax(void *private, const char *host, |
25 | const struct dax_operations *ops); | 52 | const struct dax_operations *ops); |
26 | void put_dax(struct dax_device *dax_dev); | ||
27 | bool dax_alive(struct dax_device *dax_dev); | 53 | bool dax_alive(struct dax_device *dax_dev); |
28 | void kill_dax(struct dax_device *dax_dev); | 54 | void kill_dax(struct dax_device *dax_dev); |
29 | void *dax_get_private(struct dax_device *dax_dev); | 55 | void *dax_get_private(struct dax_device *dax_dev); |