Re: [PATCH v2 13/14] fs: xfs: Validate atomic writes

Dave Chinner
2024-03-06T21:22:57Z

On Mon, Mar 04, 2024 at 01:04:27PM +0000, John Garry wrote:
> 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.
>
> Signed-off-by: John Garry <john.g.garry@oracle.com>
> ---
> 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 d0bd9d5f596c..cecc5428fd7c 100644
> --- a/fs/xfs/xfs_file.c
> +++ b/fs/xfs/xfs_file.c
> @@ -709,11 +709,20 @@ 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_mount *mp = ip->i_mount;
> struct xfs_buftarg *target = xfs_inode_buftarg(ip);
> size_t count = iov_iter_count(from);
>
> + if (iocb->ki_flags & IOCB_ATOMIC) {
> + if (!generic_atomic_write_valid(iocb->ki_pos, from,
> + i_blocksize(inode),

a.k.a. mp->m_bsize. If you use that here, then the need for the VFS
inode goes away, too.

> + XFS_FSB_TO_B(mp, xfs_get_extsz(ip)))) {
> + return -EINVAL;
> + }
> + }

Also, I think the checks are the wrong way around here. We can only
do IOCB_ATOMIC IO on force aligned/atomic write inodes, so shouldn't
we be checking that first, then basing the rest of the checks on the
assumption that atomic writes are allowed and have been set up
correctly on the inode? i.e.

if (iocb->ki_flags & IOCB_ATOMIC) {
if (!xfs_inode_has_atomicwrites(ip))
return -EINVAL;
if (!generic_atomic_write_valid(iocb->ki_pos, from,
mp->m_bsize, ip->i_extsize))
return -EINVAL;
}

because xfs_inode_has_atomicwrites() implies ip->i_extsize has been
set to the required atomic IO size?

Cheers,

Dave.
--
Dave Chinner
david@fromorbit.com