summaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
authorDarrick J. Wong <djwong@kernel.org>2024-12-02 10:57:34 -0800
committerDarrick J. Wong <djwong@kernel.org>2024-12-12 17:45:11 -0800
commita004afdc62946d3261f724c6472997085c4f0735 (patch)
tree42c3fd48de69acb3b5c0d651ccf90d3a8dedf8a5 /fs/xfs
parent44d9b07e52db25035680713c3428016cadcd2ea1 (diff)
downloadlinux-stable-a004afdc62946d3261f724c6472997085c4f0735.tar.gz
linux-stable-a004afdc62946d3261f724c6472997085c4f0735.tar.bz2
linux-stable-a004afdc62946d3261f724c6472997085c4f0735.zip
xfs: avoid nested calls to __xfs_trans_commit
Currently, __xfs_trans_commit calls xfs_defer_finish_noroll, which calls __xfs_trans_commit again on the same transaction. In other words, there's a nested function call (albeit with slightly different arguments) that has caused minor amounts of confusion in the past. There's no reason to keep this around, since there's only one place where we actually want the xfs_defer_finish_noroll, and that is in the top level xfs_trans_commit call. This also reduces stack usage a little bit. Signed-off-by: "Darrick J. Wong" <djwong@kernel.org> Reviewed-by: Christoph Hellwig <hch@lst.de>
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/xfs_trans.c26
1 files changed, 14 insertions, 12 deletions
diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c
index 4a517250efc9..26bb2343082a 100644
--- a/fs/xfs/xfs_trans.c
+++ b/fs/xfs/xfs_trans.c
@@ -860,18 +860,6 @@ __xfs_trans_commit(
trace_xfs_trans_commit(tp, _RET_IP_);
- /*
- * Finish deferred items on final commit. Only permanent transactions
- * should ever have deferred ops.
- */
- WARN_ON_ONCE(!list_empty(&tp->t_dfops) &&
- !(tp->t_flags & XFS_TRANS_PERM_LOG_RES));
- if (!regrant && (tp->t_flags & XFS_TRANS_PERM_LOG_RES)) {
- error = xfs_defer_finish_noroll(&tp);
- if (error)
- goto out_unreserve;
- }
-
error = xfs_trans_run_precommits(tp);
if (error)
goto out_unreserve;
@@ -950,6 +938,20 @@ int
xfs_trans_commit(
struct xfs_trans *tp)
{
+ /*
+ * Finish deferred items on final commit. Only permanent transactions
+ * should ever have deferred ops.
+ */
+ WARN_ON_ONCE(!list_empty(&tp->t_dfops) &&
+ !(tp->t_flags & XFS_TRANS_PERM_LOG_RES));
+ if (tp->t_flags & XFS_TRANS_PERM_LOG_RES) {
+ int error = xfs_defer_finish_noroll(&tp);
+ if (error) {
+ xfs_trans_cancel(tp);
+ return error;
+ }
+ }
+
return __xfs_trans_commit(tp, false);
}