[PATCH] namei fixes (6/19)
authorAl Viro <viro@www.linux.org.uk>
Mon, 6 Jun 2005 20:36:02 +0000 (13:36 -0700)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Mon, 6 Jun 2005 21:42:25 +0000 (14:42 -0700)
mntget(path->mnt) in do_follow_link() moved down to right before the
__do_follow_link() call and rigth after loop: resp.

dput()+mntput() on non-ELOOP branch moved up to right after __do_follow_link()
call.

resulting
loop:
mntget(path->mnt);
path_release(nd);
dput(path->mnt);
mntput(path->mnt);
replaced with equivalent
dput(path->mnt);
path_release(nd);

Equivalent transformations - the reason why we have that mntget() is that
__do_follow_link() can drop a reference to nd->mnt and that's what holds
path->mnt.  So that call can happen at any point prior to __do_follow_link()
touching nd->mnt.  The rest is obvious.

NOTE: current tree relies on symlinks *never* being mounted on anything.  It's
not hard to get rid of that assumption (actually, that will come for free
later in the series).  For now we are just not making the situation worse than
it is.

Signed-off-by: Al Viro <viro@parcelfarce.linux.theplanet.co.uk>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
fs/namei.c

index 020fb8c8d1cddb85b8b10714658b05774af9015c..519900d83bcb455eb9bdce80e53a961c4fe705b2 100644 (file)
@@ -526,7 +526,6 @@ static inline int __do_follow_link(struct dentry *dentry, struct nameidata *nd)
 static inline int do_follow_link(struct path *path, struct nameidata *nd)
 {
        int err = -ELOOP;
-       mntget(path->mnt);
        if (current->link_count >= MAX_NESTED_LINKS)
                goto loop;
        if (current->total_link_count >= 40)
@@ -539,16 +538,16 @@ static inline int do_follow_link(struct path *path, struct nameidata *nd)
        current->link_count++;
        current->total_link_count++;
        nd->depth++;
+       mntget(path->mnt);
        err = __do_follow_link(path->dentry, nd);
-       current->link_count--;
-       nd->depth--;
        dput(path->dentry);
        mntput(path->mnt);
+       current->link_count--;
+       nd->depth--;
        return err;
 loop:
-       path_release(nd);
        dput(path->dentry);
-       mntput(path->mnt);
+       path_release(nd);
        return err;
 }