summaryrefslogtreecommitdiff
path: root/fs/xfs
diff options
context:
space:
mode:
authorDave Chinner <dchinner@redhat.com>2016-02-29 22:41:33 (GMT)
committerDave Chinner <david@fromorbit.com>2016-02-29 22:41:33 (GMT)
commit64485437357dfdc9752495b3f496adfc5c816c6f (patch)
treef72baeebfa22e3319c1c5be99db8d83da944fc86 /fs/xfs
parent3a6a854a82fc1cf12c7f2095b80aff32c563b3ab (diff)
downloadlinux-64485437357dfdc9752495b3f496adfc5c816c6f.tar.xz
xfs: XFS_DIFLAG2_DAX limited by PAGE_SIZE
If the block size of a filesystem is not at least PAGE_SIZEd, then at this point in time DAX cannot be used due to the fact we can't guarantee extents are page sized or aligned without further work. Hence disallow setting the DAX flag on an inode if the block size is too small. Also, be defensive and check the block size when reading an inode in off disk. In future, we want to allow DAX to work on any filesystem, so this is temporary while we sort of the correct conbination of extent size hints and allocation alignment configurations needed to guarantee page sized and aligned extent allocation for DAX enabled files. Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Brian Foster <bfoster@redhat.com> Tested-by: Ross Zwisler <ross.zwisler@linux.intel.com> Signed-off-by: Dave Chinner <david@fromorbit.com>
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/xfs_ioctl.c12
-rw-r--r--fs/xfs/xfs_iops.c1
2 files changed, 9 insertions, 4 deletions
diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
index 55ec4d4..388b5b5 100644
--- a/fs/xfs/xfs_ioctl.c
+++ b/fs/xfs/xfs_ioctl.c
@@ -1080,11 +1080,15 @@ xfs_ioctl_setattr_dax_invalidate(
/*
* It is only valid to set the DAX flag on regular files and
- * directories. On directories it serves as an inherit hint.
+ * directories on filesystems where the block size is equal to the page
+ * size. On directories it serves as an inherit hint.
*/
- if ((fa->fsx_xflags & FS_XFLAG_DAX) &&
- !(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode)))
- return -EINVAL;
+ if (fa->fsx_xflags & FS_XFLAG_DAX) {
+ if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode)))
+ return -EINVAL;
+ if (ip->i_mount->m_sb.sb_blocksize != PAGE_SIZE)
+ return -EINVAL;
+ }
/* If the DAX state is not changing, we have nothing to do here. */
if ((fa->fsx_xflags & FS_XFLAG_DAX) && IS_DAX(inode))
diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c
index 5d4f973..f7386dc 100644
--- a/fs/xfs/xfs_iops.c
+++ b/fs/xfs/xfs_iops.c
@@ -1206,6 +1206,7 @@ xfs_diflags_to_iflags(
if (flags & XFS_DIFLAG_NOATIME)
inode->i_flags |= S_NOATIME;
if (S_ISREG(inode->i_mode) &&
+ ip->i_mount->m_sb.sb_blocksize == PAGE_SIZE &&
(ip->i_mount->m_flags & XFS_MOUNT_DAX ||
ip->i_d.di_flags2 & XFS_DIFLAG2_DAX))
inode->i_flags |= S_DAX;