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>
This commit is contained in:
Родитель
74d71a01ab
Коммит
ef51042472
|
@ -6,7 +6,6 @@ menuconfig BLOCK
|
|||
default y
|
||||
select SBITMAP
|
||||
select SRCU
|
||||
select DAX
|
||||
help
|
||||
Provide block layer support for the kernel.
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include <linux/module.h>
|
||||
#include <linux/mount.h>
|
||||
#include <linux/magic.h>
|
||||
#include <linux/genhd.h>
|
||||
#include <linux/cdev.h>
|
||||
#include <linux/hash.h>
|
||||
#include <linux/slab.h>
|
||||
|
@ -47,6 +48,75 @@ void dax_read_unlock(int id)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(dax_read_unlock);
|
||||
|
||||
int bdev_dax_pgoff(struct block_device *bdev, sector_t sector, size_t size,
|
||||
pgoff_t *pgoff)
|
||||
{
|
||||
phys_addr_t phys_off = (get_start_sect(bdev) + sector) * 512;
|
||||
|
||||
if (pgoff)
|
||||
*pgoff = PHYS_PFN(phys_off);
|
||||
if (phys_off % PAGE_SIZE || size % PAGE_SIZE)
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(bdev_dax_pgoff);
|
||||
|
||||
/**
|
||||
* __bdev_dax_supported() - Check if the device supports dax for filesystem
|
||||
* @sb: The superblock of the device
|
||||
* @blocksize: The block size of the device
|
||||
*
|
||||
* This is a library function for filesystems to check if the block device
|
||||
* can be mounted with dax option.
|
||||
*
|
||||
* Return: negative errno if unsupported, 0 if supported.
|
||||
*/
|
||||
int __bdev_dax_supported(struct super_block *sb, int blocksize)
|
||||
{
|
||||
struct block_device *bdev = sb->s_bdev;
|
||||
struct dax_device *dax_dev;
|
||||
pgoff_t pgoff;
|
||||
int err, id;
|
||||
void *kaddr;
|
||||
pfn_t pfn;
|
||||
long len;
|
||||
|
||||
if (blocksize != PAGE_SIZE) {
|
||||
pr_err("VFS (%s): error: unsupported blocksize for dax\n",
|
||||
sb->s_id);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
err = bdev_dax_pgoff(bdev, 0, PAGE_SIZE, &pgoff);
|
||||
if (err) {
|
||||
pr_err("VFS (%s): error: unaligned partition for dax\n",
|
||||
sb->s_id);
|
||||
return err;
|
||||
}
|
||||
|
||||
dax_dev = dax_get_by_host(bdev->bd_disk->disk_name);
|
||||
if (!dax_dev) {
|
||||
pr_err("VFS (%s): error: device does not support dax\n",
|
||||
sb->s_id);
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
id = dax_read_lock();
|
||||
len = dax_direct_access(dax_dev, pgoff, 1, &kaddr, &pfn);
|
||||
dax_read_unlock(id);
|
||||
|
||||
put_dax(dax_dev);
|
||||
|
||||
if (len < 1) {
|
||||
pr_err("VFS (%s): error: dax access failed (%ld)",
|
||||
sb->s_id, len);
|
||||
return len < 0 ? len : -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(__bdev_dax_supported);
|
||||
|
||||
/**
|
||||
* struct dax_device - anchor object for dax services
|
||||
* @inode: core vfs
|
||||
|
|
|
@ -39,6 +39,7 @@ config FS_DAX
|
|||
depends on MMU
|
||||
depends on !(ARM || MIPS || SPARC)
|
||||
select FS_IOMAP
|
||||
select DAX
|
||||
help
|
||||
Direct Access (DAX) can be used on memory-backed block devices.
|
||||
If the block device supports DAX and the filesystem supports DAX,
|
||||
|
|
|
@ -718,72 +718,6 @@ int bdev_write_page(struct block_device *bdev, sector_t sector,
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(bdev_write_page);
|
||||
|
||||
int bdev_dax_pgoff(struct block_device *bdev, sector_t sector, size_t size,
|
||||
pgoff_t *pgoff)
|
||||
{
|
||||
phys_addr_t phys_off = (get_start_sect(bdev) + sector) * 512;
|
||||
|
||||
if (pgoff)
|
||||
*pgoff = PHYS_PFN(phys_off);
|
||||
if (phys_off % PAGE_SIZE || size % PAGE_SIZE)
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(bdev_dax_pgoff);
|
||||
|
||||
/**
|
||||
* bdev_dax_supported() - Check if the device supports dax for filesystem
|
||||
* @sb: The superblock of the device
|
||||
* @blocksize: The block size of the device
|
||||
*
|
||||
* This is a library function for filesystems to check if the block device
|
||||
* can be mounted with dax option.
|
||||
*
|
||||
* Return: negative errno if unsupported, 0 if supported.
|
||||
*/
|
||||
int bdev_dax_supported(struct super_block *sb, int blocksize)
|
||||
{
|
||||
struct block_device *bdev = sb->s_bdev;
|
||||
struct dax_device *dax_dev;
|
||||
pgoff_t pgoff;
|
||||
int err, id;
|
||||
void *kaddr;
|
||||
pfn_t pfn;
|
||||
long len;
|
||||
|
||||
if (blocksize != PAGE_SIZE) {
|
||||
vfs_msg(sb, KERN_ERR, "error: unsupported blocksize for dax");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
err = bdev_dax_pgoff(bdev, 0, PAGE_SIZE, &pgoff);
|
||||
if (err) {
|
||||
vfs_msg(sb, KERN_ERR, "error: unaligned partition for dax");
|
||||
return err;
|
||||
}
|
||||
|
||||
dax_dev = dax_get_by_host(bdev->bd_disk->disk_name);
|
||||
if (!dax_dev) {
|
||||
vfs_msg(sb, KERN_ERR, "error: device does not support dax");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
id = dax_read_lock();
|
||||
len = dax_direct_access(dax_dev, pgoff, 1, &kaddr, &pfn);
|
||||
dax_read_unlock(id);
|
||||
|
||||
put_dax(dax_dev);
|
||||
|
||||
if (len < 1) {
|
||||
vfs_msg(sb, KERN_ERR,
|
||||
"error: dax access failed (%ld)", len);
|
||||
return len < 0 ? len : -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(bdev_dax_supported);
|
||||
|
||||
/*
|
||||
* pseudo-fs
|
||||
*/
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include <linux/log2.h>
|
||||
#include <linux/quotaops.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/dax.h>
|
||||
#include "ext2.h"
|
||||
#include "xattr.h"
|
||||
#include "acl.h"
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include <linux/ctype.h>
|
||||
#include <linux/log2.h>
|
||||
#include <linux/crc16.h>
|
||||
#include <linux/dax.h>
|
||||
#include <linux/cleancache.h>
|
||||
#include <linux/uaccess.h>
|
||||
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
#include "xfs_reflink.h"
|
||||
|
||||
#include <linux/namei.h>
|
||||
#include <linux/dax.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/mount.h>
|
||||
|
|
|
@ -1940,8 +1940,6 @@ extern int __blkdev_driver_ioctl(struct block_device *, fmode_t, unsigned int,
|
|||
extern int bdev_read_page(struct block_device *, sector_t, struct page *);
|
||||
extern int bdev_write_page(struct block_device *, sector_t, struct page *,
|
||||
struct writeback_control *);
|
||||
extern int bdev_dax_supported(struct super_block *, int);
|
||||
int bdev_dax_pgoff(struct block_device *, sector_t, size_t, pgoff_t *pgoff);
|
||||
#else /* CONFIG_BLOCK */
|
||||
|
||||
struct block_device;
|
||||
|
|
|
@ -18,12 +18,38 @@ struct dax_operations {
|
|||
void **, pfn_t *);
|
||||
};
|
||||
|
||||
int bdev_dax_pgoff(struct block_device *, sector_t, size_t, pgoff_t *pgoff);
|
||||
#if IS_ENABLED(CONFIG_FS_DAX)
|
||||
int __bdev_dax_supported(struct super_block *sb, int blocksize);
|
||||
static inline int bdev_dax_supported(struct super_block *sb, int blocksize)
|
||||
{
|
||||
return __bdev_dax_supported(sb, blocksize);
|
||||
}
|
||||
#else
|
||||
static inline int bdev_dax_supported(struct super_block *sb, int blocksize)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if IS_ENABLED(CONFIG_DAX)
|
||||
struct dax_device *dax_get_by_host(const char *host);
|
||||
void put_dax(struct dax_device *dax_dev);
|
||||
#else
|
||||
static inline struct dax_device *dax_get_by_host(const char *host)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline void put_dax(struct dax_device *dax_dev)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
int dax_read_lock(void);
|
||||
void dax_read_unlock(int id);
|
||||
struct dax_device *dax_get_by_host(const char *host);
|
||||
struct dax_device *alloc_dax(void *private, const char *host,
|
||||
const struct dax_operations *ops);
|
||||
void put_dax(struct dax_device *dax_dev);
|
||||
bool dax_alive(struct dax_device *dax_dev);
|
||||
void kill_dax(struct dax_device *dax_dev);
|
||||
void *dax_get_private(struct dax_device *dax_dev);
|
||||
|
|
Загрузка…
Ссылка в новой задаче