]> git.hungrycats.org Git - linux/commitdiff
[PATCH] removal of LOOKUP_POSITIVE
authorAlexander Viro <viro@math.psu.edu>
Sat, 2 Mar 2002 05:30:13 +0000 (21:30 -0800)
committerLinus Torvalds <torvalds@penguin.transmeta.com>
Sat, 2 Mar 2002 05:30:13 +0000 (21:30 -0800)
LOOKUP_POSITIVE is not needed anymore.  All callers of path_walk()
treat -ENOENT and negative dentry the same way.  If you want a proof of
correctness - I'll send it, but it's a couple of pages of induction, basically
boiling down to "let's show that for any N we can replace the
               if (lookup_flags & (LOOKUP_POSITIVE|LOOKUP_DIRECTORY))
                       break;
in link_path_walk() with
               if ((lookup_flags & (LOOKUP_POSITIVE|LOOKUP_DIRECTORY)) ||
   current->link_count <= N)
                       break;
without changing behaviour of the system".  Pretty straightforward for
N = 0, then we look for places that can lead to call link_path_walk()
with current->link_count equal to N and show that if result of the test
changes, behaviour of callers doesn't.  Since the depth of recursion is
limited, we had shown that test in question can be replaced with if (1).
And that's the only place in tree the ever checks for LOOKUP_POSITIVE.

The real reason behind that is very simple - indeed, suppose
we get a negative dentry out of path_walk().  What the hell could we
do with it?  Its parent isn't locked, so both the name and parent can
change at any moment (could have changed already).  There used to be
places that tried to play "let's get a negative dentry, lock its parent
and start doing something".  All of them racy and all of them fixed
in 2.3.  Fixed by switching to LOOKUP_PARENT...

fs/exec.c
fs/intermezzo/presto.c
fs/intermezzo/vfs.c
fs/namei.c
fs/namespace.c
fs/nfsd/export.c
fs/open.c
fs/super.c
include/linux/fs.h
net/unix/af_unix.c

index bd153a4e55ad2513f895c094d746e786dc37c35c..3c98af10b3bc5c87b672480b7d8c9db325e0d0b8 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -347,7 +347,7 @@ struct file *open_exec(const char *name)
        struct file *file;
        int err = 0;
 
-       if (path_init(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, &nd))
+       if (path_init(name, LOOKUP_FOLLOW, &nd))
                err = path_walk(name, &nd);
        file = ERR_PTR(err);
        if (!err) {
index 8c0d22467901abb8dc02d0685058bb7d97ebdbd0..0b4ac7c97e2fece41bdd33b1854a1430f3b4f9a2 100644 (file)
@@ -40,7 +40,7 @@ int presto_walk(const char *name, struct nameidata *nd)
            resolved pathname and not the symlink. SHP
            XXX: This code implies that direct symlinks do not work. SHP
         */
-        unsigned int flags = LOOKUP_POSITIVE;
+        unsigned int flags = 0;
 
         ENTRY;
         err = 0;
index 2af4d255852faa1a881bdd3c07cab8affd885396..b632c8c92eebe0667e1edfa81e2aa79cecf914c1 100644 (file)
@@ -538,7 +538,7 @@ int lento_create(const char *name, int mode, struct lento_vfs_context *info)
         }
 
         /* this looks up the parent */
-//        if (path_init(pathname, LOOKUP_FOLLOW | LOOKUP_POSITIVE, &nd))
+//        if (path_init(pathname, LOOKUP_FOLLOW, &nd))
         if (path_init(pathname,  LOOKUP_PARENT, &nd))
                 error = path_walk(pathname, &nd);
         if (error) {
@@ -687,7 +687,7 @@ int lento_link(const char * oldname, const char * newname,
                 struct nameidata nd, old_nd;
 
                 error = 0;
-                if (path_init(from, LOOKUP_POSITIVE, &old_nd))
+                if (path_init(from, 0, &old_nd))
                         error = path_walk(from, &old_nd);
                 if (error)
                         goto exit;
index 1d9d4bebd2e732de7612d6dd87caca12a365e41f..46cbb0cf6d561d69e579e7c74d571900d289714a 100644 (file)
@@ -609,18 +609,13 @@ last_component:
                }
                err = -ENOENT;
                if (!inode)
-                       goto no_inode;
+                       break;
                if (lookup_flags & LOOKUP_DIRECTORY) {
                        err = -ENOTDIR; 
                        if (!inode->i_op || !inode->i_op->lookup)
                                break;
                }
                goto return_base;
-no_inode:
-               err = -ENOENT;
-               if (lookup_flags & (LOOKUP_POSITIVE|LOOKUP_DIRECTORY))
-                       break;
-               goto return_base;
 lookup_parent:
                nd->last = this;
                nd->last_type = LAST_NORM;
@@ -691,7 +686,7 @@ void set_fs_altroot(void)
                nd.mnt = mntget(current->fs->rootmnt);
                nd.dentry = dget(current->fs->root);
                read_unlock(&current->fs->lock);
-               nd.flags = LOOKUP_FOLLOW|LOOKUP_DIRECTORY|LOOKUP_POSITIVE;
+               nd.flags = LOOKUP_FOLLOW|LOOKUP_DIRECTORY;
                if (path_walk(emul,&nd) == 0) {
                        mnt = nd.mnt;
                        dentry = nd.dentry;
@@ -1648,7 +1643,7 @@ asmlinkage long sys_link(const char * oldname, const char * newname)
                struct nameidata nd, old_nd;
 
                error = 0;
-               if (path_init(from, LOOKUP_POSITIVE, &old_nd))
+               if (path_init(from, 0, &old_nd))
                        error = path_walk(from, &old_nd);
                if (error)
                        goto exit;
index 982a0cfd1c70bd9dec945ec7bfc26a78879455d8..835719e2dc95eb76424da3413224dc0989acb678 100644 (file)
@@ -368,7 +368,7 @@ asmlinkage long sys_umount(char * name, int flags)
        if (IS_ERR(kname))
                goto out;
        retval = 0;
-       if (path_init(kname, LOOKUP_POSITIVE|LOOKUP_FOLLOW, &nd))
+       if (path_init(kname, LOOKUP_FOLLOW, &nd))
                retval = path_walk(kname, &nd);
        putname(kname);
        if (retval)
@@ -497,7 +497,7 @@ static int do_loopback(struct nameidata *nd, char *old_name, int recurse)
                return err;
        if (!old_name || !*old_name)
                return -EINVAL;
-       if (path_init(old_name, LOOKUP_POSITIVE|LOOKUP_FOLLOW, &old_nd))
+       if (path_init(old_name, LOOKUP_FOLLOW, &old_nd))
                err = path_walk(old_name, &old_nd);
        if (err)
                return err;
@@ -564,7 +564,7 @@ static int do_move_mount(struct nameidata *nd, char *old_name)
                return -EPERM;
        if (!old_name || !*old_name)
                return -EINVAL;
-       if (path_init(old_name, LOOKUP_POSITIVE|LOOKUP_FOLLOW, &old_nd))
+       if (path_init(old_name, LOOKUP_FOLLOW, &old_nd))
                err = path_walk(old_name, &old_nd);
        if (err)
                return err;
@@ -731,7 +731,7 @@ long do_mount(char * dev_name, char * dir_name, char *type_page,
        flags &= ~(MS_NOSUID|MS_NOEXEC|MS_NODEV);
 
        /* ... and get the mountpoint */
-       if (path_init(dir_name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, &nd))
+       if (path_init(dir_name, LOOKUP_FOLLOW, &nd))
                retval = path_walk(dir_name, &nd);
        if (retval)
                return retval;
@@ -924,7 +924,7 @@ asmlinkage long sys_pivot_root(const char *new_root, const char *put_old)
        if (IS_ERR(name))
                goto out0;
        error = 0;
-       if (path_init(name, LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &new_nd))
+       if (path_init(name, LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &new_nd))
                error = path_walk(name, &new_nd);
        putname(name);
        if (error)
@@ -938,7 +938,7 @@ asmlinkage long sys_pivot_root(const char *new_root, const char *put_old)
        if (IS_ERR(name))
                goto out1;
        error = 0;
-       if (path_init(name, LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &old_nd))
+       if (path_init(name, LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &old_nd))
                error = path_walk(name, &old_nd);
        putname(name);
        if (error)
index 6f7339fb8b26d8c8ef86db8ba95ef7d4a09a80b5..1913b4d4da811d2c0c0a235b0dd6b11e264cdd10 100644 (file)
@@ -239,7 +239,7 @@ exp_export(struct nfsctl_export *nxp)
 
        /* Look up the dentry */
        err = 0;
-       if (path_init(nxp->ex_path, LOOKUP_POSITIVE, &nd))
+       if (path_init(nxp->ex_path, 0, &nd))
                err = path_walk(nxp->ex_path, &nd);
        if (err)
                goto out_unlock;
@@ -408,7 +408,7 @@ exp_rootfh(struct svc_client *clp, char *path, struct knfsd_fh *f, int maxsize)
 
        err = -EPERM;
        /* NB: we probably ought to check that it's NUL-terminated */
-       if (path_init(path, LOOKUP_POSITIVE, &nd) &&
+       if (path_init(path, 0, &nd) &&
            path_walk(path, &nd)) {
                printk("nfsd: exp_rootfh path not found %s", path);
                return err;
index aba53ed8dd838642700c723c661472b0f1e9fac2..f32c5aada4fdec2534c3834e4f7d86cc2bad4812 100644 (file)
--- a/fs/open.c
+++ b/fs/open.c
@@ -368,7 +368,7 @@ asmlinkage long sys_chdir(const char * filename)
                goto out;
 
        error = 0;
-       if (path_init(name,LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY,&nd))
+       if (path_init(name,LOOKUP_FOLLOW|LOOKUP_DIRECTORY,&nd))
                error = path_walk(name, &nd);
        putname(name);
        if (error)
@@ -427,8 +427,7 @@ asmlinkage long sys_chroot(const char * filename)
        if (IS_ERR(name))
                goto out;
 
-       path_init(name, LOOKUP_POSITIVE | LOOKUP_FOLLOW |
-                     LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd);
+       path_init(name, LOOKUP_FOLLOW | LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd);
        error = path_walk(name, &nd);   
        putname(name);
        if (error)
index 948cdc93188c04787f6f8399d120cac31b381bee..39ec3ab54d4ad30eeb776b766252d19ed8c18245 100644 (file)
@@ -700,7 +700,7 @@ struct super_block *get_sb_bdev(struct file_system_type *fs_type,
        /* What device it is? */
        if (!dev_name || !*dev_name)
                return ERR_PTR(-EINVAL);
-       if (path_init(dev_name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, &nd))
+       if (path_init(dev_name, LOOKUP_FOLLOW, &nd))
                error = path_walk(dev_name, &nd);
        if (error)
                return ERR_PTR(error);
index 414bf25bea5f0a6d9b10589a9ecc4f17c785a771..9178e479f2da213cf1b7c47bd542cbb765e249b2 100644 (file)
@@ -1273,7 +1273,6 @@ extern ino_t find_inode_number(struct dentry *, struct qstr *);
 #define LOOKUP_FOLLOW          (1)
 #define LOOKUP_DIRECTORY       (2)
 #define LOOKUP_CONTINUE                (4)
-#define LOOKUP_POSITIVE                (8)
 #define LOOKUP_PARENT          (16)
 #define LOOKUP_NOALT           (32)
 /*
@@ -1311,8 +1310,8 @@ extern int follow_down(struct vfsmount **, struct dentry **);
 extern int follow_up(struct vfsmount **, struct dentry **);
 extern struct dentry * lookup_one_len(const char *, struct dentry *, int);
 extern struct dentry * lookup_hash(struct qstr *, struct dentry *);
-#define user_path_walk(name,nd)         __user_walk(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd)
-#define user_path_walk_link(name,nd) __user_walk(name, LOOKUP_POSITIVE, nd)
+#define user_path_walk(name,nd)         __user_walk(name, LOOKUP_FOLLOW, nd)
+#define user_path_walk_link(name,nd) __user_walk(name, 0, nd)
 
 extern void inode_init_once(struct inode *);
 extern void iput(struct inode *);
index 47bd034ea7fbf19065f26d8b2928d34d68b3cbc6..274d9859fbd4a15c291340b3a58c1ed5f36875c9 100644 (file)
@@ -603,8 +603,7 @@ static unix_socket *unix_find_other(struct sockaddr_un *sunname, int len,
        int err = 0;
        
        if (sunname->sun_path[0]) {
-               if (path_init(sunname->sun_path, 
-                             LOOKUP_POSITIVE|LOOKUP_FOLLOW, &nd))
+               if (path_init(sunname->sun_path, LOOKUP_FOLLOW, &nd))
                        err = path_walk(sunname->sun_path, &nd);
                if (err)
                        goto fail;