diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2016-04-26 14:17:56 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2016-05-02 19:49:33 -0400 |
commit | ce8644fcadc52da72e19ae9f0866fb3eb15d3df4 (patch) | |
tree | 5ebc6bbfa3e827378f0b771f713f0a87bd8b76e4 | |
parent | 6ac087099edf09ca357e2f765e3e24677543897c (diff) | |
download | op-kernel-dev-ce8644fcadc52da72e19ae9f0866fb3eb15d3df4.zip op-kernel-dev-ce8644fcadc52da72e19ae9f0866fb3eb15d3df4.tar.gz |
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>
-rw-r--r-- | fs/namei.c | 21 |
1 files changed, 12 insertions, 9 deletions
@@ -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; |