diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2010-01-30 15:47:29 -0500 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2010-03-03 14:07:56 -0500 |
commit | 3088dd7080d1ecc6d18c27ef9e617cbbd2a2e51e (patch) | |
tree | 4c31fc5f1710bafd79faa153839bbc617d1f715a /fs/namei.c | |
parent | de27a5bf9caef3f1fca1f315aa58eee54fbf929a (diff) | |
download | lwn-3088dd7080d1ecc6d18c27ef9e617cbbd2a2e51e.tar.gz lwn-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/namei.c')
-rw-r--r-- | fs/namei.c | 19 |
1 files changed, 3 insertions, 16 deletions
diff --git a/fs/namei.c b/fs/namei.c index b20f83d1e065..3df2ed50ab57 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); } |