On Mon, Sep 30, 2024 at 12:54:37PM +0000, John Garry wrote: > Validate that an atomic write adheres to length/offset rules. Currently > we can only write a single FS block. > > 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, > 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 | 7 +++++++ > 1 file changed, 7 insertions(+) > > diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c > index 412b1d71b52b..fa6a44b88ecc 100644 > --- a/fs/xfs/xfs_file.c > +++ b/fs/xfs/xfs_file.c > @@ -688,6 +688,13 @@ xfs_file_dio_write( > struct xfs_buftarg *target = xfs_inode_buftarg(ip); > size_t count = iov_iter_count(from); > > + if (iocb->ki_flags & IOCB_ATOMIC) { > + if (count != ip->i_mount->m_sb.sb_blocksize) > + return -EINVAL; > + if (!generic_atomic_write_valid(iocb, from)) > + return -EINVAL; > + } Does xfs_file_write_iter need a catch-all so that we don't fall back to buffered write for a directio write that returns ENOTBLK? if (iocb->ki_flags & IOCB_DIRECT) { /* * Allow a directio write to fall back to a buffered * write *only* in the case that we're doing a reflink * CoW. In all other directio scenarios we do not * allow an operation to fall back to buffered mode. */ ret = xfs_file_dio_write(iocb, from); if (ret != -ENOTBLK || (iocb->ki_flags & IOCB_ATOMIC)) return ret; } IIRC iomap_dio_rw can return ENOTBLK if pagecache invalidation fails for the region that we're trying to directio write. --D > + > /* 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 > >