summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/xfs/libxfs/xfs_defer.c38
-rw-r--r--fs/xfs/libxfs/xfs_defer.h1
-rw-r--r--fs/xfs/xfs_trans.c2
3 files changed, 27 insertions, 14 deletions
diff --git a/fs/xfs/libxfs/xfs_defer.c b/fs/xfs/libxfs/xfs_defer.c
index cbee0a86c978..a5f7dc18a62f 100644
--- a/fs/xfs/libxfs/xfs_defer.c
+++ b/fs/xfs/libxfs/xfs_defer.c
@@ -341,7 +341,7 @@ xfs_defer_reset(
* If an inode is provided, relog it to the new transaction.
*/
int
-xfs_defer_finish(
+xfs_defer_finish_noroll(
struct xfs_trans **tp)
{
struct xfs_defer_ops *dop = (*tp)->t_dfops;
@@ -430,25 +430,37 @@ xfs_defer_finish(
cleanup_fn(*tp, state, error);
}
- /*
- * Roll the transaction once more to avoid returning to the caller
- * with a dirty transaction.
- */
- if ((*tp)->t_flags & XFS_TRANS_DIRTY) {
- error = xfs_defer_trans_roll(tp);
- dop = (*tp)->t_dfops;
- }
out:
- if (error) {
+ if (error)
trace_xfs_defer_finish_error((*tp)->t_mountp, dop, error);
- } else {
+ else
trace_xfs_defer_finish_done((*tp)->t_mountp, dop, _RET_IP_);
- xfs_defer_reset(dop);
- }
return error;
}
+int
+xfs_defer_finish(
+ struct xfs_trans **tp)
+{
+ int error;
+
+ /*
+ * Finish and roll the transaction once more to avoid returning to the
+ * caller with a dirty transaction.
+ */
+ error = xfs_defer_finish_noroll(tp);
+ if (error)
+ return error;
+ if ((*tp)->t_flags & XFS_TRANS_DIRTY) {
+ error = xfs_defer_trans_roll(tp);
+ if (error)
+ return error;
+ }
+ xfs_defer_reset((*tp)->t_dfops);
+ return 0;
+}
+
/*
* Free up any items left in the list.
*/
diff --git a/fs/xfs/libxfs/xfs_defer.h b/fs/xfs/libxfs/xfs_defer.h
index 56f927803940..85c41fe4dbae 100644
--- a/fs/xfs/libxfs/xfs_defer.h
+++ b/fs/xfs/libxfs/xfs_defer.h
@@ -48,6 +48,7 @@ enum xfs_defer_ops_type {
void xfs_defer_add(struct xfs_defer_ops *dop, enum xfs_defer_ops_type type,
struct list_head *h);
+int xfs_defer_finish_noroll(struct xfs_trans **tp);
int xfs_defer_finish(struct xfs_trans **tp);
void __xfs_defer_cancel(struct xfs_defer_ops *dop);
void xfs_defer_init(struct xfs_trans *tp, struct xfs_defer_ops *dop);
diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c
index cd553aa9ecb0..7bf5c1202719 100644
--- a/fs/xfs/xfs_trans.c
+++ b/fs/xfs/xfs_trans.c
@@ -933,7 +933,7 @@ __xfs_trans_commit(
/* finish deferred items on final commit */
if (!regrant && tp->t_dfops) {
- error = xfs_defer_finish(&tp);
+ error = xfs_defer_finish_noroll(&tp);
if (error) {
xfs_defer_cancel(tp);
goto out_unreserve;