int
 xfs_dialloc(
        struct xfs_trans        **tpp,
-       xfs_ino_t               parent,
-       umode_t                 mode,
+       const struct xfs_icreate_args *args,
        xfs_ino_t               *new_ino)
 {
        struct xfs_mount        *mp = (*tpp)->t_mountp;
+       xfs_ino_t               parent = args->pip ? args->pip->i_ino : 0;
+       umode_t                 mode = args->mode & S_IFMT;
        xfs_agnumber_t          agno;
        int                     error = 0;
        xfs_agnumber_t          start_agno;
 
        return xfs_buf_offset(b, o << (mp)->m_sb.sb_inodelog);
 }
 
+struct xfs_icreate_args;
+
 /*
  * Allocate an inode on disk.  Mode is used to tell whether the new inode will
  * need space, and whether it is a directory.
  */
-int xfs_dialloc(struct xfs_trans **tpp, xfs_ino_t parent, umode_t mode,
+int xfs_dialloc(struct xfs_trans **tpp, const struct xfs_icreate_args *args,
                xfs_ino_t *new_ino);
 
 int xfs_difree(struct xfs_trans *tp, struct xfs_perag *pag,
 
                goto out_release_dquots;
 
        /* Allocate inode, set up directory. */
-       error = xfs_dialloc(&tp, dp->i_ino, mode, &ino);
+       error = xfs_dialloc(&tp, &args, &ino);
        if (error)
                goto out_trans_cancel;
        error = xfs_icreate(tp, ino, &args, &sc->tempip);
 
         * entry pointing to them, but a directory also the "." entry
         * pointing to itself.
         */
-       error = xfs_dialloc(&tp, dp->i_ino, args->mode, &ino);
+       error = xfs_dialloc(&tp, args, &ino);
        if (!error)
                error = xfs_icreate(tp, ino, args, &du.ip);
        if (error)
        if (error)
                goto out_release_dquots;
 
-       error = xfs_dialloc(&tp, dp->i_ino, args->mode, &ino);
+       error = xfs_dialloc(&tp, args, &ino);
        if (!error)
                error = xfs_icreate(tp, ino, args, &ip);
        if (error)
 
                };
                xfs_ino_t       ino;
 
-               error = xfs_dialloc(&tp, 0, S_IFREG, &ino);
+               error = xfs_dialloc(&tp, &args, &ino);
                if (!error)
                        error = xfs_icreate(tp, ino, &args, ipp);
                if (error) {
 
        /*
         * Allocate an inode for the symlink.
         */
-       error = xfs_dialloc(&tp, dp->i_ino, S_IFLNK, &ino);
+       error = xfs_dialloc(&tp, &args, &ino);
        if (!error)
                error = xfs_icreate(tp, ino, &args, &du.ip);
        if (error)