summaryrefslogtreecommitdiffstats
path: root/fs/namei.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2013-09-16 19:22:33 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2013-09-17 17:08:50 -0400
commit03da633aa7b08bdc4d86e9c2780bb89277b65cd6 (patch)
treef663ce0d2f49867c6b4f9b0631976a9e7ea9556a /fs/namei.c
parent116cc0225381415b96551f725455d067f63a76a0 (diff)
downloadlinux-03da633aa7b08bdc4d86e9c2780bb89277b65cd6.tar.bz2
atomic_open: take care of EEXIST in no-open case with O_CREAT|O_EXCL in fs/namei.c
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/namei.c')
-rw-r--r--fs/namei.c33
1 files changed, 19 insertions, 14 deletions
diff --git a/fs/namei.c b/fs/namei.c
index 22eb5484774c..645268f23eb6 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -2725,16 +2725,6 @@ static int atomic_open(struct nameidata *nd, struct dentry *dentry,
goto out;
}
- acc_mode = op->acc_mode;
- if (WARN_ON(excl && !(*opened & FILE_CREATED)))
- *opened |= FILE_CREATED;
-
- if (*opened & FILE_CREATED) {
- WARN_ON(!(open_flag & O_CREAT));
- fsnotify_create(dir, dentry);
- acc_mode = MAY_OPEN;
- }
-
if (error) { /* returned 1, that is */
if (WARN_ON(file->f_path.dentry == DENTRY_NOT_SET)) {
error = -EIO;
@@ -2744,10 +2734,19 @@ static int atomic_open(struct nameidata *nd, struct dentry *dentry,
dput(dentry);
dentry = file->f_path.dentry;
}
- WARN_ON(!dentry->d_inode && (*opened & FILE_CREATED));
- if (create_error && dentry->d_inode == NULL) {
- error = create_error;
- goto out;
+ if (*opened & FILE_CREATED)
+ fsnotify_create(dir, dentry);
+ if (!dentry->d_inode) {
+ WARN_ON(*opened & FILE_CREATED);
+ if (create_error) {
+ error = create_error;
+ goto out;
+ }
+ } else {
+ if (excl && !(*opened & FILE_CREATED)) {
+ error = -EEXIST;
+ goto out;
+ }
}
goto looked_up;
}
@@ -2756,6 +2755,12 @@ static int atomic_open(struct nameidata *nd, struct dentry *dentry,
* We didn't have the inode before the open, so check open permission
* here.
*/
+ acc_mode = op->acc_mode;
+ if (*opened & FILE_CREATED) {
+ WARN_ON(!(open_flag & O_CREAT));
+ fsnotify_create(dir, dentry);
+ acc_mode = MAY_OPEN;
+ }
error = may_open(&file->f_path, acc_mode, open_flag);
if (error)
fput(file);