summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-11-11 09:13:48 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2016-11-11 09:13:48 -0800
commita4fac3b5d18204b64ea7adf383c4e166358c0a79 (patch)
tree9815bc5024cfcd95d9fc4b4e9c952c294a070282
parent27bcd37e0240bbe33f0efe244b5aad52104115b3 (diff)
parentb77428b12b55437b28deae738d9ce8b2e0663b55 (diff)
Merge tag 'xfs-fixes-for-linus-4.9-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/dgc/linux-xfs
Pull xfs fix from Dave Chinner: "This is a fix for an unmount hang (regression) when the filesystem is shutdown. It was supposed to go to you for -rc3, but I accidentally tagged the commit prior to it in that pullreq. Summary: - fix for aborting deferred transactions on filesystem shutdown" * tag 'xfs-fixes-for-linus-4.9-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/dgc/linux-xfs: xfs: defer should abort intent items if the trans roll fails
-rw-r--r--fs/xfs/libxfs/xfs_defer.c17
1 files changed, 5 insertions, 12 deletions
diff --git a/fs/xfs/libxfs/xfs_defer.c b/fs/xfs/libxfs/xfs_defer.c
index 613c5cf19436..5c2929f94bd3 100644
--- a/fs/xfs/libxfs/xfs_defer.c
+++ b/fs/xfs/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. */