xfs: XFS_DIFLAG2_DAX limited by PAGE_SIZE
authorDave Chinner <dchinner@redhat.com>
Mon, 29 Feb 2016 22:41:33 +0000 (09:41 +1100)
committerDave Chinner <david@fromorbit.com>
Mon, 29 Feb 2016 22:41:33 +0000 (09:41 +1100)
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>
fs/xfs/xfs_ioctl.c
fs/xfs/xfs_iops.c

index 55ec4d44d4ba270306af233bdae875b4d39a6516..388b5b5b67c9e01336f4dadd79f09b350c3ef288 100644 (file)
@@ -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))
index 5d4f9739d4a4c86fafbd37fa04be4336ed40f8a3..f7386dc10a205a79386472d62b0f549e172c6ffe 100644 (file)
@@ -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;