[PATCH 05/33] xfs: plumb xfs_trans through xfs_reflink_allocate_cow and fill_cow_hole

Dave Chinner <[email protected]> Wed, 29 Jul 2026 20:01:49 +1000
Newsgroups org.kernel.vger.linux-xfs
Message-ID <[email protected]>
Add a struct xfs_trans pointer as the first parameter to
xfs_reflink_allocate_cow() and xfs_reflink_fill_cow_hole().
All callers currently pass NULL.

This is preparation for having the caller pre-allocate a transaction
and pass it down to avoid needing to cycle the ILOCK inside
fill_cow_hole().

The local transaction variable in fill_cow_hole() is renamed to
local_tp to avoid shadowing the new parameter.

Assisted-by: LLM
Signed-off-by: Dave Chinner <[email protected]>
---
 fs/xfs/xfs_iomap.c   |  2 +-
 fs/xfs/xfs_reflink.c | 17 ++++++++++-------
 fs/xfs/xfs_reflink.h |  6 +++---
 3 files changed, 14 insertions(+), 11 deletions(-)

diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
index df9fc7c6a4b9..e4e64412b431 100644
--- a/fs/xfs/xfs_iomap.c
+++ b/fs/xfs/xfs_iomap.c
@@ -913,7 +913,7 @@ xfs_direct_write_cow_iomap_begin(
 		goto out_unlock;
 
 	/* may drop and re-acquire the ilock */
-	error = xfs_reflink_allocate_cow(ip, imap, &cmap, &shared,
+	error = xfs_reflink_allocate_cow(NULL, ip, imap, &cmap, &shared,
 			lockmode,
 			(flags & IOMAP_DIRECT) || IS_DAX(VFS_I(ip)));
 	if (error)
diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c
index 480136136635..1fa899048b24 100644
--- a/fs/xfs/xfs_reflink.c
+++ b/fs/xfs/xfs_reflink.c
@@ -430,6 +430,7 @@ xfs_reflink_convert_unwritten(
 
 static int
 xfs_reflink_fill_cow_hole(
+	struct xfs_trans	*tp,
 	struct xfs_inode	*ip,
 	struct xfs_bmbt_irec	*imap,
 	struct xfs_bmbt_irec	*cmap,
@@ -438,7 +439,7 @@ xfs_reflink_fill_cow_hole(
 	bool			convert_now)
 {
 	struct xfs_mount	*mp = ip->i_mount;
-	struct xfs_trans	*tp;
+	struct xfs_trans	*local_tp;
 	xfs_filblks_t		resaligned;
 	unsigned int		seq_before = READ_ONCE(ip->i_df.if_seq);
 	unsigned int		dblocks = 0, rblocks = 0;
@@ -460,7 +461,7 @@ xfs_reflink_fill_cow_hole(
 	*lockmode = 0;
 
 	error = xfs_trans_alloc_inode(ip, &M_RES(mp)->tr_write, dblocks,
-			rblocks, false, &tp);
+			rblocks, false, &local_tp);
 	if (error)
 		return error;
 
@@ -487,20 +488,21 @@ xfs_reflink_fill_cow_hole(
 		goto out_trans_cancel;
 
 	if (found) {
-		xfs_trans_cancel(tp);
+		xfs_trans_cancel(local_tp);
 		goto convert;
 	}
 
 	/* Allocate the entire reservation as unwritten blocks. */
 	nimaps = 1;
-	error = xfs_bmapi_write(tp, ip, imap->br_startoff, imap->br_blockcount,
+	error = xfs_bmapi_write(local_tp, ip, imap->br_startoff,
+			imap->br_blockcount,
 			XFS_BMAPI_COWFORK | XFS_BMAPI_PREALLOC, 0, cmap,
 			&nimaps);
 	if (error)
 		goto out_trans_cancel;
 
 	xfs_inode_set_cowblocks_tag(ip);
-	error = xfs_trans_commit(tp);
+	error = xfs_trans_commit(local_tp);
 	if (error)
 		return error;
 
@@ -508,7 +510,7 @@ xfs_reflink_fill_cow_hole(
 	return xfs_reflink_convert_unwritten(ip, imap, cmap, convert_now);
 
 out_trans_cancel:
-	xfs_trans_cancel(tp);
+	xfs_trans_cancel(local_tp);
 	return error;
 }
 
@@ -597,6 +599,7 @@ xfs_reflink_fill_delalloc(
 /* Allocate all CoW reservations covering a range of blocks in a file. */
 int
 xfs_reflink_allocate_cow(
+	struct xfs_trans	*tp,
 	struct xfs_inode	*ip,
 	struct xfs_bmbt_irec	*imap,
 	struct xfs_bmbt_irec	*cmap,
@@ -627,7 +630,7 @@ xfs_reflink_allocate_cow(
 	 * Allocate a real extent in the CoW fork.
 	 */
 	if (cmap->br_startoff > imap->br_startoff)
-		return xfs_reflink_fill_cow_hole(ip, imap, cmap, shared,
+		return xfs_reflink_fill_cow_hole(NULL, ip, imap, cmap, shared,
 				lockmode, convert_now);
 
 	/*
diff --git a/fs/xfs/xfs_reflink.h b/fs/xfs/xfs_reflink.h
index 9d1ed9bb0bee..6a984363edbc 100644
--- a/fs/xfs/xfs_reflink.h
+++ b/fs/xfs/xfs_reflink.h
@@ -30,9 +30,9 @@ int xfs_reflink_trim_around_shared(struct xfs_inode *ip,
 int xfs_bmap_trim_cow(struct xfs_inode *ip, struct xfs_bmbt_irec *imap,
 		bool *shared);
 
-int xfs_reflink_allocate_cow(struct xfs_inode *ip, struct xfs_bmbt_irec *imap,
-		struct xfs_bmbt_irec *cmap, bool *shared, uint *lockmode,
-		bool convert_now);
+int xfs_reflink_allocate_cow(struct xfs_trans *tp, struct xfs_inode *ip,
+		struct xfs_bmbt_irec *imap, struct xfs_bmbt_irec *cmap,
+		bool *shared, uint *lockmode, bool convert_now);
 extern int xfs_reflink_convert_cow(struct xfs_inode *ip, xfs_off_t offset,
 		xfs_off_t count);
 int xfs_reflink_convert_cow_locked(struct xfs_inode *ip,
-- 
2.55.0