summaryrefslogtreecommitdiff
path: root/fs/namei.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2016-04-26 14:17:56 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2016-05-02 19:49:33 -0400
commitce8644fcadc52da72e19ae9f0866fb3eb15d3df4 (patch)
tree5ebc6bbfa3e827378f0b771f713f0a87bd8b76e4 /fs/namei.c
parent6ac087099edf09ca357e2f765e3e24677543897c (diff)
lookup_open(): expand the call of vfs_create()
Lift IS_DEADDIR handling up into the part common with atomic_open(), remove it from the latter. Collapse permission checks into the call of may_o_create(), getting it closer to atomic_open() case. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/namei.c')
-rw-r--r--fs/namei.c21
1 files changed, 12 insertions, 9 deletions
diff --git a/fs/namei.c b/fs/namei.c
index 8145b415e257..f2d55c835bb9 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -2838,12 +2838,6 @@ static int atomic_open(struct nameidata *nd, struct dentry *dentry,
BUG_ON(dentry->d_inode);
- /* Don't create child dentry for a dead directory. */
- if (unlikely(IS_DEADDIR(dir))) {
- error = -ENOENT;
- goto out;
- }
-
mode = op->mode;
if ((open_flag & O_CREAT) && !IS_POSIXACL(dir))
mode &= ~current_umask();
@@ -3004,6 +2998,9 @@ static int lookup_open(struct nameidata *nd, struct path *path,
int error;
bool need_lookup = false;
+ if (unlikely(IS_DEADDIR(dir_inode)))
+ return -ENOENT;
+
*opened &= ~FILE_CREATED;
dentry = lookup_dcache(&nd->last, dir, nd->flags);
if (IS_ERR(dentry))
@@ -3049,13 +3046,19 @@ static int lookup_open(struct nameidata *nd, struct path *path,
goto out_dput;
}
*opened |= FILE_CREATED;
- error = security_path_mknod(&nd->path, dentry, mode, 0);
+ audit_inode_child(dir_inode, dentry, AUDIT_TYPE_CHILD_CREATE);
+ error = may_o_create(&nd->path, dentry, mode);
if (error)
goto out_dput;
- error = vfs_create(dir->d_inode, dentry, mode,
- nd->flags & LOOKUP_EXCL);
+ if (!dir_inode->i_op->create) {
+ error = -EACCES;
+ goto out_dput;
+ }
+ error = dir_inode->i_op->create(dir_inode, dentry, mode,
+ op->open_flag & O_EXCL);
if (error)
goto out_dput;
+ fsnotify_create(dir_inode, dentry);
}
out_no_open:
path->dentry = dentry;