irqchip: tegra: Add Tegra210 support
[firefly-linux-kernel-4.4.55.git] / fs / namei.c
index 0bc7742a591dfd786504382d23abef2975cb6b03..c83145af4bfc0ea9bb159002e3545e8a8cd65157 100644 (file)
  * POSIX.1 2.4: an empty pathname is invalid (ENOENT).
  * PATH_MAX includes the nul terminator --RR.
  */
-void final_putname(struct filename *name)
-{
-       if (name->separate) {
-               __putname(name->name);
-               kfree(name);
-       } else {
-               __putname(name);
-       }
-}
 
 #define EMBEDDED_NAME_MAX      (PATH_MAX - sizeof(struct filename))
 
@@ -145,6 +136,7 @@ getname_flags(const char __user *filename, int flags, int *empty)
        result = __getname();
        if (unlikely(!result))
                return ERR_PTR(-ENOMEM);
+       result->refcnt = 1;
 
        /*
         * First, try to embed the struct filename inside the names_cache
@@ -179,6 +171,7 @@ recopy:
                }
                result->name = kname;
                result->separate = true;
+               result->refcnt = 1;
                max = PATH_MAX;
                goto recopy;
        }
@@ -202,7 +195,7 @@ recopy:
        return result;
 
 error:
-       final_putname(result);
+       putname(result);
        return err;
 }
 
@@ -243,18 +236,25 @@ getname_kernel(const char * filename)
        memcpy((char *)result->name, filename, len);
        result->uptr = NULL;
        result->aname = NULL;
+       result->refcnt = 1;
+       audit_getname(result);
 
        return result;
 }
 
-#ifdef CONFIG_AUDITSYSCALL
 void putname(struct filename *name)
 {
-       if (unlikely(!audit_dummy_context()))
-               return audit_putname(name);
-       final_putname(name);
+       BUG_ON(name->refcnt <= 0);
+
+       if (--name->refcnt > 0)
+               return;
+
+       if (name->separate) {
+               __putname(name->name);
+               kfree(name);
+       } else
+               __putname(name);
 }
-#endif
 
 static int check_acl(struct inode *inode, int mask)
 {
@@ -2373,13 +2373,17 @@ static int
 filename_mountpoint(int dfd, struct filename *s, struct path *path,
                        unsigned int flags)
 {
-       int error = path_mountpoint(dfd, s->name, path, flags | LOOKUP_RCU);
+       int error;
+       if (IS_ERR(s))
+               return PTR_ERR(s);
+       error = path_mountpoint(dfd, s->name, path, flags | LOOKUP_RCU);
        if (unlikely(error == -ECHILD))
                error = path_mountpoint(dfd, s->name, path, flags);
        if (unlikely(error == -ESTALE))
                error = path_mountpoint(dfd, s->name, path, flags | LOOKUP_REVAL);
        if (likely(!error))
                audit_inode(s, path->dentry, 0);
+       putname(s);
        return error;
 }
 
@@ -2401,27 +2405,14 @@ int
 user_path_mountpoint_at(int dfd, const char __user *name, unsigned int flags,
                        struct path *path)
 {
-       struct filename *s = getname(name);
-       int error;
-       if (IS_ERR(s))
-               return PTR_ERR(s);
-       error = filename_mountpoint(dfd, s, path, flags);
-       putname(s);
-       return error;
+       return filename_mountpoint(dfd, getname(name), path, flags);
 }
 
 int
 kern_path_mountpoint(int dfd, const char *name, struct path *path,
                        unsigned int flags)
 {
-       struct filename *s = getname_kernel(name);
-       int retval = PTR_ERR(s);
-
-       if (!IS_ERR(s)) {
-               retval = filename_mountpoint(dfd, s, path, flags);
-               putname(s);
-       }
-       return retval;
+       return filename_mountpoint(dfd, getname_kernel(name), path, flags);
 }
 EXPORT_SYMBOL(kern_path_mountpoint);
 
@@ -2823,7 +2814,7 @@ no_open:
                        } else if (!dentry->d_inode) {
                                goto out;
                        } else if ((open_flag & O_TRUNC) &&
-                                  S_ISREG(dentry->d_inode->i_mode)) {
+                                  d_is_reg(dentry)) {
                                goto out;
                        }
                        /* will fail later, go on to get the right error */