* 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;
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.
*/
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);
/* 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;