diff options
author | Darrick J. Wong <darrick.wong@oracle.com> | 2016-10-25 13:00:12 +1100 |
---|---|---|
committer | Dave Chinner <david@fromorbit.com> | 2016-10-25 13:00:12 +1100 |
commit | 077dd509197e756884774b85775031d3ed57ac6d (patch) | |
tree | 6c08515b8f63735cc048c66144aa2ce28f9ebc65 | |
parent | 2873ab2b85202c69689ab863b68971a0278512cc (diff) | |
download | xfsprogs-dev-libxfs-4.9-sync.tar.gz |
xfs: defer should abort intent items if the trans roll failslibxfs-4.9-sync
Source kernel commit: b77428b12b55437b28deae738d9ce8b2e0663b55
If the deferred ops transaction roll fails, we need to abort the intent
items if we haven't already logged a done item for it, regardless of
whether or not the deferred ops has had a transaction committed. Dave
found this while running generic/388.
Move the tracepoint to make it easier to track object lifetimes.
Reported-by: Dave Chinner <david@fromorbit.com>
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>
-rw-r--r-- | libxfs/xfs_defer.c | 17 |
1 files changed, 5 insertions, 12 deletions
diff --git a/libxfs/xfs_defer.c b/libxfs/xfs_defer.c index 290a5f04e7..d880d59e9f 100644 --- a/libxfs/xfs_defer.c +++ b/libxfs/xfs_defer.c @@ -199,9 +199,9 @@ xfs_defer_intake_work( struct xfs_defer_pending *dfp; list_for_each_entry(dfp, &dop->dop_intake, dfp_list) { - trace_xfs_defer_intake_work(tp->t_mountp, dfp); dfp->dfp_intent = dfp->dfp_type->create_intent(tp, dfp->dfp_count); + trace_xfs_defer_intake_work(tp->t_mountp, dfp); list_sort(tp->t_mountp, &dfp->dfp_work, dfp->dfp_type->diff_items); list_for_each(li, &dfp->dfp_work) @@ -221,21 +221,14 @@ xfs_defer_trans_abort( struct xfs_defer_pending *dfp; trace_xfs_defer_trans_abort(tp->t_mountp, dop); - /* - * If the transaction was committed, drop the intent reference - * since we're bailing out of here. The other reference is - * dropped when the intent hits the AIL. If the transaction - * was not committed, the intent is freed by the intent item - * unlock handler on abort. - */ - if (!dop->dop_committed) - return; - /* Abort intent items. */ + /* Abort intent items that don't have a done item. */ list_for_each_entry(dfp, &dop->dop_pending, dfp_list) { trace_xfs_defer_pending_abort(tp->t_mountp, dfp); - if (!dfp->dfp_done) + if (dfp->dfp_intent && !dfp->dfp_done) { dfp->dfp_type->abort_intent(dfp->dfp_intent); + dfp->dfp_intent = NULL; + } } /* Shut down FS. */ |