diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2020-01-26 16:02:29 +0100 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2020-03-14 02:09:12 +0100 |
commit | 7be219b4dcd9c698a120726e48a52b96f554fd2c (patch) | |
tree | 9b0a4527b5326297de13937d6b71c95122ea8964 /fs/namei.c | |
parent | atomic_open(): return the right dentry in FMODE_OPENED case (diff) | |
download | linux-7be219b4dcd9c698a120726e48a52b96f554fd2c.tar.xz linux-7be219b4dcd9c698a120726e48a52b96f554fd2c.zip |
atomic_open(): lift the call of may_open() into do_last()
there we'll be able to merge it with its counterparts in other
cases, and there's no reason to do it before the parent has
been unlocked
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to '')
-rw-r--r-- | fs/namei.c | 26 |
1 files changed, 11 insertions, 15 deletions
diff --git a/fs/namei.c b/fs/namei.c index 88f985aff4f8..7e932d9a71a9 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -2949,23 +2949,12 @@ static struct dentry *atomic_open(struct nameidata *nd, struct dentry *dentry, d_lookup_done(dentry); if (!error) { if (file->f_mode & FMODE_OPENED) { - int acc_mode = op->acc_mode; if (unlikely(dentry != file->f_path.dentry)) { dput(dentry); dentry = dget(file->f_path.dentry); } - /* - * We didn't have the inode before the open, so check open - * permission here. - */ - if (file->f_mode & FMODE_CREATED) { - WARN_ON(!(open_flag & O_CREAT)); + if (file->f_mode & FMODE_CREATED) fsnotify_create(dir, dentry); - acc_mode = 0; - } - error = may_open(&file->f_path, acc_mode, open_flag); - if (WARN_ON(error > 0)) - error = -EINVAL; } else if (WARN_ON(file->f_path.dentry == DENTRY_NOT_SET)) { error = -EIO; } else { @@ -3208,12 +3197,19 @@ static const char *do_last(struct nameidata *nd, } if (file->f_mode & FMODE_OPENED) { - if ((file->f_mode & FMODE_CREATED) || - !S_ISREG(file_inode(file)->i_mode)) + if (file->f_mode & FMODE_CREATED) { + open_flag &= ~O_TRUNC; + will_truncate = false; + acc_mode = 0; + } else if (!S_ISREG(file_inode(file)->i_mode)) will_truncate = false; audit_inode(nd->name, file->f_path.dentry, 0); - dput(dentry); + dput(nd->path.dentry); + nd->path.dentry = dentry; + error = may_open(&nd->path, acc_mode, open_flag); + if (error) + goto out; goto opened; } |