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 <[email protected]>
Cc: Darrick J. Wong <[email protected]>
Cc: Matthew Wilcox (Oracle) <[email protected]>
Cc: Christoph Hellwig <[email protected]>
Cc: Dave Chinner <[email protected]>
Signed-off-by: Yafang Shao <[email protected]>
---
 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

--
Linux-cachefs mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/linux-cachefs

Reply via email to