]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - fs/namei.c
Merge branch 'work.autofs' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
[linux.git] / fs / namei.c
index 209c51a5226c9cf1529e50c9696d09c469c3e2ab..671c3c1a3425bab83d07a6b1091360dc7d03b9f0 100644 (file)
@@ -596,14 +596,12 @@ static void terminate_walk(struct nameidata *nd)
                path_put(&nd->path);
                for (i = 0; i < nd->depth; i++)
                        path_put(&nd->stack[i].link);
-               if (nd->root.mnt && !(nd->flags & LOOKUP_ROOT)) {
+               if (nd->flags & LOOKUP_ROOT_GRABBED) {
                        path_put(&nd->root);
-                       nd->root.mnt = NULL;
+                       nd->flags &= ~LOOKUP_ROOT_GRABBED;
                }
        } else {
                nd->flags &= ~LOOKUP_RCU;
-               if (!(nd->flags & LOOKUP_ROOT))
-                       nd->root.mnt = NULL;
                rcu_read_unlock();
        }
        nd->depth = 0;
@@ -641,6 +639,14 @@ static bool legitimize_links(struct nameidata *nd)
        return true;
 }
 
+static bool legitimize_root(struct nameidata *nd)
+{
+       if (!nd->root.mnt || (nd->flags & LOOKUP_ROOT))
+               return true;
+       nd->flags |= LOOKUP_ROOT_GRABBED;
+       return legitimize_path(nd, &nd->root, nd->root_seq);
+}
+
 /*
  * Path walking has 2 modes, rcu-walk and ref-walk (see
  * Documentation/filesystems/path-lookup.txt).  In situations when we can't
@@ -671,23 +677,18 @@ static int unlazy_walk(struct nameidata *nd)
 
        nd->flags &= ~LOOKUP_RCU;
        if (unlikely(!legitimize_links(nd)))
-               goto out2;
-       if (unlikely(!legitimize_path(nd, &nd->path, nd->seq)))
                goto out1;
-       if (nd->root.mnt && !(nd->flags & LOOKUP_ROOT)) {
-               if (unlikely(!legitimize_path(nd, &nd->root, nd->root_seq)))
-                       goto out;
-       }
+       if (unlikely(!legitimize_path(nd, &nd->path, nd->seq)))
+               goto out;
+       if (unlikely(!legitimize_root(nd)))
+               goto out;
        rcu_read_unlock();
        BUG_ON(nd->inode != parent->d_inode);
        return 0;
 
-out2:
+out1:
        nd->path.mnt = NULL;
        nd->path.dentry = NULL;
-out1:
-       if (!(nd->flags & LOOKUP_ROOT))
-               nd->root.mnt = NULL;
 out:
        rcu_read_unlock();
        return -ECHILD;
@@ -727,23 +728,14 @@ static int unlazy_child(struct nameidata *nd, struct dentry *dentry, unsigned se
         */
        if (unlikely(!lockref_get_not_dead(&dentry->d_lockref)))
                goto out;
-       if (unlikely(read_seqcount_retry(&dentry->d_seq, seq))) {
-               rcu_read_unlock();
-               dput(dentry);
-               goto drop_root_mnt;
-       }
+       if (unlikely(read_seqcount_retry(&dentry->d_seq, seq)))
+               goto out_dput;
        /*
         * Sequence counts matched. Now make sure that the root is
         * still valid and get it if required.
         */
-       if (nd->root.mnt && !(nd->flags & LOOKUP_ROOT)) {
-               if (unlikely(!legitimize_path(nd, &nd->root, nd->root_seq))) {
-                       rcu_read_unlock();
-                       dput(dentry);
-                       return -ECHILD;
-               }
-       }
-
+       if (unlikely(!legitimize_root(nd)))
+               goto out_dput;
        rcu_read_unlock();
        return 0;
 
@@ -753,9 +745,10 @@ static int unlazy_child(struct nameidata *nd, struct dentry *dentry, unsigned se
        nd->path.dentry = NULL;
 out:
        rcu_read_unlock();
-drop_root_mnt:
-       if (!(nd->flags & LOOKUP_ROOT))
-               nd->root.mnt = NULL;
+       return -ECHILD;
+out_dput:
+       rcu_read_unlock();
+       dput(dentry);
        return -ECHILD;
 }
 
@@ -819,6 +812,7 @@ static void set_root(struct nameidata *nd)
                } while (read_seqcount_retry(&fs->seq, seq));
        } else {
                get_fs_root(fs, &nd->root);
+               nd->flags |= LOOKUP_ROOT_GRABBED;
        }
 }
 
@@ -1735,8 +1729,6 @@ static int pick_link(struct nameidata *nd, struct path *link,
                                nd->flags &= ~LOOKUP_RCU;
                                nd->path.mnt = NULL;
                                nd->path.dentry = NULL;
-                               if (!(nd->flags & LOOKUP_ROOT))
-                                       nd->root.mnt = NULL;
                                rcu_read_unlock();
                        } else if (likely(unlazy_walk(nd)) == 0)
                                error = nd_alloc_stack(nd);
@@ -2350,7 +2342,7 @@ int filename_lookup(int dfd, struct filename *name, unsigned flags,
                retval = path_lookupat(&nd, flags | LOOKUP_REVAL, path);
 
        if (likely(!retval))
-               audit_inode(name, path->dentry, flags & LOOKUP_PARENT);
+               audit_inode(name, path->dentry, 0);
        restore_nameidata();
        putname(name);
        return retval;
@@ -2391,7 +2383,7 @@ static struct filename *filename_parentat(int dfd, struct filename *name,
        if (likely(!retval)) {
                *last = nd.last;
                *type = nd.last_type;
-               audit_inode(name, parent->dentry, LOOKUP_PARENT);
+               audit_inode(name, parent->dentry, AUDIT_INODE_PARENT);
        } else {
                putname(name);
                name = ERR_PTR(retval);
@@ -2718,7 +2710,7 @@ filename_mountpoint(int dfd, struct filename *name, struct path *path,
        if (unlikely(error == -ESTALE))
                error = path_mountpoint(&nd, flags | LOOKUP_REVAL, path);
        if (likely(!error))
-               audit_inode(name, path->dentry, flags & LOOKUP_NO_EVAL);
+               audit_inode(name, path->dentry, AUDIT_INODE_NOEVAL);
        restore_nameidata();
        putname(name);
        return error;
@@ -3299,7 +3291,7 @@ static int do_last(struct nameidata *nd,
                if (error)
                        return error;
 
-               audit_inode(nd->name, dir, LOOKUP_PARENT);
+               audit_inode(nd->name, dir, AUDIT_INODE_PARENT);
                /* trailing slashes? */
                if (unlikely(nd->last.name[nd->last.len]))
                        return -EISDIR;