diff options
author | Al Viro <viro@www.linux.org.uk> | 2005-06-06 16:36:08 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-06-06 17:42:26 -0400 |
commit | ba7a4c1a76f56c607560f1676680ff491747bdae (patch) | |
tree | c68f4fd0d5802819eb16dc6c126b2c24f4e09634 | |
parent | a15a3f6fc67d910f43098acec6e19d25a37d7cb9 (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.c | 10 |
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: | |||
1530 | exit_dput: | 1527 | exit_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; | ||
1535 | exit: | 1531 | exit: |
1536 | path_release(nd); | 1532 | path_release(nd); |
1537 | return error; | 1533 | return error; |