--- initial
+++ final
@@ -1,173 +1,172 @@
 int xfs_symlink(struct xfs_inode *dp, struct xfs_name *link_name, const char *target_path, umode_t mode, struct xfs_inode **ipp) {
   struct xfs_mount *mp = dp->i_mount;
   struct xfs_trans *tp = NULL;
   struct xfs_inode *ip = NULL;
   int error = 0;
   int pathlen;
   struct xfs_defer_ops dfops;
   xfs_fsblock_t first_block;
   bool unlock_dp_on_error = false;
   xfs_fileoff_t first_fsb;
   xfs_filblks_t fs_blocks;
   int nmaps;
   struct xfs_bmbt_irec mval[XFS_SYMLINK_MAPS];
   xfs_daddr_t d;
   const char *cur_chunk;
   int byte_cnt;
   int n;
   xfs_buf_t *bp;
   prid_t prid;
   struct xfs_dquot *udqp = NULL;
   struct xfs_dquot *gdqp = NULL;
   struct xfs_dquot *pdqp = NULL;
   uint resblks;
   *ipp = NULL;
   trace_xfs_symlink(dp, link_name);
   if (XFS_FORCED_SHUTDOWN(mp)) return -EIO;
   /*
    * Check component lengths of the target path name.
    */
   pathlen = strlen(target_path);
   if (pathlen >= XFS_SYMLINK_MAXLEN) /* total string too long */
     return -ENAMETOOLONG;
   udqp = gdqp = NULL;
   prid = xfs_get_initial_prid(dp);
   /*
    * Make sure that we have allocated dquot(s) on disk.
    */
   error = xfs_qm_vop_dqalloc(dp, xfs_kuid_to_uid(current_fsuid()), xfs_kgid_to_gid(current_fsgid()), prid, XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT, &udqp, &gdqp, &pdqp);
   if (error) return error;
   /*
    * The symlink will fit into the inode data fork?
    * There can't be any attributes so we get the whole variable part.
    */
   if (pathlen <= XFS_LITINO(mp, dp->i_d.di_version))
     fs_blocks = 0;
   else
     fs_blocks = xfs_symlink_blocks(mp, pathlen);
   resblks = XFS_SYMLINK_SPACE_RES(mp, link_name->len, fs_blocks);
   error = xfs_trans_alloc(mp, &M_RES(mp)->tr_symlink, resblks, 0, 0, &tp);
   if (error) goto out_release_inode;
   xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT);
   unlock_dp_on_error = true;
   /*
    * Check whether the directory allows new symlinks or not.
    */
   if (dp->i_d.di_flags & XFS_DIFLAG_NOSYMLINKS) {
     error = -EPERM;
     goto out_trans_cancel;
   }
   /*
    * Reserve disk quota : blocks and inode.
    */
   error = xfs_trans_reserve_quota(tp, mp, udqp, gdqp, pdqp, resblks, 1, 0);
   if (error) goto out_trans_cancel;
   /*
    * Initialize the bmap freelist prior to calling either
    * bmapi or the directory create code.
    */
-  xfs_defer_init(&dfops, &first_block);
-  tp->t_dfops = &dfops;
+  xfs_defer_init(tp, &dfops, &first_block);
   /*
    * Allocate an inode for the symlink.
    */
   error = xfs_dir_ialloc(&tp, dp, S_IFLNK | (mode & ~S_IFMT), 1, 0, prid, &ip);
   if (error) goto out_trans_cancel;
   /*
    * Now we join the directory inode to the transaction.  We do not do it
    * earlier because xfs_dir_ialloc might commit the previous transaction
    * (and release all the locks).  An error from here on will result in
    * the transaction cancel unlocking dp so don't do it explicitly in the
    * error path.
    */
   xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL);
   unlock_dp_on_error = false;
   /*
    * Also attach the dquot(s) to it, if applicable.
    */
   xfs_qm_vop_create_dqattach(tp, ip, udqp, gdqp, pdqp);
   if (resblks) resblks -= XFS_IALLOC_SPACE_RES(mp);
   /*
    * If the symlink will fit into the inode, write it inline.
    */
   if (pathlen <= XFS_IFORK_DSIZE(ip)) {
     xfs_init_local_fork(ip, XFS_DATA_FORK, target_path, pathlen);
     ip->i_d.di_size = pathlen;
     ip->i_d.di_format = XFS_DINODE_FMT_LOCAL;
     xfs_trans_log_inode(tp, ip, XFS_ILOG_DDATA | XFS_ILOG_CORE);
   } else {
     int offset;
     first_fsb = 0;
     nmaps = XFS_SYMLINK_MAPS;
     error = xfs_bmapi_write(tp, ip, first_fsb, fs_blocks, XFS_BMAPI_METADATA, &first_block, resblks, mval, &nmaps);
     if (error) goto out_bmap_cancel;
     if (resblks) resblks -= fs_blocks;
     ip->i_d.di_size = pathlen;
     xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
     cur_chunk = target_path;
     offset = 0;
     for (n = 0; n < nmaps; n++) {
       char *buf;
       d = XFS_FSB_TO_DADDR(mp, mval[n].br_startblock);
       byte_cnt = XFS_FSB_TO_B(mp, mval[n].br_blockcount);
       bp = xfs_trans_get_buf(tp, mp->m_ddev_targp, d, BTOBB(byte_cnt), 0);
       if (!bp) {
         error = -ENOMEM;
         goto out_bmap_cancel;
       }
       bp->b_ops = &xfs_symlink_buf_ops;
       byte_cnt = XFS_SYMLINK_BUF_SPACE(mp, byte_cnt);
       byte_cnt = min(byte_cnt, pathlen);
       buf = bp->b_addr;
       buf += xfs_symlink_hdr_set(mp, ip->i_ino, offset, byte_cnt, bp);
       memcpy(buf, cur_chunk, byte_cnt);
       cur_chunk += byte_cnt;
       pathlen -= byte_cnt;
       offset += byte_cnt;
       xfs_trans_buf_set_type(tp, bp, XFS_BLFT_SYMLINK_BUF);
       xfs_trans_log_buf(tp, bp, 0, (buf + byte_cnt - 1) - (char *)bp->b_addr);
     }
     ASSERT(pathlen == 0);
   }
   /*
    * Create the directory entry for the symlink.
    */
   error = xfs_dir_createname(tp, dp, link_name, ip->i_ino, &first_block, resblks);
   if (error) goto out_bmap_cancel;
   xfs_trans_ichgtime(tp, dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
   xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE);
   /*
    * If this is a synchronous mount, make sure that the
    * symlink 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, tp->t_dfops);
   if (error) goto out_bmap_cancel;
   error = xfs_trans_commit(tp);
   if (error) goto out_release_inode;
   xfs_qm_dqrele(udqp);
   xfs_qm_dqrele(gdqp);
   xfs_qm_dqrele(pdqp);
   *ipp = ip;
   return 0;
 out_bmap_cancel:
   xfs_defer_cancel(tp->t_dfops);
 out_trans_cancel:
   xfs_trans_cancel(tp);
 out_release_inode:
   /*
    * Wait until after the current transaction is aborted to finish the
    * setup of the inode and release the inode.  This prevents recursive
    * transactions and deadlocks from xfs_inactive.
    */
   if (ip) {
     xfs_finish_inode_setup(ip);
     IRELE(ip);
   }
   xfs_qm_dqrele(udqp);
   xfs_qm_dqrele(gdqp);
   xfs_qm_dqrele(pdqp);
   if (unlock_dp_on_error) 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);