Skip to contentSkip to conversation

xfs: reflink should flush after an unaligned directio cow write

PATCH In review Darrick J. Wong 2 participants 2 messages Nov 21, 2018 – Nov 22, 2018 XFS filesystem

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 xfs: reflink should flush after an unaligned directio cow write

From: Darrick J. Wong <[email protected]>

If userspace hands us a not-block-aligned directio write, we'll fall back to a buffered write for the read-modify-write operation. Unfortunately, we don't flush the page cache after a successful fallback CoW, which means we break userspace's expectation that the data has been sent to the drive. Fix that by upgrading the iocb to DSYNC so that the buffered CoW is synchronous.

---
 fs/xfs/xfs_file.c |    8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)
fs/xfs/xfs_file.c +7 -1
index e47425071e65..675da7e9c001 100644
@@ -692,6 +692,8 @@ xfs_file_write_iter(
 	struct xfs_inode	*ip = XFS_I(inode);
 	ssize_t			ret;
 	size_t			ocount = iov_iter_count(from);
+	bool			was_dsync = iocb->ki_flags & IOCB_DSYNC;
+	int			error;
 
 	XFS_STATS_INC(ip->i_mount, xs_write_calls);
 
@@ -714,9 +716,13 @@ xfs_file_write_iter(
 		ret = xfs_file_dio_aio_write(iocb, from);
 		if (ret != -EREMCHG)
 			return ret;
+		iocb->ki_flags |= IOCB_DSYNC;
 	}
 
-	return xfs_file_buffered_aio_write(iocb, from);
+	error = xfs_file_buffered_aio_write(iocb, from);
+	if (!was_dsync)
+		iocb->ki_flags &= ~IOCB_DSYNC;
+	return error;
 }
 
 static void
#1 lore raw
Quoted 7 lines · Darrick J. Wong

From: Darrick J. Wong <[email protected]>

If userspace hands us a not-block-aligned directio write, we'll fall back to a buffered write for the read-modify-write operation. Unfortunately, we don't flush the page cache after a successful fallback CoW, which means we break userspace's expectation that the data has been sent to the drive.

There is not such expectation. Even with O_DIRECT you need an explicit O_DSYNC to guarantee that. Note that generic_file_direct_write doesn't force O_DSYNC either.