diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-11-11 12:13:48 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-11-11 12:13:48 -0500 |
commit | a4fac3b5d18204b64ea7adf383c4e166358c0a79 (patch) | |
tree | 9815bc5024cfcd95d9fc4b4e9c952c294a070282 /fs | |
parent | 27bcd37e0240bbe33f0efe244b5aad52104115b3 (diff) | |
parent | b77428b12b55437b28deae738d9ce8b2e0663b55 (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
Diffstat (limited to 'fs')
-rw-r--r-- | fs/xfs/libxfs/xfs_defer.c | 17 |
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( | |||
199 | struct xfs_defer_pending *dfp; | 199 | struct xfs_defer_pending *dfp; |
200 | 200 | ||
201 | list_for_each_entry(dfp, &dop->dop_intake, dfp_list) { | 201 | list_for_each_entry(dfp, &dop->dop_intake, dfp_list) { |
202 | trace_xfs_defer_intake_work(tp->t_mountp, dfp); | ||
203 | dfp->dfp_intent = dfp->dfp_type->create_intent(tp, | 202 | dfp->dfp_intent = dfp->dfp_type->create_intent(tp, |
204 | dfp->dfp_count); | 203 | dfp->dfp_count); |
204 | trace_xfs_defer_intake_work(tp->t_mountp, dfp); | ||
205 | list_sort(tp->t_mountp, &dfp->dfp_work, | 205 | list_sort(tp->t_mountp, &dfp->dfp_work, |
206 | dfp->dfp_type->diff_items); | 206 | dfp->dfp_type->diff_items); |
207 | list_for_each(li, &dfp->dfp_work) | 207 | list_for_each(li, &dfp->dfp_work) |
@@ -221,21 +221,14 @@ xfs_defer_trans_abort( | |||
221 | struct xfs_defer_pending *dfp; | 221 | struct xfs_defer_pending *dfp; |
222 | 222 | ||
223 | trace_xfs_defer_trans_abort(tp->t_mountp, dop); | 223 | trace_xfs_defer_trans_abort(tp->t_mountp, dop); |
224 | /* | ||
225 | * If the transaction was committed, drop the intent reference | ||
226 | * since we're bailing out of here. The other reference is | ||
227 | * dropped when the intent hits the AIL. If the transaction | ||
228 | * was not committed, the intent is freed by the intent item | ||
229 | * unlock handler on abort. | ||
230 | */ | ||
231 | if (!dop->dop_committed) | ||
232 | return; | ||
233 | 224 | ||
234 | /* Abort intent items. */ | 225 | /* Abort intent items that don't have a done item. */ |
235 | list_for_each_entry(dfp, &dop->dop_pending, dfp_list) { | 226 | list_for_each_entry(dfp, &dop->dop_pending, dfp_list) { |
236 | trace_xfs_defer_pending_abort(tp->t_mountp, dfp); | 227 | trace_xfs_defer_pending_abort(tp->t_mountp, dfp); |
237 | if (!dfp->dfp_done) | 228 | if (dfp->dfp_intent && !dfp->dfp_done) { |
238 | dfp->dfp_type->abort_intent(dfp->dfp_intent); | 229 | dfp->dfp_type->abort_intent(dfp->dfp_intent); |
230 | dfp->dfp_intent = NULL; | ||
231 | } | ||
239 | } | 232 | } |
240 | 233 | ||
241 | /* Shut down FS. */ | 234 | /* Shut down FS. */ |