--- initial
+++ final
@@ -1,118 +1,117 @@
 int xfs_iomap_write_direct(xfs_inode_t *ip, xfs_off_t offset, size_t count, xfs_bmbt_irec_t *imap, int nmaps) {
   xfs_mount_t *mp = ip->i_mount;
   xfs_fileoff_t offset_fsb;
   xfs_fileoff_t last_fsb;
   xfs_filblks_t count_fsb, resaligned;
   xfs_fsblock_t firstfsb;
   xfs_extlen_t extsz;
   int nimaps;
   int quota_flag;
   int rt;
   xfs_trans_t *tp;
   struct xfs_defer_ops dfops;
   uint qblocks, resblks, resrtextents;
   int error;
   int lockmode;
   int bmapi_flags = XFS_BMAPI_PREALLOC;
   uint tflags = 0;
   rt = XFS_IS_REALTIME_INODE(ip);
   extsz = xfs_get_extsz_hint(ip);
   lockmode = XFS_ILOCK_SHARED; /* locked by caller */
   ASSERT(xfs_isilocked(ip, lockmode));
   offset_fsb = XFS_B_TO_FSBT(mp, offset);
   last_fsb = XFS_B_TO_FSB(mp, ((xfs_ufsize_t)(offset + count)));
   if ((offset + count) > XFS_ISIZE(ip)) {
     /*
      * Assert that the in-core extent list is present since this can
      * call xfs_iread_extents() and we only have the ilock shared.
      * This should be safe because the lock was held around a bmapi
      * call in the caller and we only need it to access the in-core
      * list.
      */
     ASSERT(XFS_IFORK_PTR(ip, XFS_DATA_FORK)->if_flags & XFS_IFEXTENTS);
     error = xfs_iomap_eof_align_last_fsb(ip, extsz, &last_fsb);
     if (error) goto out_unlock;
   } else {
     if (nmaps && (imap->br_startblock == HOLESTARTBLOCK)) last_fsb = min(last_fsb, (xfs_fileoff_t)imap->br_blockcount + imap->br_startoff);
   }
   count_fsb = last_fsb - offset_fsb;
   ASSERT(count_fsb > 0);
   resaligned = xfs_aligned_fsb_count(offset_fsb, count_fsb, extsz);
   if (unlikely(rt)) {
     resrtextents = qblocks = resaligned;
     resrtextents /= mp->m_sb.sb_rextsize;
     resblks = XFS_DIOSTRAT_SPACE_RES(mp, 0);
     quota_flag = XFS_QMOPT_RES_RTBLKS;
   } else {
     resrtextents = 0;
     resblks = qblocks = XFS_DIOSTRAT_SPACE_RES(mp, resaligned);
     quota_flag = XFS_QMOPT_RES_REGBLKS;
   }
   /*
    * Drop the shared lock acquired by the caller, attach the dquot if
    * necessary and move on to transaction setup.
    */
   xfs_iunlock(ip, lockmode);
   error = xfs_qm_dqattach(ip);
   if (error) return error;
   /*
    * For DAX, we do not allocate unwritten extents, but instead we zero
    * the block before we commit the transaction.  Ideally we'd like to do
    * this outside the transaction context, but if we commit and then crash
    * we may not have zeroed the blocks and this will be exposed on
    * recovery of the allocation. Hence we must zero before commit.
    *
    * Further, if we are mapping unwritten extents here, we need to zero
    * and convert them to written so that we don't need an unwritten extent
    * callback for DAX. This also means that we need to be able to dip into
    * the reserve block pool for bmbt block allocation if there is no space
    * left but we need to do unwritten extent conversion.
    */
   if (IS_DAX(VFS_I(ip))) {
     bmapi_flags = XFS_BMAPI_CONVERT | XFS_BMAPI_ZERO;
     if (imap->br_state == XFS_EXT_UNWRITTEN) {
       tflags |= XFS_TRANS_RESERVE;
       resblks = XFS_DIOSTRAT_SPACE_RES(mp, 0) << 1;
     }
   }
   error = xfs_trans_alloc(mp, &M_RES(mp)->tr_write, resblks, resrtextents, tflags, &tp);
   if (error) return error;
   lockmode = XFS_ILOCK_EXCL;
   xfs_ilock(ip, lockmode);
   error = xfs_trans_reserve_quota_nblks(tp, ip, qblocks, 0, quota_flag);
   if (error) goto out_trans_cancel;
   xfs_trans_ijoin(tp, ip, 0);
   /*
    * From this point onwards we overwrite the imap pointer that the
    * caller gave to us.
    */
-  xfs_defer_init(&dfops, &firstfsb);
-  tp->t_dfops = &dfops;
+  xfs_defer_init(tp, &dfops, &firstfsb);
   nimaps = 1;
   error = xfs_bmapi_write(tp, ip, offset_fsb, count_fsb, bmapi_flags, &firstfsb, resblks, imap, &nimaps);
   if (error) goto out_bmap_cancel;
   /*
    * Complete the transaction
    */
   error = xfs_defer_finish(&tp, tp->t_dfops);
   if (error) goto out_bmap_cancel;
   error = xfs_trans_commit(tp);
   if (error) goto out_unlock;
   /*
    * Copy any maps to caller's array and return any error.
    */
   if (nimaps == 0) {
     error = -ENOSPC;
     goto out_unlock;
   }
   if (!(imap->br_startblock || XFS_IS_REALTIME_INODE(ip))) error = xfs_alert_fsblock_zero(ip, imap);
 out_unlock:
   xfs_iunlock(ip, lockmode);
   return error;
 out_bmap_cancel:
   xfs_defer_cancel(tp->t_dfops);
   xfs_trans_unreserve_quota_nblks(tp, ip, (long)qblocks, 0, quota_flag);
 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);