Linux filesystem development
 help / color / mirror / Atom feed
* [PATCH] xfs: punch COW fork delalloc on COW writeback failure
@ 2026-07-09  6:26 Ravi Singh
  2026-07-09  7:58 ` Dave Chinner
  0 siblings, 1 reply; 3+ messages in thread
From: Ravi Singh @ 2026-07-09  6:26 UTC (permalink / raw)
  To: linux-xfs; +Cc: dchinner, bfoster, hch, djwong, cem, linux-fsdevel

When a COW writeback I/O fails, xfs_end_ioend_write() cancels the COW
fork extents and punches out any overlapping delalloc blocks.  Currently
the delalloc punch targets XFS_DATA_FORK, but on the error path
xfs_reflink_end_cow() is never called, so the COW fork extents have not
been moved to the data fork yet.  Any overlapping delalloc that needs to
be cleaned up is therefore still in the COW fork.

Punching the data fork is incorrect because it can remove delalloc
reservations that belong to a concurrent buffered write.  In particular,
the convert_delay path in xfs_buffered_write_iomap_begin() drops the
ILOCK before calling xfs_bmapi_convert_delalloc(), and a concurrent COW
writeback failure punching data fork delalloc during this window causes
xfs_bmapi_convert_one_delalloc() to find the extent missing and trigger
a WARN_ON_ONCE(whichfork != XFS_COW_FORK).

This is the same class of wrong-fork issue fixed by commit f6f91d290c8b
("xfs: punch delalloc extents from the COW fork for COW writes") for the
xfs_buffered_write_iomap_end() path.

Fix xfs_end_ioend_write() to punch delalloc from XFS_COW_FORK instead
of XFS_DATA_FORK for IOMAP_IOEND_SHARED ioends.

Fixes: 5ca5916b6bc9 ("xfs: punch out data fork delalloc blocks on COW writeback failure")
Signed-off-by: Ravi Singh <ravising@redhat.com>
---
 fs/xfs/xfs_aops.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c
index 51293b6f331f..8268a3f80398 100644
--- a/fs/xfs/xfs_aops.c
+++ b/fs/xfs/xfs_aops.c
@@ -131,11 +131,11 @@ xfs_end_ioend_write(
 	}

 	/*
-	 * Clean up all COW blocks and underlying data fork delalloc blocks on
-	 * I/O error. The delalloc punch is required because this ioend was
-	 * mapped to blocks in the COW fork and the associated pages are no
-	 * longer dirty. If we don't remove delalloc blocks here, they become
-	 * stale and can corrupt free space accounting on unmount.
+	 * Clean up COW blocks and COW fork delalloc blocks on I/O error.
+	 * On the error path xfs_reflink_end_cow() is never called, so the
+	 * COW fork extents have not been moved to the data fork yet.  Any
+	 * overlapping delalloc that needs to be cleaned up is therefore
+	 * still in the COW fork.
 	 */
 	error = blk_status_to_errno(ioend->io_bio.bi_status);
 	if (unlikely(error)) {
@@ -153,7 +153,7 @@ xfs_end_ioend_write(
 		if (ioend->io_flags & IOMAP_IOEND_SHARED) {
 			ASSERT(!is_zoned);
 			xfs_reflink_cancel_cow_range(ip, offset, size, true);
-			xfs_bmap_punch_delalloc_range(ip, XFS_DATA_FORK, offset,
+			xfs_bmap_punch_delalloc_range(ip, XFS_COW_FORK, offset,
 					offset + size, NULL);
 		}
 		goto done;
--
2.39.3


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

end of thread, other threads:[~2026-07-09 12:02 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-09  6:26 [PATCH] xfs: punch COW fork delalloc on COW writeback failure Ravi Singh
2026-07-09  7:58 ` Dave Chinner
2026-07-09 12:02   ` Ravi Singh

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox