diff options
Diffstat (limited to 'fs/namei.c')
-rw-r--r-- | fs/namei.c | 61 |
1 files changed, 27 insertions, 34 deletions
diff --git a/fs/namei.c b/fs/namei.c index 4359d22f43f4..8d62a89d7bff 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -2827,14 +2827,11 @@ static int atomic_open(struct nameidata *nd, struct dentry *dentry, int open_flag, umode_t mode, int *opened) { + struct dentry *const DENTRY_NOT_SET = (void *) -1UL; struct inode *dir = nd->path.dentry->d_inode; int error; - int acc_mode; - struct dentry *const DENTRY_NOT_SET = (void *) -1UL; - bool excl; - excl = (open_flag & (O_EXCL | O_CREAT)) == (O_EXCL | O_CREAT); - if (excl) + if (!(~open_flag & (O_EXCL | O_CREAT))) /* both O_EXCL and O_CREAT */ open_flag &= ~O_TRUNC; if (nd->flags & LOOKUP_DIRECTORY) @@ -2845,39 +2842,35 @@ static int atomic_open(struct nameidata *nd, struct dentry *dentry, error = dir->i_op->atomic_open(dir, dentry, file, open_to_namei_flags(open_flag), mode, opened); - if (error < 0) - goto out; - - if (error) { /* returned 1, that is */ + if (!error) { + /* + * We didn't have the inode before the open, so check open + * permission here. + */ + int acc_mode = op->acc_mode; + if (*opened & FILE_CREATED) { + WARN_ON(!(open_flag & O_CREAT)); + 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 (error > 0) { if (WARN_ON(file->f_path.dentry == DENTRY_NOT_SET)) { error = -EIO; - goto out; - } - if (file->f_path.dentry) { - dput(dentry); - dentry = file->f_path.dentry; + } else { + if (file->f_path.dentry) { + dput(dentry); + dentry = file->f_path.dentry; + } + if (*opened & FILE_CREATED) + fsnotify_create(dir, dentry); + path->dentry = dentry; + path->mnt = nd->path.mnt; + return 1; } - if (*opened & FILE_CREATED) - fsnotify_create(dir, dentry); - path->dentry = dentry; - path->mnt = nd->path.mnt; - return 1; } - - /* - * 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 = 0; - } - error = may_open(&file->f_path, acc_mode, open_flag); - if (WARN_ON(error > 0)) - error = -EINVAL; -out: dput(dentry); return error; } |