aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Viro <viro@www.linux.org.uk>2005-06-06 16:36:08 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-06-06 17:42:26 -0400
commitba7a4c1a76f56c607560f1676680ff491747bdae (patch)
treec68f4fd0d5802819eb16dc6c126b2c24f4e09634
parenta15a3f6fc67d910f43098acec6e19d25a37d7cb9 (diff)
[PATCH] namei fixes (13/19)
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>
-rw-r--r--fs/namei.c10
1 files changed, 3 insertions, 7 deletions
diff --git a/fs/namei.c b/fs/namei.c
index 37fcf941fa3f..5153f57ee6b3 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1501,11 +1501,8 @@ do_last:
1501 1501
1502 if (__follow_mount(&path)) { 1502 if (__follow_mount(&path)) {
1503 error = -ELOOP; 1503 error = -ELOOP;
1504 if (flag & O_NOFOLLOW) { 1504 if (flag & O_NOFOLLOW)
1505 dput(path.dentry); 1505 goto exit_dput;
1506 mntput(path.mnt);
1507 goto exit;
1508 }
1509 } 1506 }
1510 error = -ENOENT; 1507 error = -ENOENT;
1511 if (!path.dentry->d_inode) 1508 if (!path.dentry->d_inode)
@@ -1530,8 +1527,7 @@ ok:
1530exit_dput: 1527exit_dput:
1531 dput(path.dentry); 1528 dput(path.dentry);
1532 if (nd->mnt != path.mnt) 1529 if (nd->mnt != path.mnt)
1533 mntput(nd->mnt); 1530 mntput(path.mnt);
1534 nd->mnt = path.mnt;
1535exit: 1531exit:
1536 path_release(nd); 1532 path_release(nd);
1537 return error; 1533 return error;