aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Chinner <dchinner@redhat.com>2015-06-03 19:19:18 -0400
committerDave Chinner <david@fromorbit.com>2015-06-03 19:19:18 -0400
commitcbe4dab119f211ff6642d617f541087894e99e4f (patch)
tree6751ee32423a7799e7ad31befc1c248365545030
parent6e1ba0bcb84b3f97616feb07c27f974509ba57be (diff)
xfs: add initial DAX support
Add initial DAX support to XFS. To do this we need a new mount option to turn DAX on filesystem, and we need to propagate this into the inode flags whenever an inode is instantiated so that the per-inode checks throughout the code Do The Right Thing. Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Brian Foster <bfoster@redhat.com> Signed-off-by: Dave Chinner <david@fromorbit.com>
-rw-r--r--fs/xfs/xfs_iops.c24
-rw-r--r--fs/xfs/xfs_mount.h2
-rw-r--r--fs/xfs/xfs_super.c25
3 files changed, 37 insertions, 14 deletions
diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c
index 0994f95c368f..3e8d32d41f35 100644
--- a/fs/xfs/xfs_iops.c
+++ b/fs/xfs/xfs_iops.c
@@ -1195,22 +1195,22 @@ xfs_diflags_to_iflags(
1195 struct inode *inode, 1195 struct inode *inode,
1196 struct xfs_inode *ip) 1196 struct xfs_inode *ip)
1197{ 1197{
1198 if (ip->i_d.di_flags & XFS_DIFLAG_IMMUTABLE) 1198 uint16_t flags = ip->i_d.di_flags;
1199
1200 inode->i_flags &= ~(S_IMMUTABLE | S_APPEND | S_SYNC |
1201 S_NOATIME | S_DAX);
1202
1203 if (flags & XFS_DIFLAG_IMMUTABLE)
1199 inode->i_flags |= S_IMMUTABLE; 1204 inode->i_flags |= S_IMMUTABLE;
1200 else 1205 if (flags & XFS_DIFLAG_APPEND)
1201 inode->i_flags &= ~S_IMMUTABLE;
1202 if (ip->i_d.di_flags & XFS_DIFLAG_APPEND)
1203 inode->i_flags |= S_APPEND; 1206 inode->i_flags |= S_APPEND;
1204 else 1207 if (flags & XFS_DIFLAG_SYNC)
1205 inode->i_flags &= ~S_APPEND;
1206 if (ip->i_d.di_flags & XFS_DIFLAG_SYNC)
1207 inode->i_flags |= S_SYNC; 1208 inode->i_flags |= S_SYNC;
1208 else 1209 if (flags & XFS_DIFLAG_NOATIME)
1209 inode->i_flags &= ~S_SYNC;
1210 if (ip->i_d.di_flags & XFS_DIFLAG_NOATIME)
1211 inode->i_flags |= S_NOATIME; 1210 inode->i_flags |= S_NOATIME;
1212 else 1211 /* XXX: Also needs an on-disk per inode flag! */
1213 inode->i_flags &= ~S_NOATIME; 1212 if (ip->i_mount->m_flags & XFS_MOUNT_DAX)
1213 inode->i_flags |= S_DAX;
1214} 1214}
1215 1215
1216/* 1216/*
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index 8c995a2ccb6f..cd44e88efa53 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -179,6 +179,8 @@ typedef struct xfs_mount {
179 allocator */ 179 allocator */
180#define XFS_MOUNT_NOATTR2 (1ULL << 25) /* disable use of attr2 format */ 180#define XFS_MOUNT_NOATTR2 (1ULL << 25) /* disable use of attr2 format */
181 181
182#define XFS_MOUNT_DAX (1ULL << 62) /* TEST ONLY! */
183
182 184
183/* 185/*
184 * Default minimum read and write sizes. 186 * Default minimum read and write sizes.
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index 858e1e62bbaa..1fb16562c159 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -112,6 +112,8 @@ static struct xfs_kobj xfs_dbg_kobj; /* global debug sysfs attrs */
112#define MNTOPT_DISCARD "discard" /* Discard unused blocks */ 112#define MNTOPT_DISCARD "discard" /* Discard unused blocks */
113#define MNTOPT_NODISCARD "nodiscard" /* Do not discard unused blocks */ 113#define MNTOPT_NODISCARD "nodiscard" /* Do not discard unused blocks */
114 114
115#define MNTOPT_DAX "dax" /* Enable direct access to bdev pages */
116
115/* 117/*
116 * Table driven mount option parser. 118 * Table driven mount option parser.
117 * 119 *
@@ -363,6 +365,10 @@ xfs_parseargs(
363 mp->m_flags |= XFS_MOUNT_DISCARD; 365 mp->m_flags |= XFS_MOUNT_DISCARD;
364 } else if (!strcmp(this_char, MNTOPT_NODISCARD)) { 366 } else if (!strcmp(this_char, MNTOPT_NODISCARD)) {
365 mp->m_flags &= ~XFS_MOUNT_DISCARD; 367 mp->m_flags &= ~XFS_MOUNT_DISCARD;
368#ifdef CONFIG_FS_DAX
369 } else if (!strcmp(this_char, MNTOPT_DAX)) {
370 mp->m_flags |= XFS_MOUNT_DAX;
371#endif
366 } else { 372 } else {
367 xfs_warn(mp, "unknown mount option [%s].", this_char); 373 xfs_warn(mp, "unknown mount option [%s].", this_char);
368 return -EINVAL; 374 return -EINVAL;
@@ -452,8 +458,8 @@ done:
452} 458}
453 459
454struct proc_xfs_info { 460struct proc_xfs_info {
455 int flag; 461 uint64_t flag;
456 char *str; 462 char *str;
457}; 463};
458 464
459STATIC int 465STATIC int
@@ -474,6 +480,7 @@ xfs_showargs(
474 { XFS_MOUNT_GRPID, "," MNTOPT_GRPID }, 480 { XFS_MOUNT_GRPID, "," MNTOPT_GRPID },
475 { XFS_MOUNT_DISCARD, "," MNTOPT_DISCARD }, 481 { XFS_MOUNT_DISCARD, "," MNTOPT_DISCARD },
476 { XFS_MOUNT_SMALL_INUMS, "," MNTOPT_32BITINODE }, 482 { XFS_MOUNT_SMALL_INUMS, "," MNTOPT_32BITINODE },
483 { XFS_MOUNT_DAX, "," MNTOPT_DAX },
477 { 0, NULL } 484 { 0, NULL }
478 }; 485 };
479 static struct proc_xfs_info xfs_info_unset[] = { 486 static struct proc_xfs_info xfs_info_unset[] = {
@@ -1507,6 +1514,20 @@ xfs_fs_fill_super(
1507 if (XFS_SB_VERSION_NUM(&mp->m_sb) == XFS_SB_VERSION_5) 1514 if (XFS_SB_VERSION_NUM(&mp->m_sb) == XFS_SB_VERSION_5)
1508 sb->s_flags |= MS_I_VERSION; 1515 sb->s_flags |= MS_I_VERSION;
1509 1516
1517 if (mp->m_flags & XFS_MOUNT_DAX) {
1518 xfs_warn(mp,
1519 "DAX enabled. Warning: EXPERIMENTAL, use at your own risk");
1520 if (sb->s_blocksize != PAGE_SIZE) {
1521 xfs_alert(mp,
1522 "Filesystem block size invalid for DAX Turning DAX off.");
1523 mp->m_flags &= ~XFS_MOUNT_DAX;
1524 } else if (!sb->s_bdev->bd_disk->fops->direct_access) {
1525 xfs_alert(mp,
1526 "Block device does not support DAX Turning DAX off.");
1527 mp->m_flags &= ~XFS_MOUNT_DAX;
1528 }
1529 }
1530
1510 error = xfs_mountfs(mp); 1531 error = xfs_mountfs(mp);
1511 if (error) 1532 if (error)
1512 goto out_filestream_unmount; 1533 goto out_filestream_unmount;