Linux XFS filesystem development
 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 v7 02/11] xfs: flush the shifted range before changing the file
Date: Tue, 10 Nov 2026 14:04:20 -0500	[thread overview]
Message-ID: <20261110190417.32650-4-mason@kernel.org> (raw)
In-Reply-To: <20261110190417.32650-1-mason@kernel.org>

If writeback of the range to be shifted fails, collapse range on XFS can
fail with its hole already punched, and insert range with the file
already grown.

Both calls change the file first: collapse range punches its hole, and
insert range grows i_size. Only then does xfs_prepare_shift() flush the
range from the offset to EOF, and that flush fails if the writeback
fails.

The fix used here is to flush and invalidate that range before the file
is changed.

Signed-off-by: Chris Mason <mason@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---

Notes:
    v6->v7:
    - No change.

 fs/xfs/xfs_file.c | 25 +++++++++++++++++++++++--
 1 file changed, 23 insertions(+), 2 deletions(-)

diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
index 396aca8c66a9..be1f775128d1 100644
--- a/fs/xfs/xfs_file.c
+++ b/fs/xfs/xfs_file.c
@@ -1201,6 +1201,22 @@ xfs_falloc_setsize(
 			&iattr);
 }
 
+/*
+ * Collapse and insert range change the file in several steps, and each step
+ * writes back and empties the part of the page cache that it needs.  That can
+ * fail.  Do it here for everything that is going to move, before the first
+ * step, so that a failure leaves the file as it was.  xfs_prepare_shift()
+ * starts one allocation unit before the offset, so do the same.
+ */
+static int
+xfs_falloc_flush_shift_range(
+	struct xfs_inode	*ip,
+	loff_t			offset)
+{
+	offset -= min_t(loff_t, offset, xfs_inode_alloc_unitsize(ip));
+	return xfs_flush_unmap_range(ip, offset, XFS_ISIZE(ip) - offset);
+}
+
 static int
 xfs_falloc_collapse_range(
 	struct file		*file,
@@ -1222,6 +1238,10 @@ xfs_falloc_collapse_range(
 	if (offset + len >= i_size_read(inode))
 		return -EINVAL;
 
+	error = xfs_falloc_flush_shift_range(XFS_I(inode), offset);
+	if (error)
+		return error;
+
 	error = xfs_collapse_file_space(XFS_I(inode), offset, len, ac);
 	if (error)
 		return error;
@@ -1263,9 +1283,10 @@ xfs_falloc_insert_range(
 	 * fork. This shifts back out beyond EOF, but creates an expectedly
 	 * written post-eof block. The insert is going to flush, unmap and
 	 * cancel prealloc across this whole range, so flush EOF now before we
-	 * bump i_size to provide consistent behavior.
+	 * bump i_size to provide consistent behavior.  Flush and unmap the rest
+	 * of the range as well, so that a failure to do so leaves i_size alone.
 	 */
-	error = filemap_write_and_wait_range(inode->i_mapping, isize, isize);
+	error = xfs_falloc_flush_shift_range(XFS_I(inode), offset);
 	if (error)
 		return error;
 
-- 
2.55.0


  parent reply	other threads:[~2026-11-10 19:04 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-10 19:04 [PATCH v7 00/11] reflink and atomic write bugs Chris Mason
2026-11-10 19:04 ` Chris Mason
2026-11-10 19:04 ` [PATCH v7 01/11] xfs: don't skip the flush before shifting extents Chris Mason
2026-11-10 19:04 ` Chris Mason [this message]
2026-11-10 19:04 ` [PATCH v7 03/11] xfs: don't change the block map under a dirty folio Chris Mason
2026-11-10 19:04 ` [PATCH v7 04/11] iomap: don't punch delalloc under a dirty EOF block Chris Mason
2026-11-10 19:04 ` [PATCH v7 05/11] fs: validate atomic writes after O_APPEND and limits Chris Mason
2026-11-11  4:54   ` Tal Zussman
2026-11-10 19:04 ` [PATCH v7 06/11] xfs: recheck direct write alignment after write checks Chris Mason
2026-11-10 19:04 ` [PATCH v7 07/11] xfs: test for reflink after the dio " Chris Mason
2026-11-10 19:04 ` [PATCH v7 08/11] xfs: refuse writes to files racing with realtime inode flag changes Chris Mason
2026-11-10 19:04 ` [PATCH v7 09/11] xfs: test for always COW after the dio write checks Chris Mason
2026-11-11 15:15   ` Christoph Hellwig
2026-11-10 19:04 ` [PATCH v7 10/11] xfs: refuse fallocate racing with realtime flag changes Chris Mason
2026-11-10 19:04 ` [PATCH v7 11/11] xfs: restart faults " Chris Mason
2026-11-11 15:16   ` 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=20261110190417.32650-4-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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox