aboutsummaryrefslogtreecommitdiff
path: root/fs/xfs/libxfs/xfs_defer.c
diff options
context:
space:
mode:
authorGravatar Darrick J. Wong <djwong@kernel.org> 2023-11-30 10:45:28 -0800
committerGravatar Darrick J. Wong <djwong@kernel.org> 2023-12-06 18:45:15 -0800
commit3dd75c8db1c1675a26d3e228bab349c1fc065867 (patch)
tree902c260865c8e85da5a52179ae7b073616b8db0f /fs/xfs/libxfs/xfs_defer.c
parentxfs: don't set XFS_TRANS_HAS_INTENT_DONE when there's no ATTRD log item (diff)
downloadlinux-3dd75c8db1c1675a26d3e228bab349c1fc065867.tar.gz
linux-3dd75c8db1c1675a26d3e228bab349c1fc065867.tar.bz2
linux-3dd75c8db1c1675a26d3e228bab349c1fc065867.zip
xfs: hoist intent done flag setting to ->finish_item callsite
Each log intent item's ->finish_item call chain inevitably includes some code to set the dirty flag of the transaction. If there's an associated log intent done item, it also sets the item's dirty flag and the transaction's INTENT_DONE flag. This is repeated throughout the codebase. Reduce the LOC by moving all that to xfs_defer_finish_one. Signed-off-by: Darrick J. Wong <djwong@kernel.org> Reviewed-by: Christoph Hellwig <hch@lst.de>
Diffstat (limited to 'fs/xfs/libxfs/xfs_defer.c')
-rw-r--r--fs/xfs/libxfs/xfs_defer.c28
1 files changed, 27 insertions, 1 deletions
diff --git a/fs/xfs/libxfs/xfs_defer.c b/fs/xfs/libxfs/xfs_defer.c
index dd565e4e3daf..6214abedf394 100644
--- a/fs/xfs/libxfs/xfs_defer.c
+++ b/fs/xfs/libxfs/xfs_defer.c
@@ -191,6 +191,32 @@ static const struct xfs_defer_op_type *defer_op_types[] = {
[XFS_DEFER_OPS_TYPE_ATTR] = &xfs_attr_defer_type,
};
+/* Create a log intent done item for a log intent item. */
+static inline void
+xfs_defer_create_done(
+ struct xfs_trans *tp,
+ struct xfs_defer_pending *dfp)
+{
+ const struct xfs_defer_op_type *ops = defer_op_types[dfp->dfp_type];
+ struct xfs_log_item *lip;
+
+ /*
+ * Mark the transaction dirty, even on error. This ensures the
+ * transaction is aborted, which:
+ *
+ * 1.) releases the log intent item and frees the log done item
+ * 2.) shuts down the filesystem
+ */
+ tp->t_flags |= XFS_TRANS_DIRTY;
+ lip = ops->create_done(tp, dfp->dfp_intent, dfp->dfp_count);
+ if (!lip)
+ return;
+
+ tp->t_flags |= XFS_TRANS_HAS_INTENT_DONE;
+ set_bit(XFS_LI_DIRTY, &lip->li_flags);
+ dfp->dfp_done = lip;
+}
+
/*
* Ensure there's a log intent item associated with this deferred work item if
* the operation must be restarted on crash. Returns 1 if there's a log item;
@@ -496,7 +522,7 @@ xfs_defer_finish_one(
trace_xfs_defer_pending_finish(tp->t_mountp, dfp);
- dfp->dfp_done = ops->create_done(tp, dfp->dfp_intent, dfp->dfp_count);
+ xfs_defer_create_done(tp, dfp);
list_for_each_safe(li, n, &dfp->dfp_work) {
list_del(li);
dfp->dfp_count--;