imamnurby/smpl_train_seed8 huggingface dataset:
--- initial
+++ final
@@ -1,35 +1,35 @@
 STATIC int xfs_attr_leaf_removename(struct xfs_da_args *args) {
   struct xfs_inode *dp;
   struct xfs_buf *bp;
   int error, forkoff;
   trace_xfs_attr_leaf_removename(args);
   /*
    * Remove the attribute.
    */
   dp = args->dp;
   args->blkno = 0;
   error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno, -1, &bp);
   if (error) return error;
   error = xfs_attr3_leaf_lookup_int(bp, args);
   if (error == -ENOATTR) {
     xfs_trans_brelse(args->trans, bp);
     return error;
   }
   xfs_attr3_leaf_remove(bp, args);
   /*
    * If the result is small enough, shrink it all into the inode.
    */
   if ((forkoff = xfs_attr_shortform_allfit(bp, dp))) {
-    xfs_defer_init(args->trans->t_dfops, args->firstblock);
+    xfs_defer_init(NULL, args->trans->t_dfops, args->firstblock);
     error = xfs_attr3_leaf_to_shortform(bp, args, forkoff);
     /* bp is gone due to xfs_da_shrink_inode */
     if (error) goto out_defer_cancel;
     xfs_defer_ijoin(args->trans->t_dfops, dp);
     error = xfs_defer_finish(&args->trans, args->trans->t_dfops);
     if (error) goto out_defer_cancel;
   }
   return 0;
 out_defer_cancel:
   xfs_defer_cancel(args->trans->t_dfops);
   return error;
 }<sep>@@
expression e1,e2,tp;
@@

-		xfs_defer_init(e1, e2);
+		xfs_defer_init(NULL, e1, e2);
--- initial
+++ final
@@ -1,62 +1,61 @@
 int xfs_attr_remove(struct xfs_inode *dp, const unsigned char *name, int flags) {
   struct xfs_mount *mp = dp->i_mount;
   struct xfs_da_args args;
   struct xfs_defer_ops dfops;
   xfs_fsblock_t firstblock;
   int error;
   XFS_STATS_INC(mp, xs_attr_remove);
   if (XFS_FORCED_SHUTDOWN(dp->i_mount)) return -EIO;
   error = xfs_attr_args_init(&args, dp, name, flags);
   if (error) return error;
   args.firstblock = &firstblock;
   /*
    * we have no control over the attribute names that userspace passes us
    * to remove, so we have to allow the name lookup prior to attribute
    * removal to fail.
    */
   args.op_flags = XFS_DA_OP_OKNOENT;
   error = xfs_qm_dqattach(dp);
   if (error) return error;
   /*
    * Root fork attributes can use reserved data blocks for this
    * operation if necessary
    */
   error = xfs_trans_alloc(mp, &M_RES(mp)->tr_attrrm, XFS_ATTRRM_SPACE_RES(mp), 0, (flags & ATTR_ROOT) ? XFS_TRANS_RESERVE : 0, &args.trans);
   if (error) return error;
-  xfs_defer_init(&dfops, &firstblock);
-  args.trans->t_dfops = &dfops;
+  xfs_defer_init(args.trans, &dfops, &firstblock);
   xfs_ilock(dp, XFS_ILOCK_EXCL);
   /*
    * No need to make quota reservations here. We expect to release some
    * blocks not allocate in the common case.
    */
   xfs_trans_ijoin(args.trans, dp, 0);
   if (!xfs_inode_hasattr(dp)) {
     error = -ENOATTR;
   } else if (dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) {
     ASSERT(dp->i_afp->if_flags & XFS_IFINLINE);
     error = xfs_attr_shortform_remove(&args);
   } else if (xfs_bmap_one_block(dp, XFS_ATTR_FORK)) {
     error = xfs_attr_leaf_removename(&args);
   } else {
     error = xfs_attr_node_removename(&args);
   }
   if (error) goto out;
   /*
    * If this is a synchronous mount, make sure that the
    * transaction goes to disk before returning to the user.
    */
   if (mp->m_flags & XFS_MOUNT_WSYNC) xfs_trans_set_sync(args.trans);
   if ((flags & ATTR_KERNOTIME) == 0) xfs_trans_ichgtime(args.trans, dp, XFS_ICHGTIME_CHG);
   /*
    * Commit the last in the sequence of transactions.
    */
   xfs_trans_log_inode(args.trans, dp, XFS_ILOG_CORE);
   error = xfs_trans_commit(args.trans);
   xfs_iunlock(dp, XFS_ILOCK_EXCL);
   return error;
 out:
   if (args.trans) xfs_trans_cancel(args.trans);
   xfs_iunlock(dp, XFS_ILOCK_EXCL);
   return error;
 }<sep>@@
expression e1,e2,tp;
@@

-		xfs_defer_init(e1, e2);
-		(tp)->t_dfops = e1;
+		xfs_defer_init(tp, e1, e2);
--- initial
+++ final
@@ -1,39 +1,38 @@
 int xfs_collapse_file_space(struct xfs_inode *ip, xfs_off_t offset, xfs_off_t len) {
   struct xfs_mount *mp = ip->i_mount;
   struct xfs_trans *tp;
   int error;
   struct xfs_defer_ops dfops;
   xfs_fsblock_t first_block;
   xfs_fileoff_t next_fsb = XFS_B_TO_FSB(mp, offset + len);
   xfs_fileoff_t shift_fsb = XFS_B_TO_FSB(mp, len);
   uint resblks = XFS_DIOSTRAT_SPACE_RES(mp, 0);
   bool done = false;
   ASSERT(xfs_isilocked(ip, XFS_IOLOCK_EXCL));
   ASSERT(xfs_isilocked(ip, XFS_MMAPLOCK_EXCL));
   trace_xfs_collapse_file_space(ip);
   error = xfs_free_file_space(ip, offset, len);
   if (error) return error;
   error = xfs_prepare_shift(ip, offset);
   if (error) return error;
   while (!error && !done) {
     error = xfs_trans_alloc(mp, &M_RES(mp)->tr_write, resblks, 0, 0, &tp);
     if (error) break;
     xfs_ilock(ip, XFS_ILOCK_EXCL);
     error = xfs_trans_reserve_quota(tp, mp, ip->i_udquot, ip->i_gdquot, ip->i_pdquot, resblks, 0, XFS_QMOPT_RES_REGBLKS);
     if (error) goto out_trans_cancel;
     xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
-    xfs_defer_init(&dfops, &first_block);
-    tp->t_dfops = &dfops;
+    xfs_defer_init(tp, &dfops, &first_block);
     error = xfs_bmap_collapse_extents(tp, ip, &next_fsb, shift_fsb, &done, &first_block);
     if (error) goto out_bmap_cancel;
     error = xfs_defer_finish(&tp, tp->t_dfops);
     if (error) goto out_bmap_cancel;
     error = xfs_trans_commit(tp);
   }
   return error;
 out_bmap_cancel:
   xfs_defer_cancel(tp->t_dfops);
 out_trans_cancel:
   xfs_trans_cancel(tp);
   return error;
 }<sep>@@
expression e1,e2,tp;
@@

-		xfs_defer_init(e1, e2);
-		(tp)->t_dfops = e1;
+		xfs_defer_init(tp, e1, e2);
--- initial
+++ final
@@ -1,43 +1,42 @@
 int xfs_insert_file_space(struct xfs_inode *ip, loff_t offset, loff_t len) {
   struct xfs_mount *mp = ip->i_mount;
   struct xfs_trans *tp;
   int error;
   struct xfs_defer_ops dfops;
   xfs_fsblock_t first_block;
   xfs_fileoff_t stop_fsb = XFS_B_TO_FSB(mp, offset);
   xfs_fileoff_t next_fsb = NULLFSBLOCK;
   xfs_fileoff_t shift_fsb = XFS_B_TO_FSB(mp, len);
   bool done = false;
   ASSERT(xfs_isilocked(ip, XFS_IOLOCK_EXCL));
   ASSERT(xfs_isilocked(ip, XFS_MMAPLOCK_EXCL));
   trace_xfs_insert_file_space(ip);
   error = xfs_bmap_can_insert_extents(ip, stop_fsb, shift_fsb);
   if (error) return error;
   error = xfs_prepare_shift(ip, offset);
   if (error) return error;
   /*
    * The extent shifting code works on extent granularity. So, if stop_fsb
    * is not the starting block of extent, we need to split the extent at
    * stop_fsb.
    */
   error = xfs_bmap_split_extent(ip, stop_fsb);
   if (error) return error;
   while (!error && !done) {
     error = xfs_trans_alloc(mp, &M_RES(mp)->tr_write, 0, 0, 0, &tp);
     if (error) break;
     xfs_ilock(ip, XFS_ILOCK_EXCL);
     xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
-    xfs_defer_init(&dfops, &first_block);
-    tp->t_dfops = &dfops;
+    xfs_defer_init(tp, &dfops, &first_block);
     error = xfs_bmap_insert_extents(tp, ip, &next_fsb, shift_fsb, &done, stop_fsb, &first_block);
     if (error) goto out_bmap_cancel;
     error = xfs_defer_finish(&tp, tp->t_dfops);
     if (error) goto out_bmap_cancel;
     error = xfs_trans_commit(tp);
   }
   return error;
 out_bmap_cancel:
   xfs_defer_cancel(tp->t_dfops);
   xfs_trans_cancel(tp);
   return error;
 }<sep>@@
expression e1,e2,tp;
@@

-		xfs_defer_init(e1, e2);
-		(tp)->t_dfops = e1;
+		xfs_defer_init(tp, e1, e2);
--- initial
+++ final
@@ -1,33 +1,32 @@
 static int xfs_unmap_extent(struct xfs_inode *ip, xfs_fileoff_t startoffset_fsb, xfs_filblks_t len_fsb, int *done) {
   struct xfs_mount *mp = ip->i_mount;
   struct xfs_trans *tp;
   struct xfs_defer_ops dfops;
   xfs_fsblock_t firstfsb;
   uint resblks = XFS_DIOSTRAT_SPACE_RES(mp, 0);
   int error;
   error = xfs_trans_alloc(mp, &M_RES(mp)->tr_write, resblks, 0, 0, &tp);
   if (error) {
     ASSERT(error == -ENOSPC || XFS_FORCED_SHUTDOWN(mp));
     return error;
   }
   xfs_ilock(ip, XFS_ILOCK_EXCL);
   error = xfs_trans_reserve_quota(tp, mp, ip->i_udquot, ip->i_gdquot, ip->i_pdquot, resblks, 0, XFS_QMOPT_RES_REGBLKS);
   if (error) goto out_trans_cancel;
   xfs_trans_ijoin(tp, ip, 0);
-  xfs_defer_init(&dfops, &firstfsb);
-  tp->t_dfops = &dfops;
+  xfs_defer_init(tp, &dfops, &firstfsb);
   error = xfs_bunmapi(tp, ip, startoffset_fsb, len_fsb, 0, 2, &firstfsb, done);
   if (error) goto out_bmap_cancel;
   xfs_defer_ijoin(tp->t_dfops, ip);
   error = xfs_defer_finish(&tp, tp->t_dfops);
   if (error) goto out_bmap_cancel;
   error = xfs_trans_commit(tp);
 out_unlock:
   xfs_iunlock(ip, XFS_ILOCK_EXCL);
   return error;
 out_bmap_cancel:
   xfs_defer_cancel(tp->t_dfops);
 out_trans_cancel:
   xfs_trans_cancel(tp);
   goto out_unlock;
 }<sep>@@
expression e1,e2,tp;
@@

-		xfs_defer_init(e1, e2);
-		(tp)->t_dfops = e1;
+		xfs_defer_init(tp, e1, e2);
--- initial
+++ final
@@ -1,22 +1,21 @@
 int xfs_bmap_split_extent(struct xfs_inode *ip, xfs_fileoff_t split_fsb) {
   struct xfs_mount *mp = ip->i_mount;
   struct xfs_trans *tp;
   struct xfs_defer_ops dfops;
   xfs_fsblock_t firstfsb;
   int error;
   error = xfs_trans_alloc(mp, &M_RES(mp)->tr_write, XFS_DIOSTRAT_SPACE_RES(mp, 0), 0, 0, &tp);
   if (error) return error;
-  xfs_defer_init(&dfops, &firstfsb);
-  tp->t_dfops = &dfops;
+  xfs_defer_init(tp, &dfops, &firstfsb);
   xfs_ilock(ip, XFS_ILOCK_EXCL);
   xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
   error = xfs_bmap_split_extent_at(tp, ip, split_fsb, &firstfsb);
   if (error) goto out;
   error = xfs_defer_finish(&tp, &dfops);
   if (error) goto out;
   return xfs_trans_commit(tp);
 out:
   xfs_defer_cancel(&dfops);
   xfs_trans_cancel(tp);
   return error;
 }<sep>@@
expression e1,e2,tp;
@@

-		xfs_defer_init(e1, e2);
-		(tp)->t_dfops = e1;
+		xfs_defer_init(tp, e1, e2);
--- initial
+++ final
@@ -1,28 +1,27 @@
 static int xfs_qm_dqread_alloc(struct xfs_mount *mp, struct xfs_dquot *dqp, struct xfs_buf **bpp) {
   struct xfs_trans *tp;
   struct xfs_defer_ops dfops;
   struct xfs_buf *bp;
   xfs_fsblock_t firstblock;
   int error;
   error = xfs_trans_alloc(mp, &M_RES(mp)->tr_qm_dqalloc, XFS_QM_DQALLOC_SPACE_RES(mp), 0, 0, &tp);
   if (error) goto err;
-  xfs_defer_init(&dfops, &firstblock);
-  tp->t_dfops = &dfops;
+  xfs_defer_init(tp, &dfops, &firstblock);
   error = xfs_dquot_disk_alloc(&tp, dqp, &bp);
   if (error) goto err_cancel;
   error = xfs_trans_commit(tp);
   if (error) {
     /*
      * Buffer was held to the transaction, so we have to unlock it
      * manually here because we're not passing it back.
      */
     xfs_buf_relse(bp);
     goto err;
   }
   *bpp = bp;
   return 0;
 err_cancel:
   xfs_trans_cancel(tp);
 err:
   return error;
 }<sep>@@
expression e1,e2,tp;
@@

-		xfs_defer_init(e1, e2);
-		(tp)->t_dfops = e1;
+		xfs_defer_init(tp, e1, e2);
--- initial
+++ final
@@ -1,68 +1,67 @@
 STATIC int xfs_inactive_ifree(struct xfs_inode *ip) {
   struct xfs_defer_ops dfops;
   xfs_fsblock_t first_block;
   struct xfs_mount *mp = ip->i_mount;
   struct xfs_trans *tp;
   int error;
   /*
    * We try to use a per-AG reservation for any block needed by the finobt
    * tree, but as the finobt feature predates the per-AG reservation
    * support a degraded file system might not have enough space for the
    * reservation at mount time.  In that case try to dip into the reserved
    * pool and pray.
    *
    * Send a warning if the reservation does happen to fail, as the inode
    * now remains allocated and sits on the unlinked list until the fs is
    * repaired.
    */
   if (unlikely(mp->m_inotbt_nores)) {
     error = xfs_trans_alloc(mp, &M_RES(mp)->tr_ifree, XFS_IFREE_SPACE_RES(mp), 0, XFS_TRANS_RESERVE, &tp);
   } else {
     error = xfs_trans_alloc(mp, &M_RES(mp)->tr_ifree, 0, 0, 0, &tp);
   }
   if (error) {
     if (error == -ENOSPC) {
       xfs_warn_ratelimited(mp, "Failed to remove inode(s) from unlinked list. "
                                "Please free space, unmount and run xfs_repair.");
     } else {
       ASSERT(XFS_FORCED_SHUTDOWN(mp));
     }
     return error;
   }
   xfs_ilock(ip, XFS_ILOCK_EXCL);
   xfs_trans_ijoin(tp, ip, 0);
-  xfs_defer_init(&dfops, &first_block);
-  tp->t_dfops = &dfops;
+  xfs_defer_init(tp, &dfops, &first_block);
   error = xfs_ifree(tp, ip);
   if (error) {
     /*
      * If we fail to free the inode, shut down.  The cancel
      * might do that, we need to make sure.  Otherwise the
      * inode might be lost for a long time or forever.
      */
     if (!XFS_FORCED_SHUTDOWN(mp)) {
       xfs_notice(mp, "%s: xfs_ifree returned error %d", __func__, error);
       xfs_force_shutdown(mp, SHUTDOWN_META_IO_ERROR);
     }
     xfs_trans_cancel(tp);
     xfs_iunlock(ip, XFS_ILOCK_EXCL);
     return error;
   }
   /*
    * Credit the quota account(s). The inode is gone.
    */
   xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_ICOUNT, -1);
   /*
    * Just ignore errors at this point.  There is nothing we can do except
    * to try to keep going. Make sure it's not a silent error.
    */
   error = xfs_defer_finish(&tp, &dfops);
   if (error) {
     xfs_notice(mp, "%s: xfs_defer_finish returned error %d", __func__, error);
     xfs_defer_cancel(&dfops);
   }
   error = xfs_trans_commit(tp);
   if (error) xfs_notice(mp, "%s: xfs_trans_commit returned error %d", __func__, error);
   xfs_iunlock(ip, XFS_ILOCK_EXCL);
   return 0;
 }<sep>@@
expression e1,e2,tp;
@@

-		xfs_defer_init(e1, e2);
-		(tp)->t_dfops = e1;
+		xfs_defer_init(tp, e1, e2);
--- initial
+++ final
@@ -1,69 +1,68 @@
 int xfs_link(xfs_inode_t *tdp, xfs_inode_t *sip, struct xfs_name *target_name) {
   xfs_mount_t *mp = tdp->i_mount;
   xfs_trans_t *tp;
   int error;
   struct xfs_defer_ops dfops;
   xfs_fsblock_t first_block;
   int resblks;
   trace_xfs_link(tdp, target_name);
   ASSERT(!S_ISDIR(VFS_I(sip)->i_mode));
   if (XFS_FORCED_SHUTDOWN(mp)) return -EIO;
   error = xfs_qm_dqattach(sip);
   if (error) goto std_return;
   error = xfs_qm_dqattach(tdp);
   if (error) goto std_return;
   resblks = XFS_LINK_SPACE_RES(mp, target_name->len);
   error = xfs_trans_alloc(mp, &M_RES(mp)->tr_link, resblks, 0, 0, &tp);
   if (error == -ENOSPC) {
     resblks = 0;
     error = xfs_trans_alloc(mp, &M_RES(mp)->tr_link, 0, 0, 0, &tp);
   }
   if (error) goto std_return;
   xfs_lock_two_inodes(sip, XFS_ILOCK_EXCL, tdp, XFS_ILOCK_EXCL);
   xfs_trans_ijoin(tp, sip, XFS_ILOCK_EXCL);
   xfs_trans_ijoin(tp, tdp, XFS_ILOCK_EXCL);
   /*
    * If we are using project inheritance, we only allow hard link
    * creation in our tree when the project IDs are the same; else
    * the tree quota mechanism could be circumvented.
    */
   if (unlikely((tdp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) && (xfs_get_projid(tdp) != xfs_get_projid(sip)))) {
     error = -EXDEV;
     goto error_return;
   }
   if (!resblks) {
     error = xfs_dir_canenter(tp, tdp, target_name);
     if (error) goto error_return;
   }
-  xfs_defer_init(&dfops, &first_block);
-  tp->t_dfops = &dfops;
+  xfs_defer_init(tp, &dfops, &first_block);
   /*
    * Handle initial link state of O_TMPFILE inode
    */
   if (VFS_I(sip)->i_nlink == 0) {
     error = xfs_iunlink_remove(tp, sip);
     if (error) goto error_return;
   }
   error = xfs_dir_createname(tp, tdp, target_name, sip->i_ino, &first_block, resblks);
   if (error) goto error_return;
   xfs_trans_ichgtime(tp, tdp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
   xfs_trans_log_inode(tp, tdp, XFS_ILOG_CORE);
   error = xfs_bumplink(tp, sip);
   if (error) goto error_return;
   /*
    * If this is a synchronous mount, make sure that the
    * link transaction goes to disk before returning to
    * the user.
    */
   if (mp->m_flags & (XFS_MOUNT_WSYNC | XFS_MOUNT_DIRSYNC)) xfs_trans_set_sync(tp);
   error = xfs_defer_finish(&tp, &dfops);
   if (error) {
     xfs_defer_cancel(&dfops);
     goto error_return;
   }
   return xfs_trans_commit(tp);
 error_return:
   xfs_trans_cancel(tp);
 std_return:
   return error;
 }<sep>@@
expression e1,e2,tp;
@@

-		xfs_defer_init(e1, e2);
-		(tp)->t_dfops = e1;
+		xfs_defer_init(tp, e1, e2);
--- initial
+++ final
@@ -1,59 +1,59 @@
 STATIC int xlog_recover_process_intents(struct xlog *log) {
   struct xfs_defer_ops dfops;
   struct xfs_ail_cursor cur;
   struct xfs_log_item *lip;
   struct xfs_ail *ailp;
   xfs_fsblock_t firstfsb;
   int error = 0;
 #if defined(DEBUG) || defined(XFS_WARN)
   xfs_lsn_t last_lsn;
 #endif
   ailp = log->l_ailp;
   spin_lock(&ailp->ail_lock);
   lip = xfs_trans_ail_cursor_first(ailp, &cur, 0);
 #if defined(DEBUG) || defined(XFS_WARN)
   last_lsn = xlog_assign_lsn(log->l_curr_cycle, log->l_curr_block);
 #endif
-  xfs_defer_init(&dfops, &firstfsb);
+  xfs_defer_init(NULL, &dfops, &firstfsb);
   while (lip != NULL) {
     /*
      * We're done when we see something other than an intent.
      * There should be no intents left in the AIL now.
      */
     if (!xlog_item_is_intent(lip)) {
 #ifdef DEBUG
       for (; lip; lip = xfs_trans_ail_cursor_next(ailp, &cur))
         ASSERT(!xlog_item_is_intent(lip));
 #endif
       break;
     }
     /*
      * We should never see a redo item with a LSN higher than
      * the last transaction we found in the log at the start
      * of recovery.
      */
     ASSERT(XFS_LSN_CMP(last_lsn, lip->li_lsn) >= 0);
     /*
      * NOTE: If your intent processing routine can create more
      * deferred ops, you /must/ attach them to the dfops in this
      * routine or else those subsequent intents will get
      * replayed in the wrong order!
      */
     switch (lip->li_type) {
     case XFS_LI_EFI: error = xlog_recover_process_efi(log->l_mp, ailp, lip); break;
     case XFS_LI_RUI: error = xlog_recover_process_rui(log->l_mp, ailp, lip); break;
     case XFS_LI_CUI: error = xlog_recover_process_cui(log->l_mp, ailp, lip, &dfops); break;
     case XFS_LI_BUI: error = xlog_recover_process_bui(log->l_mp, ailp, lip, &dfops); break;
     }
     if (error) goto out;
     lip = xfs_trans_ail_cursor_next(ailp, &cur);
   }
 out:
   xfs_trans_ail_cursor_done(&cur);
   spin_unlock(&ailp->ail_lock);
   if (error)
     xfs_defer_cancel(&dfops);
   else
     error = xlog_finish_defer_ops(log->l_mp, &dfops);
   return error;
 }<sep>@@
expression e1,e2,tp;
@@

-		xfs_defer_init(e1, e2);
+		xfs_defer_init(NULL, e1, e2);
--- initial
+++ final
@@ -1,82 +1,81 @@
 int xfs_refcount_recover_cow_leftovers(struct xfs_mount *mp, xfs_agnumber_t agno) {
   struct xfs_trans *tp;
   struct xfs_btree_cur *cur;
   struct xfs_buf *agbp;
   struct xfs_refcount_recovery *rr, *n;
   struct list_head debris;
   union xfs_btree_irec low;
   union xfs_btree_irec high;
   struct xfs_defer_ops dfops;
   xfs_fsblock_t fsb;
   xfs_agblock_t agbno;
   int error;
   if (mp->m_sb.sb_agblocks >= XFS_REFC_COW_START) return -EOPNOTSUPP;
   INIT_LIST_HEAD(&debris);
   /*
    * In this first part, we use an empty transaction to gather up
    * all the leftover CoW extents so that we can subsequently
    * delete them.  The empty transaction is used to avoid
    * a buffer lock deadlock if there happens to be a loop in the
    * refcountbt because we're allowed to re-grab a buffer that is
    * already attached to our transaction.  When we're done
    * recording the CoW debris we cancel the (empty) transaction
    * and everything goes away cleanly.
    */
   error = xfs_trans_alloc_empty(mp, &tp);
   if (error) return error;
   error = xfs_alloc_read_agf(mp, tp, agno, 0, &agbp);
   if (error) goto out_trans;
   if (!agbp) {
     error = -ENOMEM;
     goto out_trans;
   }
   cur = xfs_refcountbt_init_cursor(mp, tp, agbp, agno);
   /* Find all the leftover CoW staging extents. */
   memset(&low, 0, sizeof(low));
   memset(&high, 0, sizeof(high));
   low.rc.rc_startblock = XFS_REFC_COW_START;
   high.rc.rc_startblock = -1U;
   error = xfs_btree_query_range(cur, &low, &high, xfs_refcount_recover_extent, &debris);
   if (error) goto out_cursor;
   xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
   xfs_trans_brelse(tp, agbp);
   xfs_trans_cancel(tp);
   /* Now iterate the list to free the leftovers */
   list_for_each_entry_safe(rr, n, &debris, rr_list) {
     /* Set up transaction. */
     error = xfs_trans_alloc(mp, &M_RES(mp)->tr_write, 0, 0, 0, &tp);
     if (error) goto out_free;
     trace_xfs_refcount_recover_extent(mp, agno, &rr->rr_rrec);
     /* Free the orphan record */
-    xfs_defer_init(&dfops, &fsb);
-    tp->t_dfops = &dfops;
+    xfs_defer_init(tp, &dfops, &fsb);
     agbno = rr->rr_rrec.rc_startblock - XFS_REFC_COW_START;
     fsb = XFS_AGB_TO_FSB(mp, agno, agbno);
     error = xfs_refcount_free_cow_extent(mp, tp->t_dfops, fsb, rr->rr_rrec.rc_blockcount);
     if (error) goto out_defer;
     /* Free the block. */
     xfs_bmap_add_free(mp, tp->t_dfops, fsb, rr->rr_rrec.rc_blockcount, NULL);
     error = xfs_defer_finish(&tp, tp->t_dfops);
     if (error) goto out_defer;
     error = xfs_trans_commit(tp);
     if (error) goto out_free;
     list_del(&rr->rr_list);
     kmem_free(rr);
   }
   return error;
 out_defer:
   xfs_defer_cancel(tp->t_dfops);
 out_trans:
   xfs_trans_cancel(tp);
 out_free:
   /* Free the leftover list */
   list_for_each_entry_safe(rr, n, &debris, rr_list) {
     list_del(&rr->rr_list);
     kmem_free(rr);
   }
   return error;
 out_cursor:
   xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
   xfs_trans_brelse(tp, agbp);
   goto out_trans;
 }<sep>@@
expression e1,e2,tp;
@@

-		xfs_defer_init(e1, e2);
-		(tp)->t_dfops = e1;
+		xfs_defer_init(tp, e1, e2);
--- initial
+++ final
@@ -1,74 +1,73 @@
 int xfs_reflink_allocate_cow(struct xfs_inode *ip, struct xfs_bmbt_irec *imap, bool *shared, uint *lockmode) {
   struct xfs_mount *mp = ip->i_mount;
   xfs_fileoff_t offset_fsb = imap->br_startoff;
   xfs_filblks_t count_fsb = imap->br_blockcount;
   struct xfs_bmbt_irec got;
   struct xfs_defer_ops dfops;
   struct xfs_trans *tp = NULL;
   xfs_fsblock_t first_block;
   int nimaps, error = 0;
   bool trimmed;
   xfs_filblks_t resaligned;
   xfs_extlen_t resblks = 0;
   struct xfs_iext_cursor icur;
 retry:
   ASSERT(xfs_is_reflink_inode(ip));
   ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
   /*
    * Even if the extent is not shared we might have a preallocation for
    * it in the COW fork.  If so use it.
    */
   if (xfs_iext_lookup_extent(ip, ip->i_cowfp, offset_fsb, &icur, &got) && got.br_startoff <= offset_fsb) {
     *shared = true;
     /* If we have a real allocation in the COW fork we're done. */
     if (!isnullstartblock(got.br_startblock)) {
       xfs_trim_extent(&got, offset_fsb, count_fsb);
       *imap = got;
       goto convert;
     }
     xfs_trim_extent(imap, got.br_startoff, got.br_blockcount);
   } else {
     error = xfs_reflink_trim_around_shared(ip, imap, shared, &trimmed);
     if (error || !*shared) goto out;
   }
   if (!tp) {
     resaligned = xfs_aligned_fsb_count(imap->br_startoff, imap->br_blockcount, xfs_get_cowextsz_hint(ip));
     resblks = XFS_DIOSTRAT_SPACE_RES(mp, resaligned);
     xfs_iunlock(ip, *lockmode);
     error = xfs_trans_alloc(mp, &M_RES(mp)->tr_write, resblks, 0, 0, &tp);
     *lockmode = XFS_ILOCK_EXCL;
     xfs_ilock(ip, *lockmode);
     if (error) return error;
     error = xfs_qm_dqattach_locked(ip, false);
     if (error) goto out;
     goto retry;
   }
   error = xfs_trans_reserve_quota_nblks(tp, ip, resblks, 0, XFS_QMOPT_RES_REGBLKS);
   if (error) goto out;
   xfs_trans_ijoin(tp, ip, 0);
-  xfs_defer_init(&dfops, &first_block);
-  tp->t_dfops = &dfops;
+  xfs_defer_init(tp, &dfops, &first_block);
   nimaps = 1;
   /* Allocate the entire reservation as unwritten blocks. */
   error = xfs_bmapi_write(tp, ip, imap->br_startoff, imap->br_blockcount, XFS_BMAPI_COWFORK | XFS_BMAPI_PREALLOC, &first_block, resblks, imap, &nimaps);
   if (error) goto out_bmap_cancel;
   xfs_inode_set_cowblocks_tag(ip);
   /* Finish up. */
   error = xfs_defer_finish(&tp, tp->t_dfops);
   if (error) goto out_bmap_cancel;
   error = xfs_trans_commit(tp);
   if (error) return error;
   /*
    * Allocation succeeded but the requested range was not even partially
    * satisfied?  Bail out!
    */
   if (nimaps == 0) return -ENOSPC;
 convert:
   return xfs_reflink_convert_cow_extent(ip, imap, offset_fsb, count_fsb);
 out_bmap_cancel:
   xfs_defer_cancel(tp->t_dfops);
   xfs_trans_unreserve_quota_nblks(tp, ip, (long)resblks, 0, XFS_QMOPT_RES_REGBLKS);
 out:
   if (tp) xfs_trans_cancel(tp);
   return error;
 }<sep>@@
expression e1,e2,tp;
@@

-		xfs_defer_init(e1, e2);
-		(tp)->t_dfops = e1;
+		xfs_defer_init(tp, e1, e2);