diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/xfs/xfs_inode.c | 59 | ||||
-rw-r--r-- | fs/xfs/xfs_inode.h | 9 | ||||
-rw-r--r-- | fs/xfs/xfs_iops.c | 50 |
3 files changed, 61 insertions, 57 deletions
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 0533fa6a58f5..95906b4d44ab 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -695,44 +695,34 @@ xfs_bumplink( int xfs_create( - struct user_namespace *mnt_userns, - xfs_inode_t *dp, + struct xfs_inode *dp, struct xfs_name *name, - umode_t mode, - dev_t rdev, - bool init_xattrs, - xfs_inode_t **ipp) + const struct xfs_icreate_args *args, + struct xfs_inode **ipp) { - struct xfs_icreate_args args = { - .rdev = rdev, - .nlink = S_ISDIR(mode) ? 2 : 1, - }; - int is_dir = S_ISDIR(mode); 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; 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; + bool unlock_dp_on_error = false; + bool is_dir = S_ISDIR(args->mode); + uint resblks; + int error; + ASSERT(args->pip == dp); trace_xfs_create(dp, name); if (xfs_is_shutdown(mp)) return -EIO; - xfs_icreate_args_inherit(&args, dp, mnt_userns, mode); - if (init_xattrs) - args.flags |= XFS_ICREATE_ARGS_INIT_XATTRS; - /* * Make sure that we have allocated dquot(s) on disk. */ - error = xfs_qm_vop_dqalloc(dp, args.uid, args.gid, args.prid, + error = xfs_qm_vop_dqalloc(dp, args->uid, args->gid, args->prid, XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT, &udqp, &gdqp, &pdqp); if (error) @@ -776,9 +766,9 @@ xfs_create( * 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; @@ -859,32 +849,31 @@ xfs_create( int xfs_create_tmpfile( - struct user_namespace *mnt_userns, struct xfs_inode *dp, - umode_t mode, + const struct xfs_icreate_args *args, struct xfs_inode **ipp) { - struct xfs_icreate_args args = { NULL }; struct xfs_mount *mp = dp->i_mount; struct xfs_inode *ip = NULL; struct xfs_trans *tp = NULL; - int error; 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; + uint resblks; + int error; + + ASSERT(args->nlink == 0); + ASSERT(args->pip == dp); if (xfs_is_shutdown(mp)) return -EIO; - xfs_icreate_args_inherit(&args, dp, mnt_userns, mode); - /* * Make sure that we have allocated dquot(s) on disk. */ - error = xfs_qm_vop_dqalloc(dp, args.uid, args.gid, args.prid, + error = xfs_qm_vop_dqalloc(dp, args->uid, args->gid, args->prid, XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT, &udqp, &gdqp, &pdqp); if (error) @@ -898,9 +887,9 @@ xfs_create_tmpfile( 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; @@ -2878,11 +2867,15 @@ xfs_rename_alloc_whiteout( struct xfs_inode *dp, struct xfs_inode **wip) { + struct xfs_icreate_args args = { + .nlink = 0, + }; struct xfs_inode *tmpfile; int error; - error = xfs_create_tmpfile(mnt_userns, dp, S_IFCHR | WHITEOUT_MODE, - &tmpfile); + xfs_icreate_args_inherit(&args, dp, mnt_userns, S_IFCHR | WHITEOUT_MODE); + + error = xfs_create_tmpfile(dp, &args, &tmpfile); if (error) return error; diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index 5eb4dd5ccd6d..47c025a8984f 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h @@ -409,12 +409,11 @@ int xfs_release(struct xfs_inode *ip); void xfs_inactive(struct xfs_inode *ip); int xfs_lookup(struct xfs_inode *dp, struct xfs_name *name, struct xfs_inode **ipp, struct xfs_name *ci_name); -int xfs_create(struct user_namespace *mnt_userns, - struct xfs_inode *dp, struct xfs_name *name, - umode_t mode, dev_t rdev, bool need_xattr, +int xfs_create(struct xfs_inode *dp, struct xfs_name *name, + const struct xfs_icreate_args *iargs, struct xfs_inode **ipp); -int xfs_create_tmpfile(struct user_namespace *mnt_userns, - struct xfs_inode *dp, umode_t mode, +int xfs_create_tmpfile(struct xfs_inode *dp, + 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); diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c index b606d2827ed6..28f2ea1999c9 100644 --- a/fs/xfs/xfs_iops.c +++ b/fs/xfs/xfs_iops.c @@ -163,44 +163,56 @@ xfs_create_need_xattr( STATIC int xfs_generic_create( struct user_namespace *mnt_userns, - struct inode *dir, - struct dentry *dentry, - umode_t mode, - dev_t rdev, - bool tmpfile) /* unnamed file */ + struct inode *dir, + struct dentry *dentry, + umode_t mode, + dev_t rdev, + bool 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 = { + .rdev = rdev, + }; + struct inode *inode; + struct xfs_inode *ip = NULL; + struct posix_acl *default_acl, *acl; + struct xfs_name name; + int error; + + xfs_icreate_args_inherit(&args, XFS_I(dir), mnt_userns, mode); + if (tmpfile) + args.nlink = 0; + else if (S_ISDIR(mode)) + args.nlink = 2; + else + args.nlink = 1; /* * 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(mnt_userns, 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_ARGS_INIT_XATTRS; + error = xfs_create(XFS_I(dir), &name, &args, &ip); } else { - error = xfs_create_tmpfile(mnt_userns, XFS_I(dir), mode, &ip); + error = xfs_create_tmpfile(XFS_I(dir), &args, &ip); } if (unlikely(error)) goto out_free_acl; |