Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ef510424 authored by Dan Williams's avatar Dan Williams
Browse files

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: default avatarJan Kara <jack@suse.com>
Reported-by: default avatarGeert Uytterhoeven <geert@linux-m68k.org>
Signed-off-by: default avatarDan Williams <dan.j.williams@intel.com>
parent 74d71a01
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -6,7 +6,6 @@ menuconfig BLOCK
       default y
       select SBITMAP
       select SRCU
       select DAX
       help
	 Provide block layer support for the kernel.

+70 −0
Original line number Diff line number Diff line
@@ -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
+1 −0
Original line number Diff line number Diff line
@@ -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,
+0 −66
Original line number Diff line number Diff line
@@ -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
 */
+1 −0
Original line number Diff line number Diff line
@@ -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"
Loading