Validate that an atomic write adheres to length/offset rules. Since we require extent alignment for atomic writes, this effectively also enforces that the BIO which iomap produces is aligned. For an IOCB with IOCB_ATOMIC set to get as far as xfs_file_dio_write(), FMODE_CAN_ATOMIC_WRITE will need to be set for the file; for this, FORCEALIGN and also ATOMICWRITES flags would also need to be set for the inode. Signed-off-by: John Garry <john.g.garry@xxxxxxxxxx> --- fs/xfs/xfs_file.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index 24fe3c2e03da..eeb267ae2bf2 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c @@ -695,12 +695,21 @@ xfs_file_dio_write( struct kiocb *iocb, struct iov_iter *from) { - struct xfs_inode *ip = XFS_I(file_inode(iocb->ki_filp)); + struct inode *inode = file_inode(iocb->ki_filp); + struct xfs_inode *ip = XFS_I(inode); struct xfs_buftarg *target = xfs_inode_buftarg(ip); size_t count = iov_iter_count(from); + struct xfs_mount *mp = ip->i_mount; bool unaligned; u64 unitsize; + if (iocb->ki_flags & IOCB_ATOMIC) { + if (!generic_atomic_write_valid_size(iocb->ki_pos, from, + i_blocksize(inode), XFS_FSB_TO_B(mp, ip->i_extsize))) { + return -EINVAL; + } + } + /* direct I/O must be aligned to device logical sector size */ if ((iocb->ki_pos | count) & target->bt_logical_sectormask) return -EINVAL; -- 2.31.1