summaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/xfs/xfs_inode.c59
-rw-r--r--fs/xfs/xfs_inode.h9
-rw-r--r--fs/xfs/xfs_iops.c50
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;