Skip to content

Commit

Permalink
block, dax: move "select DAX" from BLOCK to FS_DAX
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
djbw committed May 8, 2017
1 parent 74d71a0 commit ef51042
Show file tree
Hide file tree
Showing 9 changed files with 102 additions and 71 deletions.
1 change: 0 additions & 1 deletion block/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ menuconfig BLOCK
default y
select SBITMAP
select SRCU
select DAX
help
Provide block layer support for the kernel.

Expand Down
70 changes: 70 additions & 0 deletions drivers/dax/super.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions fs/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
66 changes: 0 additions & 66 deletions fs/block_dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down
1 change: 1 addition & 0 deletions fs/ext2/super.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
1 change: 1 addition & 0 deletions fs/ext4/super.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>

Expand Down
1 change: 1 addition & 0 deletions fs/xfs/xfs_super.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
2 changes: 0 additions & 2 deletions include/linux/blkdev.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
30 changes: 28 additions & 2 deletions include/linux/dax.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit ef51042

Please sign in to comment.