Linux XFS filesystem development
 help / color / mirror / Atom feed
* [PATCH] xfs: fix nofs context corruption in xfs_btree_split_worker
@ 2026-07-20  5:05 Yun Zhou
  2026-07-20  8:35 ` Christoph Hellwig
  2026-07-24 13:42 ` Christoph Hellwig
  0 siblings, 2 replies; 6+ messages in thread
From: Yun Zhou @ 2026-07-20  5:05 UTC (permalink / raw)
  To: cem; +Cc: linux-xfs, linux-kernel, yun.zhou, akpm

xfs_btree_split_worker() calls xfs_trans_set_context() on the shared
transaction, overwriting tp->t_pflags saved by the submitting thread.
This can cause the submitting thread's NOFS protection to be cleared
prematurely when the transaction is freed, risking deadlocks from
allocations recursing into fs_reclaim.

    Thread A (NOFS set)             Worker
    -------------------             ------
    xfs_trans_alloc()
      xfs_trans_set_context(tp)
        tp->t_pflags = 0  (*)
    ...
    xfs_btree_split()
      queue_work(split_worker)
                                    xfs_trans_set_context(tp)
                                      tp->t_pflags = NOFS  (clobbers!)
                                    __xfs_btree_split()
                                    xfs_trans_clear_context(tp)
      wait_for_completion()
    ...
    xfs_trans_free(tp)
      memalloc_nofs_restore(NOFS)
        -> clears Thread A's NOFS!

    (*) returns 0 because NOFS was already set by outer scope

Fix by using a local memalloc_nofs_save()/restore() in the worker
instead of touching the shared transaction state.

Reported-by: sashiko <sashiko@sashiko.dev>
Fixes: 756b1c343333 ("xfs: use current->journal_info for detecting transaction recursion")
Signed-off-by: Yun Zhou <yun.zhou@windriver.com>
---
 fs/xfs/libxfs/xfs_btree.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_btree.c b/fs/xfs/libxfs/xfs_btree.c
index 60ef7f08b1d3..1e4c43b7fa3d 100644
--- a/fs/xfs/libxfs/xfs_btree.c
+++ b/fs/xfs/libxfs/xfs_btree.c
@@ -3010,6 +3010,7 @@ xfs_btree_split_worker(
 						struct xfs_btree_split_args, work);
 	unsigned long		pflags;
 	unsigned long		new_pflags = 0;
+	unsigned int		nofs_flags;
 
 	/*
 	 * we are in a transaction context here, but may also be doing work
@@ -3021,12 +3022,12 @@ xfs_btree_split_worker(
 		new_pflags |= PF_MEMALLOC | PF_KSWAPD;
 
 	current_set_flags_nested(&pflags, new_pflags);
-	xfs_trans_set_context(args->cur->bc_tp);
+	nofs_flags = memalloc_nofs_save();
 
 	args->result = __xfs_btree_split(args->cur, args->level, args->ptrp,
 					 args->key, args->curp, args->stat);
 
-	xfs_trans_clear_context(args->cur->bc_tp);
+	memalloc_nofs_restore(nofs_flags);
 	current_restore_flags_nested(&pflags, new_pflags);
 
 	/*
-- 
2.43.0


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

end of thread, other threads:[~2026-07-24 13:42 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-20  5:05 [PATCH] xfs: fix nofs context corruption in xfs_btree_split_worker Yun Zhou
2026-07-20  8:35 ` Christoph Hellwig
2026-07-24  7:54   ` Zhou, Yun
2026-07-24  8:06     ` Christoph Hellwig
2026-07-24  8:14       ` Zhou, Yun
2026-07-24 13:42 ` Christoph Hellwig

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