From: <raven@themaw.net>

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;

_