atomic_open(): reorder and clean up a bit
authorAl Viro <viro@zeniv.linux.org.uk>
Thu, 28 Apr 2016 06:03:55 +0000 (02:03 -0400)
committerAl Viro <viro@zeniv.linux.org.uk>
Mon, 2 May 2016 23:51:15 +0000 (19:51 -0400)
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
fs/namei.c

index 4359d22..8d62a89 100644 (file)
@@ -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;
 }