int
 xfs_create(
-       struct mnt_idmap        *idmap,
-       struct xfs_inode        *dp,
+       const struct xfs_icreate_args *args,
        struct xfs_name         *name,
-       umode_t                 mode,
-       dev_t                   rdev,
-       bool                    init_xattrs,
-       xfs_inode_t             **ipp)
+       struct xfs_inode        **ipp)
 {
-       struct xfs_icreate_args args = {
-               .idmap          = idmap,
-               .pip            = dp,
-               .rdev           = rdev,
-               .mode           = mode,
-               .flags          = init_xattrs ? XFS_ICREATE_INIT_XATTRS : 0,
-       };
-       int                     is_dir = S_ISDIR(mode);
+       struct xfs_inode        *dp = args->pip;
        struct xfs_mount        *mp = dp->i_mount;
        struct xfs_inode        *ip = NULL;
        struct xfs_trans        *tp = NULL;
-       int                     error;
-       bool                    unlock_dp_on_error = false;
-       prid_t                  prid;
        struct xfs_dquot        *udqp = NULL;
        struct xfs_dquot        *gdqp = NULL;
        struct xfs_dquot        *pdqp = NULL;
        struct xfs_trans_res    *tres;
-       uint                    resblks;
-       xfs_ino_t               ino;
        struct xfs_parent_args  *ppargs;
+       xfs_ino_t               ino;
+       prid_t                  prid;
+       bool                    unlock_dp_on_error = false;
+       bool                    is_dir = S_ISDIR(args->mode);
+       uint                    resblks;
+       int                     error;
 
        trace_xfs_create(dp, name);
 
         * computation code must match what the VFS uses to assign i_[ug]id.
         * INHERIT adjusts the gid computation for setgid/grpid systems.
         */
-       error = xfs_qm_vop_dqalloc(dp, mapped_fsuid(idmap, i_user_ns(VFS_I(dp))),
-                       mapped_fsgid(idmap, i_user_ns(VFS_I(dp))), prid,
+       error = xfs_qm_vop_dqalloc(dp,
+                       mapped_fsuid(args->idmap, i_user_ns(VFS_I(dp))),
+                       mapped_fsgid(args->idmap, i_user_ns(VFS_I(dp))), prid,
                        XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT,
                        &udqp, &gdqp, &pdqp);
        if (error)
         * entry pointing to them, but a directory also the "." entry
         * pointing to itself.
         */
-       error = xfs_dialloc(&tp, dp->i_ino, mode, &ino);
+       error = xfs_dialloc(&tp, dp->i_ino, args->mode, &ino);
        if (!error)
-               error = xfs_icreate(tp, ino, &args, &ip);
+               error = xfs_icreate(tp, ino, args, &ip);
        if (error)
                goto out_trans_cancel;
 
 
 int
 xfs_create_tmpfile(
-       struct mnt_idmap        *idmap,
-       struct xfs_inode        *dp,
-       umode_t                 mode,
-       bool                    init_xattrs,
+       const struct xfs_icreate_args *args,
        struct xfs_inode        **ipp)
 {
-       struct xfs_icreate_args args = {
-               .idmap          = idmap,
-               .pip            = dp,
-               .mode           = mode,
-               .flags          = XFS_ICREATE_TMPFILE,
-       };
+       struct xfs_inode        *dp = args->pip;
        struct xfs_mount        *mp = dp->i_mount;
        struct xfs_inode        *ip = NULL;
        struct xfs_trans        *tp = NULL;
-       int                     error;
-       prid_t                  prid;
        struct xfs_dquot        *udqp = NULL;
        struct xfs_dquot        *gdqp = NULL;
        struct xfs_dquot        *pdqp = NULL;
        struct xfs_trans_res    *tres;
-       uint                    resblks;
        xfs_ino_t               ino;
+       prid_t                  prid;
+       uint                    resblks;
+       int                     error;
+
+       ASSERT(args->flags & XFS_ICREATE_TMPFILE);
 
        if (xfs_is_shutdown(mp))
                return -EIO;
 
        prid = xfs_get_initial_prid(dp);
-       if (init_xattrs)
-               args.flags |= XFS_ICREATE_INIT_XATTRS;
 
        /*
         * Make sure that we have allocated dquot(s) on disk.  The uid/gid
         * computation code must match what the VFS uses to assign i_[ug]id.
         * INHERIT adjusts the gid computation for setgid/grpid systems.
         */
-       error = xfs_qm_vop_dqalloc(dp, mapped_fsuid(idmap, i_user_ns(VFS_I(dp))),
-                       mapped_fsgid(idmap, i_user_ns(VFS_I(dp))), prid,
+       error = xfs_qm_vop_dqalloc(dp,
+                       mapped_fsuid(args->idmap, i_user_ns(VFS_I(dp))),
+                       mapped_fsgid(args->idmap, i_user_ns(VFS_I(dp))), prid,
                        XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT,
                        &udqp, &gdqp, &pdqp);
        if (error)
        if (error)
                goto out_release_dquots;
 
-       error = xfs_dialloc(&tp, dp->i_ino, mode, &ino);
+       error = xfs_dialloc(&tp, dp->i_ino, args->mode, &ino);
        if (!error)
-               error = xfs_icreate(tp, ino, &args, &ip);
+               error = xfs_icreate(tp, ino, args, &ip);
        if (error)
                goto out_trans_cancel;
 
        struct xfs_inode        *dp,
        struct xfs_inode        **wip)
 {
+       struct xfs_icreate_args args = {
+               .idmap          = idmap,
+               .pip            = dp,
+               .mode           = S_IFCHR | WHITEOUT_MODE,
+               .flags          = XFS_ICREATE_TMPFILE,
+       };
        struct xfs_inode        *tmpfile;
        struct qstr             name;
        int                     error;
 
-       error = xfs_create_tmpfile(idmap, dp, S_IFCHR | WHITEOUT_MODE,
-                       xfs_has_parent(dp->i_mount), &tmpfile);
+       if (xfs_has_parent(dp->i_mount))
+               args.flags |= XFS_ICREATE_INIT_XATTRS;
+
+       error = xfs_create_tmpfile(&args, &tmpfile);
        if (error)
                return error;
 
 
 int            xfs_inactive(struct xfs_inode *ip);
 int            xfs_lookup(struct xfs_inode *dp, const struct xfs_name *name,
                           struct xfs_inode **ipp, struct xfs_name *ci_name);
-int            xfs_create(struct mnt_idmap *idmap,
-                          struct xfs_inode *dp, struct xfs_name *name,
-                          umode_t mode, dev_t rdev, bool need_xattr,
-                          struct xfs_inode **ipp);
-int            xfs_create_tmpfile(struct mnt_idmap *idmap,
-                          struct xfs_inode *dp, umode_t mode, bool init_xattrs,
+int            xfs_create(const struct xfs_icreate_args *iargs,
+                          struct xfs_name *name, struct xfs_inode **ipp);
+int            xfs_create_tmpfile(const struct xfs_icreate_args *iargs,
                           struct xfs_inode **ipp);
 int            xfs_remove(struct xfs_inode *dp, struct xfs_name *name,
                           struct xfs_inode *ip);
 
        dev_t                   rdev,
        struct file             *tmpfile)       /* unnamed file */
 {
-       struct inode    *inode;
-       struct xfs_inode *ip = NULL;
-       struct posix_acl *default_acl, *acl;
-       struct xfs_name name;
-       int             error;
+       struct xfs_icreate_args args = {
+               .idmap          = idmap,
+               .pip            = XFS_I(dir),
+               .rdev           = rdev,
+               .mode           = mode,
+       };
+       struct inode            *inode;
+       struct xfs_inode        *ip = NULL;
+       struct posix_acl        *default_acl, *acl;
+       struct xfs_name         name;
+       int                     error;
 
        /*
         * Irix uses Missed'em'V split, but doesn't want to see
         * the upper 5 bits of (14bit) major.
         */
-       if (S_ISCHR(mode) || S_ISBLK(mode)) {
-               if (unlikely(!sysv_valid_dev(rdev) || MAJOR(rdev) & ~0x1ff))
+       if (S_ISCHR(args.mode) || S_ISBLK(args.mode)) {
+               if (unlikely(!sysv_valid_dev(args.rdev) ||
+                            MAJOR(args.rdev) & ~0x1ff))
                        return -EINVAL;
        } else {
-               rdev = 0;
+               args.rdev = 0;
        }
 
-       error = posix_acl_create(dir, &mode, &default_acl, &acl);
+       error = posix_acl_create(dir, &args.mode, &default_acl, &acl);
        if (error)
                return error;
 
        /* Verify mode is valid also for tmpfile case */
-       error = xfs_dentry_mode_to_name(&name, dentry, mode);
+       error = xfs_dentry_mode_to_name(&name, dentry, args.mode);
        if (unlikely(error))
                goto out_free_acl;
 
        if (!tmpfile) {
-               error = xfs_create(idmap, XFS_I(dir), &name, mode, rdev,
-                               xfs_create_need_xattr(dir, default_acl, acl),
-                               &ip);
+               if (xfs_create_need_xattr(dir, default_acl, acl))
+                       args.flags |= XFS_ICREATE_INIT_XATTRS;
+
+               error = xfs_create(&args, &name, &ip);
        } else {
-               bool    init_xattrs = false;
+               args.flags |= XFS_ICREATE_TMPFILE;
 
                /*
                 * If this temporary file will be linkable, set up the file
                 */
                if (!(tmpfile->f_flags & O_EXCL) &&
                    xfs_has_parent(XFS_I(dir)->i_mount))
-                       init_xattrs = true;
+                       args.flags |= XFS_ICREATE_INIT_XATTRS;
 
-               error = xfs_create_tmpfile(idmap, XFS_I(dir), mode,
-                               init_xattrs, &ip);
+               error = xfs_create_tmpfile(&args, &ip);
        }
        if (unlikely(error))
                goto out_free_acl;