RE:(2) [PATCH 7/8] xfs: map the whole range of a pNFS layout in one ->map_blocks call
From: Daejun Park
Date: Sun Oct 11 2026 - 22:50:43 EST
On Thu, Oct 08, 2026 at 12:37:46PM -0400, Chuck Lever wrote:
> The same freeing can happen to blocks a client holds a write layout
> for, AFAICS. But that is not new. Commit 527851124d10 handed out the
> same blocks.
>
> This is however the patch where a fix could go.
Yes. xfs_fs_map_blocks() marks the inode XFS_DIFLAG_PREALLOC only when
it allocates, so a write layout past EOF over blocks that buffered
writes preallocated leaves the inode unmarked, and blockgc frees those
blocks while the client holds them.
With pynfs as the client on nfsd-testing: a file grown to 1 MiB by two
buffered writes on the server had 960 KiB preallocated past EOF, and an
RW LAYOUTGET for that range got it as one INVALID_DATA extent, without
the inode being marked. About 300 seconds later, with the default
speculative_prealloc_lifetime, blockgc freed the 960 KiB while the
layout was still held. Small files written on the server after that, and
after a sync so that the freed extents were no longer busy, got those
blocks, and the client's write through the layout replaced 978944 bytes
of their data. The LAYOUTCOMMIT then got NFS4ERR_IO, as
xfs_iomap_write_unwritten() allocated for the hole with no blocks
reserved, and XFS shut down with "Corruption of in-memory data (0x8)
detected at xfs_trans_mod_sb", in six runs out of six. Committing 30
seconds after the LAYOUTGET, before blockgc, works.
I would rather fix it on its own, before the series, so that it can go
to stable: mark the inode as preallocated also when a write mapping
ends past EOF and nothing was allocated. With that, the same test keeps
the blocks and the LAYOUTCOMMIT succeeds. I will send it to the XFS
list, and patch 7 of v2 will keep the check for the mappings of the
whole call.