From: Mike Waychison The attached patch ensures that we grab vfsmount_lock when grabbing a reference to mnt_parent in follow_up and follow_dotdot. We also don't need to access ->mnt_parent in follow_mount and __follow_down to mntput because we already the parent pointer on the stack. --- 25-akpm/fs/namei.c | 16 +++++++++------- 1 files changed, 9 insertions(+), 7 deletions(-) diff -puN fs/namei.c~namei-needs-vfsmount_lock fs/namei.c --- 25/fs/namei.c~namei-needs-vfsmount_lock Mon Jan 26 16:05:22 2004 +++ 25-akpm/fs/namei.c Mon Jan 26 16:05:22 2004 @@ -420,15 +420,15 @@ int follow_up(struct vfsmount **mnt, str { struct vfsmount *parent; struct dentry *mountpoint; - spin_lock(&dcache_lock); + spin_lock(&vfsmount_lock); parent=(*mnt)->mnt_parent; if (parent == *mnt) { - spin_unlock(&dcache_lock); + spin_unlock(&vfsmount_lock); return 0; } mntget(parent); mountpoint=dget((*mnt)->mnt_mountpoint); - spin_unlock(&dcache_lock); + spin_unlock(&vfsmount_lock); dput(*dentry); *dentry = mountpoint; mntput(*mnt); @@ -446,9 +446,9 @@ static int follow_mount(struct vfsmount struct vfsmount *mounted = lookup_mnt(*mnt, *dentry); if (!mounted) break; + mntput(*mnt); *mnt = mounted; dput(*dentry); - mntput(mounted->mnt_parent); *dentry = dget(mounted->mnt_root); res = 1; } @@ -464,9 +464,9 @@ static inline int __follow_down(struct v mounted = lookup_mnt(*mnt, *dentry); if (mounted) { + mntput(*mnt); *mnt = mounted; dput(*dentry); - mntput(mounted->mnt_parent); *dentry = dget(mounted->mnt_root); return 1; } @@ -498,14 +498,16 @@ static inline void follow_dotdot(struct dput(old); break; } + spin_unlock(&dcache_lock); + spin_lock(&vfsmount_lock); parent = (*mnt)->mnt_parent; if (parent == *mnt) { - spin_unlock(&dcache_lock); + spin_unlock(&vfsmount_lock); break; } mntget(parent); *dentry = dget((*mnt)->mnt_mountpoint); - spin_unlock(&dcache_lock); + spin_unlock(&vfsmount_lock); dput(old); mntput(*mnt); *mnt = parent; _