* [PATCH v2 0/2] fs, dax: lookup dax_device at mount time
@ 2017-08-28 3:48 ` Dan Williams
0 siblings, 0 replies; 28+ messages in thread
From: Dan Williams @ 2017-08-28 3:48 UTC (permalink / raw)
To: linux-fsdevel
Cc: jack, linux-nvdimm, Darrick J. Wong, linux-xfs, Andreas Dilger,
Jan Kara, Theodore Ts'o, linux-ext4, hch
Changes since v1:
* Move the lookup to mount time. (Christoph)
---
Christoph notes:
I just noticed that we now do a fs_dax_get_by_host in every
iomap_begin call for DAX. This function iterates a list, does a
string compared and igrab. I really think we need to cache this in
the superblock (possible even the fs superblock) similar to what we
do for the block device.
This passes the libnvdimm unit tests.
---
Dan Williams (2):
fs, xfs: perform dax_device lookup at mount
ext2, ext4: use the super_block dax_device
drivers/dax/super.c | 10 ++++++++++
fs/ext2/inode.c | 10 ++--------
fs/ext4/inode.c | 10 ++--------
fs/super.c | 26 +++++++++++++++++++++++---
fs/xfs/xfs_aops.c | 13 +++++++++++++
fs/xfs/xfs_aops.h | 1 +
fs/xfs/xfs_buf.c | 4 +++-
fs/xfs/xfs_buf.h | 3 ++-
fs/xfs/xfs_iomap.c | 10 +---------
fs/xfs/xfs_super.c | 21 +++++++++++++++++----
include/linux/dax.h | 6 ++++++
include/linux/fs.h | 1 +
12 files changed, 81 insertions(+), 34 deletions(-)
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v2 0/2] fs, dax: lookup dax_device at mount time
@ 2017-08-28 3:48 ` Dan Williams
0 siblings, 0 replies; 28+ messages in thread
From: Dan Williams @ 2017-08-28 3:48 UTC (permalink / raw)
To: linux-fsdevel
Cc: jack, Darrick J. Wong, linux-nvdimm, linux-xfs, Andreas Dilger,
Jan Kara, Theodore Ts'o, linux-ext4, hch
Changes since v1:
* Move the lookup to mount time. (Christoph)
---
Christoph notes:
I just noticed that we now do a fs_dax_get_by_host in every
iomap_begin call for DAX. This function iterates a list, does a
string compared and igrab. I really think we need to cache this in
the superblock (possible even the fs superblock) similar to what we
do for the block device.
This passes the libnvdimm unit tests.
---
Dan Williams (2):
fs, xfs: perform dax_device lookup at mount
ext2, ext4: use the super_block dax_device
drivers/dax/super.c | 10 ++++++++++
fs/ext2/inode.c | 10 ++--------
fs/ext4/inode.c | 10 ++--------
fs/super.c | 26 +++++++++++++++++++++++---
fs/xfs/xfs_aops.c | 13 +++++++++++++
fs/xfs/xfs_aops.h | 1 +
fs/xfs/xfs_buf.c | 4 +++-
fs/xfs/xfs_buf.h | 3 ++-
fs/xfs/xfs_iomap.c | 10 +---------
fs/xfs/xfs_super.c | 21 +++++++++++++++++----
include/linux/dax.h | 6 ++++++
include/linux/fs.h | 1 +
12 files changed, 81 insertions(+), 34 deletions(-)
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v2 1/2] fs, xfs: perform dax_device lookup at mount
2017-08-28 3:48 ` Dan Williams
(?)
@ 2017-08-28 3:48 ` Dan Williams
-1 siblings, 0 replies; 28+ messages in thread
From: Dan Williams @ 2017-08-28 3:48 UTC (permalink / raw)
To: linux-fsdevel
Cc: jack, Darrick J. Wong, linux-nvdimm, linux-xfs, linux-ext4, hch
The ->iomap_begin() operation is a hot path, so cache the
fs_dax_get_by_host() result at mount time to avoid the incurring the
hash lookup overhead on a per-i/o basis.
Cc: "Darrick J. Wong" <darrick.wong@oracle.com>
Reported-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
drivers/dax/super.c | 10 ++++++++++
fs/super.c | 26 +++++++++++++++++++++++---
fs/xfs/xfs_aops.c | 13 +++++++++++++
fs/xfs/xfs_aops.h | 1 +
fs/xfs/xfs_buf.c | 4 +++-
fs/xfs/xfs_buf.h | 3 ++-
fs/xfs/xfs_iomap.c | 10 +---------
fs/xfs/xfs_super.c | 21 +++++++++++++++++----
include/linux/dax.h | 6 ++++++
include/linux/fs.h | 1 +
10 files changed, 77 insertions(+), 18 deletions(-)
diff --git a/drivers/dax/super.c b/drivers/dax/super.c
index 938eb4868f7f..b699aac268a6 100644
--- a/drivers/dax/super.c
+++ b/drivers/dax/super.c
@@ -46,6 +46,8 @@ void dax_read_unlock(int id)
EXPORT_SYMBOL_GPL(dax_read_unlock);
#ifdef CONFIG_BLOCK
+#include <linux/blkdev.h>
+
int bdev_dax_pgoff(struct block_device *bdev, sector_t sector, size_t size,
pgoff_t *pgoff)
{
@@ -59,6 +61,14 @@ int bdev_dax_pgoff(struct block_device *bdev, sector_t sector, size_t size,
}
EXPORT_SYMBOL(bdev_dax_pgoff);
+struct dax_device *fs_dax_get_by_bdev(struct block_device *bdev)
+{
+ if (!blk_queue_dax(bdev->bd_queue))
+ return NULL;
+ return fs_dax_get_by_host(bdev->bd_disk->disk_name);
+}
+EXPORT_SYMBOL_GPL(fs_dax_get_by_bdev);
+
/**
* __bdev_dax_supported() - Check if the device supports dax for filesystem
* @sb: The superblock of the device
diff --git a/fs/super.c b/fs/super.c
index 6bc3352adcf3..671889b02bed 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -23,6 +23,7 @@
#include <linux/export.h>
#include <linux/slab.h>
#include <linux/blkdev.h>
+#include <linux/dax.h>
#include <linux/mount.h>
#include <linux/security.h>
#include <linux/writeback.h> /* for the emergency remount stuff */
@@ -1048,9 +1049,17 @@ struct dentry *mount_ns(struct file_system_type *fs_type,
EXPORT_SYMBOL(mount_ns);
#ifdef CONFIG_BLOCK
+struct sget_devs {
+ struct block_device *bdev;
+ struct dax_device *dax_dev;
+};
+
static int set_bdev_super(struct super_block *s, void *data)
{
- s->s_bdev = data;
+ struct sget_devs *devs = data;
+
+ s->s_bdev = devs->bdev;
+ s->s_daxdev = devs->dax_dev;
s->s_dev = s->s_bdev->bd_dev;
s->s_bdi = bdi_get(s->s_bdev->bd_bdi);
@@ -1059,14 +1068,18 @@ static int set_bdev_super(struct super_block *s, void *data)
static int test_bdev_super(struct super_block *s, void *data)
{
- return (void *)s->s_bdev == data;
+ struct sget_devs *devs = data;
+
+ return s->s_bdev == devs->bdev;
}
struct dentry *mount_bdev(struct file_system_type *fs_type,
int flags, const char *dev_name, void *data,
int (*fill_super)(struct super_block *, void *, int))
{
+ struct sget_devs devs;
struct block_device *bdev;
+ struct dax_device *dax_dev;
struct super_block *s;
fmode_t mode = FMODE_READ | FMODE_EXCL;
int error = 0;
@@ -1077,6 +1090,7 @@ struct dentry *mount_bdev(struct file_system_type *fs_type,
bdev = blkdev_get_by_path(dev_name, mode, fs_type);
if (IS_ERR(bdev))
return ERR_CAST(bdev);
+ dax_dev = fs_dax_get_by_bdev(bdev);
/*
* once the super is inserted into the list by sget, s_umount
@@ -1089,8 +1103,10 @@ struct dentry *mount_bdev(struct file_system_type *fs_type,
error = -EBUSY;
goto error_bdev;
}
+ devs.bdev = bdev;
+ devs.dax_dev = dax_dev;
s = sget(fs_type, test_bdev_super, set_bdev_super, flags | MS_NOSEC,
- bdev);
+ &devs);
mutex_unlock(&bdev->bd_fsfreeze_mutex);
if (IS_ERR(s))
goto error_s;
@@ -1111,6 +1127,7 @@ struct dentry *mount_bdev(struct file_system_type *fs_type,
*/
up_write(&s->s_umount);
blkdev_put(bdev, mode);
+ fs_put_dax(dax_dev);
down_write(&s->s_umount);
} else {
s->s_mode = mode;
@@ -1132,6 +1149,7 @@ struct dentry *mount_bdev(struct file_system_type *fs_type,
error = PTR_ERR(s);
error_bdev:
blkdev_put(bdev, mode);
+ fs_put_dax(dax_dev);
error:
return ERR_PTR(error);
}
@@ -1140,6 +1158,7 @@ EXPORT_SYMBOL(mount_bdev);
void kill_block_super(struct super_block *sb)
{
struct block_device *bdev = sb->s_bdev;
+ struct dax_device *dax_dev = sb->s_daxdev;
fmode_t mode = sb->s_mode;
bdev->bd_super = NULL;
@@ -1147,6 +1166,7 @@ void kill_block_super(struct super_block *sb)
sync_blockdev(bdev);
WARN_ON_ONCE(!(mode & FMODE_EXCL));
blkdev_put(bdev, mode | FMODE_EXCL);
+ fs_put_dax(dax_dev);
}
EXPORT_SYMBOL(kill_block_super);
diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c
index 6bf120bb1a17..78185f3b10b2 100644
--- a/fs/xfs/xfs_aops.c
+++ b/fs/xfs/xfs_aops.c
@@ -80,6 +80,19 @@ xfs_find_bdev_for_inode(
return mp->m_ddev_targp->bt_bdev;
}
+struct dax_device *
+xfs_find_daxdev_for_inode(
+ struct inode *inode)
+{
+ struct xfs_inode *ip = XFS_I(inode);
+ struct xfs_mount *mp = ip->i_mount;
+
+ if (XFS_IS_REALTIME_INODE(ip))
+ return mp->m_rtdev_targp->bt_daxdev;
+ else
+ return mp->m_ddev_targp->bt_daxdev;
+}
+
/*
* We're now finished for good with this page. Update the page state via the
* associated buffer_heads, paying attention to the start and end offsets that
diff --git a/fs/xfs/xfs_aops.h b/fs/xfs/xfs_aops.h
index cc174ec6c2fd..88c85ea63da0 100644
--- a/fs/xfs/xfs_aops.h
+++ b/fs/xfs/xfs_aops.h
@@ -59,5 +59,6 @@ int xfs_setfilesize(struct xfs_inode *ip, xfs_off_t offset, size_t size);
extern void xfs_count_page_state(struct page *, int *, int *);
extern struct block_device *xfs_find_bdev_for_inode(struct inode *);
+extern struct dax_device *xfs_find_daxdev_for_inode(struct inode *);
#endif /* __XFS_AOPS_H__ */
diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c
index 72f038492ba8..6deb86c845d1 100644
--- a/fs/xfs/xfs_buf.c
+++ b/fs/xfs/xfs_buf.c
@@ -1802,7 +1802,8 @@ xfs_setsize_buftarg_early(
xfs_buftarg_t *
xfs_alloc_buftarg(
struct xfs_mount *mp,
- struct block_device *bdev)
+ struct block_device *bdev,
+ struct dax_device *dax_dev)
{
xfs_buftarg_t *btp;
@@ -1811,6 +1812,7 @@ xfs_alloc_buftarg(
btp->bt_mount = mp;
btp->bt_dev = bdev->bd_dev;
btp->bt_bdev = bdev;
+ btp->bt_daxdev = dax_dev;
if (xfs_setsize_buftarg_early(btp, bdev))
goto error;
diff --git a/fs/xfs/xfs_buf.h b/fs/xfs/xfs_buf.h
index 20721261dae5..bf71507ddb16 100644
--- a/fs/xfs/xfs_buf.h
+++ b/fs/xfs/xfs_buf.h
@@ -108,6 +108,7 @@ typedef unsigned int xfs_buf_flags_t;
typedef struct xfs_buftarg {
dev_t bt_dev;
struct block_device *bt_bdev;
+ struct dax_device *bt_daxdev;
struct xfs_mount *bt_mount;
unsigned int bt_meta_sectorsize;
size_t bt_meta_sectormask;
@@ -385,7 +386,7 @@ xfs_buf_update_cksum(struct xfs_buf *bp, unsigned long cksum_offset)
* Handling of buftargs.
*/
extern xfs_buftarg_t *xfs_alloc_buftarg(struct xfs_mount *,
- struct block_device *);
+ struct block_device *, struct dax_device *);
extern void xfs_free_buftarg(struct xfs_mount *, struct xfs_buftarg *);
extern void xfs_wait_buftarg(xfs_buftarg_t *);
extern int xfs_setsize_buftarg(xfs_buftarg_t *, unsigned int);
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
index 813394c62849..7c934e407332 100644
--- a/fs/xfs/xfs_iomap.c
+++ b/fs/xfs/xfs_iomap.c
@@ -69,6 +69,7 @@ xfs_bmbt_to_iomap(
iomap->offset = XFS_FSB_TO_B(mp, imap->br_startoff);
iomap->length = XFS_FSB_TO_B(mp, imap->br_blockcount);
iomap->bdev = xfs_find_bdev_for_inode(VFS_I(ip));
+ iomap->dax_dev = xfs_find_daxdev_for_inode(VFS_I(ip));
}
xfs_extlen_t
@@ -976,7 +977,6 @@ xfs_file_iomap_begin(
int nimaps = 1, error = 0;
bool shared = false, trimmed = false;
unsigned lockmode;
- struct block_device *bdev;
if (XFS_FORCED_SHUTDOWN(mp))
return -EIO;
@@ -1087,13 +1087,6 @@ xfs_file_iomap_begin(
xfs_bmbt_to_iomap(ip, iomap, &imap);
- /* optionally associate a dax device with the iomap bdev */
- bdev = iomap->bdev;
- if (blk_queue_dax(bdev->bd_queue))
- iomap->dax_dev = fs_dax_get_by_host(bdev->bd_disk->disk_name);
- else
- iomap->dax_dev = NULL;
-
if (shared)
iomap->flags |= IOMAP_F_SHARED;
return 0;
@@ -1171,7 +1164,6 @@ xfs_file_iomap_end(
unsigned flags,
struct iomap *iomap)
{
- fs_put_dax(iomap->dax_dev);
if ((flags & IOMAP_WRITE) && iomap->type == IOMAP_DELALLOC)
return xfs_file_iomap_end_delalloc(XFS_I(inode), offset,
length, written, iomap);
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index 38aaacdbb8b3..d863f96b16e2 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -716,13 +716,19 @@ xfs_close_devices(
{
if (mp->m_logdev_targp && mp->m_logdev_targp != mp->m_ddev_targp) {
struct block_device *logdev = mp->m_logdev_targp->bt_bdev;
+ struct dax_device *dax_logdev = mp->m_logdev_targp->bt_daxdev;
+
xfs_free_buftarg(mp, mp->m_logdev_targp);
xfs_blkdev_put(logdev);
+ fs_put_dax(dax_logdev);
}
if (mp->m_rtdev_targp) {
struct block_device *rtdev = mp->m_rtdev_targp->bt_bdev;
+ struct dax_device *dax_rtdev = mp->m_rtdev_targp->bt_daxdev;
+
xfs_free_buftarg(mp, mp->m_rtdev_targp);
xfs_blkdev_put(rtdev);
+ fs_put_dax(dax_rtdev);
}
xfs_free_buftarg(mp, mp->m_ddev_targp);
}
@@ -742,7 +748,9 @@ xfs_open_devices(
struct xfs_mount *mp)
{
struct block_device *ddev = mp->m_super->s_bdev;
+ struct dax_device *dax_ddev = mp->m_super->s_daxdev;
struct block_device *logdev = NULL, *rtdev = NULL;
+ struct dax_device *dax_logdev = NULL, *dax_rtdev = NULL;
int error;
/*
@@ -752,6 +760,7 @@ xfs_open_devices(
error = xfs_blkdev_get(mp, mp->m_logname, &logdev);
if (error)
goto out;
+ dax_logdev = fs_dax_get_by_bdev(logdev);
}
if (mp->m_rtname) {
@@ -765,24 +774,25 @@ xfs_open_devices(
error = -EINVAL;
goto out_close_rtdev;
}
+ dax_rtdev = fs_dax_get_by_bdev(rtdev);
}
/*
* Setup xfs_mount buffer target pointers
*/
error = -ENOMEM;
- mp->m_ddev_targp = xfs_alloc_buftarg(mp, ddev);
+ mp->m_ddev_targp = xfs_alloc_buftarg(mp, ddev, dax_ddev);
if (!mp->m_ddev_targp)
goto out_close_rtdev;
if (rtdev) {
- mp->m_rtdev_targp = xfs_alloc_buftarg(mp, rtdev);
+ mp->m_rtdev_targp = xfs_alloc_buftarg(mp, rtdev, dax_rtdev);
if (!mp->m_rtdev_targp)
goto out_free_ddev_targ;
}
if (logdev && logdev != ddev) {
- mp->m_logdev_targp = xfs_alloc_buftarg(mp, logdev);
+ mp->m_logdev_targp = xfs_alloc_buftarg(mp, logdev, dax_logdev);
if (!mp->m_logdev_targp)
goto out_free_rtdev_targ;
} else {
@@ -798,9 +808,12 @@ xfs_open_devices(
xfs_free_buftarg(mp, mp->m_ddev_targp);
out_close_rtdev:
xfs_blkdev_put(rtdev);
+ fs_put_dax(dax_rtdev);
out_close_logdev:
- if (logdev && logdev != ddev)
+ if (logdev && logdev != ddev) {
xfs_blkdev_put(logdev);
+ fs_put_dax(dax_logdev);
+ }
out:
return error;
}
diff --git a/include/linux/dax.h b/include/linux/dax.h
index df97b7af7e2c..6e32be3badec 100644
--- a/include/linux/dax.h
+++ b/include/linux/dax.h
@@ -57,6 +57,7 @@ static inline void fs_put_dax(struct dax_device *dax_dev)
put_dax(dax_dev);
}
+struct dax_device *fs_dax_get_by_bdev(struct block_device *bdev);
#else
static inline int bdev_dax_supported(struct super_block *sb, int blocksize)
{
@@ -71,6 +72,11 @@ static inline struct dax_device *fs_dax_get_by_host(const char *host)
static inline void fs_put_dax(struct dax_device *dax_dev)
{
}
+
+struct dax_device *fs_dax_get_by_bdev(struct block_device *bdev)
+{
+ return NULL;
+}
#endif
int dax_read_lock(void);
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 6e1fd5d21248..d0e3234a1fae 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1334,6 +1334,7 @@ struct super_block {
struct hlist_bl_head s_anon; /* anonymous dentries for (nfs) exporting */
struct list_head s_mounts; /* list of mounts; _not_ for fs use */
struct block_device *s_bdev;
+ struct dax_device *s_daxdev;
struct backing_dev_info *s_bdi;
struct mtd_info *s_mtd;
struct hlist_node s_instances;
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH v2 1/2] fs, xfs: perform dax_device lookup at mount
@ 2017-08-28 3:48 ` Dan Williams
0 siblings, 0 replies; 28+ messages in thread
From: Dan Williams @ 2017-08-28 3:48 UTC (permalink / raw)
To: linux-fsdevel
Cc: jack, linux-nvdimm, Darrick J. Wong, linux-xfs, linux-ext4, hch
The ->iomap_begin() operation is a hot path, so cache the
fs_dax_get_by_host() result at mount time to avoid the incurring the
hash lookup overhead on a per-i/o basis.
Cc: "Darrick J. Wong" <darrick.wong@oracle.com>
Reported-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
drivers/dax/super.c | 10 ++++++++++
fs/super.c | 26 +++++++++++++++++++++++---
fs/xfs/xfs_aops.c | 13 +++++++++++++
fs/xfs/xfs_aops.h | 1 +
fs/xfs/xfs_buf.c | 4 +++-
fs/xfs/xfs_buf.h | 3 ++-
fs/xfs/xfs_iomap.c | 10 +---------
fs/xfs/xfs_super.c | 21 +++++++++++++++++----
include/linux/dax.h | 6 ++++++
include/linux/fs.h | 1 +
10 files changed, 77 insertions(+), 18 deletions(-)
diff --git a/drivers/dax/super.c b/drivers/dax/super.c
index 938eb4868f7f..b699aac268a6 100644
--- a/drivers/dax/super.c
+++ b/drivers/dax/super.c
@@ -46,6 +46,8 @@ void dax_read_unlock(int id)
EXPORT_SYMBOL_GPL(dax_read_unlock);
#ifdef CONFIG_BLOCK
+#include <linux/blkdev.h>
+
int bdev_dax_pgoff(struct block_device *bdev, sector_t sector, size_t size,
pgoff_t *pgoff)
{
@@ -59,6 +61,14 @@ int bdev_dax_pgoff(struct block_device *bdev, sector_t sector, size_t size,
}
EXPORT_SYMBOL(bdev_dax_pgoff);
+struct dax_device *fs_dax_get_by_bdev(struct block_device *bdev)
+{
+ if (!blk_queue_dax(bdev->bd_queue))
+ return NULL;
+ return fs_dax_get_by_host(bdev->bd_disk->disk_name);
+}
+EXPORT_SYMBOL_GPL(fs_dax_get_by_bdev);
+
/**
* __bdev_dax_supported() - Check if the device supports dax for filesystem
* @sb: The superblock of the device
diff --git a/fs/super.c b/fs/super.c
index 6bc3352adcf3..671889b02bed 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -23,6 +23,7 @@
#include <linux/export.h>
#include <linux/slab.h>
#include <linux/blkdev.h>
+#include <linux/dax.h>
#include <linux/mount.h>
#include <linux/security.h>
#include <linux/writeback.h> /* for the emergency remount stuff */
@@ -1048,9 +1049,17 @@ struct dentry *mount_ns(struct file_system_type *fs_type,
EXPORT_SYMBOL(mount_ns);
#ifdef CONFIG_BLOCK
+struct sget_devs {
+ struct block_device *bdev;
+ struct dax_device *dax_dev;
+};
+
static int set_bdev_super(struct super_block *s, void *data)
{
- s->s_bdev = data;
+ struct sget_devs *devs = data;
+
+ s->s_bdev = devs->bdev;
+ s->s_daxdev = devs->dax_dev;
s->s_dev = s->s_bdev->bd_dev;
s->s_bdi = bdi_get(s->s_bdev->bd_bdi);
@@ -1059,14 +1068,18 @@ static int set_bdev_super(struct super_block *s, void *data)
static int test_bdev_super(struct super_block *s, void *data)
{
- return (void *)s->s_bdev == data;
+ struct sget_devs *devs = data;
+
+ return s->s_bdev == devs->bdev;
}
struct dentry *mount_bdev(struct file_system_type *fs_type,
int flags, const char *dev_name, void *data,
int (*fill_super)(struct super_block *, void *, int))
{
+ struct sget_devs devs;
struct block_device *bdev;
+ struct dax_device *dax_dev;
struct super_block *s;
fmode_t mode = FMODE_READ | FMODE_EXCL;
int error = 0;
@@ -1077,6 +1090,7 @@ struct dentry *mount_bdev(struct file_system_type *fs_type,
bdev = blkdev_get_by_path(dev_name, mode, fs_type);
if (IS_ERR(bdev))
return ERR_CAST(bdev);
+ dax_dev = fs_dax_get_by_bdev(bdev);
/*
* once the super is inserted into the list by sget, s_umount
@@ -1089,8 +1103,10 @@ struct dentry *mount_bdev(struct file_system_type *fs_type,
error = -EBUSY;
goto error_bdev;
}
+ devs.bdev = bdev;
+ devs.dax_dev = dax_dev;
s = sget(fs_type, test_bdev_super, set_bdev_super, flags | MS_NOSEC,
- bdev);
+ &devs);
mutex_unlock(&bdev->bd_fsfreeze_mutex);
if (IS_ERR(s))
goto error_s;
@@ -1111,6 +1127,7 @@ struct dentry *mount_bdev(struct file_system_type *fs_type,
*/
up_write(&s->s_umount);
blkdev_put(bdev, mode);
+ fs_put_dax(dax_dev);
down_write(&s->s_umount);
} else {
s->s_mode = mode;
@@ -1132,6 +1149,7 @@ struct dentry *mount_bdev(struct file_system_type *fs_type,
error = PTR_ERR(s);
error_bdev:
blkdev_put(bdev, mode);
+ fs_put_dax(dax_dev);
error:
return ERR_PTR(error);
}
@@ -1140,6 +1158,7 @@ EXPORT_SYMBOL(mount_bdev);
void kill_block_super(struct super_block *sb)
{
struct block_device *bdev = sb->s_bdev;
+ struct dax_device *dax_dev = sb->s_daxdev;
fmode_t mode = sb->s_mode;
bdev->bd_super = NULL;
@@ -1147,6 +1166,7 @@ void kill_block_super(struct super_block *sb)
sync_blockdev(bdev);
WARN_ON_ONCE(!(mode & FMODE_EXCL));
blkdev_put(bdev, mode | FMODE_EXCL);
+ fs_put_dax(dax_dev);
}
EXPORT_SYMBOL(kill_block_super);
diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c
index 6bf120bb1a17..78185f3b10b2 100644
--- a/fs/xfs/xfs_aops.c
+++ b/fs/xfs/xfs_aops.c
@@ -80,6 +80,19 @@ xfs_find_bdev_for_inode(
return mp->m_ddev_targp->bt_bdev;
}
+struct dax_device *
+xfs_find_daxdev_for_inode(
+ struct inode *inode)
+{
+ struct xfs_inode *ip = XFS_I(inode);
+ struct xfs_mount *mp = ip->i_mount;
+
+ if (XFS_IS_REALTIME_INODE(ip))
+ return mp->m_rtdev_targp->bt_daxdev;
+ else
+ return mp->m_ddev_targp->bt_daxdev;
+}
+
/*
* We're now finished for good with this page. Update the page state via the
* associated buffer_heads, paying attention to the start and end offsets that
diff --git a/fs/xfs/xfs_aops.h b/fs/xfs/xfs_aops.h
index cc174ec6c2fd..88c85ea63da0 100644
--- a/fs/xfs/xfs_aops.h
+++ b/fs/xfs/xfs_aops.h
@@ -59,5 +59,6 @@ int xfs_setfilesize(struct xfs_inode *ip, xfs_off_t offset, size_t size);
extern void xfs_count_page_state(struct page *, int *, int *);
extern struct block_device *xfs_find_bdev_for_inode(struct inode *);
+extern struct dax_device *xfs_find_daxdev_for_inode(struct inode *);
#endif /* __XFS_AOPS_H__ */
diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c
index 72f038492ba8..6deb86c845d1 100644
--- a/fs/xfs/xfs_buf.c
+++ b/fs/xfs/xfs_buf.c
@@ -1802,7 +1802,8 @@ xfs_setsize_buftarg_early(
xfs_buftarg_t *
xfs_alloc_buftarg(
struct xfs_mount *mp,
- struct block_device *bdev)
+ struct block_device *bdev,
+ struct dax_device *dax_dev)
{
xfs_buftarg_t *btp;
@@ -1811,6 +1812,7 @@ xfs_alloc_buftarg(
btp->bt_mount = mp;
btp->bt_dev = bdev->bd_dev;
btp->bt_bdev = bdev;
+ btp->bt_daxdev = dax_dev;
if (xfs_setsize_buftarg_early(btp, bdev))
goto error;
diff --git a/fs/xfs/xfs_buf.h b/fs/xfs/xfs_buf.h
index 20721261dae5..bf71507ddb16 100644
--- a/fs/xfs/xfs_buf.h
+++ b/fs/xfs/xfs_buf.h
@@ -108,6 +108,7 @@ typedef unsigned int xfs_buf_flags_t;
typedef struct xfs_buftarg {
dev_t bt_dev;
struct block_device *bt_bdev;
+ struct dax_device *bt_daxdev;
struct xfs_mount *bt_mount;
unsigned int bt_meta_sectorsize;
size_t bt_meta_sectormask;
@@ -385,7 +386,7 @@ xfs_buf_update_cksum(struct xfs_buf *bp, unsigned long cksum_offset)
* Handling of buftargs.
*/
extern xfs_buftarg_t *xfs_alloc_buftarg(struct xfs_mount *,
- struct block_device *);
+ struct block_device *, struct dax_device *);
extern void xfs_free_buftarg(struct xfs_mount *, struct xfs_buftarg *);
extern void xfs_wait_buftarg(xfs_buftarg_t *);
extern int xfs_setsize_buftarg(xfs_buftarg_t *, unsigned int);
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
index 813394c62849..7c934e407332 100644
--- a/fs/xfs/xfs_iomap.c
+++ b/fs/xfs/xfs_iomap.c
@@ -69,6 +69,7 @@ xfs_bmbt_to_iomap(
iomap->offset = XFS_FSB_TO_B(mp, imap->br_startoff);
iomap->length = XFS_FSB_TO_B(mp, imap->br_blockcount);
iomap->bdev = xfs_find_bdev_for_inode(VFS_I(ip));
+ iomap->dax_dev = xfs_find_daxdev_for_inode(VFS_I(ip));
}
xfs_extlen_t
@@ -976,7 +977,6 @@ xfs_file_iomap_begin(
int nimaps = 1, error = 0;
bool shared = false, trimmed = false;
unsigned lockmode;
- struct block_device *bdev;
if (XFS_FORCED_SHUTDOWN(mp))
return -EIO;
@@ -1087,13 +1087,6 @@ xfs_file_iomap_begin(
xfs_bmbt_to_iomap(ip, iomap, &imap);
- /* optionally associate a dax device with the iomap bdev */
- bdev = iomap->bdev;
- if (blk_queue_dax(bdev->bd_queue))
- iomap->dax_dev = fs_dax_get_by_host(bdev->bd_disk->disk_name);
- else
- iomap->dax_dev = NULL;
-
if (shared)
iomap->flags |= IOMAP_F_SHARED;
return 0;
@@ -1171,7 +1164,6 @@ xfs_file_iomap_end(
unsigned flags,
struct iomap *iomap)
{
- fs_put_dax(iomap->dax_dev);
if ((flags & IOMAP_WRITE) && iomap->type == IOMAP_DELALLOC)
return xfs_file_iomap_end_delalloc(XFS_I(inode), offset,
length, written, iomap);
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index 38aaacdbb8b3..d863f96b16e2 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -716,13 +716,19 @@ xfs_close_devices(
{
if (mp->m_logdev_targp && mp->m_logdev_targp != mp->m_ddev_targp) {
struct block_device *logdev = mp->m_logdev_targp->bt_bdev;
+ struct dax_device *dax_logdev = mp->m_logdev_targp->bt_daxdev;
+
xfs_free_buftarg(mp, mp->m_logdev_targp);
xfs_blkdev_put(logdev);
+ fs_put_dax(dax_logdev);
}
if (mp->m_rtdev_targp) {
struct block_device *rtdev = mp->m_rtdev_targp->bt_bdev;
+ struct dax_device *dax_rtdev = mp->m_rtdev_targp->bt_daxdev;
+
xfs_free_buftarg(mp, mp->m_rtdev_targp);
xfs_blkdev_put(rtdev);
+ fs_put_dax(dax_rtdev);
}
xfs_free_buftarg(mp, mp->m_ddev_targp);
}
@@ -742,7 +748,9 @@ xfs_open_devices(
struct xfs_mount *mp)
{
struct block_device *ddev = mp->m_super->s_bdev;
+ struct dax_device *dax_ddev = mp->m_super->s_daxdev;
struct block_device *logdev = NULL, *rtdev = NULL;
+ struct dax_device *dax_logdev = NULL, *dax_rtdev = NULL;
int error;
/*
@@ -752,6 +760,7 @@ xfs_open_devices(
error = xfs_blkdev_get(mp, mp->m_logname, &logdev);
if (error)
goto out;
+ dax_logdev = fs_dax_get_by_bdev(logdev);
}
if (mp->m_rtname) {
@@ -765,24 +774,25 @@ xfs_open_devices(
error = -EINVAL;
goto out_close_rtdev;
}
+ dax_rtdev = fs_dax_get_by_bdev(rtdev);
}
/*
* Setup xfs_mount buffer target pointers
*/
error = -ENOMEM;
- mp->m_ddev_targp = xfs_alloc_buftarg(mp, ddev);
+ mp->m_ddev_targp = xfs_alloc_buftarg(mp, ddev, dax_ddev);
if (!mp->m_ddev_targp)
goto out_close_rtdev;
if (rtdev) {
- mp->m_rtdev_targp = xfs_alloc_buftarg(mp, rtdev);
+ mp->m_rtdev_targp = xfs_alloc_buftarg(mp, rtdev, dax_rtdev);
if (!mp->m_rtdev_targp)
goto out_free_ddev_targ;
}
if (logdev && logdev != ddev) {
- mp->m_logdev_targp = xfs_alloc_buftarg(mp, logdev);
+ mp->m_logdev_targp = xfs_alloc_buftarg(mp, logdev, dax_logdev);
if (!mp->m_logdev_targp)
goto out_free_rtdev_targ;
} else {
@@ -798,9 +808,12 @@ xfs_open_devices(
xfs_free_buftarg(mp, mp->m_ddev_targp);
out_close_rtdev:
xfs_blkdev_put(rtdev);
+ fs_put_dax(dax_rtdev);
out_close_logdev:
- if (logdev && logdev != ddev)
+ if (logdev && logdev != ddev) {
xfs_blkdev_put(logdev);
+ fs_put_dax(dax_logdev);
+ }
out:
return error;
}
diff --git a/include/linux/dax.h b/include/linux/dax.h
index df97b7af7e2c..6e32be3badec 100644
--- a/include/linux/dax.h
+++ b/include/linux/dax.h
@@ -57,6 +57,7 @@ static inline void fs_put_dax(struct dax_device *dax_dev)
put_dax(dax_dev);
}
+struct dax_device *fs_dax_get_by_bdev(struct block_device *bdev);
#else
static inline int bdev_dax_supported(struct super_block *sb, int blocksize)
{
@@ -71,6 +72,11 @@ static inline struct dax_device *fs_dax_get_by_host(const char *host)
static inline void fs_put_dax(struct dax_device *dax_dev)
{
}
+
+struct dax_device *fs_dax_get_by_bdev(struct block_device *bdev)
+{
+ return NULL;
+}
#endif
int dax_read_lock(void);
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 6e1fd5d21248..d0e3234a1fae 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1334,6 +1334,7 @@ struct super_block {
struct hlist_bl_head s_anon; /* anonymous dentries for (nfs) exporting */
struct list_head s_mounts; /* list of mounts; _not_ for fs use */
struct block_device *s_bdev;
+ struct dax_device *s_daxdev;
struct backing_dev_info *s_bdi;
struct mtd_info *s_mtd;
struct hlist_node s_instances;
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH v2 1/2] fs, xfs: perform dax_device lookup at mount
@ 2017-08-28 3:48 ` Dan Williams
0 siblings, 0 replies; 28+ messages in thread
From: Dan Williams @ 2017-08-28 3:48 UTC (permalink / raw)
To: linux-fsdevel-u79uwXL29TY76Z2rM5mHXA
Cc: jack-AlSwsSmVLrQ, Darrick J. Wong,
linux-nvdimm-hn68Rpc1hR1g9hUCZPvPmw,
linux-xfs-u79uwXL29TY76Z2rM5mHXA,
linux-ext4-u79uwXL29TY76Z2rM5mHXA, hch-jcswGhMUV9g
The ->iomap_begin() operation is a hot path, so cache the
fs_dax_get_by_host() result at mount time to avoid the incurring the
hash lookup overhead on a per-i/o basis.
Cc: "Darrick J. Wong" <darrick.wong-QHcLZuEGTsvQT0dZR+AlfA@public.gmane.org>
Reported-by: Christoph Hellwig <hch-jcswGhMUV9g@public.gmane.org>
Signed-off-by: Dan Williams <dan.j.williams-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
---
drivers/dax/super.c | 10 ++++++++++
fs/super.c | 26 +++++++++++++++++++++++---
fs/xfs/xfs_aops.c | 13 +++++++++++++
fs/xfs/xfs_aops.h | 1 +
fs/xfs/xfs_buf.c | 4 +++-
fs/xfs/xfs_buf.h | 3 ++-
fs/xfs/xfs_iomap.c | 10 +---------
fs/xfs/xfs_super.c | 21 +++++++++++++++++----
include/linux/dax.h | 6 ++++++
include/linux/fs.h | 1 +
10 files changed, 77 insertions(+), 18 deletions(-)
diff --git a/drivers/dax/super.c b/drivers/dax/super.c
index 938eb4868f7f..b699aac268a6 100644
--- a/drivers/dax/super.c
+++ b/drivers/dax/super.c
@@ -46,6 +46,8 @@ void dax_read_unlock(int id)
EXPORT_SYMBOL_GPL(dax_read_unlock);
#ifdef CONFIG_BLOCK
+#include <linux/blkdev.h>
+
int bdev_dax_pgoff(struct block_device *bdev, sector_t sector, size_t size,
pgoff_t *pgoff)
{
@@ -59,6 +61,14 @@ int bdev_dax_pgoff(struct block_device *bdev, sector_t sector, size_t size,
}
EXPORT_SYMBOL(bdev_dax_pgoff);
+struct dax_device *fs_dax_get_by_bdev(struct block_device *bdev)
+{
+ if (!blk_queue_dax(bdev->bd_queue))
+ return NULL;
+ return fs_dax_get_by_host(bdev->bd_disk->disk_name);
+}
+EXPORT_SYMBOL_GPL(fs_dax_get_by_bdev);
+
/**
* __bdev_dax_supported() - Check if the device supports dax for filesystem
* @sb: The superblock of the device
diff --git a/fs/super.c b/fs/super.c
index 6bc3352adcf3..671889b02bed 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -23,6 +23,7 @@
#include <linux/export.h>
#include <linux/slab.h>
#include <linux/blkdev.h>
+#include <linux/dax.h>
#include <linux/mount.h>
#include <linux/security.h>
#include <linux/writeback.h> /* for the emergency remount stuff */
@@ -1048,9 +1049,17 @@ struct dentry *mount_ns(struct file_system_type *fs_type,
EXPORT_SYMBOL(mount_ns);
#ifdef CONFIG_BLOCK
+struct sget_devs {
+ struct block_device *bdev;
+ struct dax_device *dax_dev;
+};
+
static int set_bdev_super(struct super_block *s, void *data)
{
- s->s_bdev = data;
+ struct sget_devs *devs = data;
+
+ s->s_bdev = devs->bdev;
+ s->s_daxdev = devs->dax_dev;
s->s_dev = s->s_bdev->bd_dev;
s->s_bdi = bdi_get(s->s_bdev->bd_bdi);
@@ -1059,14 +1068,18 @@ static int set_bdev_super(struct super_block *s, void *data)
static int test_bdev_super(struct super_block *s, void *data)
{
- return (void *)s->s_bdev == data;
+ struct sget_devs *devs = data;
+
+ return s->s_bdev == devs->bdev;
}
struct dentry *mount_bdev(struct file_system_type *fs_type,
int flags, const char *dev_name, void *data,
int (*fill_super)(struct super_block *, void *, int))
{
+ struct sget_devs devs;
struct block_device *bdev;
+ struct dax_device *dax_dev;
struct super_block *s;
fmode_t mode = FMODE_READ | FMODE_EXCL;
int error = 0;
@@ -1077,6 +1090,7 @@ struct dentry *mount_bdev(struct file_system_type *fs_type,
bdev = blkdev_get_by_path(dev_name, mode, fs_type);
if (IS_ERR(bdev))
return ERR_CAST(bdev);
+ dax_dev = fs_dax_get_by_bdev(bdev);
/*
* once the super is inserted into the list by sget, s_umount
@@ -1089,8 +1103,10 @@ struct dentry *mount_bdev(struct file_system_type *fs_type,
error = -EBUSY;
goto error_bdev;
}
+ devs.bdev = bdev;
+ devs.dax_dev = dax_dev;
s = sget(fs_type, test_bdev_super, set_bdev_super, flags | MS_NOSEC,
- bdev);
+ &devs);
mutex_unlock(&bdev->bd_fsfreeze_mutex);
if (IS_ERR(s))
goto error_s;
@@ -1111,6 +1127,7 @@ struct dentry *mount_bdev(struct file_system_type *fs_type,
*/
up_write(&s->s_umount);
blkdev_put(bdev, mode);
+ fs_put_dax(dax_dev);
down_write(&s->s_umount);
} else {
s->s_mode = mode;
@@ -1132,6 +1149,7 @@ struct dentry *mount_bdev(struct file_system_type *fs_type,
error = PTR_ERR(s);
error_bdev:
blkdev_put(bdev, mode);
+ fs_put_dax(dax_dev);
error:
return ERR_PTR(error);
}
@@ -1140,6 +1158,7 @@ EXPORT_SYMBOL(mount_bdev);
void kill_block_super(struct super_block *sb)
{
struct block_device *bdev = sb->s_bdev;
+ struct dax_device *dax_dev = sb->s_daxdev;
fmode_t mode = sb->s_mode;
bdev->bd_super = NULL;
@@ -1147,6 +1166,7 @@ void kill_block_super(struct super_block *sb)
sync_blockdev(bdev);
WARN_ON_ONCE(!(mode & FMODE_EXCL));
blkdev_put(bdev, mode | FMODE_EXCL);
+ fs_put_dax(dax_dev);
}
EXPORT_SYMBOL(kill_block_super);
diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c
index 6bf120bb1a17..78185f3b10b2 100644
--- a/fs/xfs/xfs_aops.c
+++ b/fs/xfs/xfs_aops.c
@@ -80,6 +80,19 @@ xfs_find_bdev_for_inode(
return mp->m_ddev_targp->bt_bdev;
}
+struct dax_device *
+xfs_find_daxdev_for_inode(
+ struct inode *inode)
+{
+ struct xfs_inode *ip = XFS_I(inode);
+ struct xfs_mount *mp = ip->i_mount;
+
+ if (XFS_IS_REALTIME_INODE(ip))
+ return mp->m_rtdev_targp->bt_daxdev;
+ else
+ return mp->m_ddev_targp->bt_daxdev;
+}
+
/*
* We're now finished for good with this page. Update the page state via the
* associated buffer_heads, paying attention to the start and end offsets that
diff --git a/fs/xfs/xfs_aops.h b/fs/xfs/xfs_aops.h
index cc174ec6c2fd..88c85ea63da0 100644
--- a/fs/xfs/xfs_aops.h
+++ b/fs/xfs/xfs_aops.h
@@ -59,5 +59,6 @@ int xfs_setfilesize(struct xfs_inode *ip, xfs_off_t offset, size_t size);
extern void xfs_count_page_state(struct page *, int *, int *);
extern struct block_device *xfs_find_bdev_for_inode(struct inode *);
+extern struct dax_device *xfs_find_daxdev_for_inode(struct inode *);
#endif /* __XFS_AOPS_H__ */
diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c
index 72f038492ba8..6deb86c845d1 100644
--- a/fs/xfs/xfs_buf.c
+++ b/fs/xfs/xfs_buf.c
@@ -1802,7 +1802,8 @@ xfs_setsize_buftarg_early(
xfs_buftarg_t *
xfs_alloc_buftarg(
struct xfs_mount *mp,
- struct block_device *bdev)
+ struct block_device *bdev,
+ struct dax_device *dax_dev)
{
xfs_buftarg_t *btp;
@@ -1811,6 +1812,7 @@ xfs_alloc_buftarg(
btp->bt_mount = mp;
btp->bt_dev = bdev->bd_dev;
btp->bt_bdev = bdev;
+ btp->bt_daxdev = dax_dev;
if (xfs_setsize_buftarg_early(btp, bdev))
goto error;
diff --git a/fs/xfs/xfs_buf.h b/fs/xfs/xfs_buf.h
index 20721261dae5..bf71507ddb16 100644
--- a/fs/xfs/xfs_buf.h
+++ b/fs/xfs/xfs_buf.h
@@ -108,6 +108,7 @@ typedef unsigned int xfs_buf_flags_t;
typedef struct xfs_buftarg {
dev_t bt_dev;
struct block_device *bt_bdev;
+ struct dax_device *bt_daxdev;
struct xfs_mount *bt_mount;
unsigned int bt_meta_sectorsize;
size_t bt_meta_sectormask;
@@ -385,7 +386,7 @@ xfs_buf_update_cksum(struct xfs_buf *bp, unsigned long cksum_offset)
* Handling of buftargs.
*/
extern xfs_buftarg_t *xfs_alloc_buftarg(struct xfs_mount *,
- struct block_device *);
+ struct block_device *, struct dax_device *);
extern void xfs_free_buftarg(struct xfs_mount *, struct xfs_buftarg *);
extern void xfs_wait_buftarg(xfs_buftarg_t *);
extern int xfs_setsize_buftarg(xfs_buftarg_t *, unsigned int);
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
index 813394c62849..7c934e407332 100644
--- a/fs/xfs/xfs_iomap.c
+++ b/fs/xfs/xfs_iomap.c
@@ -69,6 +69,7 @@ xfs_bmbt_to_iomap(
iomap->offset = XFS_FSB_TO_B(mp, imap->br_startoff);
iomap->length = XFS_FSB_TO_B(mp, imap->br_blockcount);
iomap->bdev = xfs_find_bdev_for_inode(VFS_I(ip));
+ iomap->dax_dev = xfs_find_daxdev_for_inode(VFS_I(ip));
}
xfs_extlen_t
@@ -976,7 +977,6 @@ xfs_file_iomap_begin(
int nimaps = 1, error = 0;
bool shared = false, trimmed = false;
unsigned lockmode;
- struct block_device *bdev;
if (XFS_FORCED_SHUTDOWN(mp))
return -EIO;
@@ -1087,13 +1087,6 @@ xfs_file_iomap_begin(
xfs_bmbt_to_iomap(ip, iomap, &imap);
- /* optionally associate a dax device with the iomap bdev */
- bdev = iomap->bdev;
- if (blk_queue_dax(bdev->bd_queue))
- iomap->dax_dev = fs_dax_get_by_host(bdev->bd_disk->disk_name);
- else
- iomap->dax_dev = NULL;
-
if (shared)
iomap->flags |= IOMAP_F_SHARED;
return 0;
@@ -1171,7 +1164,6 @@ xfs_file_iomap_end(
unsigned flags,
struct iomap *iomap)
{
- fs_put_dax(iomap->dax_dev);
if ((flags & IOMAP_WRITE) && iomap->type == IOMAP_DELALLOC)
return xfs_file_iomap_end_delalloc(XFS_I(inode), offset,
length, written, iomap);
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index 38aaacdbb8b3..d863f96b16e2 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -716,13 +716,19 @@ xfs_close_devices(
{
if (mp->m_logdev_targp && mp->m_logdev_targp != mp->m_ddev_targp) {
struct block_device *logdev = mp->m_logdev_targp->bt_bdev;
+ struct dax_device *dax_logdev = mp->m_logdev_targp->bt_daxdev;
+
xfs_free_buftarg(mp, mp->m_logdev_targp);
xfs_blkdev_put(logdev);
+ fs_put_dax(dax_logdev);
}
if (mp->m_rtdev_targp) {
struct block_device *rtdev = mp->m_rtdev_targp->bt_bdev;
+ struct dax_device *dax_rtdev = mp->m_rtdev_targp->bt_daxdev;
+
xfs_free_buftarg(mp, mp->m_rtdev_targp);
xfs_blkdev_put(rtdev);
+ fs_put_dax(dax_rtdev);
}
xfs_free_buftarg(mp, mp->m_ddev_targp);
}
@@ -742,7 +748,9 @@ xfs_open_devices(
struct xfs_mount *mp)
{
struct block_device *ddev = mp->m_super->s_bdev;
+ struct dax_device *dax_ddev = mp->m_super->s_daxdev;
struct block_device *logdev = NULL, *rtdev = NULL;
+ struct dax_device *dax_logdev = NULL, *dax_rtdev = NULL;
int error;
/*
@@ -752,6 +760,7 @@ xfs_open_devices(
error = xfs_blkdev_get(mp, mp->m_logname, &logdev);
if (error)
goto out;
+ dax_logdev = fs_dax_get_by_bdev(logdev);
}
if (mp->m_rtname) {
@@ -765,24 +774,25 @@ xfs_open_devices(
error = -EINVAL;
goto out_close_rtdev;
}
+ dax_rtdev = fs_dax_get_by_bdev(rtdev);
}
/*
* Setup xfs_mount buffer target pointers
*/
error = -ENOMEM;
- mp->m_ddev_targp = xfs_alloc_buftarg(mp, ddev);
+ mp->m_ddev_targp = xfs_alloc_buftarg(mp, ddev, dax_ddev);
if (!mp->m_ddev_targp)
goto out_close_rtdev;
if (rtdev) {
- mp->m_rtdev_targp = xfs_alloc_buftarg(mp, rtdev);
+ mp->m_rtdev_targp = xfs_alloc_buftarg(mp, rtdev, dax_rtdev);
if (!mp->m_rtdev_targp)
goto out_free_ddev_targ;
}
if (logdev && logdev != ddev) {
- mp->m_logdev_targp = xfs_alloc_buftarg(mp, logdev);
+ mp->m_logdev_targp = xfs_alloc_buftarg(mp, logdev, dax_logdev);
if (!mp->m_logdev_targp)
goto out_free_rtdev_targ;
} else {
@@ -798,9 +808,12 @@ xfs_open_devices(
xfs_free_buftarg(mp, mp->m_ddev_targp);
out_close_rtdev:
xfs_blkdev_put(rtdev);
+ fs_put_dax(dax_rtdev);
out_close_logdev:
- if (logdev && logdev != ddev)
+ if (logdev && logdev != ddev) {
xfs_blkdev_put(logdev);
+ fs_put_dax(dax_logdev);
+ }
out:
return error;
}
diff --git a/include/linux/dax.h b/include/linux/dax.h
index df97b7af7e2c..6e32be3badec 100644
--- a/include/linux/dax.h
+++ b/include/linux/dax.h
@@ -57,6 +57,7 @@ static inline void fs_put_dax(struct dax_device *dax_dev)
put_dax(dax_dev);
}
+struct dax_device *fs_dax_get_by_bdev(struct block_device *bdev);
#else
static inline int bdev_dax_supported(struct super_block *sb, int blocksize)
{
@@ -71,6 +72,11 @@ static inline struct dax_device *fs_dax_get_by_host(const char *host)
static inline void fs_put_dax(struct dax_device *dax_dev)
{
}
+
+struct dax_device *fs_dax_get_by_bdev(struct block_device *bdev)
+{
+ return NULL;
+}
#endif
int dax_read_lock(void);
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 6e1fd5d21248..d0e3234a1fae 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1334,6 +1334,7 @@ struct super_block {
struct hlist_bl_head s_anon; /* anonymous dentries for (nfs) exporting */
struct list_head s_mounts; /* list of mounts; _not_ for fs use */
struct block_device *s_bdev;
+ struct dax_device *s_daxdev;
struct backing_dev_info *s_bdi;
struct mtd_info *s_mtd;
struct hlist_node s_instances;
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH v2 2/2] ext2, ext4: use the super_block dax_device
2017-08-28 3:48 ` Dan Williams
(?)
@ 2017-08-28 3:48 ` Dan Williams
-1 siblings, 0 replies; 28+ messages in thread
From: Dan Williams @ 2017-08-28 3:48 UTC (permalink / raw)
To: linux-fsdevel
Cc: jack, linux-nvdimm, linux-xfs, Andreas Dilger, Jan Kara,
Theodore Ts'o, linux-ext4, hch
The ->iomap_begin() operation is a hot path, and now that mount_bdev()
arranges for the dax_device to be populated in the super_block, we can
just reference that attribute directly rather than perform a new lookup.
Cc: Jan Kara <jack@suse.com>
Cc: "Theodore Ts'o" <tytso@mit.edu>
Cc: Andreas Dilger <adilger.kernel@dilger.ca>
Reported-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
fs/ext2/inode.c | 10 ++--------
fs/ext4/inode.c | 10 ++--------
2 files changed, 4 insertions(+), 16 deletions(-)
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c
index 30163d007b2f..7102b77a83c6 100644
--- a/fs/ext2/inode.c
+++ b/fs/ext2/inode.c
@@ -800,7 +800,6 @@ int ext2_get_block(struct inode *inode, sector_t iblock,
static int ext2_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
unsigned flags, struct iomap *iomap)
{
- struct block_device *bdev;
unsigned int blkbits = inode->i_blkbits;
unsigned long first_block = offset >> blkbits;
unsigned long max_blocks = (length + (1 << blkbits) - 1) >> blkbits;
@@ -814,13 +813,9 @@ static int ext2_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
return ret;
iomap->flags = 0;
- bdev = inode->i_sb->s_bdev;
- iomap->bdev = bdev;
+ iomap->bdev = inode->i_sb->s_bdev;
iomap->offset = (u64)first_block << blkbits;
- if (blk_queue_dax(bdev->bd_queue))
- iomap->dax_dev = fs_dax_get_by_host(bdev->bd_disk->disk_name);
- else
- iomap->dax_dev = NULL;
+ iomap->dax_dev = inode->i_sb->s_daxdev;
if (ret == 0) {
iomap->type = IOMAP_HOLE;
@@ -842,7 +837,6 @@ static int
ext2_iomap_end(struct inode *inode, loff_t offset, loff_t length,
ssize_t written, unsigned flags, struct iomap *iomap)
{
- fs_put_dax(iomap->dax_dev);
if (iomap->type == IOMAP_MAPPED &&
written < length &&
(flags & IOMAP_WRITE))
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index c774bdc22759..311690522366 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -3404,7 +3404,6 @@ static int ext4_releasepage(struct page *page, gfp_t wait)
static int ext4_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
unsigned flags, struct iomap *iomap)
{
- struct block_device *bdev;
unsigned int blkbits = inode->i_blkbits;
unsigned long first_block = offset >> blkbits;
unsigned long last_block = (offset + length - 1) >> blkbits;
@@ -3473,12 +3472,8 @@ static int ext4_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
}
iomap->flags = 0;
- bdev = inode->i_sb->s_bdev;
- iomap->bdev = bdev;
- if (blk_queue_dax(bdev->bd_queue))
- iomap->dax_dev = fs_dax_get_by_host(bdev->bd_disk->disk_name);
- else
- iomap->dax_dev = NULL;
+ iomap->bdev = inode->i_sb->s_bdev;
+ iomap->dax_dev = inode->i_sb->s_daxdev;
iomap->offset = first_block << blkbits;
if (ret == 0) {
@@ -3511,7 +3506,6 @@ static int ext4_iomap_end(struct inode *inode, loff_t offset, loff_t length,
int blkbits = inode->i_blkbits;
bool truncate = false;
- fs_put_dax(iomap->dax_dev);
if (!(flags & IOMAP_WRITE) || (flags & IOMAP_FAULT))
return 0;
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH v2 2/2] ext2, ext4: use the super_block dax_device
@ 2017-08-28 3:48 ` Dan Williams
0 siblings, 0 replies; 28+ messages in thread
From: Dan Williams @ 2017-08-28 3:48 UTC (permalink / raw)
To: linux-fsdevel
Cc: Theodore Ts'o, linux-nvdimm, linux-xfs, Andreas Dilger,
Jan Kara, jack, linux-ext4, hch
The ->iomap_begin() operation is a hot path, and now that mount_bdev()
arranges for the dax_device to be populated in the super_block, we can
just reference that attribute directly rather than perform a new lookup.
Cc: Jan Kara <jack@suse.com>
Cc: "Theodore Ts'o" <tytso@mit.edu>
Cc: Andreas Dilger <adilger.kernel@dilger.ca>
Reported-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
fs/ext2/inode.c | 10 ++--------
fs/ext4/inode.c | 10 ++--------
2 files changed, 4 insertions(+), 16 deletions(-)
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c
index 30163d007b2f..7102b77a83c6 100644
--- a/fs/ext2/inode.c
+++ b/fs/ext2/inode.c
@@ -800,7 +800,6 @@ int ext2_get_block(struct inode *inode, sector_t iblock,
static int ext2_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
unsigned flags, struct iomap *iomap)
{
- struct block_device *bdev;
unsigned int blkbits = inode->i_blkbits;
unsigned long first_block = offset >> blkbits;
unsigned long max_blocks = (length + (1 << blkbits) - 1) >> blkbits;
@@ -814,13 +813,9 @@ static int ext2_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
return ret;
iomap->flags = 0;
- bdev = inode->i_sb->s_bdev;
- iomap->bdev = bdev;
+ iomap->bdev = inode->i_sb->s_bdev;
iomap->offset = (u64)first_block << blkbits;
- if (blk_queue_dax(bdev->bd_queue))
- iomap->dax_dev = fs_dax_get_by_host(bdev->bd_disk->disk_name);
- else
- iomap->dax_dev = NULL;
+ iomap->dax_dev = inode->i_sb->s_daxdev;
if (ret == 0) {
iomap->type = IOMAP_HOLE;
@@ -842,7 +837,6 @@ static int
ext2_iomap_end(struct inode *inode, loff_t offset, loff_t length,
ssize_t written, unsigned flags, struct iomap *iomap)
{
- fs_put_dax(iomap->dax_dev);
if (iomap->type == IOMAP_MAPPED &&
written < length &&
(flags & IOMAP_WRITE))
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index c774bdc22759..311690522366 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -3404,7 +3404,6 @@ static int ext4_releasepage(struct page *page, gfp_t wait)
static int ext4_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
unsigned flags, struct iomap *iomap)
{
- struct block_device *bdev;
unsigned int blkbits = inode->i_blkbits;
unsigned long first_block = offset >> blkbits;
unsigned long last_block = (offset + length - 1) >> blkbits;
@@ -3473,12 +3472,8 @@ static int ext4_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
}
iomap->flags = 0;
- bdev = inode->i_sb->s_bdev;
- iomap->bdev = bdev;
- if (blk_queue_dax(bdev->bd_queue))
- iomap->dax_dev = fs_dax_get_by_host(bdev->bd_disk->disk_name);
- else
- iomap->dax_dev = NULL;
+ iomap->bdev = inode->i_sb->s_bdev;
+ iomap->dax_dev = inode->i_sb->s_daxdev;
iomap->offset = first_block << blkbits;
if (ret == 0) {
@@ -3511,7 +3506,6 @@ static int ext4_iomap_end(struct inode *inode, loff_t offset, loff_t length,
int blkbits = inode->i_blkbits;
bool truncate = false;
- fs_put_dax(iomap->dax_dev);
if (!(flags & IOMAP_WRITE) || (flags & IOMAP_FAULT))
return 0;
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH v2 2/2] ext2, ext4: use the super_block dax_device
@ 2017-08-28 3:48 ` Dan Williams
0 siblings, 0 replies; 28+ messages in thread
From: Dan Williams @ 2017-08-28 3:48 UTC (permalink / raw)
To: linux-fsdevel-u79uwXL29TY76Z2rM5mHXA
Cc: jack-AlSwsSmVLrQ, linux-nvdimm-hn68Rpc1hR1g9hUCZPvPmw,
linux-xfs-u79uwXL29TY76Z2rM5mHXA, Andreas Dilger, Jan Kara,
Theodore Ts'o, linux-ext4-u79uwXL29TY76Z2rM5mHXA,
hch-jcswGhMUV9g
The ->iomap_begin() operation is a hot path, and now that mount_bdev()
arranges for the dax_device to be populated in the super_block, we can
just reference that attribute directly rather than perform a new lookup.
Cc: Jan Kara <jack-IBi9RG/b67k@public.gmane.org>
Cc: "Theodore Ts'o" <tytso-3s7WtUTddSA@public.gmane.org>
Cc: Andreas Dilger <adilger.kernel-m1MBpc4rdrD3fQ9qLvQP4Q@public.gmane.org>
Reported-by: Christoph Hellwig <hch-jcswGhMUV9g@public.gmane.org>
Signed-off-by: Dan Williams <dan.j.williams-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
---
fs/ext2/inode.c | 10 ++--------
fs/ext4/inode.c | 10 ++--------
2 files changed, 4 insertions(+), 16 deletions(-)
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c
index 30163d007b2f..7102b77a83c6 100644
--- a/fs/ext2/inode.c
+++ b/fs/ext2/inode.c
@@ -800,7 +800,6 @@ int ext2_get_block(struct inode *inode, sector_t iblock,
static int ext2_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
unsigned flags, struct iomap *iomap)
{
- struct block_device *bdev;
unsigned int blkbits = inode->i_blkbits;
unsigned long first_block = offset >> blkbits;
unsigned long max_blocks = (length + (1 << blkbits) - 1) >> blkbits;
@@ -814,13 +813,9 @@ static int ext2_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
return ret;
iomap->flags = 0;
- bdev = inode->i_sb->s_bdev;
- iomap->bdev = bdev;
+ iomap->bdev = inode->i_sb->s_bdev;
iomap->offset = (u64)first_block << blkbits;
- if (blk_queue_dax(bdev->bd_queue))
- iomap->dax_dev = fs_dax_get_by_host(bdev->bd_disk->disk_name);
- else
- iomap->dax_dev = NULL;
+ iomap->dax_dev = inode->i_sb->s_daxdev;
if (ret == 0) {
iomap->type = IOMAP_HOLE;
@@ -842,7 +837,6 @@ static int
ext2_iomap_end(struct inode *inode, loff_t offset, loff_t length,
ssize_t written, unsigned flags, struct iomap *iomap)
{
- fs_put_dax(iomap->dax_dev);
if (iomap->type == IOMAP_MAPPED &&
written < length &&
(flags & IOMAP_WRITE))
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index c774bdc22759..311690522366 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -3404,7 +3404,6 @@ static int ext4_releasepage(struct page *page, gfp_t wait)
static int ext4_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
unsigned flags, struct iomap *iomap)
{
- struct block_device *bdev;
unsigned int blkbits = inode->i_blkbits;
unsigned long first_block = offset >> blkbits;
unsigned long last_block = (offset + length - 1) >> blkbits;
@@ -3473,12 +3472,8 @@ static int ext4_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
}
iomap->flags = 0;
- bdev = inode->i_sb->s_bdev;
- iomap->bdev = bdev;
- if (blk_queue_dax(bdev->bd_queue))
- iomap->dax_dev = fs_dax_get_by_host(bdev->bd_disk->disk_name);
- else
- iomap->dax_dev = NULL;
+ iomap->bdev = inode->i_sb->s_bdev;
+ iomap->dax_dev = inode->i_sb->s_daxdev;
iomap->offset = first_block << blkbits;
if (ret == 0) {
@@ -3511,7 +3506,6 @@ static int ext4_iomap_end(struct inode *inode, loff_t offset, loff_t length,
int blkbits = inode->i_blkbits;
bool truncate = false;
- fs_put_dax(iomap->dax_dev);
if (!(flags & IOMAP_WRITE) || (flags & IOMAP_FAULT))
return 0;
^ permalink raw reply related [flat|nested] 28+ messages in thread
* Re: [PATCH v2 2/2] ext2, ext4: use the super_block dax_device
2017-08-28 3:48 ` Dan Williams
(?)
@ 2017-08-28 8:27 ` Jan Kara
-1 siblings, 0 replies; 28+ messages in thread
From: Jan Kara @ 2017-08-28 8:27 UTC (permalink / raw)
To: Dan Williams
Cc: Theodore Ts'o, linux-nvdimm, linux-xfs, Andreas Dilger,
Jan Kara, linux-fsdevel, jack, linux-ext4, hch
On Sun 27-08-17 20:48:46, Dan Williams wrote:
> The ->iomap_begin() operation is a hot path, and now that mount_bdev()
> arranges for the dax_device to be populated in the super_block, we can
> just reference that attribute directly rather than perform a new lookup.
>
> Cc: Jan Kara <jack@suse.com>
> Cc: "Theodore Ts'o" <tytso@mit.edu>
> Cc: Andreas Dilger <adilger.kernel@dilger.ca>
> Reported-by: Christoph Hellwig <hch@lst.de>
> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Looks good. You can add:
Reviewed-by: Jan Kara <jack@suse.cz>
Honza
> ---
> fs/ext2/inode.c | 10 ++--------
> fs/ext4/inode.c | 10 ++--------
> 2 files changed, 4 insertions(+), 16 deletions(-)
>
> diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c
> index 30163d007b2f..7102b77a83c6 100644
> --- a/fs/ext2/inode.c
> +++ b/fs/ext2/inode.c
> @@ -800,7 +800,6 @@ int ext2_get_block(struct inode *inode, sector_t iblock,
> static int ext2_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
> unsigned flags, struct iomap *iomap)
> {
> - struct block_device *bdev;
> unsigned int blkbits = inode->i_blkbits;
> unsigned long first_block = offset >> blkbits;
> unsigned long max_blocks = (length + (1 << blkbits) - 1) >> blkbits;
> @@ -814,13 +813,9 @@ static int ext2_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
> return ret;
>
> iomap->flags = 0;
> - bdev = inode->i_sb->s_bdev;
> - iomap->bdev = bdev;
> + iomap->bdev = inode->i_sb->s_bdev;
> iomap->offset = (u64)first_block << blkbits;
> - if (blk_queue_dax(bdev->bd_queue))
> - iomap->dax_dev = fs_dax_get_by_host(bdev->bd_disk->disk_name);
> - else
> - iomap->dax_dev = NULL;
> + iomap->dax_dev = inode->i_sb->s_daxdev;
>
> if (ret == 0) {
> iomap->type = IOMAP_HOLE;
> @@ -842,7 +837,6 @@ static int
> ext2_iomap_end(struct inode *inode, loff_t offset, loff_t length,
> ssize_t written, unsigned flags, struct iomap *iomap)
> {
> - fs_put_dax(iomap->dax_dev);
> if (iomap->type == IOMAP_MAPPED &&
> written < length &&
> (flags & IOMAP_WRITE))
> diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
> index c774bdc22759..311690522366 100644
> --- a/fs/ext4/inode.c
> +++ b/fs/ext4/inode.c
> @@ -3404,7 +3404,6 @@ static int ext4_releasepage(struct page *page, gfp_t wait)
> static int ext4_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
> unsigned flags, struct iomap *iomap)
> {
> - struct block_device *bdev;
> unsigned int blkbits = inode->i_blkbits;
> unsigned long first_block = offset >> blkbits;
> unsigned long last_block = (offset + length - 1) >> blkbits;
> @@ -3473,12 +3472,8 @@ static int ext4_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
> }
>
> iomap->flags = 0;
> - bdev = inode->i_sb->s_bdev;
> - iomap->bdev = bdev;
> - if (blk_queue_dax(bdev->bd_queue))
> - iomap->dax_dev = fs_dax_get_by_host(bdev->bd_disk->disk_name);
> - else
> - iomap->dax_dev = NULL;
> + iomap->bdev = inode->i_sb->s_bdev;
> + iomap->dax_dev = inode->i_sb->s_daxdev;
> iomap->offset = first_block << blkbits;
>
> if (ret == 0) {
> @@ -3511,7 +3506,6 @@ static int ext4_iomap_end(struct inode *inode, loff_t offset, loff_t length,
> int blkbits = inode->i_blkbits;
> bool truncate = false;
>
> - fs_put_dax(iomap->dax_dev);
> if (!(flags & IOMAP_WRITE) || (flags & IOMAP_FAULT))
> return 0;
>
>
--
Jan Kara <jack@suse.com>
SUSE Labs, CR
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v2 2/2] ext2, ext4: use the super_block dax_device
@ 2017-08-28 8:27 ` Jan Kara
0 siblings, 0 replies; 28+ messages in thread
From: Jan Kara @ 2017-08-28 8:27 UTC (permalink / raw)
To: Dan Williams
Cc: linux-fsdevel, Theodore Ts'o, linux-nvdimm, linux-xfs,
Andreas Dilger, Jan Kara, jack, linux-ext4, hch
On Sun 27-08-17 20:48:46, Dan Williams wrote:
> The ->iomap_begin() operation is a hot path, and now that mount_bdev()
> arranges for the dax_device to be populated in the super_block, we can
> just reference that attribute directly rather than perform a new lookup.
>
> Cc: Jan Kara <jack@suse.com>
> Cc: "Theodore Ts'o" <tytso@mit.edu>
> Cc: Andreas Dilger <adilger.kernel@dilger.ca>
> Reported-by: Christoph Hellwig <hch@lst.de>
> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Looks good. You can add:
Reviewed-by: Jan Kara <jack@suse.cz>
Honza
> ---
> fs/ext2/inode.c | 10 ++--------
> fs/ext4/inode.c | 10 ++--------
> 2 files changed, 4 insertions(+), 16 deletions(-)
>
> diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c
> index 30163d007b2f..7102b77a83c6 100644
> --- a/fs/ext2/inode.c
> +++ b/fs/ext2/inode.c
> @@ -800,7 +800,6 @@ int ext2_get_block(struct inode *inode, sector_t iblock,
> static int ext2_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
> unsigned flags, struct iomap *iomap)
> {
> - struct block_device *bdev;
> unsigned int blkbits = inode->i_blkbits;
> unsigned long first_block = offset >> blkbits;
> unsigned long max_blocks = (length + (1 << blkbits) - 1) >> blkbits;
> @@ -814,13 +813,9 @@ static int ext2_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
> return ret;
>
> iomap->flags = 0;
> - bdev = inode->i_sb->s_bdev;
> - iomap->bdev = bdev;
> + iomap->bdev = inode->i_sb->s_bdev;
> iomap->offset = (u64)first_block << blkbits;
> - if (blk_queue_dax(bdev->bd_queue))
> - iomap->dax_dev = fs_dax_get_by_host(bdev->bd_disk->disk_name);
> - else
> - iomap->dax_dev = NULL;
> + iomap->dax_dev = inode->i_sb->s_daxdev;
>
> if (ret == 0) {
> iomap->type = IOMAP_HOLE;
> @@ -842,7 +837,6 @@ static int
> ext2_iomap_end(struct inode *inode, loff_t offset, loff_t length,
> ssize_t written, unsigned flags, struct iomap *iomap)
> {
> - fs_put_dax(iomap->dax_dev);
> if (iomap->type == IOMAP_MAPPED &&
> written < length &&
> (flags & IOMAP_WRITE))
> diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
> index c774bdc22759..311690522366 100644
> --- a/fs/ext4/inode.c
> +++ b/fs/ext4/inode.c
> @@ -3404,7 +3404,6 @@ static int ext4_releasepage(struct page *page, gfp_t wait)
> static int ext4_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
> unsigned flags, struct iomap *iomap)
> {
> - struct block_device *bdev;
> unsigned int blkbits = inode->i_blkbits;
> unsigned long first_block = offset >> blkbits;
> unsigned long last_block = (offset + length - 1) >> blkbits;
> @@ -3473,12 +3472,8 @@ static int ext4_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
> }
>
> iomap->flags = 0;
> - bdev = inode->i_sb->s_bdev;
> - iomap->bdev = bdev;
> - if (blk_queue_dax(bdev->bd_queue))
> - iomap->dax_dev = fs_dax_get_by_host(bdev->bd_disk->disk_name);
> - else
> - iomap->dax_dev = NULL;
> + iomap->bdev = inode->i_sb->s_bdev;
> + iomap->dax_dev = inode->i_sb->s_daxdev;
> iomap->offset = first_block << blkbits;
>
> if (ret == 0) {
> @@ -3511,7 +3506,6 @@ static int ext4_iomap_end(struct inode *inode, loff_t offset, loff_t length,
> int blkbits = inode->i_blkbits;
> bool truncate = false;
>
> - fs_put_dax(iomap->dax_dev);
> if (!(flags & IOMAP_WRITE) || (flags & IOMAP_FAULT))
> return 0;
>
>
--
Jan Kara <jack@suse.com>
SUSE Labs, CR
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v2 2/2] ext2, ext4: use the super_block dax_device
@ 2017-08-28 8:27 ` Jan Kara
0 siblings, 0 replies; 28+ messages in thread
From: Jan Kara @ 2017-08-28 8:27 UTC (permalink / raw)
To: Dan Williams
Cc: Theodore Ts'o, linux-nvdimm-hn68Rpc1hR1g9hUCZPvPmw,
linux-xfs-u79uwXL29TY76Z2rM5mHXA, Andreas Dilger, Jan Kara,
linux-fsdevel-u79uwXL29TY76Z2rM5mHXA, jack-AlSwsSmVLrQ,
linux-ext4-u79uwXL29TY76Z2rM5mHXA, hch-jcswGhMUV9g
On Sun 27-08-17 20:48:46, Dan Williams wrote:
> The ->iomap_begin() operation is a hot path, and now that mount_bdev()
> arranges for the dax_device to be populated in the super_block, we can
> just reference that attribute directly rather than perform a new lookup.
>
> Cc: Jan Kara <jack-IBi9RG/b67k@public.gmane.org>
> Cc: "Theodore Ts'o" <tytso-3s7WtUTddSA@public.gmane.org>
> Cc: Andreas Dilger <adilger.kernel-m1MBpc4rdrD3fQ9qLvQP4Q@public.gmane.org>
> Reported-by: Christoph Hellwig <hch-jcswGhMUV9g@public.gmane.org>
> Signed-off-by: Dan Williams <dan.j.williams-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
Looks good. You can add:
Reviewed-by: Jan Kara <jack-AlSwsSmVLrQ@public.gmane.org>
Honza
> ---
> fs/ext2/inode.c | 10 ++--------
> fs/ext4/inode.c | 10 ++--------
> 2 files changed, 4 insertions(+), 16 deletions(-)
>
> diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c
> index 30163d007b2f..7102b77a83c6 100644
> --- a/fs/ext2/inode.c
> +++ b/fs/ext2/inode.c
> @@ -800,7 +800,6 @@ int ext2_get_block(struct inode *inode, sector_t iblock,
> static int ext2_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
> unsigned flags, struct iomap *iomap)
> {
> - struct block_device *bdev;
> unsigned int blkbits = inode->i_blkbits;
> unsigned long first_block = offset >> blkbits;
> unsigned long max_blocks = (length + (1 << blkbits) - 1) >> blkbits;
> @@ -814,13 +813,9 @@ static int ext2_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
> return ret;
>
> iomap->flags = 0;
> - bdev = inode->i_sb->s_bdev;
> - iomap->bdev = bdev;
> + iomap->bdev = inode->i_sb->s_bdev;
> iomap->offset = (u64)first_block << blkbits;
> - if (blk_queue_dax(bdev->bd_queue))
> - iomap->dax_dev = fs_dax_get_by_host(bdev->bd_disk->disk_name);
> - else
> - iomap->dax_dev = NULL;
> + iomap->dax_dev = inode->i_sb->s_daxdev;
>
> if (ret == 0) {
> iomap->type = IOMAP_HOLE;
> @@ -842,7 +837,6 @@ static int
> ext2_iomap_end(struct inode *inode, loff_t offset, loff_t length,
> ssize_t written, unsigned flags, struct iomap *iomap)
> {
> - fs_put_dax(iomap->dax_dev);
> if (iomap->type == IOMAP_MAPPED &&
> written < length &&
> (flags & IOMAP_WRITE))
> diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
> index c774bdc22759..311690522366 100644
> --- a/fs/ext4/inode.c
> +++ b/fs/ext4/inode.c
> @@ -3404,7 +3404,6 @@ static int ext4_releasepage(struct page *page, gfp_t wait)
> static int ext4_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
> unsigned flags, struct iomap *iomap)
> {
> - struct block_device *bdev;
> unsigned int blkbits = inode->i_blkbits;
> unsigned long first_block = offset >> blkbits;
> unsigned long last_block = (offset + length - 1) >> blkbits;
> @@ -3473,12 +3472,8 @@ static int ext4_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
> }
>
> iomap->flags = 0;
> - bdev = inode->i_sb->s_bdev;
> - iomap->bdev = bdev;
> - if (blk_queue_dax(bdev->bd_queue))
> - iomap->dax_dev = fs_dax_get_by_host(bdev->bd_disk->disk_name);
> - else
> - iomap->dax_dev = NULL;
> + iomap->bdev = inode->i_sb->s_bdev;
> + iomap->dax_dev = inode->i_sb->s_daxdev;
> iomap->offset = first_block << blkbits;
>
> if (ret == 0) {
> @@ -3511,7 +3506,6 @@ static int ext4_iomap_end(struct inode *inode, loff_t offset, loff_t length,
> int blkbits = inode->i_blkbits;
> bool truncate = false;
>
> - fs_put_dax(iomap->dax_dev);
> if (!(flags & IOMAP_WRITE) || (flags & IOMAP_FAULT))
> return 0;
>
>
--
Jan Kara <jack-IBi9RG/b67k@public.gmane.org>
SUSE Labs, CR
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v2 1/2] fs, xfs: perform dax_device lookup at mount
2017-08-28 3:48 ` Dan Williams
(?)
@ 2017-08-28 8:31 ` Jan Kara
-1 siblings, 0 replies; 28+ messages in thread
From: Jan Kara @ 2017-08-28 8:31 UTC (permalink / raw)
To: Dan Williams
Cc: jack, Darrick J. Wong, linux-nvdimm, linux-xfs, linux-fsdevel,
linux-ext4, hch
On Sun 27-08-17 20:48:40, Dan Williams wrote:
> The ->iomap_begin() operation is a hot path, so cache the
> fs_dax_get_by_host() result at mount time to avoid the incurring the
> hash lookup overhead on a per-i/o basis.
>
> Cc: "Darrick J. Wong" <darrick.wong@oracle.com>
> Reported-by: Christoph Hellwig <hch@lst.de>
> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Looks good to me. For the generic parts:
Reviewed-by: Jan Kara <jack@suse.cz>
[XFS part looks correct to me as well but I don't feel expert enough to
give any tags there].
Honza
> ---
> drivers/dax/super.c | 10 ++++++++++
> fs/super.c | 26 +++++++++++++++++++++++---
> fs/xfs/xfs_aops.c | 13 +++++++++++++
> fs/xfs/xfs_aops.h | 1 +
> fs/xfs/xfs_buf.c | 4 +++-
> fs/xfs/xfs_buf.h | 3 ++-
> fs/xfs/xfs_iomap.c | 10 +---------
> fs/xfs/xfs_super.c | 21 +++++++++++++++++----
> include/linux/dax.h | 6 ++++++
> include/linux/fs.h | 1 +
> 10 files changed, 77 insertions(+), 18 deletions(-)
>
> diff --git a/drivers/dax/super.c b/drivers/dax/super.c
> index 938eb4868f7f..b699aac268a6 100644
> --- a/drivers/dax/super.c
> +++ b/drivers/dax/super.c
> @@ -46,6 +46,8 @@ void dax_read_unlock(int id)
> EXPORT_SYMBOL_GPL(dax_read_unlock);
>
> #ifdef CONFIG_BLOCK
> +#include <linux/blkdev.h>
> +
> int bdev_dax_pgoff(struct block_device *bdev, sector_t sector, size_t size,
> pgoff_t *pgoff)
> {
> @@ -59,6 +61,14 @@ int bdev_dax_pgoff(struct block_device *bdev, sector_t sector, size_t size,
> }
> EXPORT_SYMBOL(bdev_dax_pgoff);
>
> +struct dax_device *fs_dax_get_by_bdev(struct block_device *bdev)
> +{
> + if (!blk_queue_dax(bdev->bd_queue))
> + return NULL;
> + return fs_dax_get_by_host(bdev->bd_disk->disk_name);
> +}
> +EXPORT_SYMBOL_GPL(fs_dax_get_by_bdev);
> +
> /**
> * __bdev_dax_supported() - Check if the device supports dax for filesystem
> * @sb: The superblock of the device
> diff --git a/fs/super.c b/fs/super.c
> index 6bc3352adcf3..671889b02bed 100644
> --- a/fs/super.c
> +++ b/fs/super.c
> @@ -23,6 +23,7 @@
> #include <linux/export.h>
> #include <linux/slab.h>
> #include <linux/blkdev.h>
> +#include <linux/dax.h>
> #include <linux/mount.h>
> #include <linux/security.h>
> #include <linux/writeback.h> /* for the emergency remount stuff */
> @@ -1048,9 +1049,17 @@ struct dentry *mount_ns(struct file_system_type *fs_type,
> EXPORT_SYMBOL(mount_ns);
>
> #ifdef CONFIG_BLOCK
> +struct sget_devs {
> + struct block_device *bdev;
> + struct dax_device *dax_dev;
> +};
> +
> static int set_bdev_super(struct super_block *s, void *data)
> {
> - s->s_bdev = data;
> + struct sget_devs *devs = data;
> +
> + s->s_bdev = devs->bdev;
> + s->s_daxdev = devs->dax_dev;
> s->s_dev = s->s_bdev->bd_dev;
> s->s_bdi = bdi_get(s->s_bdev->bd_bdi);
>
> @@ -1059,14 +1068,18 @@ static int set_bdev_super(struct super_block *s, void *data)
>
> static int test_bdev_super(struct super_block *s, void *data)
> {
> - return (void *)s->s_bdev == data;
> + struct sget_devs *devs = data;
> +
> + return s->s_bdev == devs->bdev;
> }
>
> struct dentry *mount_bdev(struct file_system_type *fs_type,
> int flags, const char *dev_name, void *data,
> int (*fill_super)(struct super_block *, void *, int))
> {
> + struct sget_devs devs;
> struct block_device *bdev;
> + struct dax_device *dax_dev;
> struct super_block *s;
> fmode_t mode = FMODE_READ | FMODE_EXCL;
> int error = 0;
> @@ -1077,6 +1090,7 @@ struct dentry *mount_bdev(struct file_system_type *fs_type,
> bdev = blkdev_get_by_path(dev_name, mode, fs_type);
> if (IS_ERR(bdev))
> return ERR_CAST(bdev);
> + dax_dev = fs_dax_get_by_bdev(bdev);
>
> /*
> * once the super is inserted into the list by sget, s_umount
> @@ -1089,8 +1103,10 @@ struct dentry *mount_bdev(struct file_system_type *fs_type,
> error = -EBUSY;
> goto error_bdev;
> }
> + devs.bdev = bdev;
> + devs.dax_dev = dax_dev;
> s = sget(fs_type, test_bdev_super, set_bdev_super, flags | MS_NOSEC,
> - bdev);
> + &devs);
> mutex_unlock(&bdev->bd_fsfreeze_mutex);
> if (IS_ERR(s))
> goto error_s;
> @@ -1111,6 +1127,7 @@ struct dentry *mount_bdev(struct file_system_type *fs_type,
> */
> up_write(&s->s_umount);
> blkdev_put(bdev, mode);
> + fs_put_dax(dax_dev);
> down_write(&s->s_umount);
> } else {
> s->s_mode = mode;
> @@ -1132,6 +1149,7 @@ struct dentry *mount_bdev(struct file_system_type *fs_type,
> error = PTR_ERR(s);
> error_bdev:
> blkdev_put(bdev, mode);
> + fs_put_dax(dax_dev);
> error:
> return ERR_PTR(error);
> }
> @@ -1140,6 +1158,7 @@ EXPORT_SYMBOL(mount_bdev);
> void kill_block_super(struct super_block *sb)
> {
> struct block_device *bdev = sb->s_bdev;
> + struct dax_device *dax_dev = sb->s_daxdev;
> fmode_t mode = sb->s_mode;
>
> bdev->bd_super = NULL;
> @@ -1147,6 +1166,7 @@ void kill_block_super(struct super_block *sb)
> sync_blockdev(bdev);
> WARN_ON_ONCE(!(mode & FMODE_EXCL));
> blkdev_put(bdev, mode | FMODE_EXCL);
> + fs_put_dax(dax_dev);
> }
>
> EXPORT_SYMBOL(kill_block_super);
> diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c
> index 6bf120bb1a17..78185f3b10b2 100644
> --- a/fs/xfs/xfs_aops.c
> +++ b/fs/xfs/xfs_aops.c
> @@ -80,6 +80,19 @@ xfs_find_bdev_for_inode(
> return mp->m_ddev_targp->bt_bdev;
> }
>
> +struct dax_device *
> +xfs_find_daxdev_for_inode(
> + struct inode *inode)
> +{
> + struct xfs_inode *ip = XFS_I(inode);
> + struct xfs_mount *mp = ip->i_mount;
> +
> + if (XFS_IS_REALTIME_INODE(ip))
> + return mp->m_rtdev_targp->bt_daxdev;
> + else
> + return mp->m_ddev_targp->bt_daxdev;
> +}
> +
> /*
> * We're now finished for good with this page. Update the page state via the
> * associated buffer_heads, paying attention to the start and end offsets that
> diff --git a/fs/xfs/xfs_aops.h b/fs/xfs/xfs_aops.h
> index cc174ec6c2fd..88c85ea63da0 100644
> --- a/fs/xfs/xfs_aops.h
> +++ b/fs/xfs/xfs_aops.h
> @@ -59,5 +59,6 @@ int xfs_setfilesize(struct xfs_inode *ip, xfs_off_t offset, size_t size);
>
> extern void xfs_count_page_state(struct page *, int *, int *);
> extern struct block_device *xfs_find_bdev_for_inode(struct inode *);
> +extern struct dax_device *xfs_find_daxdev_for_inode(struct inode *);
>
> #endif /* __XFS_AOPS_H__ */
> diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c
> index 72f038492ba8..6deb86c845d1 100644
> --- a/fs/xfs/xfs_buf.c
> +++ b/fs/xfs/xfs_buf.c
> @@ -1802,7 +1802,8 @@ xfs_setsize_buftarg_early(
> xfs_buftarg_t *
> xfs_alloc_buftarg(
> struct xfs_mount *mp,
> - struct block_device *bdev)
> + struct block_device *bdev,
> + struct dax_device *dax_dev)
> {
> xfs_buftarg_t *btp;
>
> @@ -1811,6 +1812,7 @@ xfs_alloc_buftarg(
> btp->bt_mount = mp;
> btp->bt_dev = bdev->bd_dev;
> btp->bt_bdev = bdev;
> + btp->bt_daxdev = dax_dev;
>
> if (xfs_setsize_buftarg_early(btp, bdev))
> goto error;
> diff --git a/fs/xfs/xfs_buf.h b/fs/xfs/xfs_buf.h
> index 20721261dae5..bf71507ddb16 100644
> --- a/fs/xfs/xfs_buf.h
> +++ b/fs/xfs/xfs_buf.h
> @@ -108,6 +108,7 @@ typedef unsigned int xfs_buf_flags_t;
> typedef struct xfs_buftarg {
> dev_t bt_dev;
> struct block_device *bt_bdev;
> + struct dax_device *bt_daxdev;
> struct xfs_mount *bt_mount;
> unsigned int bt_meta_sectorsize;
> size_t bt_meta_sectormask;
> @@ -385,7 +386,7 @@ xfs_buf_update_cksum(struct xfs_buf *bp, unsigned long cksum_offset)
> * Handling of buftargs.
> */
> extern xfs_buftarg_t *xfs_alloc_buftarg(struct xfs_mount *,
> - struct block_device *);
> + struct block_device *, struct dax_device *);
> extern void xfs_free_buftarg(struct xfs_mount *, struct xfs_buftarg *);
> extern void xfs_wait_buftarg(xfs_buftarg_t *);
> extern int xfs_setsize_buftarg(xfs_buftarg_t *, unsigned int);
> diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
> index 813394c62849..7c934e407332 100644
> --- a/fs/xfs/xfs_iomap.c
> +++ b/fs/xfs/xfs_iomap.c
> @@ -69,6 +69,7 @@ xfs_bmbt_to_iomap(
> iomap->offset = XFS_FSB_TO_B(mp, imap->br_startoff);
> iomap->length = XFS_FSB_TO_B(mp, imap->br_blockcount);
> iomap->bdev = xfs_find_bdev_for_inode(VFS_I(ip));
> + iomap->dax_dev = xfs_find_daxdev_for_inode(VFS_I(ip));
> }
>
> xfs_extlen_t
> @@ -976,7 +977,6 @@ xfs_file_iomap_begin(
> int nimaps = 1, error = 0;
> bool shared = false, trimmed = false;
> unsigned lockmode;
> - struct block_device *bdev;
>
> if (XFS_FORCED_SHUTDOWN(mp))
> return -EIO;
> @@ -1087,13 +1087,6 @@ xfs_file_iomap_begin(
>
> xfs_bmbt_to_iomap(ip, iomap, &imap);
>
> - /* optionally associate a dax device with the iomap bdev */
> - bdev = iomap->bdev;
> - if (blk_queue_dax(bdev->bd_queue))
> - iomap->dax_dev = fs_dax_get_by_host(bdev->bd_disk->disk_name);
> - else
> - iomap->dax_dev = NULL;
> -
> if (shared)
> iomap->flags |= IOMAP_F_SHARED;
> return 0;
> @@ -1171,7 +1164,6 @@ xfs_file_iomap_end(
> unsigned flags,
> struct iomap *iomap)
> {
> - fs_put_dax(iomap->dax_dev);
> if ((flags & IOMAP_WRITE) && iomap->type == IOMAP_DELALLOC)
> return xfs_file_iomap_end_delalloc(XFS_I(inode), offset,
> length, written, iomap);
> diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
> index 38aaacdbb8b3..d863f96b16e2 100644
> --- a/fs/xfs/xfs_super.c
> +++ b/fs/xfs/xfs_super.c
> @@ -716,13 +716,19 @@ xfs_close_devices(
> {
> if (mp->m_logdev_targp && mp->m_logdev_targp != mp->m_ddev_targp) {
> struct block_device *logdev = mp->m_logdev_targp->bt_bdev;
> + struct dax_device *dax_logdev = mp->m_logdev_targp->bt_daxdev;
> +
> xfs_free_buftarg(mp, mp->m_logdev_targp);
> xfs_blkdev_put(logdev);
> + fs_put_dax(dax_logdev);
> }
> if (mp->m_rtdev_targp) {
> struct block_device *rtdev = mp->m_rtdev_targp->bt_bdev;
> + struct dax_device *dax_rtdev = mp->m_rtdev_targp->bt_daxdev;
> +
> xfs_free_buftarg(mp, mp->m_rtdev_targp);
> xfs_blkdev_put(rtdev);
> + fs_put_dax(dax_rtdev);
> }
> xfs_free_buftarg(mp, mp->m_ddev_targp);
> }
> @@ -742,7 +748,9 @@ xfs_open_devices(
> struct xfs_mount *mp)
> {
> struct block_device *ddev = mp->m_super->s_bdev;
> + struct dax_device *dax_ddev = mp->m_super->s_daxdev;
> struct block_device *logdev = NULL, *rtdev = NULL;
> + struct dax_device *dax_logdev = NULL, *dax_rtdev = NULL;
> int error;
>
> /*
> @@ -752,6 +760,7 @@ xfs_open_devices(
> error = xfs_blkdev_get(mp, mp->m_logname, &logdev);
> if (error)
> goto out;
> + dax_logdev = fs_dax_get_by_bdev(logdev);
> }
>
> if (mp->m_rtname) {
> @@ -765,24 +774,25 @@ xfs_open_devices(
> error = -EINVAL;
> goto out_close_rtdev;
> }
> + dax_rtdev = fs_dax_get_by_bdev(rtdev);
> }
>
> /*
> * Setup xfs_mount buffer target pointers
> */
> error = -ENOMEM;
> - mp->m_ddev_targp = xfs_alloc_buftarg(mp, ddev);
> + mp->m_ddev_targp = xfs_alloc_buftarg(mp, ddev, dax_ddev);
> if (!mp->m_ddev_targp)
> goto out_close_rtdev;
>
> if (rtdev) {
> - mp->m_rtdev_targp = xfs_alloc_buftarg(mp, rtdev);
> + mp->m_rtdev_targp = xfs_alloc_buftarg(mp, rtdev, dax_rtdev);
> if (!mp->m_rtdev_targp)
> goto out_free_ddev_targ;
> }
>
> if (logdev && logdev != ddev) {
> - mp->m_logdev_targp = xfs_alloc_buftarg(mp, logdev);
> + mp->m_logdev_targp = xfs_alloc_buftarg(mp, logdev, dax_logdev);
> if (!mp->m_logdev_targp)
> goto out_free_rtdev_targ;
> } else {
> @@ -798,9 +808,12 @@ xfs_open_devices(
> xfs_free_buftarg(mp, mp->m_ddev_targp);
> out_close_rtdev:
> xfs_blkdev_put(rtdev);
> + fs_put_dax(dax_rtdev);
> out_close_logdev:
> - if (logdev && logdev != ddev)
> + if (logdev && logdev != ddev) {
> xfs_blkdev_put(logdev);
> + fs_put_dax(dax_logdev);
> + }
> out:
> return error;
> }
> diff --git a/include/linux/dax.h b/include/linux/dax.h
> index df97b7af7e2c..6e32be3badec 100644
> --- a/include/linux/dax.h
> +++ b/include/linux/dax.h
> @@ -57,6 +57,7 @@ static inline void fs_put_dax(struct dax_device *dax_dev)
> put_dax(dax_dev);
> }
>
> +struct dax_device *fs_dax_get_by_bdev(struct block_device *bdev);
> #else
> static inline int bdev_dax_supported(struct super_block *sb, int blocksize)
> {
> @@ -71,6 +72,11 @@ static inline struct dax_device *fs_dax_get_by_host(const char *host)
> static inline void fs_put_dax(struct dax_device *dax_dev)
> {
> }
> +
> +struct dax_device *fs_dax_get_by_bdev(struct block_device *bdev)
> +{
> + return NULL;
> +}
> #endif
>
> int dax_read_lock(void);
> diff --git a/include/linux/fs.h b/include/linux/fs.h
> index 6e1fd5d21248..d0e3234a1fae 100644
> --- a/include/linux/fs.h
> +++ b/include/linux/fs.h
> @@ -1334,6 +1334,7 @@ struct super_block {
> struct hlist_bl_head s_anon; /* anonymous dentries for (nfs) exporting */
> struct list_head s_mounts; /* list of mounts; _not_ for fs use */
> struct block_device *s_bdev;
> + struct dax_device *s_daxdev;
> struct backing_dev_info *s_bdi;
> struct mtd_info *s_mtd;
> struct hlist_node s_instances;
>
--
Jan Kara <jack@suse.com>
SUSE Labs, CR
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v2 1/2] fs, xfs: perform dax_device lookup at mount
@ 2017-08-28 8:31 ` Jan Kara
0 siblings, 0 replies; 28+ messages in thread
From: Jan Kara @ 2017-08-28 8:31 UTC (permalink / raw)
To: Dan Williams
Cc: linux-fsdevel, jack, linux-nvdimm, Darrick J. Wong, linux-xfs,
linux-ext4, hch
On Sun 27-08-17 20:48:40, Dan Williams wrote:
> The ->iomap_begin() operation is a hot path, so cache the
> fs_dax_get_by_host() result at mount time to avoid the incurring the
> hash lookup overhead on a per-i/o basis.
>
> Cc: "Darrick J. Wong" <darrick.wong@oracle.com>
> Reported-by: Christoph Hellwig <hch@lst.de>
> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Looks good to me. For the generic parts:
Reviewed-by: Jan Kara <jack@suse.cz>
[XFS part looks correct to me as well but I don't feel expert enough to
give any tags there].
Honza
> ---
> drivers/dax/super.c | 10 ++++++++++
> fs/super.c | 26 +++++++++++++++++++++++---
> fs/xfs/xfs_aops.c | 13 +++++++++++++
> fs/xfs/xfs_aops.h | 1 +
> fs/xfs/xfs_buf.c | 4 +++-
> fs/xfs/xfs_buf.h | 3 ++-
> fs/xfs/xfs_iomap.c | 10 +---------
> fs/xfs/xfs_super.c | 21 +++++++++++++++++----
> include/linux/dax.h | 6 ++++++
> include/linux/fs.h | 1 +
> 10 files changed, 77 insertions(+), 18 deletions(-)
>
> diff --git a/drivers/dax/super.c b/drivers/dax/super.c
> index 938eb4868f7f..b699aac268a6 100644
> --- a/drivers/dax/super.c
> +++ b/drivers/dax/super.c
> @@ -46,6 +46,8 @@ void dax_read_unlock(int id)
> EXPORT_SYMBOL_GPL(dax_read_unlock);
>
> #ifdef CONFIG_BLOCK
> +#include <linux/blkdev.h>
> +
> int bdev_dax_pgoff(struct block_device *bdev, sector_t sector, size_t size,
> pgoff_t *pgoff)
> {
> @@ -59,6 +61,14 @@ int bdev_dax_pgoff(struct block_device *bdev, sector_t sector, size_t size,
> }
> EXPORT_SYMBOL(bdev_dax_pgoff);
>
> +struct dax_device *fs_dax_get_by_bdev(struct block_device *bdev)
> +{
> + if (!blk_queue_dax(bdev->bd_queue))
> + return NULL;
> + return fs_dax_get_by_host(bdev->bd_disk->disk_name);
> +}
> +EXPORT_SYMBOL_GPL(fs_dax_get_by_bdev);
> +
> /**
> * __bdev_dax_supported() - Check if the device supports dax for filesystem
> * @sb: The superblock of the device
> diff --git a/fs/super.c b/fs/super.c
> index 6bc3352adcf3..671889b02bed 100644
> --- a/fs/super.c
> +++ b/fs/super.c
> @@ -23,6 +23,7 @@
> #include <linux/export.h>
> #include <linux/slab.h>
> #include <linux/blkdev.h>
> +#include <linux/dax.h>
> #include <linux/mount.h>
> #include <linux/security.h>
> #include <linux/writeback.h> /* for the emergency remount stuff */
> @@ -1048,9 +1049,17 @@ struct dentry *mount_ns(struct file_system_type *fs_type,
> EXPORT_SYMBOL(mount_ns);
>
> #ifdef CONFIG_BLOCK
> +struct sget_devs {
> + struct block_device *bdev;
> + struct dax_device *dax_dev;
> +};
> +
> static int set_bdev_super(struct super_block *s, void *data)
> {
> - s->s_bdev = data;
> + struct sget_devs *devs = data;
> +
> + s->s_bdev = devs->bdev;
> + s->s_daxdev = devs->dax_dev;
> s->s_dev = s->s_bdev->bd_dev;
> s->s_bdi = bdi_get(s->s_bdev->bd_bdi);
>
> @@ -1059,14 +1068,18 @@ static int set_bdev_super(struct super_block *s, void *data)
>
> static int test_bdev_super(struct super_block *s, void *data)
> {
> - return (void *)s->s_bdev == data;
> + struct sget_devs *devs = data;
> +
> + return s->s_bdev == devs->bdev;
> }
>
> struct dentry *mount_bdev(struct file_system_type *fs_type,
> int flags, const char *dev_name, void *data,
> int (*fill_super)(struct super_block *, void *, int))
> {
> + struct sget_devs devs;
> struct block_device *bdev;
> + struct dax_device *dax_dev;
> struct super_block *s;
> fmode_t mode = FMODE_READ | FMODE_EXCL;
> int error = 0;
> @@ -1077,6 +1090,7 @@ struct dentry *mount_bdev(struct file_system_type *fs_type,
> bdev = blkdev_get_by_path(dev_name, mode, fs_type);
> if (IS_ERR(bdev))
> return ERR_CAST(bdev);
> + dax_dev = fs_dax_get_by_bdev(bdev);
>
> /*
> * once the super is inserted into the list by sget, s_umount
> @@ -1089,8 +1103,10 @@ struct dentry *mount_bdev(struct file_system_type *fs_type,
> error = -EBUSY;
> goto error_bdev;
> }
> + devs.bdev = bdev;
> + devs.dax_dev = dax_dev;
> s = sget(fs_type, test_bdev_super, set_bdev_super, flags | MS_NOSEC,
> - bdev);
> + &devs);
> mutex_unlock(&bdev->bd_fsfreeze_mutex);
> if (IS_ERR(s))
> goto error_s;
> @@ -1111,6 +1127,7 @@ struct dentry *mount_bdev(struct file_system_type *fs_type,
> */
> up_write(&s->s_umount);
> blkdev_put(bdev, mode);
> + fs_put_dax(dax_dev);
> down_write(&s->s_umount);
> } else {
> s->s_mode = mode;
> @@ -1132,6 +1149,7 @@ struct dentry *mount_bdev(struct file_system_type *fs_type,
> error = PTR_ERR(s);
> error_bdev:
> blkdev_put(bdev, mode);
> + fs_put_dax(dax_dev);
> error:
> return ERR_PTR(error);
> }
> @@ -1140,6 +1158,7 @@ EXPORT_SYMBOL(mount_bdev);
> void kill_block_super(struct super_block *sb)
> {
> struct block_device *bdev = sb->s_bdev;
> + struct dax_device *dax_dev = sb->s_daxdev;
> fmode_t mode = sb->s_mode;
>
> bdev->bd_super = NULL;
> @@ -1147,6 +1166,7 @@ void kill_block_super(struct super_block *sb)
> sync_blockdev(bdev);
> WARN_ON_ONCE(!(mode & FMODE_EXCL));
> blkdev_put(bdev, mode | FMODE_EXCL);
> + fs_put_dax(dax_dev);
> }
>
> EXPORT_SYMBOL(kill_block_super);
> diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c
> index 6bf120bb1a17..78185f3b10b2 100644
> --- a/fs/xfs/xfs_aops.c
> +++ b/fs/xfs/xfs_aops.c
> @@ -80,6 +80,19 @@ xfs_find_bdev_for_inode(
> return mp->m_ddev_targp->bt_bdev;
> }
>
> +struct dax_device *
> +xfs_find_daxdev_for_inode(
> + struct inode *inode)
> +{
> + struct xfs_inode *ip = XFS_I(inode);
> + struct xfs_mount *mp = ip->i_mount;
> +
> + if (XFS_IS_REALTIME_INODE(ip))
> + return mp->m_rtdev_targp->bt_daxdev;
> + else
> + return mp->m_ddev_targp->bt_daxdev;
> +}
> +
> /*
> * We're now finished for good with this page. Update the page state via the
> * associated buffer_heads, paying attention to the start and end offsets that
> diff --git a/fs/xfs/xfs_aops.h b/fs/xfs/xfs_aops.h
> index cc174ec6c2fd..88c85ea63da0 100644
> --- a/fs/xfs/xfs_aops.h
> +++ b/fs/xfs/xfs_aops.h
> @@ -59,5 +59,6 @@ int xfs_setfilesize(struct xfs_inode *ip, xfs_off_t offset, size_t size);
>
> extern void xfs_count_page_state(struct page *, int *, int *);
> extern struct block_device *xfs_find_bdev_for_inode(struct inode *);
> +extern struct dax_device *xfs_find_daxdev_for_inode(struct inode *);
>
> #endif /* __XFS_AOPS_H__ */
> diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c
> index 72f038492ba8..6deb86c845d1 100644
> --- a/fs/xfs/xfs_buf.c
> +++ b/fs/xfs/xfs_buf.c
> @@ -1802,7 +1802,8 @@ xfs_setsize_buftarg_early(
> xfs_buftarg_t *
> xfs_alloc_buftarg(
> struct xfs_mount *mp,
> - struct block_device *bdev)
> + struct block_device *bdev,
> + struct dax_device *dax_dev)
> {
> xfs_buftarg_t *btp;
>
> @@ -1811,6 +1812,7 @@ xfs_alloc_buftarg(
> btp->bt_mount = mp;
> btp->bt_dev = bdev->bd_dev;
> btp->bt_bdev = bdev;
> + btp->bt_daxdev = dax_dev;
>
> if (xfs_setsize_buftarg_early(btp, bdev))
> goto error;
> diff --git a/fs/xfs/xfs_buf.h b/fs/xfs/xfs_buf.h
> index 20721261dae5..bf71507ddb16 100644
> --- a/fs/xfs/xfs_buf.h
> +++ b/fs/xfs/xfs_buf.h
> @@ -108,6 +108,7 @@ typedef unsigned int xfs_buf_flags_t;
> typedef struct xfs_buftarg {
> dev_t bt_dev;
> struct block_device *bt_bdev;
> + struct dax_device *bt_daxdev;
> struct xfs_mount *bt_mount;
> unsigned int bt_meta_sectorsize;
> size_t bt_meta_sectormask;
> @@ -385,7 +386,7 @@ xfs_buf_update_cksum(struct xfs_buf *bp, unsigned long cksum_offset)
> * Handling of buftargs.
> */
> extern xfs_buftarg_t *xfs_alloc_buftarg(struct xfs_mount *,
> - struct block_device *);
> + struct block_device *, struct dax_device *);
> extern void xfs_free_buftarg(struct xfs_mount *, struct xfs_buftarg *);
> extern void xfs_wait_buftarg(xfs_buftarg_t *);
> extern int xfs_setsize_buftarg(xfs_buftarg_t *, unsigned int);
> diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
> index 813394c62849..7c934e407332 100644
> --- a/fs/xfs/xfs_iomap.c
> +++ b/fs/xfs/xfs_iomap.c
> @@ -69,6 +69,7 @@ xfs_bmbt_to_iomap(
> iomap->offset = XFS_FSB_TO_B(mp, imap->br_startoff);
> iomap->length = XFS_FSB_TO_B(mp, imap->br_blockcount);
> iomap->bdev = xfs_find_bdev_for_inode(VFS_I(ip));
> + iomap->dax_dev = xfs_find_daxdev_for_inode(VFS_I(ip));
> }
>
> xfs_extlen_t
> @@ -976,7 +977,6 @@ xfs_file_iomap_begin(
> int nimaps = 1, error = 0;
> bool shared = false, trimmed = false;
> unsigned lockmode;
> - struct block_device *bdev;
>
> if (XFS_FORCED_SHUTDOWN(mp))
> return -EIO;
> @@ -1087,13 +1087,6 @@ xfs_file_iomap_begin(
>
> xfs_bmbt_to_iomap(ip, iomap, &imap);
>
> - /* optionally associate a dax device with the iomap bdev */
> - bdev = iomap->bdev;
> - if (blk_queue_dax(bdev->bd_queue))
> - iomap->dax_dev = fs_dax_get_by_host(bdev->bd_disk->disk_name);
> - else
> - iomap->dax_dev = NULL;
> -
> if (shared)
> iomap->flags |= IOMAP_F_SHARED;
> return 0;
> @@ -1171,7 +1164,6 @@ xfs_file_iomap_end(
> unsigned flags,
> struct iomap *iomap)
> {
> - fs_put_dax(iomap->dax_dev);
> if ((flags & IOMAP_WRITE) && iomap->type == IOMAP_DELALLOC)
> return xfs_file_iomap_end_delalloc(XFS_I(inode), offset,
> length, written, iomap);
> diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
> index 38aaacdbb8b3..d863f96b16e2 100644
> --- a/fs/xfs/xfs_super.c
> +++ b/fs/xfs/xfs_super.c
> @@ -716,13 +716,19 @@ xfs_close_devices(
> {
> if (mp->m_logdev_targp && mp->m_logdev_targp != mp->m_ddev_targp) {
> struct block_device *logdev = mp->m_logdev_targp->bt_bdev;
> + struct dax_device *dax_logdev = mp->m_logdev_targp->bt_daxdev;
> +
> xfs_free_buftarg(mp, mp->m_logdev_targp);
> xfs_blkdev_put(logdev);
> + fs_put_dax(dax_logdev);
> }
> if (mp->m_rtdev_targp) {
> struct block_device *rtdev = mp->m_rtdev_targp->bt_bdev;
> + struct dax_device *dax_rtdev = mp->m_rtdev_targp->bt_daxdev;
> +
> xfs_free_buftarg(mp, mp->m_rtdev_targp);
> xfs_blkdev_put(rtdev);
> + fs_put_dax(dax_rtdev);
> }
> xfs_free_buftarg(mp, mp->m_ddev_targp);
> }
> @@ -742,7 +748,9 @@ xfs_open_devices(
> struct xfs_mount *mp)
> {
> struct block_device *ddev = mp->m_super->s_bdev;
> + struct dax_device *dax_ddev = mp->m_super->s_daxdev;
> struct block_device *logdev = NULL, *rtdev = NULL;
> + struct dax_device *dax_logdev = NULL, *dax_rtdev = NULL;
> int error;
>
> /*
> @@ -752,6 +760,7 @@ xfs_open_devices(
> error = xfs_blkdev_get(mp, mp->m_logname, &logdev);
> if (error)
> goto out;
> + dax_logdev = fs_dax_get_by_bdev(logdev);
> }
>
> if (mp->m_rtname) {
> @@ -765,24 +774,25 @@ xfs_open_devices(
> error = -EINVAL;
> goto out_close_rtdev;
> }
> + dax_rtdev = fs_dax_get_by_bdev(rtdev);
> }
>
> /*
> * Setup xfs_mount buffer target pointers
> */
> error = -ENOMEM;
> - mp->m_ddev_targp = xfs_alloc_buftarg(mp, ddev);
> + mp->m_ddev_targp = xfs_alloc_buftarg(mp, ddev, dax_ddev);
> if (!mp->m_ddev_targp)
> goto out_close_rtdev;
>
> if (rtdev) {
> - mp->m_rtdev_targp = xfs_alloc_buftarg(mp, rtdev);
> + mp->m_rtdev_targp = xfs_alloc_buftarg(mp, rtdev, dax_rtdev);
> if (!mp->m_rtdev_targp)
> goto out_free_ddev_targ;
> }
>
> if (logdev && logdev != ddev) {
> - mp->m_logdev_targp = xfs_alloc_buftarg(mp, logdev);
> + mp->m_logdev_targp = xfs_alloc_buftarg(mp, logdev, dax_logdev);
> if (!mp->m_logdev_targp)
> goto out_free_rtdev_targ;
> } else {
> @@ -798,9 +808,12 @@ xfs_open_devices(
> xfs_free_buftarg(mp, mp->m_ddev_targp);
> out_close_rtdev:
> xfs_blkdev_put(rtdev);
> + fs_put_dax(dax_rtdev);
> out_close_logdev:
> - if (logdev && logdev != ddev)
> + if (logdev && logdev != ddev) {
> xfs_blkdev_put(logdev);
> + fs_put_dax(dax_logdev);
> + }
> out:
> return error;
> }
> diff --git a/include/linux/dax.h b/include/linux/dax.h
> index df97b7af7e2c..6e32be3badec 100644
> --- a/include/linux/dax.h
> +++ b/include/linux/dax.h
> @@ -57,6 +57,7 @@ static inline void fs_put_dax(struct dax_device *dax_dev)
> put_dax(dax_dev);
> }
>
> +struct dax_device *fs_dax_get_by_bdev(struct block_device *bdev);
> #else
> static inline int bdev_dax_supported(struct super_block *sb, int blocksize)
> {
> @@ -71,6 +72,11 @@ static inline struct dax_device *fs_dax_get_by_host(const char *host)
> static inline void fs_put_dax(struct dax_device *dax_dev)
> {
> }
> +
> +struct dax_device *fs_dax_get_by_bdev(struct block_device *bdev)
> +{
> + return NULL;
> +}
> #endif
>
> int dax_read_lock(void);
> diff --git a/include/linux/fs.h b/include/linux/fs.h
> index 6e1fd5d21248..d0e3234a1fae 100644
> --- a/include/linux/fs.h
> +++ b/include/linux/fs.h
> @@ -1334,6 +1334,7 @@ struct super_block {
> struct hlist_bl_head s_anon; /* anonymous dentries for (nfs) exporting */
> struct list_head s_mounts; /* list of mounts; _not_ for fs use */
> struct block_device *s_bdev;
> + struct dax_device *s_daxdev;
> struct backing_dev_info *s_bdi;
> struct mtd_info *s_mtd;
> struct hlist_node s_instances;
>
--
Jan Kara <jack@suse.com>
SUSE Labs, CR
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v2 1/2] fs, xfs: perform dax_device lookup at mount
@ 2017-08-28 8:31 ` Jan Kara
0 siblings, 0 replies; 28+ messages in thread
From: Jan Kara @ 2017-08-28 8:31 UTC (permalink / raw)
To: Dan Williams
Cc: jack-AlSwsSmVLrQ, Darrick J. Wong,
linux-nvdimm-hn68Rpc1hR1g9hUCZPvPmw,
linux-xfs-u79uwXL29TY76Z2rM5mHXA,
linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
linux-ext4-u79uwXL29TY76Z2rM5mHXA, hch-jcswGhMUV9g
On Sun 27-08-17 20:48:40, Dan Williams wrote:
> The ->iomap_begin() operation is a hot path, so cache the
> fs_dax_get_by_host() result at mount time to avoid the incurring the
> hash lookup overhead on a per-i/o basis.
>
> Cc: "Darrick J. Wong" <darrick.wong-QHcLZuEGTsvQT0dZR+AlfA@public.gmane.org>
> Reported-by: Christoph Hellwig <hch-jcswGhMUV9g@public.gmane.org>
> Signed-off-by: Dan Williams <dan.j.williams-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
Looks good to me. For the generic parts:
Reviewed-by: Jan Kara <jack-AlSwsSmVLrQ@public.gmane.org>
[XFS part looks correct to me as well but I don't feel expert enough to
give any tags there].
Honza
> ---
> drivers/dax/super.c | 10 ++++++++++
> fs/super.c | 26 +++++++++++++++++++++++---
> fs/xfs/xfs_aops.c | 13 +++++++++++++
> fs/xfs/xfs_aops.h | 1 +
> fs/xfs/xfs_buf.c | 4 +++-
> fs/xfs/xfs_buf.h | 3 ++-
> fs/xfs/xfs_iomap.c | 10 +---------
> fs/xfs/xfs_super.c | 21 +++++++++++++++++----
> include/linux/dax.h | 6 ++++++
> include/linux/fs.h | 1 +
> 10 files changed, 77 insertions(+), 18 deletions(-)
>
> diff --git a/drivers/dax/super.c b/drivers/dax/super.c
> index 938eb4868f7f..b699aac268a6 100644
> --- a/drivers/dax/super.c
> +++ b/drivers/dax/super.c
> @@ -46,6 +46,8 @@ void dax_read_unlock(int id)
> EXPORT_SYMBOL_GPL(dax_read_unlock);
>
> #ifdef CONFIG_BLOCK
> +#include <linux/blkdev.h>
> +
> int bdev_dax_pgoff(struct block_device *bdev, sector_t sector, size_t size,
> pgoff_t *pgoff)
> {
> @@ -59,6 +61,14 @@ int bdev_dax_pgoff(struct block_device *bdev, sector_t sector, size_t size,
> }
> EXPORT_SYMBOL(bdev_dax_pgoff);
>
> +struct dax_device *fs_dax_get_by_bdev(struct block_device *bdev)
> +{
> + if (!blk_queue_dax(bdev->bd_queue))
> + return NULL;
> + return fs_dax_get_by_host(bdev->bd_disk->disk_name);
> +}
> +EXPORT_SYMBOL_GPL(fs_dax_get_by_bdev);
> +
> /**
> * __bdev_dax_supported() - Check if the device supports dax for filesystem
> * @sb: The superblock of the device
> diff --git a/fs/super.c b/fs/super.c
> index 6bc3352adcf3..671889b02bed 100644
> --- a/fs/super.c
> +++ b/fs/super.c
> @@ -23,6 +23,7 @@
> #include <linux/export.h>
> #include <linux/slab.h>
> #include <linux/blkdev.h>
> +#include <linux/dax.h>
> #include <linux/mount.h>
> #include <linux/security.h>
> #include <linux/writeback.h> /* for the emergency remount stuff */
> @@ -1048,9 +1049,17 @@ struct dentry *mount_ns(struct file_system_type *fs_type,
> EXPORT_SYMBOL(mount_ns);
>
> #ifdef CONFIG_BLOCK
> +struct sget_devs {
> + struct block_device *bdev;
> + struct dax_device *dax_dev;
> +};
> +
> static int set_bdev_super(struct super_block *s, void *data)
> {
> - s->s_bdev = data;
> + struct sget_devs *devs = data;
> +
> + s->s_bdev = devs->bdev;
> + s->s_daxdev = devs->dax_dev;
> s->s_dev = s->s_bdev->bd_dev;
> s->s_bdi = bdi_get(s->s_bdev->bd_bdi);
>
> @@ -1059,14 +1068,18 @@ static int set_bdev_super(struct super_block *s, void *data)
>
> static int test_bdev_super(struct super_block *s, void *data)
> {
> - return (void *)s->s_bdev == data;
> + struct sget_devs *devs = data;
> +
> + return s->s_bdev == devs->bdev;
> }
>
> struct dentry *mount_bdev(struct file_system_type *fs_type,
> int flags, const char *dev_name, void *data,
> int (*fill_super)(struct super_block *, void *, int))
> {
> + struct sget_devs devs;
> struct block_device *bdev;
> + struct dax_device *dax_dev;
> struct super_block *s;
> fmode_t mode = FMODE_READ | FMODE_EXCL;
> int error = 0;
> @@ -1077,6 +1090,7 @@ struct dentry *mount_bdev(struct file_system_type *fs_type,
> bdev = blkdev_get_by_path(dev_name, mode, fs_type);
> if (IS_ERR(bdev))
> return ERR_CAST(bdev);
> + dax_dev = fs_dax_get_by_bdev(bdev);
>
> /*
> * once the super is inserted into the list by sget, s_umount
> @@ -1089,8 +1103,10 @@ struct dentry *mount_bdev(struct file_system_type *fs_type,
> error = -EBUSY;
> goto error_bdev;
> }
> + devs.bdev = bdev;
> + devs.dax_dev = dax_dev;
> s = sget(fs_type, test_bdev_super, set_bdev_super, flags | MS_NOSEC,
> - bdev);
> + &devs);
> mutex_unlock(&bdev->bd_fsfreeze_mutex);
> if (IS_ERR(s))
> goto error_s;
> @@ -1111,6 +1127,7 @@ struct dentry *mount_bdev(struct file_system_type *fs_type,
> */
> up_write(&s->s_umount);
> blkdev_put(bdev, mode);
> + fs_put_dax(dax_dev);
> down_write(&s->s_umount);
> } else {
> s->s_mode = mode;
> @@ -1132,6 +1149,7 @@ struct dentry *mount_bdev(struct file_system_type *fs_type,
> error = PTR_ERR(s);
> error_bdev:
> blkdev_put(bdev, mode);
> + fs_put_dax(dax_dev);
> error:
> return ERR_PTR(error);
> }
> @@ -1140,6 +1158,7 @@ EXPORT_SYMBOL(mount_bdev);
> void kill_block_super(struct super_block *sb)
> {
> struct block_device *bdev = sb->s_bdev;
> + struct dax_device *dax_dev = sb->s_daxdev;
> fmode_t mode = sb->s_mode;
>
> bdev->bd_super = NULL;
> @@ -1147,6 +1166,7 @@ void kill_block_super(struct super_block *sb)
> sync_blockdev(bdev);
> WARN_ON_ONCE(!(mode & FMODE_EXCL));
> blkdev_put(bdev, mode | FMODE_EXCL);
> + fs_put_dax(dax_dev);
> }
>
> EXPORT_SYMBOL(kill_block_super);
> diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c
> index 6bf120bb1a17..78185f3b10b2 100644
> --- a/fs/xfs/xfs_aops.c
> +++ b/fs/xfs/xfs_aops.c
> @@ -80,6 +80,19 @@ xfs_find_bdev_for_inode(
> return mp->m_ddev_targp->bt_bdev;
> }
>
> +struct dax_device *
> +xfs_find_daxdev_for_inode(
> + struct inode *inode)
> +{
> + struct xfs_inode *ip = XFS_I(inode);
> + struct xfs_mount *mp = ip->i_mount;
> +
> + if (XFS_IS_REALTIME_INODE(ip))
> + return mp->m_rtdev_targp->bt_daxdev;
> + else
> + return mp->m_ddev_targp->bt_daxdev;
> +}
> +
> /*
> * We're now finished for good with this page. Update the page state via the
> * associated buffer_heads, paying attention to the start and end offsets that
> diff --git a/fs/xfs/xfs_aops.h b/fs/xfs/xfs_aops.h
> index cc174ec6c2fd..88c85ea63da0 100644
> --- a/fs/xfs/xfs_aops.h
> +++ b/fs/xfs/xfs_aops.h
> @@ -59,5 +59,6 @@ int xfs_setfilesize(struct xfs_inode *ip, xfs_off_t offset, size_t size);
>
> extern void xfs_count_page_state(struct page *, int *, int *);
> extern struct block_device *xfs_find_bdev_for_inode(struct inode *);
> +extern struct dax_device *xfs_find_daxdev_for_inode(struct inode *);
>
> #endif /* __XFS_AOPS_H__ */
> diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c
> index 72f038492ba8..6deb86c845d1 100644
> --- a/fs/xfs/xfs_buf.c
> +++ b/fs/xfs/xfs_buf.c
> @@ -1802,7 +1802,8 @@ xfs_setsize_buftarg_early(
> xfs_buftarg_t *
> xfs_alloc_buftarg(
> struct xfs_mount *mp,
> - struct block_device *bdev)
> + struct block_device *bdev,
> + struct dax_device *dax_dev)
> {
> xfs_buftarg_t *btp;
>
> @@ -1811,6 +1812,7 @@ xfs_alloc_buftarg(
> btp->bt_mount = mp;
> btp->bt_dev = bdev->bd_dev;
> btp->bt_bdev = bdev;
> + btp->bt_daxdev = dax_dev;
>
> if (xfs_setsize_buftarg_early(btp, bdev))
> goto error;
> diff --git a/fs/xfs/xfs_buf.h b/fs/xfs/xfs_buf.h
> index 20721261dae5..bf71507ddb16 100644
> --- a/fs/xfs/xfs_buf.h
> +++ b/fs/xfs/xfs_buf.h
> @@ -108,6 +108,7 @@ typedef unsigned int xfs_buf_flags_t;
> typedef struct xfs_buftarg {
> dev_t bt_dev;
> struct block_device *bt_bdev;
> + struct dax_device *bt_daxdev;
> struct xfs_mount *bt_mount;
> unsigned int bt_meta_sectorsize;
> size_t bt_meta_sectormask;
> @@ -385,7 +386,7 @@ xfs_buf_update_cksum(struct xfs_buf *bp, unsigned long cksum_offset)
> * Handling of buftargs.
> */
> extern xfs_buftarg_t *xfs_alloc_buftarg(struct xfs_mount *,
> - struct block_device *);
> + struct block_device *, struct dax_device *);
> extern void xfs_free_buftarg(struct xfs_mount *, struct xfs_buftarg *);
> extern void xfs_wait_buftarg(xfs_buftarg_t *);
> extern int xfs_setsize_buftarg(xfs_buftarg_t *, unsigned int);
> diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
> index 813394c62849..7c934e407332 100644
> --- a/fs/xfs/xfs_iomap.c
> +++ b/fs/xfs/xfs_iomap.c
> @@ -69,6 +69,7 @@ xfs_bmbt_to_iomap(
> iomap->offset = XFS_FSB_TO_B(mp, imap->br_startoff);
> iomap->length = XFS_FSB_TO_B(mp, imap->br_blockcount);
> iomap->bdev = xfs_find_bdev_for_inode(VFS_I(ip));
> + iomap->dax_dev = xfs_find_daxdev_for_inode(VFS_I(ip));
> }
>
> xfs_extlen_t
> @@ -976,7 +977,6 @@ xfs_file_iomap_begin(
> int nimaps = 1, error = 0;
> bool shared = false, trimmed = false;
> unsigned lockmode;
> - struct block_device *bdev;
>
> if (XFS_FORCED_SHUTDOWN(mp))
> return -EIO;
> @@ -1087,13 +1087,6 @@ xfs_file_iomap_begin(
>
> xfs_bmbt_to_iomap(ip, iomap, &imap);
>
> - /* optionally associate a dax device with the iomap bdev */
> - bdev = iomap->bdev;
> - if (blk_queue_dax(bdev->bd_queue))
> - iomap->dax_dev = fs_dax_get_by_host(bdev->bd_disk->disk_name);
> - else
> - iomap->dax_dev = NULL;
> -
> if (shared)
> iomap->flags |= IOMAP_F_SHARED;
> return 0;
> @@ -1171,7 +1164,6 @@ xfs_file_iomap_end(
> unsigned flags,
> struct iomap *iomap)
> {
> - fs_put_dax(iomap->dax_dev);
> if ((flags & IOMAP_WRITE) && iomap->type == IOMAP_DELALLOC)
> return xfs_file_iomap_end_delalloc(XFS_I(inode), offset,
> length, written, iomap);
> diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
> index 38aaacdbb8b3..d863f96b16e2 100644
> --- a/fs/xfs/xfs_super.c
> +++ b/fs/xfs/xfs_super.c
> @@ -716,13 +716,19 @@ xfs_close_devices(
> {
> if (mp->m_logdev_targp && mp->m_logdev_targp != mp->m_ddev_targp) {
> struct block_device *logdev = mp->m_logdev_targp->bt_bdev;
> + struct dax_device *dax_logdev = mp->m_logdev_targp->bt_daxdev;
> +
> xfs_free_buftarg(mp, mp->m_logdev_targp);
> xfs_blkdev_put(logdev);
> + fs_put_dax(dax_logdev);
> }
> if (mp->m_rtdev_targp) {
> struct block_device *rtdev = mp->m_rtdev_targp->bt_bdev;
> + struct dax_device *dax_rtdev = mp->m_rtdev_targp->bt_daxdev;
> +
> xfs_free_buftarg(mp, mp->m_rtdev_targp);
> xfs_blkdev_put(rtdev);
> + fs_put_dax(dax_rtdev);
> }
> xfs_free_buftarg(mp, mp->m_ddev_targp);
> }
> @@ -742,7 +748,9 @@ xfs_open_devices(
> struct xfs_mount *mp)
> {
> struct block_device *ddev = mp->m_super->s_bdev;
> + struct dax_device *dax_ddev = mp->m_super->s_daxdev;
> struct block_device *logdev = NULL, *rtdev = NULL;
> + struct dax_device *dax_logdev = NULL, *dax_rtdev = NULL;
> int error;
>
> /*
> @@ -752,6 +760,7 @@ xfs_open_devices(
> error = xfs_blkdev_get(mp, mp->m_logname, &logdev);
> if (error)
> goto out;
> + dax_logdev = fs_dax_get_by_bdev(logdev);
> }
>
> if (mp->m_rtname) {
> @@ -765,24 +774,25 @@ xfs_open_devices(
> error = -EINVAL;
> goto out_close_rtdev;
> }
> + dax_rtdev = fs_dax_get_by_bdev(rtdev);
> }
>
> /*
> * Setup xfs_mount buffer target pointers
> */
> error = -ENOMEM;
> - mp->m_ddev_targp = xfs_alloc_buftarg(mp, ddev);
> + mp->m_ddev_targp = xfs_alloc_buftarg(mp, ddev, dax_ddev);
> if (!mp->m_ddev_targp)
> goto out_close_rtdev;
>
> if (rtdev) {
> - mp->m_rtdev_targp = xfs_alloc_buftarg(mp, rtdev);
> + mp->m_rtdev_targp = xfs_alloc_buftarg(mp, rtdev, dax_rtdev);
> if (!mp->m_rtdev_targp)
> goto out_free_ddev_targ;
> }
>
> if (logdev && logdev != ddev) {
> - mp->m_logdev_targp = xfs_alloc_buftarg(mp, logdev);
> + mp->m_logdev_targp = xfs_alloc_buftarg(mp, logdev, dax_logdev);
> if (!mp->m_logdev_targp)
> goto out_free_rtdev_targ;
> } else {
> @@ -798,9 +808,12 @@ xfs_open_devices(
> xfs_free_buftarg(mp, mp->m_ddev_targp);
> out_close_rtdev:
> xfs_blkdev_put(rtdev);
> + fs_put_dax(dax_rtdev);
> out_close_logdev:
> - if (logdev && logdev != ddev)
> + if (logdev && logdev != ddev) {
> xfs_blkdev_put(logdev);
> + fs_put_dax(dax_logdev);
> + }
> out:
> return error;
> }
> diff --git a/include/linux/dax.h b/include/linux/dax.h
> index df97b7af7e2c..6e32be3badec 100644
> --- a/include/linux/dax.h
> +++ b/include/linux/dax.h
> @@ -57,6 +57,7 @@ static inline void fs_put_dax(struct dax_device *dax_dev)
> put_dax(dax_dev);
> }
>
> +struct dax_device *fs_dax_get_by_bdev(struct block_device *bdev);
> #else
> static inline int bdev_dax_supported(struct super_block *sb, int blocksize)
> {
> @@ -71,6 +72,11 @@ static inline struct dax_device *fs_dax_get_by_host(const char *host)
> static inline void fs_put_dax(struct dax_device *dax_dev)
> {
> }
> +
> +struct dax_device *fs_dax_get_by_bdev(struct block_device *bdev)
> +{
> + return NULL;
> +}
> #endif
>
> int dax_read_lock(void);
> diff --git a/include/linux/fs.h b/include/linux/fs.h
> index 6e1fd5d21248..d0e3234a1fae 100644
> --- a/include/linux/fs.h
> +++ b/include/linux/fs.h
> @@ -1334,6 +1334,7 @@ struct super_block {
> struct hlist_bl_head s_anon; /* anonymous dentries for (nfs) exporting */
> struct list_head s_mounts; /* list of mounts; _not_ for fs use */
> struct block_device *s_bdev;
> + struct dax_device *s_daxdev;
> struct backing_dev_info *s_bdi;
> struct mtd_info *s_mtd;
> struct hlist_node s_instances;
>
--
Jan Kara <jack-IBi9RG/b67k@public.gmane.org>
SUSE Labs, CR
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v2 1/2] fs, xfs: perform dax_device lookup at mount
2017-08-28 3:48 ` Dan Williams
@ 2017-08-28 16:28 ` Darrick J. Wong
-1 siblings, 0 replies; 28+ messages in thread
From: Darrick J. Wong @ 2017-08-28 16:28 UTC (permalink / raw)
To: Dan Williams
Cc: jack, linux-nvdimm, linux-xfs, linux-fsdevel, linux-ext4, hch
On Sun, Aug 27, 2017 at 08:48:40PM -0700, Dan Williams wrote:
> The ->iomap_begin() operation is a hot path, so cache the
> fs_dax_get_by_host() result at mount time to avoid the incurring the
> hash lookup overhead on a per-i/o basis.
>
> Cc: "Darrick J. Wong" <darrick.wong@oracle.com>
> Reported-by: Christoph Hellwig <hch@lst.de>
> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Looks good,
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
> ---
> drivers/dax/super.c | 10 ++++++++++
> fs/super.c | 26 +++++++++++++++++++++++---
> fs/xfs/xfs_aops.c | 13 +++++++++++++
> fs/xfs/xfs_aops.h | 1 +
> fs/xfs/xfs_buf.c | 4 +++-
> fs/xfs/xfs_buf.h | 3 ++-
> fs/xfs/xfs_iomap.c | 10 +---------
> fs/xfs/xfs_super.c | 21 +++++++++++++++++----
> include/linux/dax.h | 6 ++++++
> include/linux/fs.h | 1 +
> 10 files changed, 77 insertions(+), 18 deletions(-)
>
> diff --git a/drivers/dax/super.c b/drivers/dax/super.c
> index 938eb4868f7f..b699aac268a6 100644
> --- a/drivers/dax/super.c
> +++ b/drivers/dax/super.c
> @@ -46,6 +46,8 @@ void dax_read_unlock(int id)
> EXPORT_SYMBOL_GPL(dax_read_unlock);
>
> #ifdef CONFIG_BLOCK
> +#include <linux/blkdev.h>
> +
> int bdev_dax_pgoff(struct block_device *bdev, sector_t sector, size_t size,
> pgoff_t *pgoff)
> {
> @@ -59,6 +61,14 @@ int bdev_dax_pgoff(struct block_device *bdev, sector_t sector, size_t size,
> }
> EXPORT_SYMBOL(bdev_dax_pgoff);
>
> +struct dax_device *fs_dax_get_by_bdev(struct block_device *bdev)
> +{
> + if (!blk_queue_dax(bdev->bd_queue))
> + return NULL;
> + return fs_dax_get_by_host(bdev->bd_disk->disk_name);
> +}
> +EXPORT_SYMBOL_GPL(fs_dax_get_by_bdev);
> +
> /**
> * __bdev_dax_supported() - Check if the device supports dax for filesystem
> * @sb: The superblock of the device
> diff --git a/fs/super.c b/fs/super.c
> index 6bc3352adcf3..671889b02bed 100644
> --- a/fs/super.c
> +++ b/fs/super.c
> @@ -23,6 +23,7 @@
> #include <linux/export.h>
> #include <linux/slab.h>
> #include <linux/blkdev.h>
> +#include <linux/dax.h>
> #include <linux/mount.h>
> #include <linux/security.h>
> #include <linux/writeback.h> /* for the emergency remount stuff */
> @@ -1048,9 +1049,17 @@ struct dentry *mount_ns(struct file_system_type *fs_type,
> EXPORT_SYMBOL(mount_ns);
>
> #ifdef CONFIG_BLOCK
> +struct sget_devs {
> + struct block_device *bdev;
> + struct dax_device *dax_dev;
> +};
> +
> static int set_bdev_super(struct super_block *s, void *data)
> {
> - s->s_bdev = data;
> + struct sget_devs *devs = data;
> +
> + s->s_bdev = devs->bdev;
> + s->s_daxdev = devs->dax_dev;
> s->s_dev = s->s_bdev->bd_dev;
> s->s_bdi = bdi_get(s->s_bdev->bd_bdi);
>
> @@ -1059,14 +1068,18 @@ static int set_bdev_super(struct super_block *s, void *data)
>
> static int test_bdev_super(struct super_block *s, void *data)
> {
> - return (void *)s->s_bdev == data;
> + struct sget_devs *devs = data;
> +
> + return s->s_bdev == devs->bdev;
> }
>
> struct dentry *mount_bdev(struct file_system_type *fs_type,
> int flags, const char *dev_name, void *data,
> int (*fill_super)(struct super_block *, void *, int))
> {
> + struct sget_devs devs;
> struct block_device *bdev;
> + struct dax_device *dax_dev;
> struct super_block *s;
> fmode_t mode = FMODE_READ | FMODE_EXCL;
> int error = 0;
> @@ -1077,6 +1090,7 @@ struct dentry *mount_bdev(struct file_system_type *fs_type,
> bdev = blkdev_get_by_path(dev_name, mode, fs_type);
> if (IS_ERR(bdev))
> return ERR_CAST(bdev);
> + dax_dev = fs_dax_get_by_bdev(bdev);
>
> /*
> * once the super is inserted into the list by sget, s_umount
> @@ -1089,8 +1103,10 @@ struct dentry *mount_bdev(struct file_system_type *fs_type,
> error = -EBUSY;
> goto error_bdev;
> }
> + devs.bdev = bdev;
> + devs.dax_dev = dax_dev;
> s = sget(fs_type, test_bdev_super, set_bdev_super, flags | MS_NOSEC,
> - bdev);
> + &devs);
> mutex_unlock(&bdev->bd_fsfreeze_mutex);
> if (IS_ERR(s))
> goto error_s;
> @@ -1111,6 +1127,7 @@ struct dentry *mount_bdev(struct file_system_type *fs_type,
> */
> up_write(&s->s_umount);
> blkdev_put(bdev, mode);
> + fs_put_dax(dax_dev);
> down_write(&s->s_umount);
> } else {
> s->s_mode = mode;
> @@ -1132,6 +1149,7 @@ struct dentry *mount_bdev(struct file_system_type *fs_type,
> error = PTR_ERR(s);
> error_bdev:
> blkdev_put(bdev, mode);
> + fs_put_dax(dax_dev);
> error:
> return ERR_PTR(error);
> }
> @@ -1140,6 +1158,7 @@ EXPORT_SYMBOL(mount_bdev);
> void kill_block_super(struct super_block *sb)
> {
> struct block_device *bdev = sb->s_bdev;
> + struct dax_device *dax_dev = sb->s_daxdev;
> fmode_t mode = sb->s_mode;
>
> bdev->bd_super = NULL;
> @@ -1147,6 +1166,7 @@ void kill_block_super(struct super_block *sb)
> sync_blockdev(bdev);
> WARN_ON_ONCE(!(mode & FMODE_EXCL));
> blkdev_put(bdev, mode | FMODE_EXCL);
> + fs_put_dax(dax_dev);
> }
>
> EXPORT_SYMBOL(kill_block_super);
> diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c
> index 6bf120bb1a17..78185f3b10b2 100644
> --- a/fs/xfs/xfs_aops.c
> +++ b/fs/xfs/xfs_aops.c
> @@ -80,6 +80,19 @@ xfs_find_bdev_for_inode(
> return mp->m_ddev_targp->bt_bdev;
> }
>
> +struct dax_device *
> +xfs_find_daxdev_for_inode(
> + struct inode *inode)
> +{
> + struct xfs_inode *ip = XFS_I(inode);
> + struct xfs_mount *mp = ip->i_mount;
> +
> + if (XFS_IS_REALTIME_INODE(ip))
> + return mp->m_rtdev_targp->bt_daxdev;
> + else
> + return mp->m_ddev_targp->bt_daxdev;
> +}
> +
> /*
> * We're now finished for good with this page. Update the page state via the
> * associated buffer_heads, paying attention to the start and end offsets that
> diff --git a/fs/xfs/xfs_aops.h b/fs/xfs/xfs_aops.h
> index cc174ec6c2fd..88c85ea63da0 100644
> --- a/fs/xfs/xfs_aops.h
> +++ b/fs/xfs/xfs_aops.h
> @@ -59,5 +59,6 @@ int xfs_setfilesize(struct xfs_inode *ip, xfs_off_t offset, size_t size);
>
> extern void xfs_count_page_state(struct page *, int *, int *);
> extern struct block_device *xfs_find_bdev_for_inode(struct inode *);
> +extern struct dax_device *xfs_find_daxdev_for_inode(struct inode *);
>
> #endif /* __XFS_AOPS_H__ */
> diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c
> index 72f038492ba8..6deb86c845d1 100644
> --- a/fs/xfs/xfs_buf.c
> +++ b/fs/xfs/xfs_buf.c
> @@ -1802,7 +1802,8 @@ xfs_setsize_buftarg_early(
> xfs_buftarg_t *
> xfs_alloc_buftarg(
> struct xfs_mount *mp,
> - struct block_device *bdev)
> + struct block_device *bdev,
> + struct dax_device *dax_dev)
> {
> xfs_buftarg_t *btp;
>
> @@ -1811,6 +1812,7 @@ xfs_alloc_buftarg(
> btp->bt_mount = mp;
> btp->bt_dev = bdev->bd_dev;
> btp->bt_bdev = bdev;
> + btp->bt_daxdev = dax_dev;
>
> if (xfs_setsize_buftarg_early(btp, bdev))
> goto error;
> diff --git a/fs/xfs/xfs_buf.h b/fs/xfs/xfs_buf.h
> index 20721261dae5..bf71507ddb16 100644
> --- a/fs/xfs/xfs_buf.h
> +++ b/fs/xfs/xfs_buf.h
> @@ -108,6 +108,7 @@ typedef unsigned int xfs_buf_flags_t;
> typedef struct xfs_buftarg {
> dev_t bt_dev;
> struct block_device *bt_bdev;
> + struct dax_device *bt_daxdev;
> struct xfs_mount *bt_mount;
> unsigned int bt_meta_sectorsize;
> size_t bt_meta_sectormask;
> @@ -385,7 +386,7 @@ xfs_buf_update_cksum(struct xfs_buf *bp, unsigned long cksum_offset)
> * Handling of buftargs.
> */
> extern xfs_buftarg_t *xfs_alloc_buftarg(struct xfs_mount *,
> - struct block_device *);
> + struct block_device *, struct dax_device *);
> extern void xfs_free_buftarg(struct xfs_mount *, struct xfs_buftarg *);
> extern void xfs_wait_buftarg(xfs_buftarg_t *);
> extern int xfs_setsize_buftarg(xfs_buftarg_t *, unsigned int);
> diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
> index 813394c62849..7c934e407332 100644
> --- a/fs/xfs/xfs_iomap.c
> +++ b/fs/xfs/xfs_iomap.c
> @@ -69,6 +69,7 @@ xfs_bmbt_to_iomap(
> iomap->offset = XFS_FSB_TO_B(mp, imap->br_startoff);
> iomap->length = XFS_FSB_TO_B(mp, imap->br_blockcount);
> iomap->bdev = xfs_find_bdev_for_inode(VFS_I(ip));
> + iomap->dax_dev = xfs_find_daxdev_for_inode(VFS_I(ip));
> }
>
> xfs_extlen_t
> @@ -976,7 +977,6 @@ xfs_file_iomap_begin(
> int nimaps = 1, error = 0;
> bool shared = false, trimmed = false;
> unsigned lockmode;
> - struct block_device *bdev;
>
> if (XFS_FORCED_SHUTDOWN(mp))
> return -EIO;
> @@ -1087,13 +1087,6 @@ xfs_file_iomap_begin(
>
> xfs_bmbt_to_iomap(ip, iomap, &imap);
>
> - /* optionally associate a dax device with the iomap bdev */
> - bdev = iomap->bdev;
> - if (blk_queue_dax(bdev->bd_queue))
> - iomap->dax_dev = fs_dax_get_by_host(bdev->bd_disk->disk_name);
> - else
> - iomap->dax_dev = NULL;
> -
> if (shared)
> iomap->flags |= IOMAP_F_SHARED;
> return 0;
> @@ -1171,7 +1164,6 @@ xfs_file_iomap_end(
> unsigned flags,
> struct iomap *iomap)
> {
> - fs_put_dax(iomap->dax_dev);
> if ((flags & IOMAP_WRITE) && iomap->type == IOMAP_DELALLOC)
> return xfs_file_iomap_end_delalloc(XFS_I(inode), offset,
> length, written, iomap);
> diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
> index 38aaacdbb8b3..d863f96b16e2 100644
> --- a/fs/xfs/xfs_super.c
> +++ b/fs/xfs/xfs_super.c
> @@ -716,13 +716,19 @@ xfs_close_devices(
> {
> if (mp->m_logdev_targp && mp->m_logdev_targp != mp->m_ddev_targp) {
> struct block_device *logdev = mp->m_logdev_targp->bt_bdev;
> + struct dax_device *dax_logdev = mp->m_logdev_targp->bt_daxdev;
> +
> xfs_free_buftarg(mp, mp->m_logdev_targp);
> xfs_blkdev_put(logdev);
> + fs_put_dax(dax_logdev);
> }
> if (mp->m_rtdev_targp) {
> struct block_device *rtdev = mp->m_rtdev_targp->bt_bdev;
> + struct dax_device *dax_rtdev = mp->m_rtdev_targp->bt_daxdev;
> +
> xfs_free_buftarg(mp, mp->m_rtdev_targp);
> xfs_blkdev_put(rtdev);
> + fs_put_dax(dax_rtdev);
> }
> xfs_free_buftarg(mp, mp->m_ddev_targp);
> }
> @@ -742,7 +748,9 @@ xfs_open_devices(
> struct xfs_mount *mp)
> {
> struct block_device *ddev = mp->m_super->s_bdev;
> + struct dax_device *dax_ddev = mp->m_super->s_daxdev;
> struct block_device *logdev = NULL, *rtdev = NULL;
> + struct dax_device *dax_logdev = NULL, *dax_rtdev = NULL;
> int error;
>
> /*
> @@ -752,6 +760,7 @@ xfs_open_devices(
> error = xfs_blkdev_get(mp, mp->m_logname, &logdev);
> if (error)
> goto out;
> + dax_logdev = fs_dax_get_by_bdev(logdev);
> }
>
> if (mp->m_rtname) {
> @@ -765,24 +774,25 @@ xfs_open_devices(
> error = -EINVAL;
> goto out_close_rtdev;
> }
> + dax_rtdev = fs_dax_get_by_bdev(rtdev);
> }
>
> /*
> * Setup xfs_mount buffer target pointers
> */
> error = -ENOMEM;
> - mp->m_ddev_targp = xfs_alloc_buftarg(mp, ddev);
> + mp->m_ddev_targp = xfs_alloc_buftarg(mp, ddev, dax_ddev);
> if (!mp->m_ddev_targp)
> goto out_close_rtdev;
>
> if (rtdev) {
> - mp->m_rtdev_targp = xfs_alloc_buftarg(mp, rtdev);
> + mp->m_rtdev_targp = xfs_alloc_buftarg(mp, rtdev, dax_rtdev);
> if (!mp->m_rtdev_targp)
> goto out_free_ddev_targ;
> }
>
> if (logdev && logdev != ddev) {
> - mp->m_logdev_targp = xfs_alloc_buftarg(mp, logdev);
> + mp->m_logdev_targp = xfs_alloc_buftarg(mp, logdev, dax_logdev);
> if (!mp->m_logdev_targp)
> goto out_free_rtdev_targ;
> } else {
> @@ -798,9 +808,12 @@ xfs_open_devices(
> xfs_free_buftarg(mp, mp->m_ddev_targp);
> out_close_rtdev:
> xfs_blkdev_put(rtdev);
> + fs_put_dax(dax_rtdev);
> out_close_logdev:
> - if (logdev && logdev != ddev)
> + if (logdev && logdev != ddev) {
> xfs_blkdev_put(logdev);
> + fs_put_dax(dax_logdev);
> + }
> out:
> return error;
> }
> diff --git a/include/linux/dax.h b/include/linux/dax.h
> index df97b7af7e2c..6e32be3badec 100644
> --- a/include/linux/dax.h
> +++ b/include/linux/dax.h
> @@ -57,6 +57,7 @@ static inline void fs_put_dax(struct dax_device *dax_dev)
> put_dax(dax_dev);
> }
>
> +struct dax_device *fs_dax_get_by_bdev(struct block_device *bdev);
> #else
> static inline int bdev_dax_supported(struct super_block *sb, int blocksize)
> {
> @@ -71,6 +72,11 @@ static inline struct dax_device *fs_dax_get_by_host(const char *host)
> static inline void fs_put_dax(struct dax_device *dax_dev)
> {
> }
> +
> +struct dax_device *fs_dax_get_by_bdev(struct block_device *bdev)
> +{
> + return NULL;
> +}
> #endif
>
> int dax_read_lock(void);
> diff --git a/include/linux/fs.h b/include/linux/fs.h
> index 6e1fd5d21248..d0e3234a1fae 100644
> --- a/include/linux/fs.h
> +++ b/include/linux/fs.h
> @@ -1334,6 +1334,7 @@ struct super_block {
> struct hlist_bl_head s_anon; /* anonymous dentries for (nfs) exporting */
> struct list_head s_mounts; /* list of mounts; _not_ for fs use */
> struct block_device *s_bdev;
> + struct dax_device *s_daxdev;
> struct backing_dev_info *s_bdi;
> struct mtd_info *s_mtd;
> struct hlist_node s_instances;
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-xfs" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v2 1/2] fs, xfs: perform dax_device lookup at mount
@ 2017-08-28 16:28 ` Darrick J. Wong
0 siblings, 0 replies; 28+ messages in thread
From: Darrick J. Wong @ 2017-08-28 16:28 UTC (permalink / raw)
To: Dan Williams
Cc: linux-fsdevel, jack, linux-nvdimm, linux-xfs, linux-ext4, hch
On Sun, Aug 27, 2017 at 08:48:40PM -0700, Dan Williams wrote:
> The ->iomap_begin() operation is a hot path, so cache the
> fs_dax_get_by_host() result at mount time to avoid the incurring the
> hash lookup overhead on a per-i/o basis.
>
> Cc: "Darrick J. Wong" <darrick.wong@oracle.com>
> Reported-by: Christoph Hellwig <hch@lst.de>
> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Looks good,
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
> ---
> drivers/dax/super.c | 10 ++++++++++
> fs/super.c | 26 +++++++++++++++++++++++---
> fs/xfs/xfs_aops.c | 13 +++++++++++++
> fs/xfs/xfs_aops.h | 1 +
> fs/xfs/xfs_buf.c | 4 +++-
> fs/xfs/xfs_buf.h | 3 ++-
> fs/xfs/xfs_iomap.c | 10 +---------
> fs/xfs/xfs_super.c | 21 +++++++++++++++++----
> include/linux/dax.h | 6 ++++++
> include/linux/fs.h | 1 +
> 10 files changed, 77 insertions(+), 18 deletions(-)
>
> diff --git a/drivers/dax/super.c b/drivers/dax/super.c
> index 938eb4868f7f..b699aac268a6 100644
> --- a/drivers/dax/super.c
> +++ b/drivers/dax/super.c
> @@ -46,6 +46,8 @@ void dax_read_unlock(int id)
> EXPORT_SYMBOL_GPL(dax_read_unlock);
>
> #ifdef CONFIG_BLOCK
> +#include <linux/blkdev.h>
> +
> int bdev_dax_pgoff(struct block_device *bdev, sector_t sector, size_t size,
> pgoff_t *pgoff)
> {
> @@ -59,6 +61,14 @@ int bdev_dax_pgoff(struct block_device *bdev, sector_t sector, size_t size,
> }
> EXPORT_SYMBOL(bdev_dax_pgoff);
>
> +struct dax_device *fs_dax_get_by_bdev(struct block_device *bdev)
> +{
> + if (!blk_queue_dax(bdev->bd_queue))
> + return NULL;
> + return fs_dax_get_by_host(bdev->bd_disk->disk_name);
> +}
> +EXPORT_SYMBOL_GPL(fs_dax_get_by_bdev);
> +
> /**
> * __bdev_dax_supported() - Check if the device supports dax for filesystem
> * @sb: The superblock of the device
> diff --git a/fs/super.c b/fs/super.c
> index 6bc3352adcf3..671889b02bed 100644
> --- a/fs/super.c
> +++ b/fs/super.c
> @@ -23,6 +23,7 @@
> #include <linux/export.h>
> #include <linux/slab.h>
> #include <linux/blkdev.h>
> +#include <linux/dax.h>
> #include <linux/mount.h>
> #include <linux/security.h>
> #include <linux/writeback.h> /* for the emergency remount stuff */
> @@ -1048,9 +1049,17 @@ struct dentry *mount_ns(struct file_system_type *fs_type,
> EXPORT_SYMBOL(mount_ns);
>
> #ifdef CONFIG_BLOCK
> +struct sget_devs {
> + struct block_device *bdev;
> + struct dax_device *dax_dev;
> +};
> +
> static int set_bdev_super(struct super_block *s, void *data)
> {
> - s->s_bdev = data;
> + struct sget_devs *devs = data;
> +
> + s->s_bdev = devs->bdev;
> + s->s_daxdev = devs->dax_dev;
> s->s_dev = s->s_bdev->bd_dev;
> s->s_bdi = bdi_get(s->s_bdev->bd_bdi);
>
> @@ -1059,14 +1068,18 @@ static int set_bdev_super(struct super_block *s, void *data)
>
> static int test_bdev_super(struct super_block *s, void *data)
> {
> - return (void *)s->s_bdev == data;
> + struct sget_devs *devs = data;
> +
> + return s->s_bdev == devs->bdev;
> }
>
> struct dentry *mount_bdev(struct file_system_type *fs_type,
> int flags, const char *dev_name, void *data,
> int (*fill_super)(struct super_block *, void *, int))
> {
> + struct sget_devs devs;
> struct block_device *bdev;
> + struct dax_device *dax_dev;
> struct super_block *s;
> fmode_t mode = FMODE_READ | FMODE_EXCL;
> int error = 0;
> @@ -1077,6 +1090,7 @@ struct dentry *mount_bdev(struct file_system_type *fs_type,
> bdev = blkdev_get_by_path(dev_name, mode, fs_type);
> if (IS_ERR(bdev))
> return ERR_CAST(bdev);
> + dax_dev = fs_dax_get_by_bdev(bdev);
>
> /*
> * once the super is inserted into the list by sget, s_umount
> @@ -1089,8 +1103,10 @@ struct dentry *mount_bdev(struct file_system_type *fs_type,
> error = -EBUSY;
> goto error_bdev;
> }
> + devs.bdev = bdev;
> + devs.dax_dev = dax_dev;
> s = sget(fs_type, test_bdev_super, set_bdev_super, flags | MS_NOSEC,
> - bdev);
> + &devs);
> mutex_unlock(&bdev->bd_fsfreeze_mutex);
> if (IS_ERR(s))
> goto error_s;
> @@ -1111,6 +1127,7 @@ struct dentry *mount_bdev(struct file_system_type *fs_type,
> */
> up_write(&s->s_umount);
> blkdev_put(bdev, mode);
> + fs_put_dax(dax_dev);
> down_write(&s->s_umount);
> } else {
> s->s_mode = mode;
> @@ -1132,6 +1149,7 @@ struct dentry *mount_bdev(struct file_system_type *fs_type,
> error = PTR_ERR(s);
> error_bdev:
> blkdev_put(bdev, mode);
> + fs_put_dax(dax_dev);
> error:
> return ERR_PTR(error);
> }
> @@ -1140,6 +1158,7 @@ EXPORT_SYMBOL(mount_bdev);
> void kill_block_super(struct super_block *sb)
> {
> struct block_device *bdev = sb->s_bdev;
> + struct dax_device *dax_dev = sb->s_daxdev;
> fmode_t mode = sb->s_mode;
>
> bdev->bd_super = NULL;
> @@ -1147,6 +1166,7 @@ void kill_block_super(struct super_block *sb)
> sync_blockdev(bdev);
> WARN_ON_ONCE(!(mode & FMODE_EXCL));
> blkdev_put(bdev, mode | FMODE_EXCL);
> + fs_put_dax(dax_dev);
> }
>
> EXPORT_SYMBOL(kill_block_super);
> diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c
> index 6bf120bb1a17..78185f3b10b2 100644
> --- a/fs/xfs/xfs_aops.c
> +++ b/fs/xfs/xfs_aops.c
> @@ -80,6 +80,19 @@ xfs_find_bdev_for_inode(
> return mp->m_ddev_targp->bt_bdev;
> }
>
> +struct dax_device *
> +xfs_find_daxdev_for_inode(
> + struct inode *inode)
> +{
> + struct xfs_inode *ip = XFS_I(inode);
> + struct xfs_mount *mp = ip->i_mount;
> +
> + if (XFS_IS_REALTIME_INODE(ip))
> + return mp->m_rtdev_targp->bt_daxdev;
> + else
> + return mp->m_ddev_targp->bt_daxdev;
> +}
> +
> /*
> * We're now finished for good with this page. Update the page state via the
> * associated buffer_heads, paying attention to the start and end offsets that
> diff --git a/fs/xfs/xfs_aops.h b/fs/xfs/xfs_aops.h
> index cc174ec6c2fd..88c85ea63da0 100644
> --- a/fs/xfs/xfs_aops.h
> +++ b/fs/xfs/xfs_aops.h
> @@ -59,5 +59,6 @@ int xfs_setfilesize(struct xfs_inode *ip, xfs_off_t offset, size_t size);
>
> extern void xfs_count_page_state(struct page *, int *, int *);
> extern struct block_device *xfs_find_bdev_for_inode(struct inode *);
> +extern struct dax_device *xfs_find_daxdev_for_inode(struct inode *);
>
> #endif /* __XFS_AOPS_H__ */
> diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c
> index 72f038492ba8..6deb86c845d1 100644
> --- a/fs/xfs/xfs_buf.c
> +++ b/fs/xfs/xfs_buf.c
> @@ -1802,7 +1802,8 @@ xfs_setsize_buftarg_early(
> xfs_buftarg_t *
> xfs_alloc_buftarg(
> struct xfs_mount *mp,
> - struct block_device *bdev)
> + struct block_device *bdev,
> + struct dax_device *dax_dev)
> {
> xfs_buftarg_t *btp;
>
> @@ -1811,6 +1812,7 @@ xfs_alloc_buftarg(
> btp->bt_mount = mp;
> btp->bt_dev = bdev->bd_dev;
> btp->bt_bdev = bdev;
> + btp->bt_daxdev = dax_dev;
>
> if (xfs_setsize_buftarg_early(btp, bdev))
> goto error;
> diff --git a/fs/xfs/xfs_buf.h b/fs/xfs/xfs_buf.h
> index 20721261dae5..bf71507ddb16 100644
> --- a/fs/xfs/xfs_buf.h
> +++ b/fs/xfs/xfs_buf.h
> @@ -108,6 +108,7 @@ typedef unsigned int xfs_buf_flags_t;
> typedef struct xfs_buftarg {
> dev_t bt_dev;
> struct block_device *bt_bdev;
> + struct dax_device *bt_daxdev;
> struct xfs_mount *bt_mount;
> unsigned int bt_meta_sectorsize;
> size_t bt_meta_sectormask;
> @@ -385,7 +386,7 @@ xfs_buf_update_cksum(struct xfs_buf *bp, unsigned long cksum_offset)
> * Handling of buftargs.
> */
> extern xfs_buftarg_t *xfs_alloc_buftarg(struct xfs_mount *,
> - struct block_device *);
> + struct block_device *, struct dax_device *);
> extern void xfs_free_buftarg(struct xfs_mount *, struct xfs_buftarg *);
> extern void xfs_wait_buftarg(xfs_buftarg_t *);
> extern int xfs_setsize_buftarg(xfs_buftarg_t *, unsigned int);
> diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
> index 813394c62849..7c934e407332 100644
> --- a/fs/xfs/xfs_iomap.c
> +++ b/fs/xfs/xfs_iomap.c
> @@ -69,6 +69,7 @@ xfs_bmbt_to_iomap(
> iomap->offset = XFS_FSB_TO_B(mp, imap->br_startoff);
> iomap->length = XFS_FSB_TO_B(mp, imap->br_blockcount);
> iomap->bdev = xfs_find_bdev_for_inode(VFS_I(ip));
> + iomap->dax_dev = xfs_find_daxdev_for_inode(VFS_I(ip));
> }
>
> xfs_extlen_t
> @@ -976,7 +977,6 @@ xfs_file_iomap_begin(
> int nimaps = 1, error = 0;
> bool shared = false, trimmed = false;
> unsigned lockmode;
> - struct block_device *bdev;
>
> if (XFS_FORCED_SHUTDOWN(mp))
> return -EIO;
> @@ -1087,13 +1087,6 @@ xfs_file_iomap_begin(
>
> xfs_bmbt_to_iomap(ip, iomap, &imap);
>
> - /* optionally associate a dax device with the iomap bdev */
> - bdev = iomap->bdev;
> - if (blk_queue_dax(bdev->bd_queue))
> - iomap->dax_dev = fs_dax_get_by_host(bdev->bd_disk->disk_name);
> - else
> - iomap->dax_dev = NULL;
> -
> if (shared)
> iomap->flags |= IOMAP_F_SHARED;
> return 0;
> @@ -1171,7 +1164,6 @@ xfs_file_iomap_end(
> unsigned flags,
> struct iomap *iomap)
> {
> - fs_put_dax(iomap->dax_dev);
> if ((flags & IOMAP_WRITE) && iomap->type == IOMAP_DELALLOC)
> return xfs_file_iomap_end_delalloc(XFS_I(inode), offset,
> length, written, iomap);
> diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
> index 38aaacdbb8b3..d863f96b16e2 100644
> --- a/fs/xfs/xfs_super.c
> +++ b/fs/xfs/xfs_super.c
> @@ -716,13 +716,19 @@ xfs_close_devices(
> {
> if (mp->m_logdev_targp && mp->m_logdev_targp != mp->m_ddev_targp) {
> struct block_device *logdev = mp->m_logdev_targp->bt_bdev;
> + struct dax_device *dax_logdev = mp->m_logdev_targp->bt_daxdev;
> +
> xfs_free_buftarg(mp, mp->m_logdev_targp);
> xfs_blkdev_put(logdev);
> + fs_put_dax(dax_logdev);
> }
> if (mp->m_rtdev_targp) {
> struct block_device *rtdev = mp->m_rtdev_targp->bt_bdev;
> + struct dax_device *dax_rtdev = mp->m_rtdev_targp->bt_daxdev;
> +
> xfs_free_buftarg(mp, mp->m_rtdev_targp);
> xfs_blkdev_put(rtdev);
> + fs_put_dax(dax_rtdev);
> }
> xfs_free_buftarg(mp, mp->m_ddev_targp);
> }
> @@ -742,7 +748,9 @@ xfs_open_devices(
> struct xfs_mount *mp)
> {
> struct block_device *ddev = mp->m_super->s_bdev;
> + struct dax_device *dax_ddev = mp->m_super->s_daxdev;
> struct block_device *logdev = NULL, *rtdev = NULL;
> + struct dax_device *dax_logdev = NULL, *dax_rtdev = NULL;
> int error;
>
> /*
> @@ -752,6 +760,7 @@ xfs_open_devices(
> error = xfs_blkdev_get(mp, mp->m_logname, &logdev);
> if (error)
> goto out;
> + dax_logdev = fs_dax_get_by_bdev(logdev);
> }
>
> if (mp->m_rtname) {
> @@ -765,24 +774,25 @@ xfs_open_devices(
> error = -EINVAL;
> goto out_close_rtdev;
> }
> + dax_rtdev = fs_dax_get_by_bdev(rtdev);
> }
>
> /*
> * Setup xfs_mount buffer target pointers
> */
> error = -ENOMEM;
> - mp->m_ddev_targp = xfs_alloc_buftarg(mp, ddev);
> + mp->m_ddev_targp = xfs_alloc_buftarg(mp, ddev, dax_ddev);
> if (!mp->m_ddev_targp)
> goto out_close_rtdev;
>
> if (rtdev) {
> - mp->m_rtdev_targp = xfs_alloc_buftarg(mp, rtdev);
> + mp->m_rtdev_targp = xfs_alloc_buftarg(mp, rtdev, dax_rtdev);
> if (!mp->m_rtdev_targp)
> goto out_free_ddev_targ;
> }
>
> if (logdev && logdev != ddev) {
> - mp->m_logdev_targp = xfs_alloc_buftarg(mp, logdev);
> + mp->m_logdev_targp = xfs_alloc_buftarg(mp, logdev, dax_logdev);
> if (!mp->m_logdev_targp)
> goto out_free_rtdev_targ;
> } else {
> @@ -798,9 +808,12 @@ xfs_open_devices(
> xfs_free_buftarg(mp, mp->m_ddev_targp);
> out_close_rtdev:
> xfs_blkdev_put(rtdev);
> + fs_put_dax(dax_rtdev);
> out_close_logdev:
> - if (logdev && logdev != ddev)
> + if (logdev && logdev != ddev) {
> xfs_blkdev_put(logdev);
> + fs_put_dax(dax_logdev);
> + }
> out:
> return error;
> }
> diff --git a/include/linux/dax.h b/include/linux/dax.h
> index df97b7af7e2c..6e32be3badec 100644
> --- a/include/linux/dax.h
> +++ b/include/linux/dax.h
> @@ -57,6 +57,7 @@ static inline void fs_put_dax(struct dax_device *dax_dev)
> put_dax(dax_dev);
> }
>
> +struct dax_device *fs_dax_get_by_bdev(struct block_device *bdev);
> #else
> static inline int bdev_dax_supported(struct super_block *sb, int blocksize)
> {
> @@ -71,6 +72,11 @@ static inline struct dax_device *fs_dax_get_by_host(const char *host)
> static inline void fs_put_dax(struct dax_device *dax_dev)
> {
> }
> +
> +struct dax_device *fs_dax_get_by_bdev(struct block_device *bdev)
> +{
> + return NULL;
> +}
> #endif
>
> int dax_read_lock(void);
> diff --git a/include/linux/fs.h b/include/linux/fs.h
> index 6e1fd5d21248..d0e3234a1fae 100644
> --- a/include/linux/fs.h
> +++ b/include/linux/fs.h
> @@ -1334,6 +1334,7 @@ struct super_block {
> struct hlist_bl_head s_anon; /* anonymous dentries for (nfs) exporting */
> struct list_head s_mounts; /* list of mounts; _not_ for fs use */
> struct block_device *s_bdev;
> + struct dax_device *s_daxdev;
> struct backing_dev_info *s_bdi;
> struct mtd_info *s_mtd;
> struct hlist_node s_instances;
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-xfs" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v2 1/2] fs, xfs: perform dax_device lookup at mount
2017-08-28 3:48 ` Dan Williams
(?)
@ 2017-08-29 21:26 ` Christoph Hellwig
-1 siblings, 0 replies; 28+ messages in thread
From: Christoph Hellwig @ 2017-08-29 21:26 UTC (permalink / raw)
To: Dan Williams
Cc: jack, Darrick J. Wong, linux-nvdimm, linux-xfs, linux-fsdevel,
linux-ext4, hch
Call me nitpicky, but..
First this really should be three patches, one for the DAX code, one
for the VFS code and one for XFS. The DAX and XFS bits looks fine to
me:
Reviewed-by: Christoph Hellwig <hch@lst.de>
But I'm a little worried about stuffing more DAX knowledge into the
block mount_bdev helper. For now it's probably ok as everything
else would involve a lot of refactoring and/or duplication, but
I'm generally not too happy about it.
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v2 1/2] fs, xfs: perform dax_device lookup at mount
@ 2017-08-29 21:26 ` Christoph Hellwig
0 siblings, 0 replies; 28+ messages in thread
From: Christoph Hellwig @ 2017-08-29 21:26 UTC (permalink / raw)
To: Dan Williams
Cc: linux-fsdevel, jack, linux-nvdimm, Darrick J. Wong, linux-xfs,
linux-ext4, hch
Call me nitpicky, but..
First this really should be three patches, one for the DAX code, one
for the VFS code and one for XFS. The DAX and XFS bits looks fine to
me:
Reviewed-by: Christoph Hellwig <hch@lst.de>
But I'm a little worried about stuffing more DAX knowledge into the
block mount_bdev helper. For now it's probably ok as everything
else would involve a lot of refactoring and/or duplication, but
I'm generally not too happy about it.
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v2 1/2] fs, xfs: perform dax_device lookup at mount
@ 2017-08-29 21:26 ` Christoph Hellwig
0 siblings, 0 replies; 28+ messages in thread
From: Christoph Hellwig @ 2017-08-29 21:26 UTC (permalink / raw)
To: Dan Williams
Cc: jack-AlSwsSmVLrQ, Darrick J. Wong,
linux-nvdimm-hn68Rpc1hR1g9hUCZPvPmw,
linux-xfs-u79uwXL29TY76Z2rM5mHXA,
linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
linux-ext4-u79uwXL29TY76Z2rM5mHXA, hch-jcswGhMUV9g
Call me nitpicky, but..
First this really should be three patches, one for the DAX code, one
for the VFS code and one for XFS. The DAX and XFS bits looks fine to
me:
Reviewed-by: Christoph Hellwig <hch-jcswGhMUV9g@public.gmane.org>
But I'm a little worried about stuffing more DAX knowledge into the
block mount_bdev helper. For now it's probably ok as everything
else would involve a lot of refactoring and/or duplication, but
I'm generally not too happy about it.
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v2 1/2] fs, xfs: perform dax_device lookup at mount
2017-08-29 21:26 ` Christoph Hellwig
(?)
@ 2017-08-29 21:31 ` Dan Williams
-1 siblings, 0 replies; 28+ messages in thread
From: Dan Williams @ 2017-08-29 21:31 UTC (permalink / raw)
To: Christoph Hellwig
Cc: Jan Kara, Darrick J. Wong, linux-nvdimm, linux-xfs,
linux-fsdevel, linux-ext4
On Tue, Aug 29, 2017 at 2:26 PM, Christoph Hellwig <hch@lst.de> wrote:
> Call me nitpicky, but..
>
> First this really should be three patches, one for the DAX code, one
> for the VFS code and one for XFS. The DAX and XFS bits looks fine to
> me:
>
> Reviewed-by: Christoph Hellwig <hch@lst.de>
>
> But I'm a little worried about stuffing more DAX knowledge into the
> block mount_bdev helper. For now it's probably ok as everything
> else would involve a lot of refactoring and/or duplication, but
> I'm generally not too happy about it.
I think this is why we ended up with calling dax_get_by_host() in
->iomap_begin() because the mount_bdev() touches I started with back
when this was first introduced were not very palatable. I agree with
the direction to move to mount_dax() in the future. I can respin this
into three patches and a TODO comment about how we want to kill the
dax knowledge in mount_bdev() going forward.
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v2 1/2] fs, xfs: perform dax_device lookup at mount
@ 2017-08-29 21:31 ` Dan Williams
0 siblings, 0 replies; 28+ messages in thread
From: Dan Williams @ 2017-08-29 21:31 UTC (permalink / raw)
To: Christoph Hellwig
Cc: linux-fsdevel, Jan Kara, linux-nvdimm, Darrick J. Wong,
linux-xfs, linux-ext4
On Tue, Aug 29, 2017 at 2:26 PM, Christoph Hellwig <hch@lst.de> wrote:
> Call me nitpicky, but..
>
> First this really should be three patches, one for the DAX code, one
> for the VFS code and one for XFS. The DAX and XFS bits looks fine to
> me:
>
> Reviewed-by: Christoph Hellwig <hch@lst.de>
>
> But I'm a little worried about stuffing more DAX knowledge into the
> block mount_bdev helper. For now it's probably ok as everything
> else would involve a lot of refactoring and/or duplication, but
> I'm generally not too happy about it.
I think this is why we ended up with calling dax_get_by_host() in
->iomap_begin() because the mount_bdev() touches I started with back
when this was first introduced were not very palatable. I agree with
the direction to move to mount_dax() in the future. I can respin this
into three patches and a TODO comment about how we want to kill the
dax knowledge in mount_bdev() going forward.
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v2 1/2] fs, xfs: perform dax_device lookup at mount
@ 2017-08-29 21:31 ` Dan Williams
0 siblings, 0 replies; 28+ messages in thread
From: Dan Williams @ 2017-08-29 21:31 UTC (permalink / raw)
To: Christoph Hellwig
Cc: Jan Kara, Darrick J. Wong, linux-nvdimm-hn68Rpc1hR1g9hUCZPvPmw,
linux-xfs-u79uwXL29TY76Z2rM5mHXA, linux-fsdevel, linux-ext4
On Tue, Aug 29, 2017 at 2:26 PM, Christoph Hellwig <hch-jcswGhMUV9g@public.gmane.org> wrote:
> Call me nitpicky, but..
>
> First this really should be three patches, one for the DAX code, one
> for the VFS code and one for XFS. The DAX and XFS bits looks fine to
> me:
>
> Reviewed-by: Christoph Hellwig <hch-jcswGhMUV9g@public.gmane.org>
>
> But I'm a little worried about stuffing more DAX knowledge into the
> block mount_bdev helper. For now it's probably ok as everything
> else would involve a lot of refactoring and/or duplication, but
> I'm generally not too happy about it.
I think this is why we ended up with calling dax_get_by_host() in
->iomap_begin() because the mount_bdev() touches I started with back
when this was first introduced were not very palatable. I agree with
the direction to move to mount_dax() in the future. I can respin this
into three patches and a TODO comment about how we want to kill the
dax knowledge in mount_bdev() going forward.
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v2 1/2] fs, xfs: perform dax_device lookup at mount
2017-08-29 21:31 ` Dan Williams
(?)
@ 2017-08-29 21:35 ` Dan Williams
-1 siblings, 0 replies; 28+ messages in thread
From: Dan Williams @ 2017-08-29 21:35 UTC (permalink / raw)
To: Christoph Hellwig
Cc: Jan Kara, Darrick J. Wong, linux-nvdimm, linux-xfs,
linux-fsdevel, linux-ext4
On Tue, Aug 29, 2017 at 2:31 PM, Dan Williams <dan.j.williams@intel.com> wrote:
> On Tue, Aug 29, 2017 at 2:26 PM, Christoph Hellwig <hch@lst.de> wrote:
>> Call me nitpicky, but..
>>
>> First this really should be three patches, one for the DAX code, one
>> for the VFS code and one for XFS. The DAX and XFS bits looks fine to
>> me:
>>
>> Reviewed-by: Christoph Hellwig <hch@lst.de>
>>
>> But I'm a little worried about stuffing more DAX knowledge into the
>> block mount_bdev helper. For now it's probably ok as everything
>> else would involve a lot of refactoring and/or duplication, but
>> I'm generally not too happy about it.
>
> I think this is why we ended up with calling dax_get_by_host() in
> ->iomap_begin() because the mount_bdev() touches I started with back
> when this was first introduced were not very palatable. I agree with
> the direction to move to mount_dax() in the future. I can respin this
> into three patches and a TODO comment about how we want to kill the
> dax knowledge in mount_bdev() going forward.
Actually, why not just do this directly in xfs_fs_mount()? I think I
can refactor this to not touch mount_bdev() and put all the details in
the per-fs mount/umount paths.
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v2 1/2] fs, xfs: perform dax_device lookup at mount
@ 2017-08-29 21:35 ` Dan Williams
0 siblings, 0 replies; 28+ messages in thread
From: Dan Williams @ 2017-08-29 21:35 UTC (permalink / raw)
To: Christoph Hellwig
Cc: linux-fsdevel, Jan Kara, linux-nvdimm, Darrick J. Wong,
linux-xfs, linux-ext4
On Tue, Aug 29, 2017 at 2:31 PM, Dan Williams <dan.j.williams@intel.com> wrote:
> On Tue, Aug 29, 2017 at 2:26 PM, Christoph Hellwig <hch@lst.de> wrote:
>> Call me nitpicky, but..
>>
>> First this really should be three patches, one for the DAX code, one
>> for the VFS code and one for XFS. The DAX and XFS bits looks fine to
>> me:
>>
>> Reviewed-by: Christoph Hellwig <hch@lst.de>
>>
>> But I'm a little worried about stuffing more DAX knowledge into the
>> block mount_bdev helper. For now it's probably ok as everything
>> else would involve a lot of refactoring and/or duplication, but
>> I'm generally not too happy about it.
>
> I think this is why we ended up with calling dax_get_by_host() in
> ->iomap_begin() because the mount_bdev() touches I started with back
> when this was first introduced were not very palatable. I agree with
> the direction to move to mount_dax() in the future. I can respin this
> into three patches and a TODO comment about how we want to kill the
> dax knowledge in mount_bdev() going forward.
Actually, why not just do this directly in xfs_fs_mount()? I think I
can refactor this to not touch mount_bdev() and put all the details in
the per-fs mount/umount paths.
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v2 1/2] fs, xfs: perform dax_device lookup at mount
@ 2017-08-29 21:35 ` Dan Williams
0 siblings, 0 replies; 28+ messages in thread
From: Dan Williams @ 2017-08-29 21:35 UTC (permalink / raw)
To: Christoph Hellwig
Cc: Jan Kara, Darrick J. Wong, linux-nvdimm-hn68Rpc1hR1g9hUCZPvPmw,
linux-xfs-u79uwXL29TY76Z2rM5mHXA, linux-fsdevel, linux-ext4
On Tue, Aug 29, 2017 at 2:31 PM, Dan Williams <dan.j.williams-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org> wrote:
> On Tue, Aug 29, 2017 at 2:26 PM, Christoph Hellwig <hch-jcswGhMUV9g@public.gmane.org> wrote:
>> Call me nitpicky, but..
>>
>> First this really should be three patches, one for the DAX code, one
>> for the VFS code and one for XFS. The DAX and XFS bits looks fine to
>> me:
>>
>> Reviewed-by: Christoph Hellwig <hch-jcswGhMUV9g@public.gmane.org>
>>
>> But I'm a little worried about stuffing more DAX knowledge into the
>> block mount_bdev helper. For now it's probably ok as everything
>> else would involve a lot of refactoring and/or duplication, but
>> I'm generally not too happy about it.
>
> I think this is why we ended up with calling dax_get_by_host() in
> ->iomap_begin() because the mount_bdev() touches I started with back
> when this was first introduced were not very palatable. I agree with
> the direction to move to mount_dax() in the future. I can respin this
> into three patches and a TODO comment about how we want to kill the
> dax knowledge in mount_bdev() going forward.
Actually, why not just do this directly in xfs_fs_mount()? I think I
can refactor this to not touch mount_bdev() and put all the details in
the per-fs mount/umount paths.
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v2 1/2] fs, xfs: perform dax_device lookup at mount
2017-08-29 21:35 ` Dan Williams
(?)
@ 2017-08-29 21:36 ` Christoph Hellwig
-1 siblings, 0 replies; 28+ messages in thread
From: Christoph Hellwig @ 2017-08-29 21:36 UTC (permalink / raw)
To: Dan Williams
Cc: Jan Kara, Darrick J. Wong, linux-nvdimm, linux-xfs,
linux-fsdevel, linux-ext4, Christoph Hellwig
On Tue, Aug 29, 2017 at 02:35:27PM -0700, Dan Williams wrote:
> Actually, why not just do this directly in xfs_fs_mount()? I think I
> can refactor this to not touch mount_bdev() and put all the details in
> the per-fs mount/umount paths.
Yes, and just cache in in the fs specific superblock.
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v2 1/2] fs, xfs: perform dax_device lookup at mount
@ 2017-08-29 21:36 ` Christoph Hellwig
0 siblings, 0 replies; 28+ messages in thread
From: Christoph Hellwig @ 2017-08-29 21:36 UTC (permalink / raw)
To: Dan Williams
Cc: Christoph Hellwig, linux-fsdevel, Jan Kara, linux-nvdimm,
Darrick J. Wong, linux-xfs, linux-ext4
On Tue, Aug 29, 2017 at 02:35:27PM -0700, Dan Williams wrote:
> Actually, why not just do this directly in xfs_fs_mount()? I think I
> can refactor this to not touch mount_bdev() and put all the details in
> the per-fs mount/umount paths.
Yes, and just cache in in the fs specific superblock.
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v2 1/2] fs, xfs: perform dax_device lookup at mount
@ 2017-08-29 21:36 ` Christoph Hellwig
0 siblings, 0 replies; 28+ messages in thread
From: Christoph Hellwig @ 2017-08-29 21:36 UTC (permalink / raw)
To: Dan Williams
Cc: Jan Kara, Darrick J. Wong, linux-nvdimm-hn68Rpc1hR1g9hUCZPvPmw,
linux-xfs-u79uwXL29TY76Z2rM5mHXA, linux-fsdevel, linux-ext4,
Christoph Hellwig
On Tue, Aug 29, 2017 at 02:35:27PM -0700, Dan Williams wrote:
> Actually, why not just do this directly in xfs_fs_mount()? I think I
> can refactor this to not touch mount_bdev() and put all the details in
> the per-fs mount/umount paths.
Yes, and just cache in in the fs specific superblock.
^ permalink raw reply [flat|nested] 28+ messages in thread
end of thread, other threads:[~2017-08-29 21:36 UTC | newest]
Thread overview: 28+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-08-28 3:48 [PATCH v2 0/2] fs, dax: lookup dax_device at mount time Dan Williams
2017-08-28 3:48 ` Dan Williams
2017-08-28 3:48 ` [PATCH v2 1/2] fs, xfs: perform dax_device lookup at mount Dan Williams
2017-08-28 3:48 ` Dan Williams
2017-08-28 3:48 ` Dan Williams
2017-08-28 8:31 ` Jan Kara
2017-08-28 8:31 ` Jan Kara
2017-08-28 8:31 ` Jan Kara
2017-08-28 16:28 ` Darrick J. Wong
2017-08-28 16:28 ` Darrick J. Wong
2017-08-29 21:26 ` Christoph Hellwig
2017-08-29 21:26 ` Christoph Hellwig
2017-08-29 21:26 ` Christoph Hellwig
2017-08-29 21:31 ` Dan Williams
2017-08-29 21:31 ` Dan Williams
2017-08-29 21:31 ` Dan Williams
2017-08-29 21:35 ` Dan Williams
2017-08-29 21:35 ` Dan Williams
2017-08-29 21:35 ` Dan Williams
2017-08-29 21:36 ` Christoph Hellwig
2017-08-29 21:36 ` Christoph Hellwig
2017-08-29 21:36 ` Christoph Hellwig
2017-08-28 3:48 ` [PATCH v2 2/2] ext2, ext4: use the super_block dax_device Dan Williams
2017-08-28 3:48 ` Dan Williams
2017-08-28 3:48 ` Dan Williams
2017-08-28 8:27 ` Jan Kara
2017-08-28 8:27 ` Jan Kara
2017-08-28 8:27 ` Jan Kara
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.