]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
xfs: force the log after remapping a synchronous-writes file
authorDarrick J. Wong <darrick.wong@oracle.com>
Fri, 4 Sep 2020 17:20:16 +0000 (10:20 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 29 Oct 2020 09:07:38 +0000 (10:07 +0100)
[ Upstream commit 5ffce3cc22a0e89813ed0c7162a68b639aef9ab6 ]

Commit 5833112df7e9 tried to make it so that a remap operation would
force the log out to disk if the filesystem is mounted with mandatory
synchronous writes.  Unfortunately, that commit failed to handle the
case where the inode or the file descriptor require mandatory
synchronous writes.

Refactor the check into into a helper that will look for all three
conditions, and now we can treat reflink just like any other synchronous
write.

Fixes: 5833112df7e9 ("xfs: reflink should force the log out if mounted with wsync")
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
fs/xfs/xfs_file.c

index 4d7385426149c87440e3801335f02a83cd7ae1f5..3ebc73ccc133734bad04b0a9a0801d940326f7dc 100644 (file)
@@ -1005,6 +1005,21 @@ xfs_file_fadvise(
        return ret;
 }
 
+/* Does this file, inode, or mount want synchronous writes? */
+static inline bool xfs_file_sync_writes(struct file *filp)
+{
+       struct xfs_inode        *ip = XFS_I(file_inode(filp));
+
+       if (ip->i_mount->m_flags & XFS_MOUNT_WSYNC)
+               return true;
+       if (filp->f_flags & (__O_SYNC | O_DSYNC))
+               return true;
+       if (IS_SYNC(file_inode(filp)))
+               return true;
+
+       return false;
+}
+
 STATIC loff_t
 xfs_file_remap_range(
        struct file             *file_in,
@@ -1062,7 +1077,7 @@ xfs_file_remap_range(
        if (ret)
                goto out_unlock;
 
-       if (mp->m_flags & XFS_MOUNT_WSYNC)
+       if (xfs_file_sync_writes(file_in) || xfs_file_sync_writes(file_out))
                xfs_log_force_inode(dest);
 out_unlock:
        xfs_reflink_remap_unlock(file_in, file_out);