2021-08-26 13:57:12

by Christoph Hellwig

[permalink] [raw]
Subject: dax_supported() related cleanups v2

Hi all,

this series first clarifies how to use fsdax in the Kconfig help a bit,
and then untangles the code path that checks if fsdax is supported.

Changes since v1:
- improve the FS_DAX Kconfig help text further
- write a proper commit log for a patch missing it

Diffstat
drivers/dax/super.c | 191 +++++++++++++++++++-------------------------------
drivers/md/dm-table.c | 9 --
drivers/md/dm.c | 2
fs/Kconfig | 21 ++++-
fs/ext2/super.c | 3
fs/ext4/super.c | 3
fs/xfs/xfs_super.c | 16 +++-
include/linux/dax.h | 41 +---------
8 files changed, 117 insertions(+), 169 deletions(-)


2021-08-26 13:58:34

by Christoph Hellwig

[permalink] [raw]
Subject: [PATCH 1/9] fsdax: improve the FS_DAX Kconfig description and help text

Rename the main option text to clarify it is for file system access,
and add a bit of text that explains how to actually switch a nvdimm
to a fsdax capable state.

Signed-off-by: Christoph Hellwig <[email protected]>
---
fs/Kconfig | 21 ++++++++++++++++++---
1 file changed, 18 insertions(+), 3 deletions(-)

diff --git a/fs/Kconfig b/fs/Kconfig
index a7749c126b8e..bd21535a7620 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -43,7 +43,7 @@ source "fs/f2fs/Kconfig"
source "fs/zonefs/Kconfig"

config FS_DAX
- bool "Direct Access (DAX) support"
+ bool "File system based Direct Access (DAX) support"
depends on MMU
depends on !(ARM || MIPS || SPARC)
select DEV_PAGEMAP_OPS if (ZONE_DEVICE && !FS_DAX_LIMITED)
@@ -53,8 +53,23 @@ config FS_DAX
Direct Access (DAX) can be used on memory-backed block devices.
If the block device supports DAX and the filesystem supports DAX,
then you can avoid using the pagecache to buffer I/Os. Turning
- on this option will compile in support for DAX; you will need to
- mount the filesystem using the -o dax option.
+ on this option will compile in support for DAX.
+
+ For a DAX device to support file system access it needs to have
+ struct pages. For the nfit based NVDIMMs this can be enabled
+ using the ndctl utility:
+
+ # ndctl create-namespace --force --reconfig=namespace0.0 \
+ --mode=fsdax --map=mem
+
+ See the 'create-namespace' man page for details on the overhead of
+ --map=mem:
+ https://docs.pmem.io/ndctl-user-guide/ndctl-man-pages/ndctl-create-namespace
+
+ For ndctl to work CONFIG_DEV_DAX needs to be enabled as well. For most
+ file systems DAX support needs to be manually enabled globally or
+ per-inode using a mount option as well. See the file documentation in
+ Documentation/filesystems/dax.rst for details.

If you do not have a block device that is capable of using this,
or if unsure, say N. Saying Y will increase the size of the kernel
--
2.30.2

2021-08-26 13:59:48

by Christoph Hellwig

[permalink] [raw]
Subject: [PATCH 2/9] dax: stop using bdevname

Just use the %pg format specifier instead.

Signed-off-by: Christoph Hellwig <[email protected]>
Reviewed-by: Dan Williams <[email protected]>
---
drivers/dax/super.c | 20 +++++++-------------
1 file changed, 7 insertions(+), 13 deletions(-)

diff --git a/drivers/dax/super.c b/drivers/dax/super.c
index 44736cbd446e..3e6d7e9ee34f 100644
--- a/drivers/dax/super.c
+++ b/drivers/dax/super.c
@@ -73,7 +73,6 @@ bool __generic_fsdax_supported(struct dax_device *dax_dev,
{
bool dax_enabled = false;
pgoff_t pgoff, pgoff_end;
- char buf[BDEVNAME_SIZE];
void *kaddr, *end_kaddr;
pfn_t pfn, end_pfn;
sector_t last_page;
@@ -81,29 +80,25 @@ bool __generic_fsdax_supported(struct dax_device *dax_dev,
int err, id;

if (blocksize != PAGE_SIZE) {
- pr_info("%s: error: unsupported blocksize for dax\n",
- bdevname(bdev, buf));
+ pr_info("%pg: error: unsupported blocksize for dax\n", bdev);
return false;
}

if (!dax_dev) {
- pr_debug("%s: error: dax unsupported by block device\n",
- bdevname(bdev, buf));
+ pr_debug("%pg: error: dax unsupported by block device\n", bdev);
return false;
}

err = bdev_dax_pgoff(bdev, start, PAGE_SIZE, &pgoff);
if (err) {
- pr_info("%s: error: unaligned partition for dax\n",
- bdevname(bdev, buf));
+ pr_info("%pg: error: unaligned partition for dax\n", bdev);
return false;
}

last_page = PFN_DOWN((start + sectors - 1) * 512) * PAGE_SIZE / 512;
err = bdev_dax_pgoff(bdev, last_page, PAGE_SIZE, &pgoff_end);
if (err) {
- pr_info("%s: error: unaligned partition for dax\n",
- bdevname(bdev, buf));
+ pr_info("%pg: error: unaligned partition for dax\n", bdev);
return false;
}

@@ -112,8 +107,8 @@ bool __generic_fsdax_supported(struct dax_device *dax_dev,
len2 = dax_direct_access(dax_dev, pgoff_end, 1, &end_kaddr, &end_pfn);

if (len < 1 || len2 < 1) {
- pr_info("%s: error: dax access failed (%ld)\n",
- bdevname(bdev, buf), len < 1 ? len : len2);
+ pr_info("%pg: error: dax access failed (%ld)\n",
+ bdev, len < 1 ? len : len2);
dax_read_unlock(id);
return false;
}
@@ -147,8 +142,7 @@ bool __generic_fsdax_supported(struct dax_device *dax_dev,
dax_read_unlock(id);

if (!dax_enabled) {
- pr_info("%s: error: dax support not enabled\n",
- bdevname(bdev, buf));
+ pr_info("%pg: error: dax support not enabled\n", bdev);
return false;
}
return true;
--
2.30.2

2021-08-26 14:02:02

by Christoph Hellwig

[permalink] [raw]
Subject: [PATCH 3/9] dm: use fs_dax_get_by_bdev instead of dax_get_by_host

There is no point in trying to finding the dax device if the DAX flag is
not set on the queue as none of the users of the device mapper exported
block devices could make use of the DAX capability.

Signed-off-by: Christoph Hellwig <[email protected]>
Reviewed-by: Dan Williams <[email protected]>
---
drivers/md/dm.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index 2c5f9e585211..465714341300 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -650,7 +650,7 @@ static int open_table_device(struct table_device *td, dev_t dev,
}

td->dm_dev.bdev = bdev;
- td->dm_dev.dax_dev = dax_get_by_host(bdev->bd_disk->disk_name);
+ td->dm_dev.dax_dev = fs_dax_get_by_bdev(bdev);
return 0;
}

--
2.30.2

2021-08-26 14:02:18

by Christoph Hellwig

[permalink] [raw]
Subject: [PATCH 4/9] dax: mark dax_get_by_host static

And move the code around a bit to avoid a forward declaration.

Signed-off-by: Christoph Hellwig <[email protected]>
Reviewed-by: Dan Williams <[email protected]>
---
drivers/dax/super.c | 109 ++++++++++++++++++++++----------------------
include/linux/dax.h | 5 --
2 files changed, 54 insertions(+), 60 deletions(-)

diff --git a/drivers/dax/super.c b/drivers/dax/super.c
index 3e6d7e9ee34f..e13fde57c33e 100644
--- a/drivers/dax/super.c
+++ b/drivers/dax/super.c
@@ -17,6 +17,24 @@
#include <linux/fs.h>
#include "dax-private.h"

+/**
+ * struct dax_device - anchor object for dax services
+ * @inode: core vfs
+ * @cdev: optional character interface for "device dax"
+ * @host: optional name for lookups where the device path is not available
+ * @private: dax driver private data
+ * @flags: state and boolean properties
+ */
+struct dax_device {
+ struct hlist_node list;
+ struct inode inode;
+ struct cdev cdev;
+ const char *host;
+ void *private;
+ unsigned long flags;
+ const struct dax_operations *ops;
+};
+
static dev_t dax_devt;
DEFINE_STATIC_SRCU(dax_srcu);
static struct vfsmount *dax_mnt;
@@ -40,6 +58,42 @@ void dax_read_unlock(int id)
}
EXPORT_SYMBOL_GPL(dax_read_unlock);

+static int dax_host_hash(const char *host)
+{
+ return hashlen_hash(hashlen_string("DAX", host)) % DAX_HASH_SIZE;
+}
+
+/**
+ * dax_get_by_host() - temporary lookup mechanism for filesystem-dax
+ * @host: alternate name for the device registered by a dax driver
+ */
+static struct dax_device *dax_get_by_host(const char *host)
+{
+ struct dax_device *dax_dev, *found = NULL;
+ int hash, id;
+
+ if (!host)
+ return NULL;
+
+ hash = dax_host_hash(host);
+
+ id = dax_read_lock();
+ spin_lock(&dax_host_lock);
+ hlist_for_each_entry(dax_dev, &dax_host_list[hash], list) {
+ if (!dax_alive(dax_dev)
+ || strcmp(host, dax_dev->host) != 0)
+ continue;
+
+ if (igrab(&dax_dev->inode))
+ found = dax_dev;
+ break;
+ }
+ spin_unlock(&dax_host_lock);
+ dax_read_unlock(id);
+
+ return found;
+}
+
#ifdef CONFIG_BLOCK
#include <linux/blkdev.h>

@@ -202,24 +256,6 @@ enum dax_device_flags {
DAXDEV_SYNC,
};

-/**
- * struct dax_device - anchor object for dax services
- * @inode: core vfs
- * @cdev: optional character interface for "device dax"
- * @host: optional name for lookups where the device path is not available
- * @private: dax driver private data
- * @flags: state and boolean properties
- */
-struct dax_device {
- struct hlist_node list;
- struct inode inode;
- struct cdev cdev;
- const char *host;
- void *private;
- unsigned long flags;
- const struct dax_operations *ops;
-};
-
static ssize_t write_cache_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -417,11 +453,6 @@ bool dax_alive(struct dax_device *dax_dev)
}
EXPORT_SYMBOL_GPL(dax_alive);

-static int dax_host_hash(const char *host)
-{
- return hashlen_hash(hashlen_string("DAX", host)) % DAX_HASH_SIZE;
-}
-
/*
* Note, rcu is not protecting the liveness of dax_dev, rcu is ensuring
* that any fault handlers or operations that might have seen
@@ -618,38 +649,6 @@ void put_dax(struct dax_device *dax_dev)
}
EXPORT_SYMBOL_GPL(put_dax);

-/**
- * dax_get_by_host() - temporary lookup mechanism for filesystem-dax
- * @host: alternate name for the device registered by a dax driver
- */
-struct dax_device *dax_get_by_host(const char *host)
-{
- struct dax_device *dax_dev, *found = NULL;
- int hash, id;
-
- if (!host)
- return NULL;
-
- hash = dax_host_hash(host);
-
- id = dax_read_lock();
- spin_lock(&dax_host_lock);
- hlist_for_each_entry(dax_dev, &dax_host_list[hash], list) {
- if (!dax_alive(dax_dev)
- || strcmp(host, dax_dev->host) != 0)
- continue;
-
- if (igrab(&dax_dev->inode))
- found = dax_dev;
- break;
- }
- spin_unlock(&dax_host_lock);
- dax_read_unlock(id);
-
- return found;
-}
-EXPORT_SYMBOL_GPL(dax_get_by_host);
-
/**
* inode_dax: convert a public inode into its dax_dev
* @inode: An inode with i_cdev pointing to a dax_dev
diff --git a/include/linux/dax.h b/include/linux/dax.h
index b52f084aa643..379739b55408 100644
--- a/include/linux/dax.h
+++ b/include/linux/dax.h
@@ -41,7 +41,6 @@ struct dax_operations {
extern struct attribute_group dax_attribute_group;

#if IS_ENABLED(CONFIG_DAX)
-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, unsigned long flags);
void put_dax(struct dax_device *dax_dev);
@@ -73,10 +72,6 @@ static inline bool daxdev_mapping_supported(struct vm_area_struct *vma,
return dax_synchronous(dax_dev);
}
#else
-static inline struct dax_device *dax_get_by_host(const char *host)
-{
- return NULL;
-}
static inline struct dax_device *alloc_dax(void *private, const char *host,
const struct dax_operations *ops, unsigned long flags)
{
--
2.30.2

2021-08-26 14:04:20

by Christoph Hellwig

[permalink] [raw]
Subject: [PATCH 6/9] dax: remove __generic_fsdax_supported

Just implement generic_fsdax_supported directly out of line instead of
adding a wrapper. Given that generic_fsdax_supported is only supplied
for CONFIG_FS_DAX builds this also allows to not provide it at all for
!CONFIG_FS_DAX builds.

Signed-off-by: Christoph Hellwig <[email protected]>
Reviewed-by: Dan Williams <[email protected]>
---
drivers/dax/super.c | 8 ++++----
include/linux/dax.h | 16 ++--------------
2 files changed, 6 insertions(+), 18 deletions(-)

diff --git a/drivers/dax/super.c b/drivers/dax/super.c
index 0f74f83101ab..8e8ccb3e956b 100644
--- a/drivers/dax/super.c
+++ b/drivers/dax/super.c
@@ -119,9 +119,8 @@ struct dax_device *fs_dax_get_by_bdev(struct block_device *bdev)
return dax_get_by_host(bdev->bd_disk->disk_name);
}
EXPORT_SYMBOL_GPL(fs_dax_get_by_bdev);
-#endif

-bool __generic_fsdax_supported(struct dax_device *dax_dev,
+bool generic_fsdax_supported(struct dax_device *dax_dev,
struct block_device *bdev, int blocksize, sector_t start,
sector_t sectors)
{
@@ -201,7 +200,8 @@ bool __generic_fsdax_supported(struct dax_device *dax_dev,
}
return true;
}
-EXPORT_SYMBOL_GPL(__generic_fsdax_supported);
+EXPORT_SYMBOL_GPL(generic_fsdax_supported);
+#endif /* CONFIG_FS_DAX */

/**
* __bdev_dax_supported() - Check if the device supports dax for filesystem
@@ -360,7 +360,7 @@ bool dax_supported(struct dax_device *dax_dev, struct block_device *bdev,
return false;

id = dax_read_lock();
- if (dax_alive(dax_dev))
+ if (dax_alive(dax_dev) && dax_dev->ops->dax_supported)
ret = dax_dev->ops->dax_supported(dax_dev, bdev, blocksize,
start, len);
dax_read_unlock(id);
diff --git a/include/linux/dax.h b/include/linux/dax.h
index 379739b55408..0a3ef9701e03 100644
--- a/include/linux/dax.h
+++ b/include/linux/dax.h
@@ -123,16 +123,9 @@ static inline bool bdev_dax_supported(struct block_device *bdev, int blocksize)
return __bdev_dax_supported(bdev, blocksize);
}

-bool __generic_fsdax_supported(struct dax_device *dax_dev,
+bool generic_fsdax_supported(struct dax_device *dax_dev,
struct block_device *bdev, int blocksize, sector_t start,
sector_t sectors);
-static inline bool generic_fsdax_supported(struct dax_device *dax_dev,
- struct block_device *bdev, int blocksize, sector_t start,
- sector_t sectors)
-{
- return __generic_fsdax_supported(dax_dev, bdev, blocksize, start,
- sectors);
-}

static inline void fs_put_dax(struct dax_device *dax_dev)
{
@@ -154,12 +147,7 @@ static inline bool bdev_dax_supported(struct block_device *bdev,
return false;
}

-static inline bool generic_fsdax_supported(struct dax_device *dax_dev,
- struct block_device *bdev, int blocksize, sector_t start,
- sector_t sectors)
-{
- return false;
-}
+#define generic_fsdax_supported NULL

static inline void fs_put_dax(struct dax_device *dax_dev)
{
--
2.30.2

2021-08-26 14:04:28

by Christoph Hellwig

[permalink] [raw]
Subject: [PATCH 5/9] dax: move the dax_read_lock() locking into dax_supported

Move the dax_read_lock/dax_read_unlock pair from the callers into
dax_supported to make it a little easier to use.

Signed-off-by: Christoph Hellwig <[email protected]>
Reviewed-by: Dan Williams <[email protected]>
---
drivers/dax/super.c | 16 +++++++++-------
drivers/md/dm-table.c | 9 ++-------
2 files changed, 11 insertions(+), 14 deletions(-)

diff --git a/drivers/dax/super.c b/drivers/dax/super.c
index e13fde57c33e..0f74f83101ab 100644
--- a/drivers/dax/super.c
+++ b/drivers/dax/super.c
@@ -219,7 +219,6 @@ bool __bdev_dax_supported(struct block_device *bdev, int blocksize)
struct request_queue *q;
char buf[BDEVNAME_SIZE];
bool ret;
- int id;

q = bdev_get_queue(bdev);
if (!q || !blk_queue_dax(q)) {
@@ -235,10 +234,8 @@ bool __bdev_dax_supported(struct block_device *bdev, int blocksize)
return false;
}

- id = dax_read_lock();
ret = dax_supported(dax_dev, bdev, blocksize, 0,
i_size_read(bdev->bd_inode) / 512);
- dax_read_unlock(id);

put_dax(dax_dev);

@@ -356,13 +353,18 @@ EXPORT_SYMBOL_GPL(dax_direct_access);
bool dax_supported(struct dax_device *dax_dev, struct block_device *bdev,
int blocksize, sector_t start, sector_t len)
{
- if (!dax_dev)
- return false;
+ bool ret = false;
+ int id;

- if (!dax_alive(dax_dev))
+ if (!dax_dev)
return false;

- return dax_dev->ops->dax_supported(dax_dev, bdev, blocksize, start, len);
+ id = dax_read_lock();
+ if (dax_alive(dax_dev))
+ ret = dax_dev->ops->dax_supported(dax_dev, bdev, blocksize,
+ start, len);
+ dax_read_unlock(id);
+ return ret;
}
EXPORT_SYMBOL_GPL(dax_supported);

diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c
index 0543cdf89e92..b53acca37581 100644
--- a/drivers/md/dm-table.c
+++ b/drivers/md/dm-table.c
@@ -809,14 +809,9 @@ EXPORT_SYMBOL_GPL(dm_table_set_type);
int device_not_dax_capable(struct dm_target *ti, struct dm_dev *dev,
sector_t start, sector_t len, void *data)
{
- int blocksize = *(int *) data, id;
- bool rc;
+ int blocksize = *(int *) data;

- id = dax_read_lock();
- rc = !dax_supported(dev->dax_dev, dev->bdev, blocksize, start, len);
- dax_read_unlock(id);
-
- return rc;
+ return !dax_supported(dev->dax_dev, dev->bdev, blocksize, start, len);
}

/* Check devices support synchronous DAX */
--
2.30.2

2021-08-26 14:07:39

by Christoph Hellwig

[permalink] [raw]
Subject: [PATCH 7/9] dax: stub out dax_supported for !CONFIG_FS_DAX

dax_supported calls into ->dax_supported which checks for fsdax support.
Don't bother building it for !CONFIG_FS_DAX as it will always return
false.

Signed-off-by: Christoph Hellwig <[email protected]>
Reviewed-by: Dan Williams <[email protected]>
---
drivers/dax/super.c | 36 ++++++++++++++++++------------------
include/linux/dax.h | 18 ++++++++++--------
2 files changed, 28 insertions(+), 26 deletions(-)

diff --git a/drivers/dax/super.c b/drivers/dax/super.c
index 8e8ccb3e956b..eed02729add3 100644
--- a/drivers/dax/super.c
+++ b/drivers/dax/super.c
@@ -201,6 +201,24 @@ bool generic_fsdax_supported(struct dax_device *dax_dev,
return true;
}
EXPORT_SYMBOL_GPL(generic_fsdax_supported);
+
+bool dax_supported(struct dax_device *dax_dev, struct block_device *bdev,
+ int blocksize, sector_t start, sector_t len)
+{
+ bool ret = false;
+ int id;
+
+ if (!dax_dev)
+ return false;
+
+ id = dax_read_lock();
+ if (dax_alive(dax_dev) && dax_dev->ops->dax_supported)
+ ret = dax_dev->ops->dax_supported(dax_dev, bdev, blocksize,
+ start, len);
+ dax_read_unlock(id);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(dax_supported);
#endif /* CONFIG_FS_DAX */

/**
@@ -350,24 +368,6 @@ long dax_direct_access(struct dax_device *dax_dev, pgoff_t pgoff, long nr_pages,
}
EXPORT_SYMBOL_GPL(dax_direct_access);

-bool dax_supported(struct dax_device *dax_dev, struct block_device *bdev,
- int blocksize, sector_t start, sector_t len)
-{
- bool ret = false;
- int id;
-
- if (!dax_dev)
- return false;
-
- id = dax_read_lock();
- if (dax_alive(dax_dev) && dax_dev->ops->dax_supported)
- ret = dax_dev->ops->dax_supported(dax_dev, bdev, blocksize,
- start, len);
- dax_read_unlock(id);
- return ret;
-}
-EXPORT_SYMBOL_GPL(dax_supported);
-
size_t dax_copy_from_iter(struct dax_device *dax_dev, pgoff_t pgoff, void *addr,
size_t bytes, struct iov_iter *i)
{
diff --git a/include/linux/dax.h b/include/linux/dax.h
index 0a3ef9701e03..32dce5763f2c 100644
--- a/include/linux/dax.h
+++ b/include/linux/dax.h
@@ -57,8 +57,6 @@ static inline void set_dax_synchronous(struct dax_device *dax_dev)
{
__set_dax_synchronous(dax_dev);
}
-bool dax_supported(struct dax_device *dax_dev, struct block_device *bdev,
- int blocksize, sector_t start, sector_t len);
/*
* Check if given mapping is supported by the file / underlying device.
*/
@@ -101,12 +99,6 @@ static inline bool dax_synchronous(struct dax_device *dax_dev)
static inline void set_dax_synchronous(struct dax_device *dax_dev)
{
}
-static inline bool dax_supported(struct dax_device *dax_dev,
- struct block_device *bdev, int blocksize, sector_t start,
- sector_t len)
-{
- return false;
-}
static inline bool daxdev_mapping_supported(struct vm_area_struct *vma,
struct dax_device *dax_dev)
{
@@ -127,6 +119,9 @@ bool generic_fsdax_supported(struct dax_device *dax_dev,
struct block_device *bdev, int blocksize, sector_t start,
sector_t sectors);

+bool dax_supported(struct dax_device *dax_dev, struct block_device *bdev,
+ int blocksize, sector_t start, sector_t len);
+
static inline void fs_put_dax(struct dax_device *dax_dev)
{
put_dax(dax_dev);
@@ -149,6 +144,13 @@ static inline bool bdev_dax_supported(struct block_device *bdev,

#define generic_fsdax_supported NULL

+static inline bool dax_supported(struct dax_device *dax_dev,
+ struct block_device *bdev, int blocksize, sector_t start,
+ sector_t len)
+{
+ return false;
+}
+
static inline void fs_put_dax(struct dax_device *dax_dev)
{
}
--
2.30.2

2021-08-26 14:07:42

by Christoph Hellwig

[permalink] [raw]
Subject: [PATCH 8/9] xfs: factor out a xfs_buftarg_is_dax helper

Refactor the DAX setup code in preparation of removing
bdev_dax_supported.

Signed-off-by: Christoph Hellwig <[email protected]>
Reviewed-by: Dan Williams <[email protected]>
---
fs/xfs/xfs_super.c | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index 2c9e26a44546..5a89bf601d97 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -314,6 +314,14 @@ xfs_set_inode_alloc(
return (mp->m_flags & XFS_MOUNT_32BITINODES) ? maxagi : agcount;
}

+static bool
+xfs_buftarg_is_dax(
+ struct super_block *sb,
+ struct xfs_buftarg *bt)
+{
+ return bdev_dax_supported(bt->bt_bdev, sb->s_blocksize);
+}
+
STATIC int
xfs_blkdev_get(
xfs_mount_t *mp,
@@ -1549,11 +1557,10 @@ xfs_fs_fill_super(
xfs_warn(mp,
"DAX enabled. Warning: EXPERIMENTAL, use at your own risk");

- datadev_is_dax = bdev_dax_supported(mp->m_ddev_targp->bt_bdev,
- sb->s_blocksize);
+ datadev_is_dax = xfs_buftarg_is_dax(sb, mp->m_ddev_targp);
if (mp->m_rtdev_targp)
- rtdev_is_dax = bdev_dax_supported(
- mp->m_rtdev_targp->bt_bdev, sb->s_blocksize);
+ rtdev_is_dax = xfs_buftarg_is_dax(sb,
+ mp->m_rtdev_targp);
if (!rtdev_is_dax && !datadev_is_dax) {
xfs_alert(mp,
"DAX unsupported by block device. Turning off DAX.");
--
2.30.2

2021-08-26 14:08:50

by Christoph Hellwig

[permalink] [raw]
Subject: [PATCH 9/9] dax: remove bdev_dax_supported

All callers already have a dax_device obtained from fs_dax_get_by_bdev
at hand, so just pass that to dax_supported() insted of doing another
lookup.

Signed-off-by: Christoph Hellwig <[email protected]>
Reviewed-by: Dan Williams <[email protected]>
---
drivers/dax/super.c | 42 +-----------------------------------------
fs/ext2/super.c | 3 ++-
fs/ext4/super.c | 3 ++-
fs/xfs/xfs_super.c | 3 ++-
include/linux/dax.h | 12 ------------
5 files changed, 7 insertions(+), 56 deletions(-)

diff --git a/drivers/dax/super.c b/drivers/dax/super.c
index eed02729add3..fc89e91beea7 100644
--- a/drivers/dax/super.c
+++ b/drivers/dax/super.c
@@ -220,47 +220,7 @@ bool dax_supported(struct dax_device *dax_dev, struct block_device *bdev,
}
EXPORT_SYMBOL_GPL(dax_supported);
#endif /* CONFIG_FS_DAX */
-
-/**
- * __bdev_dax_supported() - Check if the device supports dax for filesystem
- * @bdev: block device to check
- * @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: true if supported, false if unsupported
- */
-bool __bdev_dax_supported(struct block_device *bdev, int blocksize)
-{
- struct dax_device *dax_dev;
- struct request_queue *q;
- char buf[BDEVNAME_SIZE];
- bool ret;
-
- q = bdev_get_queue(bdev);
- if (!q || !blk_queue_dax(q)) {
- pr_debug("%s: error: request queue doesn't support dax\n",
- bdevname(bdev, buf));
- return false;
- }
-
- dax_dev = dax_get_by_host(bdev->bd_disk->disk_name);
- if (!dax_dev) {
- pr_debug("%s: error: device does not support dax\n",
- bdevname(bdev, buf));
- return false;
- }
-
- ret = dax_supported(dax_dev, bdev, blocksize, 0,
- i_size_read(bdev->bd_inode) / 512);
-
- put_dax(dax_dev);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(__bdev_dax_supported);
-#endif
+#endif /* CONFIG_BLOCK */

enum dax_device_flags {
/* !alive + rcu grace period == no new operations / mappings */
diff --git a/fs/ext2/super.c b/fs/ext2/super.c
index 21e09fbaa46f..26e69e48d7e0 100644
--- a/fs/ext2/super.c
+++ b/fs/ext2/super.c
@@ -949,7 +949,8 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent)
blocksize = BLOCK_SIZE << le32_to_cpu(sbi->s_es->s_log_block_size);

if (test_opt(sb, DAX)) {
- if (!bdev_dax_supported(sb->s_bdev, blocksize)) {
+ if (!dax_supported(dax_dev, sb->s_bdev, blocksize, 0,
+ bdev_nr_sectors(sb->s_bdev))) {
ext2_msg(sb, KERN_ERR,
"DAX unsupported by block device. Turning off DAX.");
clear_opt(sbi->s_mount_opt, DAX);
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index dfa09a277b56..a1726a8debce 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -4435,7 +4435,8 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
goto failed_mount;
}

- if (bdev_dax_supported(sb->s_bdev, blocksize))
+ if (dax_supported(dax_dev, sb->s_bdev, blocksize, 0,
+ bdev_nr_sectors(sb->s_bdev)))
set_bit(EXT4_FLAGS_BDEV_IS_DAX, &sbi->s_ext4_flags);

if (sbi->s_mount_opt & EXT4_MOUNT_DAX_ALWAYS) {
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index 5a89bf601d97..f4384974e52a 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -319,7 +319,8 @@ xfs_buftarg_is_dax(
struct super_block *sb,
struct xfs_buftarg *bt)
{
- return bdev_dax_supported(bt->bt_bdev, sb->s_blocksize);
+ return dax_supported(bt->bt_daxdev, bt->bt_bdev, sb->s_blocksize, 0,
+ bdev_nr_sectors(bt->bt_bdev));
}

STATIC int
diff --git a/include/linux/dax.h b/include/linux/dax.h
index 32dce5763f2c..2619d94c308d 100644
--- a/include/linux/dax.h
+++ b/include/linux/dax.h
@@ -109,12 +109,6 @@ static inline bool daxdev_mapping_supported(struct vm_area_struct *vma,
struct writeback_control;
int bdev_dax_pgoff(struct block_device *, sector_t, size_t, pgoff_t *pgoff);
#if IS_ENABLED(CONFIG_FS_DAX)
-bool __bdev_dax_supported(struct block_device *bdev, int blocksize);
-static inline bool bdev_dax_supported(struct block_device *bdev, int blocksize)
-{
- return __bdev_dax_supported(bdev, blocksize);
-}
-
bool generic_fsdax_supported(struct dax_device *dax_dev,
struct block_device *bdev, int blocksize, sector_t start,
sector_t sectors);
@@ -136,12 +130,6 @@ struct page *dax_layout_busy_page_range(struct address_space *mapping, loff_t st
dax_entry_t dax_lock_page(struct page *page);
void dax_unlock_page(struct page *page, dax_entry_t cookie);
#else
-static inline bool bdev_dax_supported(struct block_device *bdev,
- int blocksize)
-{
- return false;
-}
-
#define generic_fsdax_supported NULL

static inline bool dax_supported(struct dax_device *dax_dev,
--
2.30.2

2021-08-26 14:38:51

by Dan Williams

[permalink] [raw]
Subject: Re: [PATCH 8/9] xfs: factor out a xfs_buftarg_is_dax helper

[ add Darrick ]


On Thu, Aug 26, 2021 at 7:07 AM Christoph Hellwig <[email protected]> wrote:
>
> Refactor the DAX setup code in preparation of removing
> bdev_dax_supported.
>
> Signed-off-by: Christoph Hellwig <[email protected]>
> Reviewed-by: Dan Williams <[email protected]>
> ---
> fs/xfs/xfs_super.c | 15 +++++++++++----
> 1 file changed, 11 insertions(+), 4 deletions(-)

Darrick, any concerns with me taking this through the dax tree?

>
> diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
> index 2c9e26a44546..5a89bf601d97 100644
> --- a/fs/xfs/xfs_super.c
> +++ b/fs/xfs/xfs_super.c
> @@ -314,6 +314,14 @@ xfs_set_inode_alloc(
> return (mp->m_flags & XFS_MOUNT_32BITINODES) ? maxagi : agcount;
> }
>
> +static bool
> +xfs_buftarg_is_dax(
> + struct super_block *sb,
> + struct xfs_buftarg *bt)
> +{
> + return bdev_dax_supported(bt->bt_bdev, sb->s_blocksize);
> +}
> +
> STATIC int
> xfs_blkdev_get(
> xfs_mount_t *mp,
> @@ -1549,11 +1557,10 @@ xfs_fs_fill_super(
> xfs_warn(mp,
> "DAX enabled. Warning: EXPERIMENTAL, use at your own risk");
>
> - datadev_is_dax = bdev_dax_supported(mp->m_ddev_targp->bt_bdev,
> - sb->s_blocksize);
> + datadev_is_dax = xfs_buftarg_is_dax(sb, mp->m_ddev_targp);
> if (mp->m_rtdev_targp)
> - rtdev_is_dax = bdev_dax_supported(
> - mp->m_rtdev_targp->bt_bdev, sb->s_blocksize);
> + rtdev_is_dax = xfs_buftarg_is_dax(sb,
> + mp->m_rtdev_targp);
> if (!rtdev_is_dax && !datadev_is_dax) {
> xfs_alert(mp,
> "DAX unsupported by block device. Turning off DAX.");
> --
> 2.30.2
>
>

2021-08-26 14:42:44

by Dan Williams

[permalink] [raw]
Subject: Re: [PATCH 3/9] dm: use fs_dax_get_by_bdev instead of dax_get_by_host

On Thu, Aug 26, 2021 at 6:59 AM Christoph Hellwig <[email protected]> wrote:
>
> There is no point in trying to finding the dax device if the DAX flag is
> not set on the queue as none of the users of the device mapper exported
> block devices could make use of the DAX capability.
>
> Signed-off-by: Christoph Hellwig <[email protected]>
> Reviewed-by: Dan Williams <[email protected]>
> ---
> drivers/md/dm.c | 2 +-

Mike, any objections to me taking this through a dax branch?

> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/md/dm.c b/drivers/md/dm.c
> index 2c5f9e585211..465714341300 100644
> --- a/drivers/md/dm.c
> +++ b/drivers/md/dm.c
> @@ -650,7 +650,7 @@ static int open_table_device(struct table_device *td, dev_t dev,
> }
>
> td->dm_dev.bdev = bdev;
> - td->dm_dev.dax_dev = dax_get_by_host(bdev->bd_disk->disk_name);
> + td->dm_dev.dax_dev = fs_dax_get_by_bdev(bdev);
> return 0;
> }
>
> --
> 2.30.2
>

2021-08-26 15:13:23

by Darrick J. Wong

[permalink] [raw]
Subject: Re: [PATCH 8/9] xfs: factor out a xfs_buftarg_is_dax helper

On Thu, Aug 26, 2021 at 07:37:29AM -0700, Dan Williams wrote:
> [ add Darrick ]
>
>
> On Thu, Aug 26, 2021 at 7:07 AM Christoph Hellwig <[email protected]> wrote:
> >
> > Refactor the DAX setup code in preparation of removing
> > bdev_dax_supported.
> >
> > Signed-off-by: Christoph Hellwig <[email protected]>
> > Reviewed-by: Dan Williams <[email protected]>
> > ---
> > fs/xfs/xfs_super.c | 15 +++++++++++----
> > 1 file changed, 11 insertions(+), 4 deletions(-)
>
> Darrick, any concerns with me taking this through the dax tree?

Nope.

Reviewed-by: Darrick J. Wong <[email protected]>

--D

>
> >
> > diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
> > index 2c9e26a44546..5a89bf601d97 100644
> > --- a/fs/xfs/xfs_super.c
> > +++ b/fs/xfs/xfs_super.c
> > @@ -314,6 +314,14 @@ xfs_set_inode_alloc(
> > return (mp->m_flags & XFS_MOUNT_32BITINODES) ? maxagi : agcount;
> > }
> >
> > +static bool
> > +xfs_buftarg_is_dax(
> > + struct super_block *sb,
> > + struct xfs_buftarg *bt)
> > +{
> > + return bdev_dax_supported(bt->bt_bdev, sb->s_blocksize);
> > +}
> > +
> > STATIC int
> > xfs_blkdev_get(
> > xfs_mount_t *mp,
> > @@ -1549,11 +1557,10 @@ xfs_fs_fill_super(
> > xfs_warn(mp,
> > "DAX enabled. Warning: EXPERIMENTAL, use at your own risk");
> >
> > - datadev_is_dax = bdev_dax_supported(mp->m_ddev_targp->bt_bdev,
> > - sb->s_blocksize);
> > + datadev_is_dax = xfs_buftarg_is_dax(sb, mp->m_ddev_targp);
> > if (mp->m_rtdev_targp)
> > - rtdev_is_dax = bdev_dax_supported(
> > - mp->m_rtdev_targp->bt_bdev, sb->s_blocksize);
> > + rtdev_is_dax = xfs_buftarg_is_dax(sb,
> > + mp->m_rtdev_targp);
> > if (!rtdev_is_dax && !datadev_is_dax) {
> > xfs_alert(mp,
> > "DAX unsupported by block device. Turning off DAX.");
> > --
> > 2.30.2
> >
> >

2021-08-26 16:20:18

by Mike Snitzer

[permalink] [raw]
Subject: Re: [PATCH 3/9] dm: use fs_dax_get_by_bdev instead of dax_get_by_host

On Thu, Aug 26 2021 at 10:42P -0400,
Dan Williams <[email protected]> wrote:

> On Thu, Aug 26, 2021 at 6:59 AM Christoph Hellwig <[email protected]> wrote:
> >
> > There is no point in trying to finding the dax device if the DAX flag is
> > not set on the queue as none of the users of the device mapper exported
> > block devices could make use of the DAX capability.
> >
> > Signed-off-by: Christoph Hellwig <[email protected]>
> > Reviewed-by: Dan Williams <[email protected]>
> > ---
> > drivers/md/dm.c | 2 +-
>
> Mike, any objections to me taking this through a dax branch?

No.

Reviewed-by: Mike Snitzer <[email protected]>

Thanks.