All of lore.kernel.org
 help / color / mirror / Atom feed
From: Chris Mason <mason@kernel.org>
To: mason@kernel.org, tytso@mit.edu, cem@kernel.org,
	david@fromorbit.com, jack@suse.cz, djwong@kernel.org,
	josef@toxicpanda.com, hch@lst.de, linux-xfs@vger.kernel.org,
	linux-fsdevel@vger.kernel.org, linux-ext4@vger.kernel.org,
	tz2294@columbia.edu, brauner@kernel.org
Subject: [PATCH v8 13/15] xfs: resample the extsize hint after taking the ILOCK
Date: Wed, 11 Nov 2026 20:02:42 -0500	[thread overview]
Message-ID: <20261112010229.51029-14-mason@kernel.org> (raw)
In-Reply-To: <20261112010229.51029-1-mason@kernel.org>

A write fault on a file with an extent size hint can overrun its block
reservation and shut down the filesystem, if it races with a change of
the hint or of the realtime flag.

xfs_iomap_write_direct() sizes the reservation from the hint and the
flag before xfs_trans_alloc_inode() takes the ILOCK, and the allocator
reads both again under it. But a write fault only holds the MMAPLOCK,
and FS_IOC_FSSETXATTR changes both on a file with no blocks without it:

    write fault                         FS_IOC_FSSETXATTR
    ===========                         =================
    xfs_iomap_write_direct()
      hint is 1 block
      dblocks = 1 + bmbt blocks
                                        xfs_ilock(ILOCK_EXCL)
                                        hint = 4096 blocks
                                        xfs_iunlock(ILOCK_EXCL)
      xfs_trans_alloc_inode()
      xfs_bmapi_write()
        allocates 4096 blocks
        xfs_trans_mod_sb()
          t_blk_res_used > t_blk_res

The fix used here is to compare both with the values that sized the
reservation once the ILOCK is held, and to start over if either has
changed.

Signed-off-by: Chris Mason <mason@kernel.org>
---

Notes:
    v7->v8:
    - New patch.

 fs/xfs/xfs_iomap.c | 21 ++++++++++++++++++---
 1 file changed, 18 insertions(+), 3 deletions(-)

diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
index b414e2cff346..7fb61f56a414 100644
--- a/fs/xfs/xfs_iomap.c
+++ b/fs/xfs/xfs_iomap.c
@@ -295,9 +295,11 @@ xfs_iomap_write_direct(
 	struct xfs_mount	*mp = ip->i_mount;
 	struct xfs_trans	*tp;
 	xfs_filblks_t		resaligned;
+	xfs_extlen_t		extsz;
 	int			nimaps;
 	unsigned int		dblocks, rblocks;
 	bool			force = false;
+	bool			rt;
 	int			error;
 	int			bmapi_flags = XFS_BMAPI_PREALLOC;
 	int			nr_exts = XFS_IEXT_ADD_NOSPLIT_CNT;
@@ -312,9 +314,11 @@ xfs_iomap_write_direct(
 	 */
 	count_fsb = min_t(xfs_filblks_t, count_fsb, XFS_MAX_BMBT_EXTLEN);
 
-	resaligned = xfs_aligned_fsb_count(offset_fsb, count_fsb,
-					   xfs_get_extsz_hint(ip));
-	if (unlikely(XFS_IS_REALTIME_INODE(ip))) {
+retry:
+	extsz = xfs_get_extsz_hint(ip);
+	rt = XFS_IS_REALTIME_INODE(ip);
+	resaligned = xfs_aligned_fsb_count(offset_fsb, count_fsb, extsz);
+	if (unlikely(rt)) {
 		dblocks = XFS_DIOSTRAT_SPACE_RES(mp, 0);
 		rblocks = resaligned;
 	} else {
@@ -358,6 +362,17 @@ xfs_iomap_write_direct(
 		goto out_trans_cancel;
 	}
 
+	/*
+	 * A write fault doesn't hold the IOLOCK, so what sized the reservation
+	 * can change until we hold the ILOCK.
+	 */
+	if (extsz != xfs_get_extsz_hint(ip) ||
+	    rt != XFS_IS_REALTIME_INODE(ip)) {
+		xfs_trans_cancel(tp);
+		xfs_iunlock(ip, XFS_ILOCK_EXCL);
+		goto retry;
+	}
+
 	error = xfs_iext_count_extend(tp, ip, XFS_DATA_FORK, nr_exts);
 	if (error)
 		goto out_trans_cancel;
-- 
2.55.0


  parent reply	other threads:[~2026-11-12  1:02 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-12  1:02 [PATCH v8 00/15] reflink and atomic write bugs Chris Mason
2026-11-12  1:02 ` [PATCH v8 01/15] xfs: don't skip the flush before shifting extents Chris Mason
2026-11-12  1:02 ` [PATCH v8 02/15] xfs: flush the shifted range before changing the file Chris Mason
2026-11-12  1:02 ` [PATCH v8 03/15] xfs: don't change the block map under a dirty folio Chris Mason
2026-11-12  1:02 ` [PATCH v8 04/15] iomap: don't punch delalloc under a dirty EOF block Chris Mason
2026-11-12  1:02 ` [PATCH v8 05/15] fs: validate atomic writes after O_APPEND and limits Chris Mason
2026-11-12  1:02 ` [PATCH v8 06/15] xfs: recheck direct write alignment after write checks Chris Mason
2026-11-12  1:02 ` [PATCH v8 07/15] xfs: test for reflink after the dio " Chris Mason
2026-11-12  1:02 ` [PATCH v8 08/15] xfs: refuse writes to files racing with realtime inode flag changes Chris Mason
2026-11-12  1:02 ` [PATCH v8 09/15] xfs: test for always COW after the dio write checks Chris Mason
2026-11-12  1:02 ` [PATCH v8 10/15] xfs: refuse fallocate racing with realtime flag changes Chris Mason
2026-11-12  1:02 ` [PATCH v8 11/15] xfs: restart faults " Chris Mason
2026-11-12 13:34   ` Christoph Hellwig
2026-11-12  1:02 ` [PATCH v8 12/15] xfs: test for an extsize hint again under the ILOCK Chris Mason
2026-11-12 13:35   ` Christoph Hellwig
2026-11-12  1:02 ` Chris Mason [this message]
2026-11-12 13:35   ` [PATCH v8 13/15] xfs: resample the extsize hint after taking " Christoph Hellwig
2026-11-12 13:49     ` Chris Mason
2026-11-12  1:02 ` [PATCH v8 14/15] xfs: resample the COW extsize hint after cycling ILOCK Chris Mason
2026-11-12 13:36   ` Christoph Hellwig
2026-11-12  1:02 ` [PATCH v8 15/15] xfs: don't enable DAX on zoned inodes Chris Mason
2026-11-12 13:39   ` Christoph Hellwig

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=20261112010229.51029-14-mason@kernel.org \
    --to=mason@kernel.org \
    --cc=brauner@kernel.org \
    --cc=cem@kernel.org \
    --cc=david@fromorbit.com \
    --cc=djwong@kernel.org \
    --cc=hch@lst.de \
    --cc=jack@suse.cz \
    --cc=josef@toxicpanda.com \
    --cc=linux-ext4@vger.kernel.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-xfs@vger.kernel.org \
    --cc=tytso@mit.edu \
    --cc=tz2294@columbia.edu \
    /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 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.