Skip to content

Commit a1ca658

Browse files
hwenwurcmaiolino
authored andcommitted
xfs: fix incorrect context handling in xfs_trans_roll
The memalloc_nofs_save() and memalloc_nofs_restore() calls are incorrectly paired in xfs_trans_roll. Call path: xfs_trans_alloc() __xfs_trans_alloc() // tp->t_pflags = memalloc_nofs_save(); xfs_trans_set_context() ... xfs_defer_trans_roll() xfs_trans_roll() xfs_trans_dup() // old_tp->t_pflags = 0; xfs_trans_switch_context() __xfs_trans_commit() xfs_trans_free() // memalloc_nofs_restore(tp->t_pflags); xfs_trans_clear_context() The code passes 0 to memalloc_nofs_restore() when committing the original transaction, but memalloc_nofs_restore() should always receive the flags returned from the paired memalloc_nofs_save() call. Before commit 3f6d5e6 ("mm: introduce memalloc_flags_{save,restore}"), calling memalloc_nofs_restore(0) would unset the PF_MEMALLOC_NOFS flag, which could cause memory allocation deadlocks[1]. Fortunately, after that commit, memalloc_nofs_restore(0) does nothing, so this issue is currently harmless. Fixes: 756b1c3 ("xfs: use current->journal_info for detecting transaction recursion") Link: https://lore.kernel.org/linux-xfs/20251104131857.1587584-1-leo.lilong@huawei.com [1] Signed-off-by: Wenwu Hou <hwenwur@gmail.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Carlos Maiolino <cem@kernel.org>
1 parent 01a2896 commit a1ca658

2 files changed

Lines changed: 6 additions & 11 deletions

File tree

fs/xfs/xfs_trans.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,8 +124,6 @@ xfs_trans_dup(
124124
ntp->t_rtx_res = tp->t_rtx_res - tp->t_rtx_res_used;
125125
tp->t_rtx_res = tp->t_rtx_res_used;
126126

127-
xfs_trans_switch_context(tp, ntp);
128-
129127
/* move deferred ops over to the new tp */
130128
xfs_defer_move(ntp, tp);
131129

@@ -1043,6 +1041,12 @@ xfs_trans_roll(
10431041
* locked be logged in the prior and the next transactions.
10441042
*/
10451043
tp = *tpp;
1044+
/*
1045+
* __xfs_trans_commit cleared the NOFS flag by calling into
1046+
* xfs_trans_free. Set it again here before doing memory
1047+
* allocations.
1048+
*/
1049+
xfs_trans_set_context(tp);
10461050
error = xfs_log_regrant(tp->t_mountp, tp->t_ticket);
10471051
if (error)
10481052
return error;

fs/xfs/xfs_trans.h

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -280,13 +280,4 @@ xfs_trans_clear_context(
280280
memalloc_nofs_restore(tp->t_pflags);
281281
}
282282

283-
static inline void
284-
xfs_trans_switch_context(
285-
struct xfs_trans *old_tp,
286-
struct xfs_trans *new_tp)
287-
{
288-
new_tp->t_pflags = old_tp->t_pflags;
289-
old_tp->t_pflags = 0;
290-
}
291-
292283
#endif /* __XFS_TRANS_H__ */

0 commit comments

Comments
 (0)