From: Hugh Dickins After chdir (or chroot) to non-existent directory on 2.6.5-mm5, you can no longer unmount filesystem holding working directory (or root). --- 25-akpm/fs/open.c | 14 ++++++++++---- 1 files changed, 10 insertions(+), 4 deletions(-) diff -puN fs/open.c~umount-after-bad-chdir fs/open.c --- 25/fs/open.c~umount-after-bad-chdir 2004-04-14 11:19:46.961042360 -0700 +++ 25-akpm/fs/open.c 2004-04-14 11:19:46.966041600 -0700 @@ -517,13 +517,16 @@ asmlinkage long sys_chdir(const char __u { struct nameidata nd; int error; - struct vfsmount *old_mnt = mntget(current->fs->pwdmnt); - struct dentry *old_dentry = dget(current->fs->pwd); + struct vfsmount *old_mnt; + struct dentry *old_dentry; error = __user_walk(filename, LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &nd); if (error) goto out; + old_mnt = mntget(current->fs->pwdmnt); + old_dentry = dget(current->fs->pwd); + error = permission(nd.dentry->d_inode,MAY_EXEC,&nd); if (error) goto dput_and_out; @@ -590,13 +593,16 @@ asmlinkage long sys_chroot(const char __ { struct nameidata nd; int error; - struct vfsmount *old_mnt = mntget(current->fs->rootmnt); - struct dentry *old_dentry = dget(current->fs->root); + struct vfsmount *old_mnt; + struct dentry *old_dentry; error = __user_walk(filename, LOOKUP_FOLLOW | LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd); if (error) goto out; + old_mnt = mntget(current->fs->pwdmnt); + old_dentry = dget(current->fs->pwd); + error = permission(nd.dentry->d_inode,MAY_EXEC,&nd); if (error) goto dput_and_out; _