All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/2] xfs: refuse pNFS LAYOUTCOMMITs of ranges without blocks
@ 2026-10-14  3:42 ` Daejun Park via B4 Relay
  0 siblings, 0 replies; 9+ messages in thread
From: Daejun Park @ 2026-10-14  3:42 UTC (permalink / raw)
  To: Carlos Maiolino, linux-xfs
  Cc: Christoph Hellwig, Darrick J. Wong, Dave Chinner, Chuck Lever,
	Jeff Layton, Dai Ngo, Sergey Bashirov, linux-nfs,
	Andrey Albershteyn, linux-kernel, stable, Daejun Park

xfs_fs_commit_blocks() converts whatever range a pNFS client commits.
For a range without blocks, the conversion allocates blocks that the
transaction did not reserve and shuts XFS down, or maps blocks that
nobody wrote into the file. Patch 1 refuses such a commit with a new
XFS_BMAPI_CONVERT_ONLY flag for xfs_bmapi_write(). Patch 2 clamps the
committed length before adding it to the offset, as the sum can wrap.

Changes in v2:
- Refuse the hole in xfs_bmapi_write() with a new
  XFS_BMAPI_CONVERT_ONLY flag, as Christoph suggested, instead of
  checking all the ranges first. A range before the hole is now
  converted before the commit fails; v1 converted nothing.
- Drop the blockgc case from the message: with "xfs: mark the inode
  preallocated for pNFS write layouts past EOF" [1], blockgc keeps
  those blocks.
- Split the length clamp into patch 2. It fixes a separate bug.
- Link to v1: https://lore.kernel.org/r/20261013-xfs-pnfs-commit-hole-v1-1-740912db9102@samsung.com

XFS_BMAPI_CONVERT_ONLY takes bit 12 of the bmapi flags, which "xfs: add
XFS_BMAPI_UNWRITTEN to unmap unwritten extents in __xfs_bunmapi()" in
the fs-verity series [2] also uses. Whichever goes in second needs to
move to bit 13. The name was used before, by a flag that commit
26b91c728b2d ("xfs: make COW fork unwritten extent conversions more
robust") removed. That flag only skipped the allocation and went on to
map the hole; this one stops before it.

This series and v2 of "xfs: make pNFS LAYOUTCOMMIT stable the way
fdatasync does", sent at the same time, both change
xfs_fs_commit_blocks(). They apply in either order.

Tested on nfsd-testing d918c664efd5 with the same two patches on top,
in QEMU guests with KASAN and lockdep. The block layout was on an
NVMe/TCP namespace exported by nvmet. The client was pynfs, except for
fstests, which ran on the Linux NFSv4.2 client. XFS for-next also has
commit e3c682dd1130 ("xfs: map pNFS layouts to the end of the extent
again"), which nfsd-testing does not have. xfs_bmapi_write(),
xfs_iomap_write_unwritten(), xfs_fs_commit_blocks() and
xfs_dio_write_end_io() are the same in both trees, and so is the
changed line in xfs_end_ioend_write().

 - A LAYOUTCOMMIT of a 64 KiB hole: NFS4ERR_IO and shutdown without the
   series. With it, NFS4ERR_IO, no shutdown and nothing allocated, in 5
   runs.
 - A LAYOUTCOMMIT of a 4 KiB hole: NFS4_OK and a written block in the
   file without the series. With it, NFS4ERR_IO and nothing allocated.
 - The laid-out range and the 64 KiB hole in one LAYOUTCOMMIT: shutdown
   without the series. With it, NFS4ERR_IO, and fiemap on the server
   shows the laid-out range written and nothing allocated in the hole.
 - An extent at 4 KiB with a length of 2^64 - 4 KiB: NFS4ERR_IO and
   "nfsd: non-standard errno: -63" without the series, and with
   XFS_DEBUG "Assertion failed: bma.nallocs >= *nmap" in
   xfs_bmapi_write(). With patch 1 alone, the same nfsd warning. With
   both, NFS4ERR_IO and no warning, also with XFS_DEBUG.
 - Blocks past EOF freed by blockgc under a layout, without [1]: the
   LAYOUTCOMMIT after the client's write shut XFS down without the
   series and got NFS4ERR_IO with it.
 - pynfs block and blockextent, also with XFS_DEBUG: same as without
   the series (BLOCK3 fails either way, on a bug in the test).
 - fstests generic/075, 091 and 263 over the block layout: 075 fails
   with an fsx size error with and without the series, and XFS refused
   none of the 10384 LAYOUTCOMMITs with it.
 - O_DIRECT and buffered writes into preallocated space on the
   server's own XFS, the other callers of xfs_iomap_write_unwritten():
   converted as before, on the XFS_DEBUG kernel.
 - fstests -g quick on a local XFS (mkfs.xfs defaults from xfsprogs
   6.6.0, 10 GiB TEST and SCRATCH devices, KASAN and lockdep off),
   with and without the series: 1017 tests ran, and the same 5 failed
   either way (generic/453, 454, 563, 794 and xfs/261). Also the same
   with both series applied.
 - W=1 builds of the changed files after each patch, on XFS for-next
   0be6da616ab5 and on nfsd-testing: no warnings.

No test reaches the delalloc case of the new flag. It takes the same
branch as a hole.

For stable, patch 2 applies to every LTS tree, but should not go in
without patch 1: on its own, the clamped extent reaches the hole and
shuts XFS down, as a LAYOUTCOMMIT of a hole already does there. Patch 1
needs a backport for 7.2 and older, which do not have
fs/xfs/xfs_ioend.c.

xfs_pnfs_validate_isize() reads the extents under XFS_ILOCK_SHARED,
which xfs_iread_extents() does not allow when they are not loaded yet.
That needs a separate fix.

[1] https://lore.kernel.org/r/20261012-xfs-pnfs-eof-prealloc-v1-1-e4864d917a00@samsung.com
[2] https://lore.kernel.org/r/20261002223705.2175542-14-aalbersh@kernel.org

---
Daejun Park (2):
      xfs: refuse a pNFS LAYOUTCOMMIT of a range without blocks
      xfs: clamp a pNFS LAYOUTCOMMIT extent before computing its end

 fs/xfs/libxfs/xfs_bmap.c | 14 ++++++++++++++
 fs/xfs/libxfs/xfs_bmap.h | 10 +++++++++-
 fs/xfs/xfs_file.c        |  2 +-
 fs/xfs/xfs_ioend.c       |  2 +-
 fs/xfs/xfs_iomap.c       |  7 ++++---
 fs/xfs/xfs_iomap.h       |  3 ++-
 fs/xfs/xfs_pnfs.c        | 13 +++++++++----
 7 files changed, 40 insertions(+), 11 deletions(-)
---
base-commit: 0be6da616ab5031ea6419dc4fe0bf0e378fb6757
change-id: 20261012-xfs-pnfs-commit-hole-c30ae9a287f3

Best regards,
-- 
Daejun Park <daejun7.park@samsung.com>


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2026-10-14 13:09 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-14  3:42 [PATCH v2 0/2] xfs: refuse pNFS LAYOUTCOMMITs of ranges without blocks Daejun Park
2026-10-14  3:42 ` Daejun Park via B4 Relay
2026-10-14  3:42 ` [PATCH v2 1/2] xfs: refuse a pNFS LAYOUTCOMMIT of a range " Daejun Park
2026-10-14  3:42   ` Daejun Park via B4 Relay
2026-10-14 13:08   ` Christoph Hellwig
2026-10-14  3:42 ` [PATCH v2 2/2] xfs: clamp a pNFS LAYOUTCOMMIT extent before computing its end Daejun Park
2026-10-14  3:42   ` Daejun Park via B4 Relay
2026-10-14 13:09   ` Christoph Hellwig
2026-10-14 13:05 ` [PATCH v2 0/2] xfs: refuse pNFS LAYOUTCOMMITs of ranges without blocks Christoph Hellwig

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.