summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2016-04-28 09:03:55 +0300
committerAl Viro <viro@zeniv.linux.org.uk>2016-05-03 02:51:15 +0300
commit384f26e28fe4ddc75e7cf8e0e21595964d03d8eb (patch)
tree7b8eea6bc71df6e4b7a6321fe9e14e0927d6a174
parent1643b43fbd0524e7da7259075032936c8fb68a05 (diff)
downloadlinux-384f26e28fe4ddc75e7cf8e0e21595964d03d8eb.tar.xz
atomic_open(): reorder and clean up a bit
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r--fs/namei.c61
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;
}