]> err.no Git - linux-2.6/commitdiff
[PATCH] namei fixes (13/19)
authorAl Viro <viro@www.linux.org.uk>
Mon, 6 Jun 2005 20:36:08 +0000 (13:36 -0700)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Mon, 6 Jun 2005 21:42:26 +0000 (14:42 -0700)
In open_namei() exit_dput: we have mntput() done in the wrong order -
if nd->mnt != path.mnt we end up doing
mntput(nd->mnt);
nd->mnt = path.mnt;
dput(nd->dentry);
mntput(nd->mnt);
which drops nd->dentry too late.  Fixed by having path.mnt go first.
That allows to switch O_NOFOLLOW under if (__follow_mount(...)) back
to exit_dput, while we are at it.

Fix for early-mntput() race + equivalent transformation.

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 37fcf941fa3f92c4627dbc07c9ff5d76bb8cd338..5153f57ee6b382c12f6bc3161a97fd35530bbd4b 100644 (file)
@@ -1501,11 +1501,8 @@ do_last:
 
        if (__follow_mount(&path)) {
                error = -ELOOP;
-               if (flag & O_NOFOLLOW) {
-                       dput(path.dentry);
-                       mntput(path.mnt);
-                       goto exit;
-               }
+               if (flag & O_NOFOLLOW)
+                       goto exit_dput;
        }
        error = -ENOENT;
        if (!path.dentry->d_inode)
@@ -1530,8 +1527,7 @@ ok:
 exit_dput:
        dput(path.dentry);
        if (nd->mnt != path.mnt)
-               mntput(nd->mnt);
-       nd->mnt = path.mnt;
+               mntput(path.mnt);
 exit:
        path_release(nd);
        return error;