|
@@ -452,7 +452,12 @@ xfs_cui_recover(
|
|
|
mp->m_refc_maxlevels * 2, 0, XFS_TRANS_RESERVE, &tp);
|
|
|
if (error)
|
|
|
return error;
|
|
|
- tp->t_dfops = dfops;
|
|
|
+ /*
|
|
|
+ * Recovery stashes all deferred ops during intent processing and
|
|
|
+ * finishes them on completion. Transfer current dfops state to this
|
|
|
+ * transaction and transfer the result back before we return.
|
|
|
+ */
|
|
|
+ xfs_defer_move(tp->t_dfops, dfops);
|
|
|
cudp = xfs_trans_get_cud(tp, cuip);
|
|
|
|
|
|
for (i = 0; i < cuip->cui_format.cui_nextents; i++) {
|
|
@@ -474,8 +479,8 @@ xfs_cui_recover(
|
|
|
new_len = refc->pe_len;
|
|
|
} else
|
|
|
error = xfs_trans_log_finish_refcount_update(tp, cudp,
|
|
|
- dfops, type, refc->pe_startblock, refc->pe_len,
|
|
|
- &new_fsb, &new_len, &rcur);
|
|
|
+ tp->t_dfops, type, refc->pe_startblock,
|
|
|
+ refc->pe_len, &new_fsb, &new_len, &rcur);
|
|
|
if (error)
|
|
|
goto abort_error;
|
|
|
|
|
@@ -486,21 +491,23 @@ xfs_cui_recover(
|
|
|
switch (type) {
|
|
|
case XFS_REFCOUNT_INCREASE:
|
|
|
error = xfs_refcount_increase_extent(
|
|
|
- tp->t_mountp, dfops, &irec);
|
|
|
+ tp->t_mountp, tp->t_dfops,
|
|
|
+ &irec);
|
|
|
break;
|
|
|
case XFS_REFCOUNT_DECREASE:
|
|
|
error = xfs_refcount_decrease_extent(
|
|
|
- tp->t_mountp, dfops, &irec);
|
|
|
+ tp->t_mountp, tp->t_dfops,
|
|
|
+ &irec);
|
|
|
break;
|
|
|
case XFS_REFCOUNT_ALLOC_COW:
|
|
|
error = xfs_refcount_alloc_cow_extent(
|
|
|
- tp->t_mountp, dfops,
|
|
|
+ tp->t_mountp, tp->t_dfops,
|
|
|
irec.br_startblock,
|
|
|
irec.br_blockcount);
|
|
|
break;
|
|
|
case XFS_REFCOUNT_FREE_COW:
|
|
|
error = xfs_refcount_free_cow_extent(
|
|
|
- tp->t_mountp, dfops,
|
|
|
+ tp->t_mountp, tp->t_dfops,
|
|
|
irec.br_startblock,
|
|
|
irec.br_blockcount);
|
|
|
break;
|
|
@@ -515,18 +522,13 @@ xfs_cui_recover(
|
|
|
|
|
|
xfs_refcount_finish_one_cleanup(tp, rcur, error);
|
|
|
set_bit(XFS_CUI_RECOVERED, &cuip->cui_flags);
|
|
|
- /*
|
|
|
- * Recovery finishes all deferred ops once intent processing is
|
|
|
- * complete. Reset the trans reference because commit expects a finished
|
|
|
- * dfops or none at all.
|
|
|
- */
|
|
|
- tp->t_dfops = NULL;
|
|
|
+ xfs_defer_move(dfops, tp->t_dfops);
|
|
|
error = xfs_trans_commit(tp);
|
|
|
return error;
|
|
|
|
|
|
abort_error:
|
|
|
xfs_refcount_finish_one_cleanup(tp, rcur, error);
|
|
|
- tp->t_dfops = NULL;
|
|
|
+ xfs_defer_move(dfops, tp->t_dfops);
|
|
|
xfs_trans_cancel(tp);
|
|
|
return error;
|
|
|
}
|