In the rolling transaction, thread's NOFS state is transferred from the old transaction to the new transaction, and then the NOFS state stored in the old one should be cleared. Suggested-by: Dave Chinner <david@xxxxxxxxxxxxx> Cc: Darrick J. Wong <darrick.wong@xxxxxxxxxx> Cc: Matthew Wilcox (Oracle) <willy@xxxxxxxxxxxxx> Cc: Christoph Hellwig <hch@xxxxxx> Cc: Dave Chinner <david@xxxxxxxxxxxxx> Signed-off-by: Yafang Shao <laoar.shao@xxxxxxxxx> --- fs/xfs/xfs_trans.c | 4 +++- fs/xfs/xfs_trans.h | 10 +++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c index 11d390f0d3f2..733e0113aebe 100644 --- a/fs/xfs/xfs_trans.c +++ b/fs/xfs/xfs_trans.c @@ -119,7 +119,9 @@ xfs_trans_dup( ntp->t_rtx_res = tp->t_rtx_res - tp->t_rtx_res_used; tp->t_rtx_res = tp->t_rtx_res_used; - ntp->t_pflags = tp->t_pflags; + + /* Associate the new transaction with this thread. */ + xfs_trans_context_swap(tp, ntp); /* move deferred ops over to the new tp */ xfs_defer_move(ntp, tp); diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h index 44b11c64a15e..b428704eeb20 100644 --- a/fs/xfs/xfs_trans.h +++ b/fs/xfs/xfs_trans.h @@ -277,7 +277,15 @@ xfs_trans_context_set(struct xfs_trans *tp) static inline void xfs_trans_context_clear(struct xfs_trans *tp) { - memalloc_nofs_restore(tp->t_pflags); + if (!tp->t_flags) + memalloc_nofs_restore(tp->t_pflags); +} + +static inline void +xfs_trans_context_swap(struct xfs_trans *tp, struct xfs_trans *ntp) +{ + ntp->t_pflags = tp->t_pflags; + tp->t_flags = -1; } #endif /* __XFS_TRANS_H__ */ -- 2.18.4