xfs: reflink should flush after an unaligned directio cow write
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
@@ -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
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.