trace_xfs_trans_commit(tp, _RET_IP_);
 
-       /*
-        * Finish deferred items on final commit. Only permanent transactions
-        * should ever have deferred ops.
-        */
-       WARN_ON_ONCE(!list_empty(&tp->t_dfops) &&
-                    !(tp->t_flags & XFS_TRANS_PERM_LOG_RES));
-       if (!regrant && (tp->t_flags & XFS_TRANS_PERM_LOG_RES)) {
-               error = xfs_defer_finish_noroll(&tp);
-               if (error)
-                       goto out_unreserve;
-       }
-
        error = xfs_trans_run_precommits(tp);
        if (error)
                goto out_unreserve;
 xfs_trans_commit(
        struct xfs_trans        *tp)
 {
+       /*
+        * Finish deferred items on final commit. Only permanent transactions
+        * should ever have deferred ops.
+        */
+       WARN_ON_ONCE(!list_empty(&tp->t_dfops) &&
+                    !(tp->t_flags & XFS_TRANS_PERM_LOG_RES));
+       if (tp->t_flags & XFS_TRANS_PERM_LOG_RES) {
+               int error = xfs_defer_finish_noroll(&tp);
+               if (error) {
+                       xfs_trans_cancel(tp);
+                       return error;
+               }
+       }
+
        return __xfs_trans_commit(tp, false);
 }