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>
This commit is contained in:
parent
116cc02253
commit
03da633aa7
|
@ -267,14 +267,8 @@ v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Only creates */
|
/* Only creates */
|
||||||
if (!(flags & O_CREAT))
|
if (!(flags & O_CREAT) || dentry->d_inode)
|
||||||
return finish_no_open(file, res);
|
return finish_no_open(file, res);
|
||||||
else if (dentry->d_inode) {
|
|
||||||
if ((flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
|
|
||||||
return -EEXIST;
|
|
||||||
else
|
|
||||||
return finish_no_open(file, res);
|
|
||||||
}
|
|
||||||
|
|
||||||
v9ses = v9fs_inode2v9ses(dir);
|
v9ses = v9fs_inode2v9ses(dir);
|
||||||
|
|
||||||
|
|
33
fs/namei.c
33
fs/namei.c
|
@ -2725,16 +2725,6 @@ static int atomic_open(struct nameidata *nd, struct dentry *dentry,
|
||||||
goto out;
|
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 (error) { /* returned 1, that is */
|
||||||
if (WARN_ON(file->f_path.dentry == DENTRY_NOT_SET)) {
|
if (WARN_ON(file->f_path.dentry == DENTRY_NOT_SET)) {
|
||||||
error = -EIO;
|
error = -EIO;
|
||||||
|
@ -2744,10 +2734,19 @@ static int atomic_open(struct nameidata *nd, struct dentry *dentry,
|
||||||
dput(dentry);
|
dput(dentry);
|
||||||
dentry = file->f_path.dentry;
|
dentry = file->f_path.dentry;
|
||||||
}
|
}
|
||||||
WARN_ON(!dentry->d_inode && (*opened & FILE_CREATED));
|
if (*opened & FILE_CREATED)
|
||||||
if (create_error && dentry->d_inode == NULL) {
|
fsnotify_create(dir, dentry);
|
||||||
error = create_error;
|
if (!dentry->d_inode) {
|
||||||
goto out;
|
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;
|
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
|
* We didn't have the inode before the open, so check open permission
|
||||||
* here.
|
* 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);
|
error = may_open(&file->f_path, acc_mode, open_flag);
|
||||||
if (error)
|
if (error)
|
||||||
fput(file);
|
fput(file);
|
||||||
|
|
Loading…
Reference in New Issue