@@ -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--;
@@ -324,39 +324,17 @@ xfs_xattri_finish_update(
struct xfs_da_args *args = attr->xattri_da_args;
int error;
- if (XFS_TEST_ERROR(false, args->dp->i_mount, XFS_ERRTAG_LARP)) {
- error = -EIO;
- goto out;
- }
+ if (XFS_TEST_ERROR(false, args->dp->i_mount, XFS_ERRTAG_LARP))
+ return -EIO;
/* If an attr removal is trivially complete, we're done. */
if (attr->xattri_op_flags == XFS_ATTRI_OP_FLAGS_REMOVE &&
- !xfs_inode_hasattr(args->dp)) {
- error = 0;
- goto out;
- }
+ !xfs_inode_hasattr(args->dp))
+ return 0;
error = xfs_attr_set_iter(attr);
if (!error && attr->xattri_dela_state != XFS_DAS_DONE)
error = -EAGAIN;
-out:
- /*
- * Mark the transaction dirty, even on error. This ensures the
- * transaction is aborted, which:
- *
- * 1.) releases the ATTRI and frees the ATTRD
- * 2.) shuts down the filesystem
- */
- args->trans->t_flags |= XFS_TRANS_DIRTY;
-
- /*
- * attr intent/done items are null when logged attributes are disabled
- */
- if (attrdp) {
- args->trans->t_flags |= XFS_TRANS_HAS_INTENT_DONE;
- set_bit(XFS_LI_DIRTY, &attrdp->attrd_item.li_flags);
- }
-
return error;
}
@@ -249,21 +249,7 @@ xfs_trans_log_finish_bmap_update(
struct xfs_bud_log_item *budp,
struct xfs_bmap_intent *bi)
{
- int error;
-
- error = xfs_bmap_finish_one(tp, bi);
-
- /*
- * Mark the transaction dirty, even on error. This ensures the
- * transaction is aborted, which:
- *
- * 1.) releases the BUI and frees the BUD
- * 2.) shuts down the filesystem
- */
- tp->t_flags |= XFS_TRANS_DIRTY | XFS_TRANS_HAS_INTENT_DONE;
- set_bit(XFS_LI_DIRTY, &budp->bud_item.li_flags);
-
- return error;
+ return xfs_bmap_finish_one(tp, bi);
}
/* Sort bmap intents by inode. */
@@ -396,16 +396,6 @@ xfs_trans_free_extent(
xefi->xefi_blockcount, &oinfo, xefi->xefi_agresv,
xefi->xefi_flags & XFS_EFI_SKIP_DISCARD);
- /*
- * Mark the transaction dirty, even on error. This ensures the
- * transaction is aborted, which:
- *
- * 1.) releases the EFI and frees the EFD
- * 2.) shuts down the filesystem
- */
- tp->t_flags |= XFS_TRANS_DIRTY | XFS_TRANS_HAS_INTENT_DONE;
- set_bit(XFS_LI_DIRTY, &efdp->efd_item.li_flags);
-
/*
* If we need a new transaction to make progress, the caller will log a
* new EFI with the current contents. It will also log an EFD to cancel
@@ -601,16 +591,6 @@ xfs_agfl_free_finish_item(
error = xfs_free_agfl_block(tp, xefi->xefi_pag->pag_agno,
agbno, agbp, &oinfo);
- /*
- * Mark the transaction dirty, even on error. This ensures the
- * transaction is aborted, which:
- *
- * 1.) releases the EFI and frees the EFD
- * 2.) shuts down the filesystem
- */
- tp->t_flags |= XFS_TRANS_DIRTY;
- set_bit(XFS_LI_DIRTY, &efdp->efd_item.li_flags);
-
next_extent = efdp->efd_next_extent;
ASSERT(next_extent < efdp->efd_format.efd_nextents);
extp = &(efdp->efd_format.efd_extents[next_extent]);
@@ -256,21 +256,7 @@ xfs_trans_log_finish_refcount_update(
struct xfs_refcount_intent *ri,
struct xfs_btree_cur **pcur)
{
- int error;
-
- error = xfs_refcount_finish_one(tp, ri, pcur);
-
- /*
- * Mark the transaction dirty, even on error. This ensures the
- * transaction is aborted, which:
- *
- * 1.) releases the CUI and frees the CUD
- * 2.) shuts down the filesystem
- */
- tp->t_flags |= XFS_TRANS_DIRTY | XFS_TRANS_HAS_INTENT_DONE;
- set_bit(XFS_LI_DIRTY, &cudp->cud_item.li_flags);
-
- return error;
+ return xfs_refcount_finish_one(tp, ri, pcur);
}
/* Sort refcount intents by AG. */
@@ -297,21 +297,7 @@ xfs_trans_log_finish_rmap_update(
struct xfs_rmap_intent *ri,
struct xfs_btree_cur **pcur)
{
- int error;
-
- error = xfs_rmap_finish_one(tp, ri, pcur);
-
- /*
- * Mark the transaction dirty, even on error. This ensures the
- * transaction is aborted, which:
- *
- * 1.) releases the RUI and frees the RUD
- * 2.) shuts down the filesystem
- */
- tp->t_flags |= XFS_TRANS_DIRTY | XFS_TRANS_HAS_INTENT_DONE;
- set_bit(XFS_LI_DIRTY, &rudp->rud_item.li_flags);
-
- return error;
+ return xfs_rmap_finish_one(tp, ri, pcur);
}
/* Sort rmap intents by AG. */