Re: [PATCH] xfs: coalesce contiguous unwritten suffix into iomap for NOWAIT writes
From: Pankaj Raghav (Samsung)
Date: Mon Jun 08 2026 - 05:52:06 EST
On Fri, May 29, 2026 at 03:11:00PM -0400, Brandon Allard wrote:
> In append-only direct-IO workloads with fallocate(with KEEP_SIZE +
> ZERO_RANGE) writes can span the written/unwritten boundary of the
> preallocated extent. This is from callers needing to overwrite the
> previously written block if the last write didn't completely fill it.
>
> Prior to commit 883a790a8440 ("xfs: don't allow NOWAIT DIO across extent
> boundaries") these writes succeeded by issuing two bios: one against the
Also add this info in as Fixes tag.
> NORM head, one against the UNWRITTEN tail. That commit closed off the
> two-bio path to prevent NOWAIT callers from observing short writes when
> one bio succeeded and another returned -EAGAIN. The side effect is that
> the workload above now returns -EAGAIN on the spanning write.
>
> static bool
> xfs_bmap_hw_atomic_write_possible(
> struct xfs_inode *ip,
> @@ -961,7 +996,14 @@ xfs_direct_write_iomap_begin(
> */
> if (flags & (IOMAP_NOWAIT | IOMAP_OVERWRITE_ONLY)) {
I am wondering if adding this imap_extend_into_unwritten() inside
(IOMAP_NOWAIT | IOMAP_OVERWRITE_ONLY) will have some side effect in the
next check for IOMAP_OVERWRITE_ONLY [1]:
if (flags & IOMAP_OVERWRITE_ONLY) {
error = -EAGAIN;
if (imap.br_state != XFS_EXT_NORM &&
((offset | length) & mp->m_blockmask))
goto out_unlock;
}
We are changing the br_state to NORM->UNWRITTEN. Should you guard the
imap_extend_into_unwritten() only for NOWAIT case? Did you also test
this scenario?
> error = -EAGAIN;
> - if (!imap_spans_range(&imap, offset_fsb, end_fsb))
> + /*
> + * Sequential append workloads with adaptive preallocation can
> + * span the NORM->UNWRITTEN boundary that unwritten conversion
> + * leaves behind. Try to coalesce the next contiguous unwritten record
> + * into imap before returning -EAGAIN.
> + */
> + if (!imap_spans_range(&imap, offset_fsb, end_fsb) &&
> + !imap_extend_into_unwritten(ip, &imap, end_fsb))
> goto out_unlock;
> }
>
> --
> 2.48.1
>
[1] https://elixir.bootlin.com/linux/v7.0.11/source/fs/xfs/xfs_iomap.c#L974
--
Pankaj