summaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2010-01-30 15:47:29 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2010-03-03 14:07:56 -0500
commit3088dd7080d1ecc6d18c27ef9e617cbbd2a2e51e (patch)
tree4c31fc5f1710bafd79faa153839bbc617d1f715a /fs
parentde27a5bf9caef3f1fca1f315aa58eee54fbf929a (diff)
downloadlinux-3.10-3088dd7080d1ecc6d18c27ef9e617cbbd2a2e51e.tar.gz
linux-3.10-3088dd7080d1ecc6d18c27ef9e617cbbd2a2e51e.tar.bz2
linux-3.10-3088dd7080d1ecc6d18c27ef9e617cbbd2a2e51e.zip
Clean follow_dotdot() up a bit
No need to open-code follow_up() in it and locking can be lighter. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs')
-rw-r--r--fs/namei.c19
1 files changed, 3 insertions, 16 deletions
diff --git a/fs/namei.c b/fs/namei.c
index b20f83d1e06..3df2ed50ab5 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -689,33 +689,20 @@ static __always_inline void follow_dotdot(struct nameidata *nd)
set_root(nd);
while(1) {
- struct vfsmount *parent;
struct dentry *old = nd->path.dentry;
if (nd->path.dentry == nd->root.dentry &&
nd->path.mnt == nd->root.mnt) {
break;
}
- spin_lock(&dcache_lock);
if (nd->path.dentry != nd->path.mnt->mnt_root) {
- nd->path.dentry = dget(nd->path.dentry->d_parent);
- spin_unlock(&dcache_lock);
+ /* rare case of legitimate dget_parent()... */
+ nd->path.dentry = dget_parent(nd->path.dentry);
dput(old);
break;
}
- spin_unlock(&dcache_lock);
- spin_lock(&vfsmount_lock);
- parent = nd->path.mnt->mnt_parent;
- if (parent == nd->path.mnt) {
- spin_unlock(&vfsmount_lock);
+ if (!follow_up(&nd->path))
break;
- }
- mntget(parent);
- nd->path.dentry = dget(nd->path.mnt->mnt_mountpoint);
- spin_unlock(&vfsmount_lock);
- dput(old);
- mntput(nd->path.mnt);
- nd->path.mnt = parent;
}
follow_mount(&nd->path);
}