mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Daejun Park via B4 Relay <devnull+daejun7.park.samsung.com@kernel.org>
To: Carlos Maiolino <cem@kernel.org>, linux-xfs@vger.kernel.org
Cc: Christoph Hellwig <hch@lst.de>,
	"Darrick J. Wong" <djwong@kernel.org>,
	 Dave Chinner <dgc@kernel.org>, Chuck Lever <cel@kernel.org>,
	 Jeff Layton <jlayton@kernel.org>, Dai Ngo <Dai.Ngo@oracle.com>,
	 Sergey Bashirov <sergeybashirov@gmail.com>,
	 Andrey Albershteyn <aalbersh@kernel.org>,
	linux-nfs@vger.kernel.org,  linux-kernel@vger.kernel.org,
	stable@vger.kernel.org,  Daejun Park <daejun7.park@samsung.com>
Subject: [PATCH v4 5/9] xfs: limit the count of a pNFS write allocation to one extent
Date: Tue, 20 Oct 2026 12:08:48 +0900	[thread overview]
Message-ID: <20261020-xfs-pnfs-batch-v4-5-9230fa2ca4a4@samsung.com> (raw)
In-Reply-To: <20261020-xfs-pnfs-batch-v4-0-9230fa2ca4a4@samsung.com>

From: Daejun Park <daejun7.park@samsung.com>

xfs_fs_map_blocks() asks xfs_iomap_write_direct() to allocate from the
start of a hole to the end of the range of a LAYOUTGET, which a client
chooses, or to the end of the hole if the range ends before EOF.
xfs_iomap_write_direct() reserves blocks for that whole count, in an
unsigned int, but xfs_bmapi_write() maps at most XFS_MAX_BMBT_EXTLEN
blocks in one mapping. A count of about 2^32 blocks or more wraps the
reservation. If it wraps to a few blocks, the allocation uses more
blocks than the transaction reserved, and xfs_trans_mod_sb() shuts the
filesystem down. With 4 KiB blocks, an RW LAYOUTGET at offset 0 of an
empty file for 16 TiB does it.

Direct I/O, DAX and buffered writes with an extent size hint never ask
for that much, as xfs_direct_write_iomap_begin() limits them to 1024
pages to keep the count below 32 bits. Limit a pNFS allocation to
XFS_MAX_BMBT_EXTLEN blocks, as xfs_alloc_file_space() limits each of
its reservations for the same reason. This shrinks the reservation; the
mapping that xfs_bmapi_write() returns stays the same. nfsd asks again
for the rest of the range since commit cc6c40e09d7b ("NFSD/blocklayout:
Support multiple extents per LAYOUTGET"), while the reply has room for
another extent; before that, the layout ends with the extent and the
client asks again.

An RW LAYOUTGET for more than the free space used to fail with
NFS4ERR_NOSPC before anything was allocated, as the first call that
allocates tried to reserve blocks for all of it. Where nfsd maps one
extent per LAYOUTGET, it now gets the first extent. Where nfsd asks
again, it allocates one extent after the other: if the reply fills up
first (at most 92 extents with 4 KiB pages), the client gets those
extents, and if fewer than XFS_MAX_BMBT_EXTLEN blocks are free first,
nfsd fails the LAYOUTGET. The blocks it allocated stay past EOF, as
the inode is marked preallocated; xfs_alloc_file_space() likewise
keeps what it allocated when it runs out of space.

With pynfs as the client and a 32 GiB XFS, an RW LAYOUTGET at offset 0
of an empty file for 16 TiB shut the filesystem down: "Corruption of
in-memory data (0x8) detected at xfs_trans_mod_sb". With this patch it
gets NFS4ERR_NOSPC, also with XFS_DEBUG, XFS keeps running, and less
than 8 GiB of the filesystem, one extent's worth, is left free. One
for 100 GiB ends the same way, where it got NFS4ERR_NOSPC with nothing
allocated before. One for 16 GiB, which fits, is granted the same
three extents as before.

Suggested-by: Darrick J. Wong <djwong@kernel.org>
Link: https://lore.kernel.org/r/20261008154017.GO2705364@frogsfrogsfrogs
Suggested-by: Christoph Hellwig <hch@lst.de>
Link: https://lore.kernel.org/r/20261015060932.GD14035@lst.de
Fixes: 527851124d10 ("xfs: implement pNFS export operations")
Cc: stable@vger.kernel.org
Signed-off-by: Daejun Park <daejun7.park@samsung.com>
---
 fs/xfs/xfs_pnfs.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/fs/xfs/xfs_pnfs.c b/fs/xfs/xfs_pnfs.c
index 19eb18e129..401a790299 100644
--- a/fs/xfs/xfs_pnfs.c
+++ b/fs/xfs/xfs_pnfs.c
@@ -224,6 +224,14 @@ xfs_fs_map_blocks(
 		else if (nimaps && imap.br_startblock == HOLESTARTBLOCK)
 			end_fsb = min(end_fsb, imap.br_startoff +
 					       imap.br_blockcount);
+		/*
+		 * xfs_bmapi_write() maps at most XFS_MAX_BMBT_EXTLEN blocks
+		 * in one mapping, so don't reserve blocks for more. The
+		 * range comes from a client, and its block count may not
+		 * even fit the 32-bit reservation. The rest of the range
+		 * is mapped by a later call.
+		 */
+		end_fsb = min(end_fsb, offset_fsb + XFS_MAX_BMBT_EXTLEN);
 		xfs_iunlock(ip, lock_flags);
 
 		error = xfs_iomap_write_direct(ip, offset_fsb,

-- 
2.43.0



  parent reply	other threads:[~2026-10-20  3:08 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-20  3:08 [PATCH v4 0/9] xfs: pNFS block layout fixes Daejun Park via B4 Relay
2026-10-20  3:08 ` [PATCH v4 1/9] xfs: mark the inode preallocated for pNFS write layouts past EOF Daejun Park via B4 Relay
2026-10-22 12:41   ` Pankaj Raghav (Samsung)
2026-10-20  3:08 ` [PATCH v4 2/9] xfs: add a flag to convert unwritten extents without allocating blocks Daejun Park via B4 Relay
2026-10-22 12:43   ` Pankaj Raghav (Samsung)
2026-10-20  3:08 ` [PATCH v4 3/9] xfs: refuse a pNFS LAYOUTCOMMIT of a range without blocks Daejun Park via B4 Relay
2026-10-20  3:08 ` [PATCH v4 4/9] xfs: clamp a pNFS LAYOUTCOMMIT extent before computing its end Daejun Park via B4 Relay
2026-10-22 12:44   ` Pankaj Raghav (Samsung)
2026-10-20  3:08 ` Daejun Park via B4 Relay [this message]
2026-10-22 13:02   ` [PATCH v4 5/9] xfs: limit the count of a pNFS write allocation to one extent Pankaj Raghav (Samsung)
2026-10-20  3:08 ` [PATCH v4 6/9] xfs: clamp the pNFS layout range to the maximum file size Daejun Park via B4 Relay
2026-10-23 11:10   ` Pankaj Raghav (Samsung)
2026-10-20  3:08 ` [PATCH v4 7/9] xfs: take the invalidate lock while mapping a pNFS layout Daejun Park via B4 Relay
2026-10-20  3:08 ` [PATCH v4 8/9] xfs: add datasync and log_flushed arguments to xfs_log_force_inode() Daejun Park via B4 Relay
2026-10-20  3:08 ` [PATCH v4 9/9] xfs: make pNFS LAYOUTCOMMIT stable the way fdatasync does Daejun Park via B4 Relay

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261020-xfs-pnfs-batch-v4-5-9230fa2ca4a4@samsung.com \
    --to=devnull+daejun7.park.samsung.com@kernel.org \
    --cc=Dai.Ngo@oracle.com \
    --cc=aalbersh@kernel.org \
    --cc=cel@kernel.org \
    --cc=cem@kernel.org \
    --cc=daejun7.park@samsung.com \
    --cc=dgc@kernel.org \
    --cc=djwong@kernel.org \
    --cc=hch@lst.de \
    --cc=jlayton@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-nfs@vger.kernel.org \
    --cc=linux-xfs@vger.kernel.org \
    --cc=sergeybashirov@gmail.com \
    --cc=stable@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®