From ce8644fcadc52da72e19ae9f0866fb3eb15d3df4 Mon Sep 17 00:00:00 2001
From: Al Viro <viro@zeniv.linux.org.uk>
Date: Tue, 26 Apr 2016 14:17:56 -0400
Subject: 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>
---
 fs/namei.c | 21 ++++++++++++---------
 1 file changed, 12 insertions(+), 9 deletions(-)

(limited to 'fs/namei.c')

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;
-- 
cgit v1.2.3