> --- a/fs/xfs/xfs_bmap_util.c > +++ b/fs/xfs/xfs_bmap_util.c > @@ -977,10 +977,14 @@ xfs_free_file_space( > if (offset + len > XFS_ISIZE(ip)) > len = XFS_ISIZE(ip) - offset; > error = iomap_zero_range(VFS_I(ip), offset, len, NULL, > - &xfs_buffered_write_iomap_ops); > + IS_DAX(VFS_I(ip)) ? > + &xfs_direct_write_iomap_ops : &xfs_buffered_write_iomap_ops); > if (error) > return error; > + if (xfs_is_reflink_inode(ip)) > + xfs_reflink_end_cow(ip, offset, len);
Maybe we need to add (back) and xfs_zero_range helper that encapsulates the details? > trace_xfs_file_dax_write(ip, count, pos); > ret = dax_iomap_rw(iocb, from, &xfs_direct_write_iomap_ops); > - if (ret > 0 && iocb->ki_pos > i_size_read(inode)) { > - i_size_write(inode, iocb->ki_pos); > - error = xfs_setfilesize(ip, pos, ret); > + if (ret > 0) { > + if (iocb->ki_pos > i_size_read(inode)) { > + i_size_write(inode, iocb->ki_pos); > + error = xfs_setfilesize(ip, pos, ret); > + } > + if (xfs_is_cow_inode(ip)) > + xfs_reflink_end_cow(ip, pos, ret); Nitpick, but I'd just goto out for ret <= 0 to reduce the indentation a bit. > } > out: > xfs_iunlock(ip, iolock); > diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c > index 7b9ff824e82d..d6d4cc0f084e 100644 > --- a/fs/xfs/xfs_iomap.c > +++ b/fs/xfs/xfs_iomap.c > @@ -765,13 +765,14 @@ xfs_direct_write_iomap_begin( > goto out_unlock; > > if (imap_needs_cow(ip, flags, &imap, nimaps)) { > + bool need_convert = flags & IOMAP_DIRECT || IS_DAX(inode); > error = -EAGAIN; > if (flags & IOMAP_NOWAIT) > goto out_unlock; > > /* may drop and re-acquire the ilock */ > error = xfs_reflink_allocate_cow(ip, &imap, &cmap, &shared, > - &lockmode, flags & IOMAP_DIRECT); > + &lockmode, need_convert); Why not: error = xfs_reflink_allocate_cow(ip, &imap, &cmap, &shared, &lockmode, (flags & IOMAP_DIRECT) || IS_DAX(inode)); ?