OSDN Git Service

atomic_open(): saner calling conventions (return dentry on success)
authorAl Viro <viro@zeniv.linux.org.uk>
Thu, 9 Jan 2020 19:12:40 +0000 (14:12 -0500)
committerAl Viro <viro@zeniv.linux.org.uk>
Thu, 27 Feb 2020 19:43:56 +0000 (14:43 -0500)
Currently it either returns -E... or puts (nd->path.mnt,dentry)
into *path and returns 0.  Make it return ERR_PTR(-E...) or
dentry; adjust the caller.  Fewer arguments and it's easier
to keep track of *path contents that way.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
fs/namei.c

index c104ec7..5f8b791 100644 (file)
@@ -3087,10 +3087,10 @@ static int may_o_create(const struct path *dir, struct dentry *dentry, umode_t m
  *
  * Returns an error code otherwise.
  */
-static int atomic_open(struct nameidata *nd, struct dentry *dentry,
-                       struct path *path, struct file *file,
-                       const struct open_flags *op,
-                       int open_flag, umode_t mode)
+static struct dentry *atomic_open(struct nameidata *nd, struct dentry *dentry,
+                                 struct file *file,
+                                 const struct open_flags *op,
+                                 int open_flag, umode_t mode)
 {
        struct dentry *const DENTRY_NOT_SET = (void *) -1UL;
        struct inode *dir =  nd->path.dentry->d_inode;
@@ -3131,17 +3131,15 @@ static int atomic_open(struct nameidata *nd, struct dentry *dentry,
                        }
                        if (file->f_mode & FMODE_CREATED)
                                fsnotify_create(dir, dentry);
-                       if (unlikely(d_is_negative(dentry))) {
+                       if (unlikely(d_is_negative(dentry)))
                                error = -ENOENT;
-                       } else {
-                               path->dentry = dentry;
-                               path->mnt = nd->path.mnt;
-                               return 0;
-                       }
                }
        }
-       dput(dentry);
-       return error;
+       if (error) {
+               dput(dentry);
+               dentry = ERR_PTR(error);
+       }
+       return dentry;
 }
 
 /*
@@ -3236,11 +3234,20 @@ static int lookup_open(struct nameidata *nd, struct path *path,
        }
 
        if (dir_inode->i_op->atomic_open) {
-               error = atomic_open(nd, dentry, path, file, op, open_flag,
-                                   mode);
-               if (unlikely(error == -ENOENT) && create_error)
-                       error = create_error;
-               return error;
+               dentry = atomic_open(nd, dentry, file, op, open_flag, mode);
+               if (IS_ERR(dentry)) {
+                       error = PTR_ERR(dentry);
+                       if (unlikely(error == -ENOENT) && create_error)
+                               error = create_error;
+                       return error;
+               }
+               if (file->f_mode & FMODE_OPENED) {
+                       dput(dentry);
+                       return 0;
+               }
+               path->mnt = nd->path.mnt;
+               path->dentry = dentry;
+               return 0;
        }
 
 no_open: