Skip to content

Commit 58f88ca

Browse files
Dave Chinnerdchinner
authored andcommitted
xfs: introduce per-inode DAX enablement
Rather than just being able to turn DAX on and off via a mount option, some applications may only want to enable DAX for certain performance critical files in a filesystem. This patch introduces a new inode flag to enable DAX in the v3 inode di_flags2 field. It adds support for setting and clearing flags in the di_flags2 field via the XFS_IOC_FSSETXATTR ioctl, and sets the S_DAX inode flag appropriately when it is seen. When this flag is set on a directory, it acts as an "inherit flag". That is, inodes created in the directory will automatically inherit the on-disk inode DAX flag, enabling administrators to set up directory heirarchies that automatically use DAX. Setting this flag on an empty root directory will make the entire filesystem use DAX by default. Signed-off-by: Dave Chinner <dchinner@redhat.com>
1 parent e7b8948 commit 58f88ca

File tree

5 files changed

+52
-12
lines changed

5 files changed

+52
-12
lines changed

fs/xfs/libxfs/xfs_format.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1023,6 +1023,15 @@ static inline void xfs_dinode_put_rdev(struct xfs_dinode *dip, xfs_dev_t rdev)
10231023
XFS_DIFLAG_PROJINHERIT | XFS_DIFLAG_NOSYMLINKS | XFS_DIFLAG_EXTSIZE | \
10241024
XFS_DIFLAG_EXTSZINHERIT | XFS_DIFLAG_NODEFRAG | XFS_DIFLAG_FILESTREAM)
10251025

1026+
/*
1027+
* Values for di_flags2 These start by being exposed to userspace in the upper
1028+
* 16 bits of the XFS_XFLAG_s range.
1029+
*/
1030+
#define XFS_DIFLAG2_DAX_BIT 0 /* use DAX for this inode */
1031+
#define XFS_DIFLAG2_DAX (1 << XFS_DIFLAG2_DAX_BIT)
1032+
1033+
#define XFS_DIFLAG2_ANY (XFS_DIFLAG2_DAX)
1034+
10261035
/*
10271036
* Inode number format:
10281037
* low inopblog bits - offset in block

fs/xfs/xfs_inode.c

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -610,7 +610,9 @@ __xfs_iflock(
610610

611611
STATIC uint
612612
_xfs_dic2xflags(
613-
__uint16_t di_flags)
613+
__uint16_t di_flags,
614+
uint64_t di_flags2,
615+
bool has_attr)
614616
{
615617
uint flags = 0;
616618

@@ -645,25 +647,32 @@ _xfs_dic2xflags(
645647
flags |= FS_XFLAG_FILESTREAM;
646648
}
647649

650+
if (di_flags2 & XFS_DIFLAG2_ANY) {
651+
if (di_flags2 & XFS_DIFLAG2_DAX)
652+
flags |= FS_XFLAG_DAX;
653+
}
654+
655+
if (has_attr)
656+
flags |= FS_XFLAG_HASATTR;
657+
648658
return flags;
649659
}
650660

651661
uint
652662
xfs_ip2xflags(
653-
xfs_inode_t *ip)
663+
struct xfs_inode *ip)
654664
{
655-
xfs_icdinode_t *dic = &ip->i_d;
665+
struct xfs_icdinode *dic = &ip->i_d;
656666

657-
return _xfs_dic2xflags(dic->di_flags) |
658-
(XFS_IFORK_Q(ip) ? FS_XFLAG_HASATTR : 0);
667+
return _xfs_dic2xflags(dic->di_flags, dic->di_flags2, XFS_IFORK_Q(ip));
659668
}
660669

661670
uint
662671
xfs_dic2xflags(
663-
xfs_dinode_t *dip)
672+
struct xfs_dinode *dip)
664673
{
665-
return _xfs_dic2xflags(be16_to_cpu(dip->di_flags)) |
666-
(XFS_DFORK_Q(dip) ? FS_XFLAG_HASATTR : 0);
674+
return _xfs_dic2xflags(be16_to_cpu(dip->di_flags),
675+
be64_to_cpu(dip->di_flags2), XFS_DFORK_Q(dip));
667676
}
668677

669678
/*
@@ -862,7 +871,8 @@ xfs_ialloc(
862871
case S_IFREG:
863872
case S_IFDIR:
864873
if (pip && (pip->i_d.di_flags & XFS_DIFLAG_ANY)) {
865-
uint di_flags = 0;
874+
uint64_t di_flags2 = 0;
875+
uint di_flags = 0;
866876

867877
if (S_ISDIR(mode)) {
868878
if (pip->i_d.di_flags & XFS_DIFLAG_RTINHERIT)
@@ -898,7 +908,11 @@ xfs_ialloc(
898908
di_flags |= XFS_DIFLAG_NODEFRAG;
899909
if (pip->i_d.di_flags & XFS_DIFLAG_FILESTREAM)
900910
di_flags |= XFS_DIFLAG_FILESTREAM;
911+
if (pip->i_d.di_flags2 & XFS_DIFLAG2_DAX)
912+
di_flags2 |= XFS_DIFLAG2_DAX;
913+
901914
ip->i_d.di_flags |= di_flags;
915+
ip->i_d.di_flags2 |= di_flags2;
902916
}
903917
/* FALLTHROUGH */
904918
case S_IFLNK:

fs/xfs/xfs_ioctl.c

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -945,6 +945,7 @@ xfs_set_diflags(
945945
unsigned int xflags)
946946
{
947947
unsigned int di_flags;
948+
uint64_t di_flags2;
948949

949950
/* can't set PREALLOC this way, just preserve it */
950951
di_flags = (ip->i_d.di_flags & XFS_DIFLAG_PREALLOC);
@@ -977,8 +978,18 @@ xfs_set_diflags(
977978
if (xflags & FS_XFLAG_EXTSIZE)
978979
di_flags |= XFS_DIFLAG_EXTSIZE;
979980
}
980-
981981
ip->i_d.di_flags = di_flags;
982+
983+
/* diflags2 only valid for v3 inodes. */
984+
if (ip->i_d.di_version < 3)
985+
return;
986+
987+
di_flags2 = 0;
988+
if (xflags & FS_XFLAG_DAX)
989+
di_flags2 |= XFS_DIFLAG2_DAX;
990+
991+
ip->i_d.di_flags2 = di_flags2;
992+
982993
}
983994

984995
STATIC void
@@ -1004,6 +1015,11 @@ xfs_diflags_to_linux(
10041015
inode->i_flags |= S_NOATIME;
10051016
else
10061017
inode->i_flags &= ~S_NOATIME;
1018+
if (xflags & FS_XFLAG_DAX)
1019+
inode->i_flags |= S_DAX;
1020+
else
1021+
inode->i_flags &= ~S_DAX;
1022+
10071023
}
10081024

10091025
static int

fs/xfs/xfs_iops.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1201,8 +1201,8 @@ xfs_diflags_to_iflags(
12011201
inode->i_flags |= S_SYNC;
12021202
if (flags & XFS_DIFLAG_NOATIME)
12031203
inode->i_flags |= S_NOATIME;
1204-
/* XXX: Also needs an on-disk per inode flag! */
1205-
if (ip->i_mount->m_flags & XFS_MOUNT_DAX)
1204+
if (ip->i_mount->m_flags & XFS_MOUNT_DAX ||
1205+
ip->i_d.di_flags2 & XFS_DIFLAG2_DAX)
12061206
inode->i_flags |= S_DAX;
12071207
}
12081208

include/uapi/linux/fs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ struct fsxattr {
138138
#define FS_XFLAG_EXTSZINHERIT 0x00001000 /* inherit inode extent size */
139139
#define FS_XFLAG_NODEFRAG 0x00002000 /* do not defragment */
140140
#define FS_XFLAG_FILESTREAM 0x00004000 /* use filestream allocator */
141+
#define FS_XFLAG_DAX 0x00008000 /* use DAX for IO */
141142
#define FS_XFLAG_HASATTR 0x80000000 /* no DIFLAG for this */
142143

143144
/* the read-only stuff doesn't really belong here, but any other place is

0 commit comments

Comments
 (0)