From: Ira Weiny <ira.we...@intel.com> Switching between DAX and non-DAX on a file is racy with respect to data operations. However, if no data is involved the flag is safe to switch.
Allow toggling the physical flag if a file is empty. The file length check is not racy with respect to other operations as it is performed under XFS_MMAPLOCK_EXCL and XFS_IOLOCK_EXCL locks. Signed-off-by: Ira Weiny <ira.we...@intel.com> --- fs/xfs/xfs_ioctl.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c index d3a7340d3209..3839684c249b 100644 --- a/fs/xfs/xfs_ioctl.c +++ b/fs/xfs/xfs_ioctl.c @@ -33,6 +33,7 @@ #include "xfs_sb.h" #include "xfs_ag.h" #include "xfs_health.h" +#include "libxfs/xfs_dir2.h" #include <linux/mount.h> #include <linux/namei.h> @@ -1232,12 +1233,10 @@ xfs_diflags_to_linux( inode->i_flags |= S_NOATIME; else inode->i_flags &= ~S_NOATIME; -#if 0 /* disabled until the flag switching races are sorted out */ if (xflags & FS_XFLAG_DAX) inode->i_flags |= S_DAX; else inode->i_flags &= ~S_DAX; -#endif } static int @@ -1320,6 +1319,12 @@ xfs_ioctl_setattr_dax_invalidate( /* lock, flush and invalidate mapping in preparation for flag change */ xfs_ilock(ip, XFS_MMAPLOCK_EXCL | XFS_IOLOCK_EXCL); + + if (i_size_read(inode) != 0) { + error = -EOPNOTSUPP; + goto out_unlock; + } + error = filemap_write_and_wait(inode->i_mapping); if (error) goto out_unlock; -- 2.20.1