From: Pushed changes in sys_chdir and sys_chroot into the revalidate/lookup by using nameidata hint. --- 25-akpm/fs/autofs4/root.c | 49 ++----------------------------------------- 25-akpm/fs/open.c | 52 ---------------------------------------------- 2 files changed, 3 insertions(+), 98 deletions(-) diff -puN fs/autofs4/root.c~autofs4-fix-handling-of-chdir-and-chroot fs/autofs4/root.c --- 25/fs/autofs4/root.c~autofs4-fix-handling-of-chdir-and-chroot 2004-04-18 15:27:50.915829632 -0700 +++ 25-akpm/fs/autofs4/root.c 2004-04-18 15:27:50.921828720 -0700 @@ -77,24 +77,6 @@ static void autofs4_update_usage(struct } } -static void autofs4_check_pwd(struct file *file, struct file *fp) -{ - struct dentry *pwd = file->f_dentry; - struct dentry *new_pwd = fp->f_dentry; - struct vfsmount *new_mnt = fp->f_vfsmnt; - - /* dentry is a pwd of mountpoint so move to it */ - if (current->fs->pwd == pwd) - set_fs_pwd(current->fs, new_mnt, new_pwd); - - /* dentry is root of a chrooted mountpoint so move to it */ - if (current->fs->root == pwd) { - set_fs_root(current->fs, new_mnt, new_pwd); - /* alternate os ABI not supported */ - /* set_fs_altroot(); */ - } -} - /* * From 2.4 kernel readdir.c */ @@ -186,7 +168,7 @@ static int autofs4_dir_open(struct inode if (!empty) d_invalidate(dentry); - nd.flags = LOOKUP_CONTINUE; + nd.flags = LOOKUP_DIRECTORY; status = (dentry->d_op->d_revalidate)(dentry, &nd); if (!status) @@ -206,7 +188,6 @@ static int autofs4_dir_open(struct inode file->private_data = NULL; return status; } - autofs4_check_pwd(file, fp); file->private_data = fp; } out: @@ -324,7 +305,8 @@ static int try_to_fill_dentry(struct den return 1; } /* Trigger mount for path component or follow link */ - } else if (flags & LOOKUP_CONTINUE || current->link_count) { + } else if (flags & (LOOKUP_CONTINUE | LOOKUP_DIRECTORY) || + current->link_count) { DPRINTK(("try_to_fill_entry: waiting for mount name=%.*s\n", dentry->d_name.len, dentry->d_name.name)); @@ -337,31 +319,6 @@ static int try_to_fill_dentry(struct den dentry->d_flags &= ~DCACHE_AUTOFS_PENDING; return 0; } - /* also for chdir or chroot so subsequent path walks work properly */ - } else if (dentry == current->fs->pwd || dentry == current->fs->root) { - struct vfsmount *mnt; - - DPRINTK(("try_to_fill_entry: waiting for mount name=%.*s\n", - dentry->d_name.len, dentry->d_name.name)); - - dentry->d_flags |= DCACHE_AUTOFS_PENDING; - status = autofs4_wait(sbi, dentry, NFY_MOUNT); - - DPRINTK(("try_to_fill_entry: mount done status=%d\n", status)); - - if ( status ) { - dentry->d_flags &= ~DCACHE_AUTOFS_PENDING; - return 0; - } - - if (dentry == current->fs->pwd) { - mnt = lookup_mnt(current->fs->pwdmnt, dentry); - set_fs_pwd(current->fs, mnt, mnt->mnt_root); - } else { - mnt = lookup_mnt(current->fs->rootmnt, dentry); - set_fs_root(current->fs, mnt, mnt->mnt_root); - } - mntput(mnt); } /* We don't update the usages for the autofs daemon itself, this diff -puN fs/open.c~autofs4-fix-handling-of-chdir-and-chroot fs/open.c --- 25/fs/open.c~autofs4-fix-handling-of-chdir-and-chroot 2004-04-18 15:27:50.916829480 -0700 +++ 25-akpm/fs/open.c 2004-04-18 15:27:50.922828568 -0700 @@ -517,43 +517,18 @@ asmlinkage long sys_chdir(const char __u { struct nameidata nd; int error; - 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; set_fs_pwd(current->fs, nd.mnt, nd.dentry); - /* - * if we chdir to an autofs4 mount point we must get in early - * for subsequent path_walks to work properly. - */ - if (nd.dentry->d_op && nd.dentry->d_op->d_revalidate) { - int res; - - res = nd.dentry->d_op->d_revalidate(nd.dentry, &nd); - if (res) { - error = permission(current->fs->pwd->d_inode, MAY_EXEC, &nd); - if (!error) - goto dput_and_out; - } else - error = -ENOENT; - - set_fs_pwd(current->fs, old_mnt, old_dentry); - } - dput_and_out: - mntput(old_mnt); - dput(old_dentry); path_release(&nd); out: return error; @@ -593,16 +568,11 @@ asmlinkage long sys_chroot(const char __ { struct nameidata nd; int error; - 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; @@ -612,31 +582,9 @@ asmlinkage long sys_chroot(const char __ goto dput_and_out; set_fs_root(current->fs, nd.mnt, nd.dentry); - - /* - * if we chroot to an autofs4 mount point we must get in early - * for subsequent path_walks to work properly. - */ - if (nd.dentry->d_op && nd.dentry->d_op->d_revalidate) { - int res; - - res = nd.dentry->d_op->d_revalidate(nd.dentry, &nd); - if (res) { - error = permission(current->fs->pwd->d_inode, MAY_EXEC, &nd); - if (!error) - goto valid; - } else - error = -ENOENT; - - set_fs_root(current->fs, old_mnt, old_dentry); - goto dput_and_out; - } -valid: set_fs_altroot(); error = 0; dput_and_out: - mntput(old_mnt); - dput(old_dentry); path_release(&nd); out: return error; _