linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC 00/10] Split up struct nameidata (take 3)
@ 2007-08-08 17:16 Andreas Gruenbacher
  2007-08-08 17:16 ` [RFC 01/10] Split up struct nameidata Andreas Gruenbacher
                   ` (9 more replies)
  0 siblings, 10 replies; 35+ messages in thread
From: Andreas Gruenbacher @ 2007-08-08 17:16 UTC (permalink / raw)
  To: linux-kernel
  Cc: John Johansen, Jan Blunck, Erez Zadok, Josef 'Jeff' Sipek

In several places where no nameidata object is available, we are
currently passing NULL instead of constructing a temporary nameidata
object.  This is because struct nameidata is big, and constructing
temporary nameidata objects is not efficient.  Here is another shot at
splitting up struct nameidata: struct vfs_lookup is similar to struct
nameidata but leaves out the fields required only while walking an
actual pathname.  It fits in 24 bytes as opposed to 80 on x86.

This allows to construct temporary vfs_lookup objects where needed
instead of the NULL passing, which gets rid of the associated NULL
checking, and ensures that struct vfsmnt and the lookup intent are
passed down consistently.

In addition, the dentry and vfsmnt in struct vfs_lookup (before: struct
nameidata) are put inside a struct path. This allows to use
path{get,put} instead of mnt{get,put} plus d{get,put}, resulting in more
consistent code. The path{get,put} functions seemingly were suggested by
Erez Zadok / Josef 'Jeff' Sipek; Jan Blunck has been working on this
recently as well.


This proposal consists of the following patches:

nameidata-split.diff

	Introduce struct vfs_lookup and change struct nameidata to
	embed a struct vfs_lookup.  (Requires the next patch to build.)

nameidata-split-2.diff

	Update all nameidata users.

permission-args.diff

	Switch from struct nameidata to struct vfs_lookup in the
	permission inode operation and related functions.

file_permission.diff

	Create a temporary vfs_lookup object in file_permission().

sys_fchdir.diff
do_path_lookup.diff

	Use vfs_permission() instead of file_permission().

create-args.diff

	Switch from struct nameidata to struct vfs_lookup in the
	create inode operation and related functions.

vfs_create-nameidata.diff

	Fix all users of vfs_create() to never pass it a NULL
	vfs_lookup.  Get rid of the NULL checks.

d_revalidate-args.diff

	Switch from struct nameidata to struct vfs_lookup in the
	d_revalidate dentry operation and related functions.

lookup-args.diff

	Switch from struct nameidata to struct vfs_lookup in the
	lookup inode operation and related functions.


Ultimately, it would be nice to get rid of all the NULL nameidata /
vfs_lookup passing, particularly to the permission inode operation. At
that point, permission() could be replaced entirely by vfs_permission().
Other vfs functions like vfs_create() can be cleaned up in a similar
way.


Andreas


^ permalink raw reply	[flat|nested] 35+ messages in thread

* [RFC 01/10] Split up struct nameidata
  2007-08-08 17:16 [RFC 00/10] Split up struct nameidata (take 3) Andreas Gruenbacher
@ 2007-08-08 17:16 ` Andreas Gruenbacher
  2007-08-08 19:32   ` Christoph Hellwig
  2007-08-08 17:16 ` [RFC 02/10] Switch from nd->{mnt,dentry} to nd->lookup.path.{mnt,dentry} Andreas Gruenbacher
                   ` (8 subsequent siblings)
  9 siblings, 1 reply; 35+ messages in thread
From: Andreas Gruenbacher @ 2007-08-08 17:16 UTC (permalink / raw)
  To: linux-kernel
  Cc: John Johansen, Jan Blunck, Erez Zadok, Josef 'Jeff' Sipek

[-- Attachment #1: nameidata-split.diff --]
[-- Type: text/plain, Size: 1023 bytes --]

Split up struct nameidata into struct vfs_lookup with the lookup result
and intent and the remaining fields for performing an actual lookup.

Signed-off-by: Andreas Gruenbacher <ag@bestbits.at>

---
 include/linux/namei.h |   21 ++++++++++++---------
 1 file changed, 12 insertions(+), 9 deletions(-)

--- a/include/linux/namei.h
+++ b/include/linux/namei.h
@@ -14,14 +14,14 @@ struct open_intent {
 
 enum { MAX_NESTED_LINKS = 8 };
 
-struct nameidata {
-	struct dentry	*dentry;
+struct path {
 	struct vfsmount *mnt;
-	struct qstr	last;
+	struct dentry *dentry;
+};
+
+struct vfs_lookup {
+	struct path	 path;
 	unsigned int	flags;
-	int		last_type;
-	unsigned	depth;
-	char *saved_names[MAX_NESTED_LINKS + 1];
 
 	/* Intent data */
 	union {
@@ -29,9 +29,12 @@ struct nameidata {
 	} intent;
 };
 
-struct path {
-	struct vfsmount *mnt;
-	struct dentry *dentry;
+struct nameidata {
+	struct vfs_lookup lookup;
+	struct qstr	last;
+	int		last_type;
+	unsigned	depth;
+	char *saved_names[MAX_NESTED_LINKS + 1];
 };
 
 /*


^ permalink raw reply	[flat|nested] 35+ messages in thread

* [RFC 02/10] Switch from nd->{mnt,dentry} to nd->lookup.path.{mnt,dentry}
  2007-08-08 17:16 [RFC 00/10] Split up struct nameidata (take 3) Andreas Gruenbacher
  2007-08-08 17:16 ` [RFC 01/10] Split up struct nameidata Andreas Gruenbacher
@ 2007-08-08 17:16 ` Andreas Gruenbacher
  2007-08-08 17:16 ` [RFC 03/10] Pass no unnecessary information to iop->permission Andreas Gruenbacher
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 35+ messages in thread
From: Andreas Gruenbacher @ 2007-08-08 17:16 UTC (permalink / raw)
  To: linux-kernel
  Cc: John Johansen, Jan Blunck, Erez Zadok, Josef 'Jeff' Sipek

[-- Attachment #1: nameidata-split-2.diff --]
[-- Type: text/plain, Size: 87578 bytes --]

Switch from nd->{mnt,dentry} to nd->lookup.path.{mnt,dentry}, and from
nd->{flags,intent} to nd->lookup.{flags,intent} in the vfs and in file
systems to match the new nameidata layout.

The code generated should still be the same.

Signed-off-by: Andreas Gruenbacher <ag@bestbits.at>

---
 drivers/md/dm-table.c        |    2 
 drivers/mtd/mtdsuper.c       |   10 -
 fs/9p/vfs_inode.c            |    6 
 fs/afs/mntpt.c               |   22 +--
 fs/autofs4/root.c            |   12 -
 fs/block_dev.c               |    4 
 fs/cifs/dir.c                |    6 
 fs/coda/pioctl.c             |    2 
 fs/compat.c                  |    4 
 fs/configfs/symlink.c        |    4 
 fs/dquot.c                   |    6 
 fs/ecryptfs/dentry.c         |   12 -
 fs/ecryptfs/inode.c          |   26 ++--
 fs/ecryptfs/main.c           |    4 
 fs/exec.c                    |    8 -
 fs/ext3/super.c              |    4 
 fs/ext4/super.c              |    4 
 fs/fuse/dir.c                |    6 
 fs/gfs2/ops_fstype.c         |    4 
 fs/gfs2/ops_inode.c          |    2 
 fs/inotify_user.c            |    2 
 fs/namei.c                   |  270 +++++++++++++++++++++----------------------
 fs/namespace.c               |  168 +++++++++++++-------------
 fs/nfs/dir.c                 |   28 ++--
 fs/nfs/namespace.c           |   24 +--
 fs/nfs/nfs4proc.c            |   22 +--
 fs/nfsctl.c                  |    2 
 fs/nfsd/export.c             |   34 ++---
 fs/nfsd/nfs4recover.c        |   32 ++---
 fs/nfsd/nfs4state.c          |    2 
 fs/open.c                    |   44 +++----
 fs/proc/base.c               |    2 
 fs/proc/proc_sysctl.c        |    2 
 fs/reiserfs/super.c          |    6 
 fs/stat.c                    |   12 -
 fs/utimes.c                  |    2 
 fs/vfat/namei.c              |    2 
 fs/xattr.c                   |   16 +-
 fs/xfs/linux-2.6/xfs_ioctl.c |    6 
 kernel/auditfilter.c         |    8 -
 net/sunrpc/rpc_pipe.c        |    4 
 net/unix/af_unix.c           |   20 +--
 security/selinux/hooks.c     |    4 
 43 files changed, 430 insertions(+), 430 deletions(-)

--- a/drivers/md/dm-table.c
+++ b/drivers/md/dm-table.c
@@ -356,7 +356,7 @@ static int lookup_device(const char *pat
 	if ((r = path_lookup(path, LOOKUP_FOLLOW, &nd)))
 		return r;
 
-	inode = nd.dentry->d_inode;
+	inode = nd.lookup.path.dentry->d_inode;
 	if (!inode) {
 		r = -ENOENT;
 		goto out;
--- a/drivers/mtd/mtdsuper.c
+++ b/drivers/mtd/mtdsuper.c
@@ -182,25 +182,25 @@ int get_sb_mtd(struct file_system_type *
 	ret = path_lookup(dev_name, LOOKUP_FOLLOW, &nd);
 
 	DEBUG(1, "MTDSB: path_lookup() returned %d, inode %p\n",
-	      ret, nd.dentry ? nd.dentry->d_inode : NULL);
+	      ret, nd.lookup.path.dentry ? nd.lookup.path.dentry->d_inode : NULL);
 
 	if (ret)
 		return ret;
 
 	ret = -EINVAL;
 
-	if (!S_ISBLK(nd.dentry->d_inode->i_mode))
+	if (!S_ISBLK(nd.lookup.path.dentry->d_inode->i_mode))
 		goto out;
 
-	if (nd.mnt->mnt_flags & MNT_NODEV) {
+	if (nd.lookup.path.mnt->mnt_flags & MNT_NODEV) {
 		ret = -EACCES;
 		goto out;
 	}
 
-	if (imajor(nd.dentry->d_inode) != MTD_BLOCK_MAJOR)
+	if (imajor(nd.lookup.path.dentry->d_inode) != MTD_BLOCK_MAJOR)
 		goto not_an_MTD_device;
 
-	mtdnr = iminor(nd.dentry->d_inode);
+	mtdnr = iminor(nd.lookup.path.dentry->d_inode);
 	path_release(&nd);
 
 	return get_sb_mtd_nr(fs_type, flags, dev_name, data, mtdnr, fill_super,
--- a/fs/9p/vfs_inode.c
+++ b/fs/9p/vfs_inode.c
@@ -478,8 +478,8 @@ v9fs_vfs_create(struct inode *dir, struc
 	fid = NULL;
 	v9ses = v9fs_inode2v9ses(dir);
 	perm = unixmode2p9mode(v9ses, mode);
-	if (nd && nd->flags & LOOKUP_OPEN)
-		flags = nd->intent.open.flags - 1;
+	if (nd && nd->lookup.flags & LOOKUP_OPEN)
+		flags = nd->lookup.intent.open.flags - 1;
 	else
 		flags = O_RDWR;
 
@@ -492,7 +492,7 @@ v9fs_vfs_create(struct inode *dir, struc
 	}
 
 	/* if we are opening a file, assign the open fid to the file */
-	if (nd && nd->flags & LOOKUP_OPEN) {
+	if (nd && nd->lookup.flags & LOOKUP_OPEN) {
 		filp = lookup_instantiate_filp(nd, dentry, v9fs_open_created);
 		if (IS_ERR(filp)) {
 			err = PTR_ERR(filp);
--- a/fs/afs/mntpt.c
+++ b/fs/afs/mntpt.c
@@ -218,14 +218,14 @@ static void *afs_mntpt_follow_link(struc
 	_enter("%p{%s},{%s:%p{%s},}",
 	       dentry,
 	       dentry->d_name.name,
-	       nd->mnt->mnt_devname,
+	       nd->lookup.path.mnt->mnt_devname,
 	       dentry,
-	       nd->dentry->d_name.name);
+	       nd->lookup.path.dentry->d_name.name);
 
-	dput(nd->dentry);
-	nd->dentry = dget(dentry);
+	dput(nd->lookup.path.dentry);
+	nd->lookup.path.dentry = dget(dentry);
 
-	newmnt = afs_mntpt_do_automount(nd->dentry);
+	newmnt = afs_mntpt_do_automount(nd->lookup.path.dentry);
 	if (IS_ERR(newmnt)) {
 		path_release(nd);
 		return (void *)newmnt;
@@ -235,17 +235,17 @@ static void *afs_mntpt_follow_link(struc
 	err = do_add_mount(newmnt, nd, MNT_SHRINKABLE, &afs_vfsmounts);
 	switch (err) {
 	case 0:
-		mntput(nd->mnt);
-		dput(nd->dentry);
-		nd->mnt = newmnt;
-		nd->dentry = dget(newmnt->mnt_root);
+		mntput(nd->lookup.path.mnt);
+		dput(nd->lookup.path.dentry);
+		nd->lookup.path.mnt = newmnt;
+		nd->lookup.path.dentry = dget(newmnt->mnt_root);
 		schedule_delayed_work(&afs_mntpt_expiry_timer,
 				      afs_mntpt_expiry_timeout * HZ);
 		break;
 	case -EBUSY:
 		/* someone else made a mount here whilst we were busy */
-		while (d_mountpoint(nd->dentry) &&
-		       follow_down(&nd->mnt, &nd->dentry))
+		while (d_mountpoint(nd->lookup.path.dentry) &&
+		       follow_down(&nd->lookup.path.mnt, &nd->lookup.path.dentry))
 			;
 		err = 0;
 	default:
--- a/fs/autofs4/root.c
+++ b/fs/autofs4/root.c
@@ -133,7 +133,7 @@ static int autofs4_dir_open(struct inode
 		if (!empty)
 			d_invalidate(dentry);
 
-		nd.flags = LOOKUP_DIRECTORY;
+		nd.lookup.flags = LOOKUP_DIRECTORY;
 		ret = (dentry->d_op->d_revalidate)(dentry, &nd);
 
 		if (ret <= 0) {
@@ -330,12 +330,12 @@ static void *autofs4_follow_link(struct 
 	unsigned int lookup_type;
 	int status;
 
-	DPRINTK("dentry=%p %.*s oz_mode=%d nd->flags=%d",
+	DPRINTK("dentry=%p %.*s oz_mode=%d nd->lookup.flags=%d",
 		dentry, dentry->d_name.len, dentry->d_name.name, oz_mode,
-		nd->flags);
+		nd->lookup.flags);
 
 	/* If it's our master or we shouldn't trigger a mount we're done */
-	lookup_type = nd->flags & (LOOKUP_CONTINUE | LOOKUP_DIRECTORY);
+	lookup_type = nd->lookup.flags & (LOOKUP_CONTINUE | LOOKUP_DIRECTORY);
 	if (oz_mode || !lookup_type)
 		goto done;
 
@@ -368,7 +368,7 @@ static void *autofs4_follow_link(struct 
 		 * so we don't need to follow the mount.
 		 */
 		if (d_mountpoint(dentry)) {
-			if (!autofs4_follow_mount(&nd->mnt, &nd->dentry)) {
+			if (!autofs4_follow_mount(&nd->lookup.path.mnt, &nd->lookup.path.dentry)) {
 				status = -ENOENT;
 				goto out_error;
 			}
@@ -397,7 +397,7 @@ static int autofs4_revalidate(struct den
 	struct inode *dir = dentry->d_parent->d_inode;
 	struct autofs_sb_info *sbi = autofs4_sbi(dir->i_sb);
 	int oz_mode = autofs4_oz_mode(sbi);
-	int flags = nd ? nd->flags : 0;
+	int flags = nd ? nd->lookup.flags : 0;
 	int status = 1;
 
 	/* Pending dentry */
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -1386,12 +1386,12 @@ struct block_device *lookup_bdev(const c
 	if (error)
 		return ERR_PTR(error);
 
-	inode = nd.dentry->d_inode;
+	inode = nd.lookup.path.dentry->d_inode;
 	error = -ENOTBLK;
 	if (!S_ISBLK(inode->i_mode))
 		goto fail;
 	error = -EACCES;
-	if (nd.mnt->mnt_flags & MNT_NODEV)
+	if (nd.lookup.path.mnt->mnt_flags & MNT_NODEV)
 		goto fail;
 	error = -ENOMEM;
 	bdev = bd_acquire(inode);
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -153,8 +153,8 @@ cifs_create(struct inode *inode, struct 
 		return -ENOMEM;
 	}
 
-	if (nd && (nd->flags & LOOKUP_OPEN)) {
-		int oflags = nd->intent.open.flags;
+	if (nd && (nd->lookup.flags & LOOKUP_OPEN)) {
+		int oflags = nd->lookup.intent.open.flags;
 
 		desiredAccess = 0;
 		if (oflags & FMODE_READ)
@@ -264,7 +264,7 @@ cifs_create(struct inode *inode, struct 
 			d_instantiate(direntry, newinode);
 		}
 		if ((nd == NULL /* nfsd case - nfs srv does not set nd */) ||
-			((nd->flags & LOOKUP_OPEN) == FALSE)) {
+			((nd->lookup.flags & LOOKUP_OPEN) == FALSE)) {
 			/* mknod case - do not leave file open */
 			CIFSSMBClose(xid, pTcon, fileHandle);
 		} else if (newinode) {
--- a/fs/coda/pioctl.c
+++ b/fs/coda/pioctl.c
@@ -75,7 +75,7 @@ static int coda_pioctl(struct inode * in
 	if ( error ) {
 		return error;
         } else {
-	        target_inode = nd.dentry->d_inode;
+	        target_inode = nd.lookup.path.dentry->d_inode;
 	}
 	
 	/* return if it is not a Coda inode */
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -241,7 +241,7 @@ asmlinkage long compat_sys_statfs(const 
 	error = user_path_walk(path, &nd);
 	if (!error) {
 		struct kstatfs tmp;
-		error = vfs_statfs(nd.dentry, &tmp);
+		error = vfs_statfs(nd.lookup.path.dentry, &tmp);
 		if (!error)
 			error = put_compat_statfs(buf, &tmp);
 		path_release(&nd);
@@ -309,7 +309,7 @@ asmlinkage long compat_sys_statfs64(cons
 	error = user_path_walk(path, &nd);
 	if (!error) {
 		struct kstatfs tmp;
-		error = vfs_statfs(nd.dentry, &tmp);
+		error = vfs_statfs(nd.lookup.path.dentry, &tmp);
 		if (!error)
 			error = put_compat_statfs64(buf, &tmp);
 		path_release(&nd);
--- a/fs/configfs/symlink.c
+++ b/fs/configfs/symlink.c
@@ -99,8 +99,8 @@ static int get_target(const char *symnam
 
 	ret = path_lookup(symname, LOOKUP_FOLLOW|LOOKUP_DIRECTORY, nd);
 	if (!ret) {
-		if (nd->dentry->d_sb == configfs_sb) {
-			*target = configfs_get_config_item(nd->dentry);
+		if (nd->lookup.path.dentry->d_sb == configfs_sb) {
+			*target = configfs_get_config_item(nd->lookup.path.dentry);
 			if (!*target) {
 				ret = -ENOENT;
 				path_release(nd);
--- a/fs/dquot.c
+++ b/fs/dquot.c
@@ -1543,14 +1543,14 @@ int vfs_quota_on(struct super_block *sb,
 	error = path_lookup(path, LOOKUP_FOLLOW, &nd);
 	if (error < 0)
 		return error;
-	error = security_quota_on(nd.dentry);
+	error = security_quota_on(nd.lookup.path.dentry);
 	if (error)
 		goto out_path;
 	/* Quota file not on the same filesystem? */
-	if (nd.mnt->mnt_sb != sb)
+	if (nd.lookup.path.mnt->mnt_sb != sb)
 		error = -EXDEV;
 	else
-		error = vfs_quota_on_inode(nd.dentry->d_inode, type, format_id);
+		error = vfs_quota_on_inode(nd.lookup.path.dentry->d_inode, type, format_id);
 out_path:
 	path_release(&nd);
 	return error;
--- a/fs/ecryptfs/dentry.c
+++ b/fs/ecryptfs/dentry.c
@@ -51,13 +51,13 @@ static int ecryptfs_d_revalidate(struct 
 
 	if (!lower_dentry->d_op || !lower_dentry->d_op->d_revalidate)
 		goto out;
-	dentry_save = nd->dentry;
-	vfsmount_save = nd->mnt;
-	nd->dentry = lower_dentry;
-	nd->mnt = lower_mnt;
+	dentry_save = nd->lookup.path.dentry;
+	vfsmount_save = nd->lookup.path.mnt;
+	nd->lookup.path.dentry = lower_dentry;
+	nd->lookup.path.mnt = lower_mnt;
 	rc = lower_dentry->d_op->d_revalidate(lower_dentry, nd);
-	nd->dentry = dentry_save;
-	nd->mnt = vfsmount_save;
+	nd->lookup.path.dentry = dentry_save;
+	nd->lookup.path.mnt = vfsmount_save;
 	if (dentry->d_inode) {
 		struct inode *lower_inode =
 			ecryptfs_inode_to_lower(dentry->d_inode);
--- a/fs/ecryptfs/inode.c
+++ b/fs/ecryptfs/inode.c
@@ -77,13 +77,13 @@ ecryptfs_create_underlying_file(struct i
 	struct vfsmount *vfsmount_save;
 	int rc;
 
-	dentry_save = nd->dentry;
-	vfsmount_save = nd->mnt;
-	nd->dentry = lower_dentry;
-	nd->mnt = lower_mnt;
+	dentry_save = nd->lookup.path.dentry;
+	vfsmount_save = nd->lookup.path.mnt;
+	nd->lookup.path.dentry = lower_dentry;
+	nd->lookup.path.mnt = lower_mnt;
 	rc = vfs_create(lower_dir_inode, lower_dentry, mode, nd);
-	nd->dentry = dentry_save;
-	nd->mnt = vfsmount_save;
+	nd->lookup.path.dentry = dentry_save;
+	nd->lookup.path.mnt = vfsmount_save;
 	return rc;
 }
 
@@ -371,7 +371,7 @@ static struct dentry *ecryptfs_lookup(st
 	if (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED))
 		ecryptfs_set_default_sizes(crypt_stat);
 	rc = ecryptfs_read_and_validate_header_region(page_virt, lower_dentry,
-						      nd->mnt);
+						      nd->lookup.path.mnt);
 	if (rc) {
 		rc = ecryptfs_read_and_validate_xattr_region(page_virt, dentry);
 		if (rc) {
@@ -860,14 +860,14 @@ ecryptfs_permission(struct inode *inode,
 	int rc;
 
         if (nd) {
-		struct vfsmount *vfsmnt_save = nd->mnt;
-		struct dentry *dentry_save = nd->dentry;
+		struct vfsmount *vfsmnt_save = nd->lookup.path.mnt;
+		struct dentry *dentry_save = nd->lookup.path.dentry;
 
-		nd->mnt = ecryptfs_dentry_to_lower_mnt(nd->dentry);
-		nd->dentry = ecryptfs_dentry_to_lower(nd->dentry);
+		nd->lookup.path.mnt = ecryptfs_dentry_to_lower_mnt(nd->lookup.path.dentry);
+		nd->lookup.path.dentry = ecryptfs_dentry_to_lower(nd->lookup.path.dentry);
 		rc = permission(ecryptfs_inode_to_lower(inode), mask, nd);
-		nd->mnt = vfsmnt_save;
-		nd->dentry = dentry_save;
+		nd->lookup.path.mnt = vfsmnt_save;
+		nd->lookup.path.dentry = dentry_save;
         } else
 		rc = permission(ecryptfs_inode_to_lower(inode), mask, NULL);
         return rc;
--- a/fs/ecryptfs/main.c
+++ b/fs/ecryptfs/main.c
@@ -489,8 +489,8 @@ static int ecryptfs_read_super(struct su
 		ecryptfs_printk(KERN_WARNING, "path_lookup() failed\n");
 		goto out;
 	}
-	lower_root = nd.dentry;
-	lower_mnt = nd.mnt;
+	lower_root = nd.lookup.path.dentry;
+	lower_mnt = nd.lookup.path.mnt;
 	ecryptfs_set_superblock_lower(sb, lower_root->d_sb);
 	sb->s_maxbytes = lower_root->d_sb->s_maxbytes;
 	ecryptfs_set_dentry_lower(sb->s_root, lower_root);
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -136,10 +136,10 @@ asmlinkage long sys_uselib(const char __
 		goto out;
 
 	error = -EACCES;
-	if (nd.mnt->mnt_flags & MNT_NOEXEC)
+	if (nd.lookup.path.mnt->mnt_flags & MNT_NOEXEC)
 		goto exit;
 	error = -EINVAL;
-	if (!S_ISREG(nd.dentry->d_inode->i_mode))
+	if (!S_ISREG(nd.lookup.path.dentry->d_inode->i_mode))
 		goto exit;
 
 	error = vfs_permission(&nd, MAY_READ | MAY_EXEC);
@@ -679,9 +679,9 @@ struct file *open_exec(const char *name)
 	file = ERR_PTR(err);
 
 	if (!err) {
-		struct inode *inode = nd.dentry->d_inode;
+		struct inode *inode = nd.lookup.path.dentry->d_inode;
 		file = ERR_PTR(-EACCES);
-		if (!(nd.mnt->mnt_flags & MNT_NOEXEC) &&
+		if (!(nd.lookup.path.mnt->mnt_flags & MNT_NOEXEC) &&
 		    S_ISREG(inode->i_mode)) {
 			int err = vfs_permission(&nd, MAY_EXEC);
 			file = ERR_PTR(err);
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -2644,12 +2644,12 @@ static int ext3_quota_on(struct super_bl
 	if (err)
 		return err;
 	/* Quotafile not on the same filesystem? */
-	if (nd.mnt->mnt_sb != sb) {
+	if (nd.lookup.path.mnt->mnt_sb != sb) {
 		path_release(&nd);
 		return -EXDEV;
 	}
 	/* Quotafile not of fs root? */
-	if (nd.dentry->d_parent->d_inode != sb->s_root->d_inode)
+	if (nd.lookup.path.dentry->d_parent->d_inode != sb->s_root->d_inode)
 		printk(KERN_WARNING
 			"EXT3-fs: Quota file not on filesystem root. "
 			"Journalled quota will not work.\n");
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -2764,12 +2764,12 @@ static int ext4_quota_on(struct super_bl
 	if (err)
 		return err;
 	/* Quotafile not on the same filesystem? */
-	if (nd.mnt->mnt_sb != sb) {
+	if (nd.lookup.path.mnt->mnt_sb != sb) {
 		path_release(&nd);
 		return -EXDEV;
 	}
 	/* Quotafile not of fs root? */
-	if (nd.dentry->d_parent->d_inode != sb->s_root->d_inode)
+	if (nd.lookup.path.dentry->d_parent->d_inode != sb->s_root->d_inode)
 		printk(KERN_WARNING
 			"EXT4-fs: Quota file not on filesystem root. "
 			"Journalled quota will not work.\n");
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -315,7 +315,7 @@ static int fuse_create_open(struct inode
 	struct fuse_entry_out outentry;
 	struct fuse_file *ff;
 	struct file *file;
-	int flags = nd->intent.open.flags - 1;
+	int flags = nd->lookup.intent.open.flags - 1;
 
 	if (fc->no_create)
 		return -ENOSYS;
@@ -485,7 +485,7 @@ static int fuse_mknod(struct inode *dir,
 static int fuse_create(struct inode *dir, struct dentry *entry, int mode,
 		       struct nameidata *nd)
 {
-	if (nd && (nd->flags & LOOKUP_OPEN)) {
+	if (nd && (nd->lookup.flags & LOOKUP_OPEN)) {
 		int err = fuse_create_open(dir, entry, mode, nd);
 		if (err != -ENOSYS)
 			return err;
@@ -821,7 +821,7 @@ static int fuse_permission(struct inode 
 		if ((mask & MAY_EXEC) && !S_ISDIR(mode) && !(mode & S_IXUGO))
 			return -EACCES;
 
-		if (nd && (nd->flags & (LOOKUP_ACCESS | LOOKUP_CHDIR)))
+		if (nd && (nd->lookup.flags & (LOOKUP_ACCESS | LOOKUP_CHDIR)))
 			return fuse_access(inode, mask);
 		return 0;
 	}
--- a/fs/gfs2/ops_fstype.c
+++ b/fs/gfs2/ops_fstype.c
@@ -827,13 +827,13 @@ static struct super_block* get_gfs2_sb(c
 		       dev_name);
 		goto out;
 	}
-	error = vfs_getattr(nd.mnt, nd.dentry, &stat);
+	error = vfs_getattr(nd.lookup.path.mnt, nd.lookup.path.dentry, &stat);
 
 	fstype = get_fs_type("gfs2");
 	list_for_each(l, &fstype->fs_supers) {
 		s = list_entry(l, struct super_block, s_instances);
 		if ((S_ISBLK(stat.mode) && s->s_dev == stat.rdev) ||
-		    (S_ISDIR(stat.mode) && s == nd.dentry->d_inode->i_sb)) {
+		    (S_ISDIR(stat.mode) && s == nd.lookup.path.dentry->d_inode->i_sb)) {
 			sb = s;
 			goto free_nd;
 		}
--- a/fs/gfs2/ops_inode.c
+++ b/fs/gfs2/ops_inode.c
@@ -69,7 +69,7 @@ static int gfs2_create(struct inode *dir
 			mark_inode_dirty(inode);
 			break;
 		} else if (PTR_ERR(inode) != -EEXIST ||
-			   (nd->intent.open.flags & O_EXCL)) {
+			   (nd->lookup.intent.open.flags & O_EXCL)) {
 			gfs2_holder_uninit(ghs);
 			return PTR_ERR(inode);
 		}
--- a/fs/inotify_user.c
+++ b/fs/inotify_user.c
@@ -639,7 +639,7 @@ asmlinkage long sys_inotify_add_watch(in
 		goto fput_and_out;
 
 	/* inode held in place by reference to nd; dev by fget on fd */
-	inode = nd.dentry->d_inode;
+	inode = nd.lookup.path.dentry->d_inode;
 	dev = filp->private_data;
 
 	mutex_lock(&dev->up_mutex);
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -254,7 +254,7 @@ int permission(struct inode *inode, int 
 	 * the fs is mounted with the "noexec" flag.
 	 */
 	if ((mask & MAY_EXEC) && S_ISREG(mode) && (!(mode & S_IXUGO) ||
-			(nd && nd->mnt && (nd->mnt->mnt_flags & MNT_NOEXEC))))
+			(nd && nd->lookup.path.mnt && (nd->lookup.path.mnt->mnt_flags & MNT_NOEXEC))))
 		return -EACCES;
 
 	/* Ordinary permission routines do not understand MAY_APPEND. */
@@ -281,7 +281,7 @@ int permission(struct inode *inode, int 
  */
 int vfs_permission(struct nameidata *nd, int mask)
 {
-	return permission(nd->dentry->d_inode, mask, nd);
+	return permission(nd->lookup.path.dentry->d_inode, mask, nd);
 }
 
 /**
@@ -349,8 +349,8 @@ int deny_write_access(struct file * file
 
 void path_release(struct nameidata *nd)
 {
-	dput(nd->dentry);
-	mntput(nd->mnt);
+	dput(nd->lookup.path.dentry);
+	mntput(nd->lookup.path.mnt);
 }
 
 /*
@@ -359,8 +359,8 @@ void path_release(struct nameidata *nd)
  */
 void path_release_on_umount(struct nameidata *nd)
 {
-	dput(nd->dentry);
-	mntput_no_expire(nd->mnt);
+	dput(nd->lookup.path.dentry);
+	mntput_no_expire(nd->lookup.path.mnt);
 }
 
 /**
@@ -369,10 +369,10 @@ void path_release_on_umount(struct namei
  */
 void release_open_intent(struct nameidata *nd)
 {
-	if (nd->intent.open.file->f_path.dentry == NULL)
-		put_filp(nd->intent.open.file);
+	if (nd->lookup.intent.open.file->f_path.dentry == NULL)
+		put_filp(nd->lookup.intent.open.file);
 	else
-		fput(nd->intent.open.file);
+		fput(nd->lookup.intent.open.file);
 }
 
 static inline struct dentry *
@@ -524,16 +524,16 @@ walk_init_root(const char *name, struct 
 	struct fs_struct *fs = current->fs;
 
 	read_lock(&fs->lock);
-	if (fs->altroot && !(nd->flags & LOOKUP_NOALT)) {
-		nd->mnt = mntget(fs->altrootmnt);
-		nd->dentry = dget(fs->altroot);
+	if (fs->altroot && !(nd->lookup.flags & LOOKUP_NOALT)) {
+		nd->lookup.path.mnt = mntget(fs->altrootmnt);
+		nd->lookup.path.dentry = dget(fs->altroot);
 		read_unlock(&fs->lock);
 		if (__emul_lookup_dentry(name,nd))
 			return 0;
 		read_lock(&fs->lock);
 	}
-	nd->mnt = mntget(fs->rootmnt);
-	nd->dentry = dget(fs->root);
+	nd->lookup.path.mnt = mntget(fs->rootmnt);
+	nd->lookup.path.dentry = dget(fs->root);
 	read_unlock(&fs->lock);
 	return 1;
 }
@@ -576,17 +576,17 @@ fail:
 static inline void dput_path(struct path *path, struct nameidata *nd)
 {
 	dput(path->dentry);
-	if (path->mnt != nd->mnt)
+	if (path->mnt != nd->lookup.path.mnt)
 		mntput(path->mnt);
 }
 
 static inline void path_to_nameidata(struct path *path, struct nameidata *nd)
 {
-	dput(nd->dentry);
-	if (nd->mnt != path->mnt)
-		mntput(nd->mnt);
-	nd->mnt = path->mnt;
-	nd->dentry = path->dentry;
+	dput(nd->lookup.path.dentry);
+	if (nd->lookup.path.mnt != path->mnt)
+		mntput(nd->lookup.path.mnt);
+	nd->lookup.path.mnt = path->mnt;
+	nd->lookup.path.dentry = path->dentry;
 }
 
 static __always_inline int __do_follow_link(struct path *path, struct nameidata *nd)
@@ -598,7 +598,7 @@ static __always_inline int __do_follow_l
 	touch_atime(path->mnt, dentry);
 	nd_set_link(nd, NULL);
 
-	if (path->mnt != nd->mnt) {
+	if (path->mnt != nd->lookup.path.mnt) {
 		path_to_nameidata(path, nd);
 		dget(dentry);
 	}
@@ -728,37 +728,37 @@ static __always_inline void follow_dotdo
 
 	while(1) {
 		struct vfsmount *parent;
-		struct dentry *old = nd->dentry;
+		struct dentry *old = nd->lookup.path.dentry;
 
                 read_lock(&fs->lock);
-		if (nd->dentry == fs->root &&
-		    nd->mnt == fs->rootmnt) {
+		if (nd->lookup.path.dentry == fs->root &&
+		    nd->lookup.path.mnt == fs->rootmnt) {
                         read_unlock(&fs->lock);
 			break;
 		}
                 read_unlock(&fs->lock);
 		spin_lock(&dcache_lock);
-		if (nd->dentry != nd->mnt->mnt_root) {
-			nd->dentry = dget(nd->dentry->d_parent);
+		if (nd->lookup.path.dentry != nd->lookup.path.mnt->mnt_root) {
+			nd->lookup.path.dentry = dget(nd->lookup.path.dentry->d_parent);
 			spin_unlock(&dcache_lock);
 			dput(old);
 			break;
 		}
 		spin_unlock(&dcache_lock);
 		spin_lock(&vfsmount_lock);
-		parent = nd->mnt->mnt_parent;
-		if (parent == nd->mnt) {
+		parent = nd->lookup.path.mnt->mnt_parent;
+		if (parent == nd->lookup.path.mnt) {
 			spin_unlock(&vfsmount_lock);
 			break;
 		}
 		mntget(parent);
-		nd->dentry = dget(nd->mnt->mnt_mountpoint);
+		nd->lookup.path.dentry = dget(nd->lookup.path.mnt->mnt_mountpoint);
 		spin_unlock(&vfsmount_lock);
 		dput(old);
-		mntput(nd->mnt);
-		nd->mnt = parent;
+		mntput(nd->lookup.path.mnt);
+		nd->lookup.path.mnt = parent;
 	}
-	follow_mount(&nd->mnt, &nd->dentry);
+	follow_mount(&nd->lookup.path.mnt, &nd->lookup.path.dentry);
 }
 
 /*
@@ -769,8 +769,8 @@ static __always_inline void follow_dotdo
 static int do_lookup(struct nameidata *nd, struct qstr *name,
 		     struct path *path)
 {
-	struct vfsmount *mnt = nd->mnt;
-	struct dentry *dentry = __d_lookup(nd->dentry, name);
+	struct vfsmount *mnt = nd->lookup.path.mnt;
+	struct dentry *dentry = __d_lookup(nd->lookup.path.dentry, name);
 
 	if (!dentry)
 		goto need_lookup;
@@ -783,7 +783,7 @@ done:
 	return 0;
 
 need_lookup:
-	dentry = real_lookup(nd->dentry, name, nd);
+	dentry = real_lookup(nd->lookup.path.dentry, name, nd);
 	if (IS_ERR(dentry))
 		goto fail;
 	goto done;
@@ -813,16 +813,16 @@ static fastcall int __link_path_walk(con
 	struct path next;
 	struct inode *inode;
 	int err;
-	unsigned int lookup_flags = nd->flags;
+	unsigned int lookup_flags = nd->lookup.flags;
 	
 	while (*name=='/')
 		name++;
 	if (!*name)
 		goto return_reval;
 
-	inode = nd->dentry->d_inode;
+	inode = nd->lookup.path.dentry->d_inode;
 	if (nd->depth)
-		lookup_flags = LOOKUP_FOLLOW | (nd->flags & LOOKUP_CONTINUE);
+		lookup_flags = LOOKUP_FOLLOW | (nd->lookup.flags & LOOKUP_CONTINUE);
 
 	/* At this point we know we have a real path component. */
 	for(;;) {
@@ -830,7 +830,7 @@ static fastcall int __link_path_walk(con
 		struct qstr this;
 		unsigned int c;
 
-		nd->flags |= LOOKUP_CONTINUE;
+		nd->lookup.flags |= LOOKUP_CONTINUE;
 		err = exec_permission_lite(inode, nd);
 		if (err == -EAGAIN)
 			err = vfs_permission(nd, MAY_EXEC);
@@ -868,7 +868,7 @@ static fastcall int __link_path_walk(con
 				if (this.name[1] != '.')
 					break;
 				follow_dotdot(nd);
-				inode = nd->dentry->d_inode;
+				inode = nd->lookup.path.dentry->d_inode;
 				/* fallthrough */
 			case 1:
 				continue;
@@ -877,8 +877,8 @@ static fastcall int __link_path_walk(con
 		 * See if the low-level filesystem might want
 		 * to use its own hash..
 		 */
-		if (nd->dentry->d_op && nd->dentry->d_op->d_hash) {
-			err = nd->dentry->d_op->d_hash(nd->dentry, &this);
+		if (nd->lookup.path.dentry->d_op && nd->lookup.path.dentry->d_op->d_hash) {
+			err = nd->lookup.path.dentry->d_op->d_hash(nd->lookup.path.dentry, &this);
 			if (err < 0)
 				break;
 		}
@@ -900,7 +900,7 @@ static fastcall int __link_path_walk(con
 			if (err)
 				goto return_err;
 			err = -ENOENT;
-			inode = nd->dentry->d_inode;
+			inode = nd->lookup.path.dentry->d_inode;
 			if (!inode)
 				break;
 			err = -ENOTDIR; 
@@ -918,7 +918,7 @@ last_with_slashes:
 		lookup_flags |= LOOKUP_FOLLOW | LOOKUP_DIRECTORY;
 last_component:
 		/* Clear LOOKUP_CONTINUE iff it was previously unset */
-		nd->flags &= lookup_flags | ~LOOKUP_CONTINUE;
+		nd->lookup.flags &= lookup_flags | ~LOOKUP_CONTINUE;
 		if (lookup_flags & LOOKUP_PARENT)
 			goto lookup_parent;
 		if (this.name[0] == '.') switch (this.len) {
@@ -928,13 +928,13 @@ last_component:
 				if (this.name[1] != '.')
 					break;
 				follow_dotdot(nd);
-				inode = nd->dentry->d_inode;
+				inode = nd->lookup.path.dentry->d_inode;
 				/* fallthrough */
 			case 1:
 				goto return_reval;
 		}
-		if (nd->dentry->d_op && nd->dentry->d_op->d_hash) {
-			err = nd->dentry->d_op->d_hash(nd->dentry, &this);
+		if (nd->lookup.path.dentry->d_op && nd->lookup.path.dentry->d_op->d_hash) {
+			err = nd->lookup.path.dentry->d_op->d_hash(nd->lookup.path.dentry, &this);
 			if (err < 0)
 				break;
 		}
@@ -947,7 +947,7 @@ last_component:
 			err = do_follow_link(&next, nd);
 			if (err)
 				goto return_err;
-			inode = nd->dentry->d_inode;
+			inode = nd->lookup.path.dentry->d_inode;
 		} else
 			path_to_nameidata(&next, nd);
 		err = -ENOENT;
@@ -975,11 +975,11 @@ return_reval:
 		 * We bypassed the ordinary revalidation routines.
 		 * We may need to check the cached dentry for staleness.
 		 */
-		if (nd->dentry && nd->dentry->d_sb &&
-		    (nd->dentry->d_sb->s_type->fs_flags & FS_REVAL_DOT)) {
+		if (nd->lookup.path.dentry && nd->lookup.path.dentry->d_sb &&
+		    (nd->lookup.path.dentry->d_sb->s_type->fs_flags & FS_REVAL_DOT)) {
 			err = -ESTALE;
 			/* Note: we do not d_invalidate() */
-			if (!nd->dentry->d_op->d_revalidate(nd->dentry, nd))
+			if (!nd->lookup.path.dentry->d_op->d_revalidate(nd->lookup.path.dentry, nd))
 				break;
 		}
 return_base:
@@ -1006,20 +1006,20 @@ static int fastcall link_path_walk(const
 	int result;
 
 	/* make sure the stuff we saved doesn't go away */
-	dget(save.dentry);
-	mntget(save.mnt);
+	dget(save.lookup.path.dentry);
+	mntget(save.lookup.path.mnt);
 
 	result = __link_path_walk(name, nd);
 	if (result == -ESTALE) {
 		*nd = save;
-		dget(nd->dentry);
-		mntget(nd->mnt);
-		nd->flags |= LOOKUP_REVAL;
+		dget(nd->lookup.path.dentry);
+		mntget(nd->lookup.path.mnt);
+		nd->lookup.flags |= LOOKUP_REVAL;
 		result = __link_path_walk(name, nd);
 	}
 
-	dput(save.dentry);
-	mntput(save.mnt);
+	dput(save.lookup.path.dentry);
+	mntput(save.lookup.path.mnt);
 
 	return result;
 }
@@ -1039,9 +1039,9 @@ static int __emul_lookup_dentry(const ch
 	if (path_walk(name, nd))
 		return 0;		/* something went wrong... */
 
-	if (!nd->dentry->d_inode || S_ISDIR(nd->dentry->d_inode->i_mode)) {
-		struct dentry *old_dentry = nd->dentry;
-		struct vfsmount *old_mnt = nd->mnt;
+	if (!nd->lookup.path.dentry->d_inode || S_ISDIR(nd->lookup.path.dentry->d_inode->i_mode)) {
+		struct dentry *old_dentry = nd->lookup.path.dentry;
+		struct vfsmount *old_mnt = nd->lookup.path.mnt;
 		struct qstr last = nd->last;
 		int last_type = nd->last_type;
 		struct fs_struct *fs = current->fs;
@@ -1052,19 +1052,19 @@ static int __emul_lookup_dentry(const ch
 		 */
 		nd->last_type = LAST_ROOT;
 		read_lock(&fs->lock);
-		nd->mnt = mntget(fs->rootmnt);
-		nd->dentry = dget(fs->root);
+		nd->lookup.path.mnt = mntget(fs->rootmnt);
+		nd->lookup.path.dentry = dget(fs->root);
 		read_unlock(&fs->lock);
 		if (path_walk(name, nd) == 0) {
-			if (nd->dentry->d_inode) {
+			if (nd->lookup.path.dentry->d_inode) {
 				dput(old_dentry);
 				mntput(old_mnt);
 				return 1;
 			}
 			path_release(nd);
 		}
-		nd->dentry = old_dentry;
-		nd->mnt = old_mnt;
+		nd->lookup.path.dentry = old_dentry;
+		nd->lookup.path.mnt = old_mnt;
 		nd->last = last;
 		nd->last_type = last_type;
 	}
@@ -1084,8 +1084,8 @@ void set_fs_altroot(void)
 		goto set_it;
 	err = path_lookup(emul, LOOKUP_FOLLOW|LOOKUP_DIRECTORY|LOOKUP_NOALT, &nd);
 	if (!err) {
-		mnt = nd.mnt;
-		dentry = nd.dentry;
+		mnt = nd.lookup.path.mnt;
+		dentry = nd.lookup.path.dentry;
 	}
 set_it:
 	write_lock(&fs->lock);
@@ -1110,26 +1110,26 @@ static int fastcall do_path_lookup(int d
 	struct fs_struct *fs = current->fs;
 
 	nd->last_type = LAST_ROOT; /* if there are only slashes... */
-	nd->flags = flags;
+	nd->lookup.flags = flags;
 	nd->depth = 0;
 
 	if (*name=='/') {
 		read_lock(&fs->lock);
-		if (fs->altroot && !(nd->flags & LOOKUP_NOALT)) {
-			nd->mnt = mntget(fs->altrootmnt);
-			nd->dentry = dget(fs->altroot);
+		if (fs->altroot && !(nd->lookup.flags & LOOKUP_NOALT)) {
+			nd->lookup.path.mnt = mntget(fs->altrootmnt);
+			nd->lookup.path.dentry = dget(fs->altroot);
 			read_unlock(&fs->lock);
 			if (__emul_lookup_dentry(name,nd))
 				goto out; /* found in altroot */
 			read_lock(&fs->lock);
 		}
-		nd->mnt = mntget(fs->rootmnt);
-		nd->dentry = dget(fs->root);
+		nd->lookup.path.mnt = mntget(fs->rootmnt);
+		nd->lookup.path.dentry = dget(fs->root);
 		read_unlock(&fs->lock);
 	} else if (dfd == AT_FDCWD) {
 		read_lock(&fs->lock);
-		nd->mnt = mntget(fs->pwdmnt);
-		nd->dentry = dget(fs->pwd);
+		nd->lookup.path.mnt = mntget(fs->pwdmnt);
+		nd->lookup.path.dentry = dget(fs->pwd);
 		read_unlock(&fs->lock);
 	} else {
 		struct dentry *dentry;
@@ -1149,17 +1149,17 @@ static int fastcall do_path_lookup(int d
 		if (retval)
 			goto fput_fail;
 
-		nd->mnt = mntget(file->f_path.mnt);
-		nd->dentry = dget(dentry);
+		nd->lookup.path.mnt = mntget(file->f_path.mnt);
+		nd->lookup.path.dentry = dget(dentry);
 
 		fput_light(file, fput_needed);
 	}
 
 	retval = path_walk(name, nd);
 out:
-	if (unlikely(!retval && !audit_dummy_context() && nd->dentry &&
-				nd->dentry->d_inode))
-		audit_inode(name, nd->dentry->d_inode);
+	if (unlikely(!retval && !audit_dummy_context() && nd->lookup.path.dentry &&
+				nd->lookup.path.dentry->d_inode))
+		audit_inode(name, nd->lookup.path.dentry->d_inode);
 out_fail:
 	return retval;
 
@@ -1190,16 +1190,16 @@ int vfs_path_lookup(struct dentry *dentr
 
 	/* same as do_path_lookup */
 	nd->last_type = LAST_ROOT;
-	nd->flags = flags;
+	nd->lookup.flags = flags;
 	nd->depth = 0;
 
-	nd->mnt = mntget(mnt);
-	nd->dentry = dget(dentry);
+	nd->lookup.path.mnt = mntget(mnt);
+	nd->lookup.path.dentry = dget(dentry);
 
 	retval = path_walk(name, nd);
-	if (unlikely(!retval && !audit_dummy_context() && nd->dentry &&
-				nd->dentry->d_inode))
-		audit_inode(name, nd->dentry->d_inode);
+	if (unlikely(!retval && !audit_dummy_context() && nd->lookup.path.dentry &&
+				nd->lookup.path.dentry->d_inode))
+		audit_inode(name, nd->lookup.path.dentry->d_inode);
 
 	return retval;
 
@@ -1214,13 +1214,13 @@ static int __path_lookup_intent_open(int
 
 	if (filp == NULL)
 		return -ENFILE;
-	nd->intent.open.file = filp;
-	nd->intent.open.flags = open_flags;
-	nd->intent.open.create_mode = create_mode;
+	nd->lookup.intent.open.file = filp;
+	nd->lookup.intent.open.flags = open_flags;
+	nd->lookup.intent.open.create_mode = create_mode;
 	err = do_path_lookup(dfd, name, lookup_flags|LOOKUP_OPEN, nd);
-	if (IS_ERR(nd->intent.open.file)) {
+	if (IS_ERR(nd->lookup.intent.open.file)) {
 		if (err == 0) {
-			err = PTR_ERR(nd->intent.open.file);
+			err = PTR_ERR(nd->lookup.intent.open.file);
 			path_release(nd);
 		}
 	} else if (err != 0)
@@ -1333,7 +1333,7 @@ out:
 
 static struct dentry *lookup_hash(struct nameidata *nd)
 {
-	return __lookup_hash(&nd->last, nd->dentry, nd);
+	return __lookup_hash(&nd->last, nd->lookup.path.dentry, nd);
 }
 
 /* SMP-safe */
@@ -1566,7 +1566,7 @@ int vfs_create(struct inode *dir, struct
 
 int may_open(struct nameidata *nd, int acc_mode, int flag)
 {
-	struct dentry *dentry = nd->dentry;
+	struct dentry *dentry = nd->lookup.path.dentry;
 	struct inode *inode = dentry->d_inode;
 	int error;
 
@@ -1591,7 +1591,7 @@ int may_open(struct nameidata *nd, int a
 	if (S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) {
 	    	flag &= ~O_TRUNC;
 	} else if (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode)) {
-		if (nd->mnt->mnt_flags & MNT_NODEV)
+		if (nd->lookup.path.mnt->mnt_flags & MNT_NODEV)
 			return -EACCES;
 
 		flag &= ~O_TRUNC;
@@ -1647,14 +1647,14 @@ static int open_namei_create(struct name
 				int flag, int mode)
 {
 	int error;
-	struct dentry *dir = nd->dentry;
+	struct dentry *dir = nd->lookup.path.dentry;
 
 	if (!IS_POSIXACL(dir->d_inode))
 		mode &= ~current->fs->umask;
 	error = vfs_create(dir->d_inode, path->dentry, mode, nd);
 	mutex_unlock(&dir->d_inode->i_mutex);
-	dput(nd->dentry);
-	nd->dentry = path->dentry;
+	dput(nd->lookup.path.dentry);
+	nd->lookup.path.dentry = path->dentry;
 	if (error)
 		return error;
 	/* Don't check for write permission, don't truncate */
@@ -1721,11 +1721,11 @@ int open_namei(int dfd, const char *path
 	if (nd->last_type != LAST_NORM || nd->last.name[nd->last.len])
 		goto exit;
 
-	dir = nd->dentry;
-	nd->flags &= ~LOOKUP_PARENT;
+	dir = nd->lookup.path.dentry;
+	nd->lookup.flags &= ~LOOKUP_PARENT;
 	mutex_lock(&dir->d_inode->i_mutex);
 	path.dentry = lookup_hash(nd);
-	path.mnt = nd->mnt;
+	path.mnt = nd->lookup.path.mnt;
 
 do_last:
 	error = PTR_ERR(path.dentry);
@@ -1734,9 +1734,9 @@ do_last:
 		goto exit;
 	}
 
-	if (IS_ERR(nd->intent.open.file)) {
+	if (IS_ERR(nd->lookup.intent.open.file)) {
 		mutex_unlock(&dir->d_inode->i_mutex);
-		error = PTR_ERR(nd->intent.open.file);
+		error = PTR_ERR(nd->lookup.intent.open.file);
 		goto exit_dput;
 	}
 
@@ -1783,7 +1783,7 @@ ok:
 exit_dput:
 	dput_path(&path, nd);
 exit:
-	if (!IS_ERR(nd->intent.open.file))
+	if (!IS_ERR(nd->lookup.intent.open.file))
 		release_open_intent(nd);
 	path_release(nd);
 	return error;
@@ -1802,7 +1802,7 @@ do_link:
 	 * stored in nd->last.name and we will have to putname() it when we
 	 * are done. Procfs-like symlinks just set LAST_BIND.
 	 */
-	nd->flags |= LOOKUP_PARENT;
+	nd->lookup.flags |= LOOKUP_PARENT;
 	error = security_inode_follow_link(path.dentry, nd);
 	if (error)
 		goto exit_dput;
@@ -1815,7 +1815,7 @@ do_link:
 		release_open_intent(nd);
 		return error;
 	}
-	nd->flags &= ~LOOKUP_PARENT;
+	nd->lookup.flags &= ~LOOKUP_PARENT;
 	if (nd->last_type == LAST_BIND)
 		goto ok;
 	error = -EISDIR;
@@ -1830,10 +1830,10 @@ do_link:
 		__putname(nd->last.name);
 		goto exit;
 	}
-	dir = nd->dentry;
+	dir = nd->lookup.path.dentry;
 	mutex_lock(&dir->d_inode->i_mutex);
 	path.dentry = lookup_hash(nd);
-	path.mnt = nd->mnt;
+	path.mnt = nd->lookup.path.mnt;
 	__putname(nd->last.name);
 	goto do_last;
 }
@@ -1846,22 +1846,22 @@ do_link:
  * Simple function to lookup and return a dentry and create it
  * if it doesn't exist.  Is SMP-safe.
  *
- * Returns with nd->dentry->d_inode->i_mutex locked.
+ * Returns with nd->lookup.path.dentry->d_inode->i_mutex locked.
  */
 struct dentry *lookup_create(struct nameidata *nd, int is_dir)
 {
 	struct dentry *dentry = ERR_PTR(-EEXIST);
 
-	mutex_lock_nested(&nd->dentry->d_inode->i_mutex, I_MUTEX_PARENT);
+	mutex_lock_nested(&nd->lookup.path.dentry->d_inode->i_mutex, I_MUTEX_PARENT);
 	/*
 	 * Yucky last component or no last component at all?
 	 * (foo/., foo/.., /////)
 	 */
 	if (nd->last_type != LAST_NORM)
 		goto fail;
-	nd->flags &= ~LOOKUP_PARENT;
-	nd->flags |= LOOKUP_CREATE;
-	nd->intent.open.flags = O_EXCL;
+	nd->lookup.flags &= ~LOOKUP_PARENT;
+	nd->lookup.flags |= LOOKUP_CREATE;
+	nd->lookup.intent.open.flags = O_EXCL;
 
 	/*
 	 * Do the final lookup.
@@ -1931,19 +1931,19 @@ asmlinkage long sys_mknodat(int dfd, con
 	dentry = lookup_create(&nd, 0);
 	error = PTR_ERR(dentry);
 
-	if (!IS_POSIXACL(nd.dentry->d_inode))
+	if (!IS_POSIXACL(nd.lookup.path.dentry->d_inode))
 		mode &= ~current->fs->umask;
 	if (!IS_ERR(dentry)) {
 		switch (mode & S_IFMT) {
 		case 0: case S_IFREG:
-			error = vfs_create(nd.dentry->d_inode,dentry,mode,&nd);
+			error = vfs_create(nd.lookup.path.dentry->d_inode,dentry,mode,&nd);
 			break;
 		case S_IFCHR: case S_IFBLK:
-			error = vfs_mknod(nd.dentry->d_inode,dentry,mode,
+			error = vfs_mknod(nd.lookup.path.dentry->d_inode,dentry,mode,
 					new_decode_dev(dev));
 			break;
 		case S_IFIFO: case S_IFSOCK:
-			error = vfs_mknod(nd.dentry->d_inode,dentry,mode,0);
+			error = vfs_mknod(nd.lookup.path.dentry->d_inode,dentry,mode,0);
 			break;
 		case S_IFDIR:
 			error = -EPERM;
@@ -1953,7 +1953,7 @@ asmlinkage long sys_mknodat(int dfd, con
 		}
 		dput(dentry);
 	}
-	mutex_unlock(&nd.dentry->d_inode->i_mutex);
+	mutex_unlock(&nd.lookup.path.dentry->d_inode->i_mutex);
 	path_release(&nd);
 out:
 	putname(tmp);
@@ -2008,12 +2008,12 @@ asmlinkage long sys_mkdirat(int dfd, con
 	if (IS_ERR(dentry))
 		goto out_unlock;
 
-	if (!IS_POSIXACL(nd.dentry->d_inode))
+	if (!IS_POSIXACL(nd.lookup.path.dentry->d_inode))
 		mode &= ~current->fs->umask;
-	error = vfs_mkdir(nd.dentry->d_inode, dentry, mode);
+	error = vfs_mkdir(nd.lookup.path.dentry->d_inode, dentry, mode);
 	dput(dentry);
 out_unlock:
-	mutex_unlock(&nd.dentry->d_inode->i_mutex);
+	mutex_unlock(&nd.lookup.path.dentry->d_inode->i_mutex);
 	path_release(&nd);
 out:
 	putname(tmp);
@@ -2112,15 +2112,15 @@ static long do_rmdir(int dfd, const char
 			error = -EBUSY;
 			goto exit1;
 	}
-	mutex_lock_nested(&nd.dentry->d_inode->i_mutex, I_MUTEX_PARENT);
+	mutex_lock_nested(&nd.lookup.path.dentry->d_inode->i_mutex, I_MUTEX_PARENT);
 	dentry = lookup_hash(&nd);
 	error = PTR_ERR(dentry);
 	if (IS_ERR(dentry))
 		goto exit2;
-	error = vfs_rmdir(nd.dentry->d_inode, dentry);
+	error = vfs_rmdir(nd.lookup.path.dentry->d_inode, dentry);
 	dput(dentry);
 exit2:
-	mutex_unlock(&nd.dentry->d_inode->i_mutex);
+	mutex_unlock(&nd.lookup.path.dentry->d_inode->i_mutex);
 exit1:
 	path_release(&nd);
 exit:
@@ -2187,7 +2187,7 @@ static long do_unlinkat(int dfd, const c
 	error = -EISDIR;
 	if (nd.last_type != LAST_NORM)
 		goto exit1;
-	mutex_lock_nested(&nd.dentry->d_inode->i_mutex, I_MUTEX_PARENT);
+	mutex_lock_nested(&nd.lookup.path.dentry->d_inode->i_mutex, I_MUTEX_PARENT);
 	dentry = lookup_hash(&nd);
 	error = PTR_ERR(dentry);
 	if (!IS_ERR(dentry)) {
@@ -2197,11 +2197,11 @@ static long do_unlinkat(int dfd, const c
 		inode = dentry->d_inode;
 		if (inode)
 			atomic_inc(&inode->i_count);
-		error = vfs_unlink(nd.dentry->d_inode, dentry);
+		error = vfs_unlink(nd.lookup.path.dentry->d_inode, dentry);
 	exit2:
 		dput(dentry);
 	}
-	mutex_unlock(&nd.dentry->d_inode->i_mutex);
+	mutex_unlock(&nd.lookup.path.dentry->d_inode->i_mutex);
 	if (inode)
 		iput(inode);	/* truncate the inode here */
 exit1:
@@ -2278,10 +2278,10 @@ asmlinkage long sys_symlinkat(const char
 	if (IS_ERR(dentry))
 		goto out_unlock;
 
-	error = vfs_symlink(nd.dentry->d_inode, dentry, from, S_IALLUGO);
+	error = vfs_symlink(nd.lookup.path.dentry->d_inode, dentry, from, S_IALLUGO);
 	dput(dentry);
 out_unlock:
-	mutex_unlock(&nd.dentry->d_inode->i_mutex);
+	mutex_unlock(&nd.lookup.path.dentry->d_inode->i_mutex);
 	path_release(&nd);
 out:
 	putname(to);
@@ -2367,16 +2367,16 @@ asmlinkage long sys_linkat(int olddfd, c
 	if (error)
 		goto out;
 	error = -EXDEV;
-	if (old_nd.mnt != nd.mnt)
+	if (old_nd.lookup.path.mnt != nd.lookup.path.mnt)
 		goto out_release;
 	new_dentry = lookup_create(&nd, 0);
 	error = PTR_ERR(new_dentry);
 	if (IS_ERR(new_dentry))
 		goto out_unlock;
-	error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
+	error = vfs_link(old_nd.lookup.path.dentry, nd.lookup.path.dentry->d_inode, new_dentry);
 	dput(new_dentry);
 out_unlock:
-	mutex_unlock(&nd.dentry->d_inode->i_mutex);
+	mutex_unlock(&nd.lookup.path.dentry->d_inode->i_mutex);
 out_release:
 	path_release(&nd);
 out:
@@ -2556,15 +2556,15 @@ static int do_rename(int olddfd, const c
 		goto exit1;
 
 	error = -EXDEV;
-	if (oldnd.mnt != newnd.mnt)
+	if (oldnd.lookup.path.mnt != newnd.lookup.path.mnt)
 		goto exit2;
 
-	old_dir = oldnd.dentry;
+	old_dir = oldnd.lookup.path.dentry;
 	error = -EBUSY;
 	if (oldnd.last_type != LAST_NORM)
 		goto exit2;
 
-	new_dir = newnd.dentry;
+	new_dir = newnd.lookup.path.dentry;
 	if (newnd.last_type != LAST_NORM)
 		goto exit2;
 
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -154,13 +154,13 @@ static void __touch_mnt_namespace(struct
 
 static void detach_mnt(struct vfsmount *mnt, struct nameidata *old_nd)
 {
-	old_nd->dentry = mnt->mnt_mountpoint;
-	old_nd->mnt = mnt->mnt_parent;
+	old_nd->lookup.path.dentry = mnt->mnt_mountpoint;
+	old_nd->lookup.path.mnt = mnt->mnt_parent;
 	mnt->mnt_parent = mnt;
 	mnt->mnt_mountpoint = mnt->mnt_root;
 	list_del_init(&mnt->mnt_child);
 	list_del_init(&mnt->mnt_hash);
-	old_nd->dentry->d_mounted--;
+	old_nd->lookup.path.dentry->d_mounted--;
 }
 
 void mnt_set_mountpoint(struct vfsmount *mnt, struct dentry *dentry,
@@ -173,10 +173,10 @@ void mnt_set_mountpoint(struct vfsmount 
 
 static void attach_mnt(struct vfsmount *mnt, struct nameidata *nd)
 {
-	mnt_set_mountpoint(nd->mnt, nd->dentry, mnt);
+	mnt_set_mountpoint(nd->lookup.path.mnt, nd->lookup.path.dentry, mnt);
 	list_add_tail(&mnt->mnt_hash, mount_hashtable +
-			hash(nd->mnt, nd->dentry));
-	list_add_tail(&mnt->mnt_child, &nd->mnt->mnt_mounts);
+			hash(nd->lookup.path.mnt, nd->lookup.path.dentry));
+	list_add_tail(&mnt->mnt_child, &nd->lookup.path.mnt->mnt_mounts);
 }
 
 /*
@@ -637,16 +637,16 @@ asmlinkage long sys_umount(char __user *
 	if (retval)
 		goto out;
 	retval = -EINVAL;
-	if (nd.dentry != nd.mnt->mnt_root)
+	if (nd.lookup.path.dentry != nd.lookup.path.mnt->mnt_root)
 		goto dput_and_out;
-	if (!check_mnt(nd.mnt))
+	if (!check_mnt(nd.lookup.path.mnt))
 		goto dput_and_out;
 
 	retval = -EPERM;
 	if (!capable(CAP_SYS_ADMIN))
 		goto dput_and_out;
 
-	retval = do_umount(nd.mnt, flags);
+	retval = do_umount(nd.lookup.path.mnt, flags);
 dput_and_out:
 	path_release_on_umount(&nd);
 out:
@@ -671,10 +671,10 @@ static int mount_is_safe(struct nameidat
 		return 0;
 	return -EPERM;
 #ifdef notyet
-	if (S_ISLNK(nd->dentry->d_inode->i_mode))
+	if (S_ISLNK(nd->lookup.path.dentry->d_inode->i_mode))
 		return -EPERM;
-	if (nd->dentry->d_inode->i_mode & S_ISVTX) {
-		if (current->uid != nd->dentry->d_inode->i_uid)
+	if (nd->lookup.path.dentry->d_inode->i_mode & S_ISVTX) {
+		if (current->uid != nd->lookup.path.dentry->d_inode->i_uid)
 			return -EPERM;
 	}
 	if (vfs_permission(nd, MAY_WRITE))
@@ -723,8 +723,8 @@ struct vfsmount *copy_tree(struct vfsmou
 				q = q->mnt_parent;
 			}
 			p = s;
-			nd.mnt = q;
-			nd.dentry = p->mnt_mountpoint;
+			nd.lookup.path.mnt = q;
+			nd.lookup.path.dentry = p->mnt_mountpoint;
 			q = clone_mnt(p, p->mnt_root, flag);
 			if (!q)
 				goto Enomem;
@@ -813,8 +813,8 @@ static int attach_recursive_mnt(struct v
 			struct nameidata *nd, struct nameidata *parent_nd)
 {
 	LIST_HEAD(tree_list);
-	struct vfsmount *dest_mnt = nd->mnt;
-	struct dentry *dest_dentry = nd->dentry;
+	struct vfsmount *dest_mnt = nd->lookup.path.mnt;
+	struct dentry *dest_dentry = nd->lookup.path.dentry;
 	struct vfsmount *child, *p;
 
 	if (propagate_mnt(dest_mnt, dest_dentry, source_mnt, &tree_list))
@@ -849,13 +849,13 @@ static int graft_tree(struct vfsmount *m
 	if (mnt->mnt_sb->s_flags & MS_NOUSER)
 		return -EINVAL;
 
-	if (S_ISDIR(nd->dentry->d_inode->i_mode) !=
+	if (S_ISDIR(nd->lookup.path.dentry->d_inode->i_mode) !=
 	      S_ISDIR(mnt->mnt_root->d_inode->i_mode))
 		return -ENOTDIR;
 
 	err = -ENOENT;
-	mutex_lock(&nd->dentry->d_inode->i_mutex);
-	if (IS_DEADDIR(nd->dentry->d_inode))
+	mutex_lock(&nd->lookup.path.dentry->d_inode->i_mutex);
+	if (IS_DEADDIR(nd->lookup.path.dentry->d_inode))
 		goto out_unlock;
 
 	err = security_sb_check_sb(mnt, nd);
@@ -863,10 +863,10 @@ static int graft_tree(struct vfsmount *m
 		goto out_unlock;
 
 	err = -ENOENT;
-	if (IS_ROOT(nd->dentry) || !d_unhashed(nd->dentry))
+	if (IS_ROOT(nd->lookup.path.dentry) || !d_unhashed(nd->lookup.path.dentry))
 		err = attach_recursive_mnt(mnt, nd, NULL);
 out_unlock:
-	mutex_unlock(&nd->dentry->d_inode->i_mutex);
+	mutex_unlock(&nd->lookup.path.dentry->d_inode->i_mutex);
 	if (!err)
 		security_sb_post_addmount(mnt, nd);
 	return err;
@@ -877,14 +877,14 @@ out_unlock:
  */
 static int do_change_type(struct nameidata *nd, int flag)
 {
-	struct vfsmount *m, *mnt = nd->mnt;
+	struct vfsmount *m, *mnt = nd->lookup.path.mnt;
 	int recurse = flag & MS_REC;
 	int type = flag & ~MS_REC;
 
 	if (!capable(CAP_SYS_ADMIN))
 		return -EPERM;
 
-	if (nd->dentry != nd->mnt->mnt_root)
+	if (nd->lookup.path.dentry != nd->lookup.path.mnt->mnt_root)
 		return -EINVAL;
 
 	down_write(&namespace_sem);
@@ -914,17 +914,17 @@ static int do_loopback(struct nameidata 
 
 	down_write(&namespace_sem);
 	err = -EINVAL;
-	if (IS_MNT_UNBINDABLE(old_nd.mnt))
+	if (IS_MNT_UNBINDABLE(old_nd.lookup.path.mnt))
  		goto out;
 
-	if (!check_mnt(nd->mnt) || !check_mnt(old_nd.mnt))
+	if (!check_mnt(nd->lookup.path.mnt) || !check_mnt(old_nd.lookup.path.mnt))
 		goto out;
 
 	err = -ENOMEM;
 	if (recurse)
-		mnt = copy_tree(old_nd.mnt, old_nd.dentry, 0);
+		mnt = copy_tree(old_nd.lookup.path.mnt, old_nd.lookup.path.dentry, 0);
 	else
-		mnt = clone_mnt(old_nd.mnt, old_nd.dentry, 0);
+		mnt = clone_mnt(old_nd.lookup.path.mnt, old_nd.lookup.path.dentry, 0);
 
 	if (!mnt)
 		goto out;
@@ -953,24 +953,24 @@ static int do_remount(struct nameidata *
 		      void *data)
 {
 	int err;
-	struct super_block *sb = nd->mnt->mnt_sb;
+	struct super_block *sb = nd->lookup.path.mnt->mnt_sb;
 
 	if (!capable(CAP_SYS_ADMIN))
 		return -EPERM;
 
-	if (!check_mnt(nd->mnt))
+	if (!check_mnt(nd->lookup.path.mnt))
 		return -EINVAL;
 
-	if (nd->dentry != nd->mnt->mnt_root)
+	if (nd->lookup.path.dentry != nd->lookup.path.mnt->mnt_root)
 		return -EINVAL;
 
 	down_write(&sb->s_umount);
 	err = do_remount_sb(sb, flags, data, 0);
 	if (!err)
-		nd->mnt->mnt_flags = mnt_flags;
+		nd->lookup.path.mnt->mnt_flags = mnt_flags;
 	up_write(&sb->s_umount);
 	if (!err)
-		security_sb_post_remount(nd->mnt, flags, data);
+		security_sb_post_remount(nd->lookup.path.mnt, flags, data);
 	return err;
 }
 
@@ -998,56 +998,56 @@ static int do_move_mount(struct nameidat
 		return err;
 
 	down_write(&namespace_sem);
-	while (d_mountpoint(nd->dentry) && follow_down(&nd->mnt, &nd->dentry))
+	while (d_mountpoint(nd->lookup.path.dentry) && follow_down(&nd->lookup.path.mnt, &nd->lookup.path.dentry))
 		;
 	err = -EINVAL;
-	if (!check_mnt(nd->mnt) || !check_mnt(old_nd.mnt))
+	if (!check_mnt(nd->lookup.path.mnt) || !check_mnt(old_nd.lookup.path.mnt))
 		goto out;
 
 	err = -ENOENT;
-	mutex_lock(&nd->dentry->d_inode->i_mutex);
-	if (IS_DEADDIR(nd->dentry->d_inode))
+	mutex_lock(&nd->lookup.path.dentry->d_inode->i_mutex);
+	if (IS_DEADDIR(nd->lookup.path.dentry->d_inode))
 		goto out1;
 
-	if (!IS_ROOT(nd->dentry) && d_unhashed(nd->dentry))
+	if (!IS_ROOT(nd->lookup.path.dentry) && d_unhashed(nd->lookup.path.dentry))
 		goto out1;
 
 	err = -EINVAL;
-	if (old_nd.dentry != old_nd.mnt->mnt_root)
+	if (old_nd.lookup.path.dentry != old_nd.lookup.path.mnt->mnt_root)
 		goto out1;
 
-	if (old_nd.mnt == old_nd.mnt->mnt_parent)
+	if (old_nd.lookup.path.mnt == old_nd.lookup.path.mnt->mnt_parent)
 		goto out1;
 
-	if (S_ISDIR(nd->dentry->d_inode->i_mode) !=
-	      S_ISDIR(old_nd.dentry->d_inode->i_mode))
+	if (S_ISDIR(nd->lookup.path.dentry->d_inode->i_mode) !=
+	      S_ISDIR(old_nd.lookup.path.dentry->d_inode->i_mode))
 		goto out1;
 	/*
 	 * Don't move a mount residing in a shared parent.
 	 */
-	if (old_nd.mnt->mnt_parent && IS_MNT_SHARED(old_nd.mnt->mnt_parent))
+	if (old_nd.lookup.path.mnt->mnt_parent && IS_MNT_SHARED(old_nd.lookup.path.mnt->mnt_parent))
 		goto out1;
 	/*
 	 * Don't move a mount tree containing unbindable mounts to a destination
 	 * mount which is shared.
 	 */
-	if (IS_MNT_SHARED(nd->mnt) && tree_contains_unbindable(old_nd.mnt))
+	if (IS_MNT_SHARED(nd->lookup.path.mnt) && tree_contains_unbindable(old_nd.lookup.path.mnt))
 		goto out1;
 	err = -ELOOP;
-	for (p = nd->mnt; p->mnt_parent != p; p = p->mnt_parent)
-		if (p == old_nd.mnt)
+	for (p = nd->lookup.path.mnt; p->mnt_parent != p; p = p->mnt_parent)
+		if (p == old_nd.lookup.path.mnt)
 			goto out1;
 
-	if ((err = attach_recursive_mnt(old_nd.mnt, nd, &parent_nd)))
+	if ((err = attach_recursive_mnt(old_nd.lookup.path.mnt, nd, &parent_nd)))
 		goto out1;
 
 	spin_lock(&vfsmount_lock);
 	/* if the mount is moved, it should no longer be expire
 	 * automatically */
-	list_del_init(&old_nd.mnt->mnt_expire);
+	list_del_init(&old_nd.lookup.path.mnt->mnt_expire);
 	spin_unlock(&vfsmount_lock);
 out1:
-	mutex_unlock(&nd->dentry->d_inode->i_mutex);
+	mutex_unlock(&nd->lookup.path.dentry->d_inode->i_mutex);
 out:
 	up_write(&namespace_sem);
 	if (!err)
@@ -1090,16 +1090,16 @@ int do_add_mount(struct vfsmount *newmnt
 
 	down_write(&namespace_sem);
 	/* Something was mounted here while we slept */
-	while (d_mountpoint(nd->dentry) && follow_down(&nd->mnt, &nd->dentry))
+	while (d_mountpoint(nd->lookup.path.dentry) && follow_down(&nd->lookup.path.mnt, &nd->lookup.path.dentry))
 		;
 	err = -EINVAL;
-	if (!check_mnt(nd->mnt))
+	if (!check_mnt(nd->lookup.path.mnt))
 		goto unlock;
 
 	/* Refuse the same filesystem on the same mount point */
 	err = -EBUSY;
-	if (nd->mnt->mnt_sb == newmnt->mnt_sb &&
-	    nd->mnt->mnt_root == nd->dentry)
+	if (nd->lookup.path.mnt->mnt_sb == newmnt->mnt_sb &&
+	    nd->lookup.path.mnt->mnt_root == nd->lookup.path.dentry)
 		goto unlock;
 
 	err = -EINVAL;
@@ -1625,12 +1625,12 @@ static void chroot_fs_refs(struct nameid
 		if (fs) {
 			atomic_inc(&fs->count);
 			task_unlock(p);
-			if (fs->root == old_nd->dentry
-			    && fs->rootmnt == old_nd->mnt)
-				set_fs_root(fs, new_nd->mnt, new_nd->dentry);
-			if (fs->pwd == old_nd->dentry
-			    && fs->pwdmnt == old_nd->mnt)
-				set_fs_pwd(fs, new_nd->mnt, new_nd->dentry);
+			if (fs->root == old_nd->lookup.path.dentry
+			    && fs->rootmnt == old_nd->lookup.path.mnt)
+				set_fs_root(fs, new_nd->lookup.path.mnt, new_nd->lookup.path.dentry);
+			if (fs->pwd == old_nd->lookup.path.dentry
+			    && fs->pwdmnt == old_nd->lookup.path.mnt)
+				set_fs_pwd(fs, new_nd->lookup.path.mnt, new_nd->lookup.path.dentry);
 			put_fs_struct(fs);
 		} else
 			task_unlock(p);
@@ -1680,7 +1680,7 @@ asmlinkage long sys_pivot_root(const cha
 	if (error)
 		goto out0;
 	error = -EINVAL;
-	if (!check_mnt(new_nd.mnt))
+	if (!check_mnt(new_nd.lookup.path.mnt))
 		goto out1;
 
 	error = __user_walk(put_old, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &old_nd);
@@ -1694,55 +1694,55 @@ asmlinkage long sys_pivot_root(const cha
 	}
 
 	read_lock(&current->fs->lock);
-	user_nd.mnt = mntget(current->fs->rootmnt);
-	user_nd.dentry = dget(current->fs->root);
+	user_nd.lookup.path.mnt = mntget(current->fs->rootmnt);
+	user_nd.lookup.path.dentry = dget(current->fs->root);
 	read_unlock(&current->fs->lock);
 	down_write(&namespace_sem);
-	mutex_lock(&old_nd.dentry->d_inode->i_mutex);
+	mutex_lock(&old_nd.lookup.path.dentry->d_inode->i_mutex);
 	error = -EINVAL;
-	if (IS_MNT_SHARED(old_nd.mnt) ||
-		IS_MNT_SHARED(new_nd.mnt->mnt_parent) ||
-		IS_MNT_SHARED(user_nd.mnt->mnt_parent))
+	if (IS_MNT_SHARED(old_nd.lookup.path.mnt) ||
+		IS_MNT_SHARED(new_nd.lookup.path.mnt->mnt_parent) ||
+		IS_MNT_SHARED(user_nd.lookup.path.mnt->mnt_parent))
 		goto out2;
-	if (!check_mnt(user_nd.mnt))
+	if (!check_mnt(user_nd.lookup.path.mnt))
 		goto out2;
 	error = -ENOENT;
-	if (IS_DEADDIR(new_nd.dentry->d_inode))
+	if (IS_DEADDIR(new_nd.lookup.path.dentry->d_inode))
 		goto out2;
-	if (d_unhashed(new_nd.dentry) && !IS_ROOT(new_nd.dentry))
+	if (d_unhashed(new_nd.lookup.path.dentry) && !IS_ROOT(new_nd.lookup.path.dentry))
 		goto out2;
-	if (d_unhashed(old_nd.dentry) && !IS_ROOT(old_nd.dentry))
+	if (d_unhashed(old_nd.lookup.path.dentry) && !IS_ROOT(old_nd.lookup.path.dentry))
 		goto out2;
 	error = -EBUSY;
-	if (new_nd.mnt == user_nd.mnt || old_nd.mnt == user_nd.mnt)
+	if (new_nd.lookup.path.mnt == user_nd.lookup.path.mnt || old_nd.lookup.path.mnt == user_nd.lookup.path.mnt)
 		goto out2; /* loop, on the same file system  */
 	error = -EINVAL;
-	if (user_nd.mnt->mnt_root != user_nd.dentry)
+	if (user_nd.lookup.path.mnt->mnt_root != user_nd.lookup.path.dentry)
 		goto out2; /* not a mountpoint */
-	if (user_nd.mnt->mnt_parent == user_nd.mnt)
+	if (user_nd.lookup.path.mnt->mnt_parent == user_nd.lookup.path.mnt)
 		goto out2; /* not attached */
-	if (new_nd.mnt->mnt_root != new_nd.dentry)
+	if (new_nd.lookup.path.mnt->mnt_root != new_nd.lookup.path.dentry)
 		goto out2; /* not a mountpoint */
-	if (new_nd.mnt->mnt_parent == new_nd.mnt)
+	if (new_nd.lookup.path.mnt->mnt_parent == new_nd.lookup.path.mnt)
 		goto out2; /* not attached */
-	tmp = old_nd.mnt; /* make sure we can reach put_old from new_root */
+	tmp = old_nd.lookup.path.mnt; /* make sure we can reach put_old from new_root */
 	spin_lock(&vfsmount_lock);
-	if (tmp != new_nd.mnt) {
+	if (tmp != new_nd.lookup.path.mnt) {
 		for (;;) {
 			if (tmp->mnt_parent == tmp)
 				goto out3; /* already mounted on put_old */
-			if (tmp->mnt_parent == new_nd.mnt)
+			if (tmp->mnt_parent == new_nd.lookup.path.mnt)
 				break;
 			tmp = tmp->mnt_parent;
 		}
-		if (!is_subdir(tmp->mnt_mountpoint, new_nd.dentry))
+		if (!is_subdir(tmp->mnt_mountpoint, new_nd.lookup.path.dentry))
 			goto out3;
-	} else if (!is_subdir(old_nd.dentry, new_nd.dentry))
+	} else if (!is_subdir(old_nd.lookup.path.dentry, new_nd.lookup.path.dentry))
 		goto out3;
-	detach_mnt(new_nd.mnt, &parent_nd);
-	detach_mnt(user_nd.mnt, &root_parent);
-	attach_mnt(user_nd.mnt, &old_nd);     /* mount old root on put_old */
-	attach_mnt(new_nd.mnt, &root_parent); /* mount new_root on / */
+	detach_mnt(new_nd.lookup.path.mnt, &parent_nd);
+	detach_mnt(user_nd.lookup.path.mnt, &root_parent);
+	attach_mnt(user_nd.lookup.path.mnt, &old_nd);     /* mount old root on put_old */
+	attach_mnt(new_nd.lookup.path.mnt, &root_parent); /* mount new_root on / */
 	touch_mnt_namespace(current->nsproxy->mnt_ns);
 	spin_unlock(&vfsmount_lock);
 	chroot_fs_refs(&user_nd, &new_nd);
@@ -1751,7 +1751,7 @@ asmlinkage long sys_pivot_root(const cha
 	path_release(&root_parent);
 	path_release(&parent_nd);
 out2:
-	mutex_unlock(&old_nd.dentry->d_inode->i_mutex);
+	mutex_unlock(&old_nd.lookup.path.dentry->d_inode->i_mutex);
 	up_write(&namespace_sem);
 	path_release(&user_nd);
 	path_release(&old_nd);
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -689,9 +689,9 @@ static inline void nfs_renew_times(struc
  */
 static inline unsigned int nfs_lookup_check_intent(struct nameidata *nd, unsigned int mask)
 {
-	if (nd->flags & (LOOKUP_CONTINUE|LOOKUP_PARENT))
+	if (nd->lookup.flags & (LOOKUP_CONTINUE|LOOKUP_PARENT))
 		return 0;
-	return nd->flags & mask;
+	return nd->lookup.flags & mask;
 }
 
 /*
@@ -709,7 +709,7 @@ int nfs_lookup_verify_inode(struct inode
 
 	if (nd != NULL) {
 		/* VFS wants an on-the-wire revalidation */
-		if (nd->flags & LOOKUP_REVAL)
+		if (nd->lookup.flags & LOOKUP_REVAL)
 			goto out_force;
 		/* This is an open(2) */
 		if (nfs_lookup_check_intent(nd, LOOKUP_OPEN) != 0 &&
@@ -894,7 +894,7 @@ int nfs_is_exclusive_create(struct inode
 		return 0;
 	if (nd == NULL || nfs_lookup_check_intent(nd, LOOKUP_CREATE) == 0)
 		return 0;
-	return (nd->intent.open.flags & O_EXCL) != 0;
+	return (nd->lookup.intent.open.flags & O_EXCL) != 0;
 }
 
 static inline int nfs_reval_fsid(struct inode *dir, const struct nfs_fattr *fattr)
@@ -994,10 +994,10 @@ static int is_atomic_open(struct inode *
 	if (nd == NULL || nfs_lookup_check_intent(nd, LOOKUP_OPEN) == 0)
 		return 0;
 	/* NFS does not (yet) have a stateful open for directories */
-	if (nd->flags & LOOKUP_DIRECTORY)
+	if (nd->lookup.flags & LOOKUP_DIRECTORY)
 		return 0;
 	/* Are we trying to write to a read only partition? */
-	if (IS_RDONLY(dir) && (nd->intent.open.flags & (O_CREAT|O_TRUNC|FMODE_WRITE)))
+	if (IS_RDONLY(dir) && (nd->lookup.intent.open.flags & (O_CREAT|O_TRUNC|FMODE_WRITE)))
 		return 0;
 	return 1;
 }
@@ -1021,7 +1021,7 @@ static struct dentry *nfs_atomic_lookup(
 	dentry->d_op = NFS_PROTO(dir)->dentry_ops;
 
 	/* Let vfs_create() deal with O_EXCL */
-	if (nd->intent.open.flags & O_EXCL) {
+	if (nd->lookup.intent.open.flags & O_EXCL) {
 		d_add(dentry, NULL);
 		goto out;
 	}
@@ -1036,7 +1036,7 @@ static struct dentry *nfs_atomic_lookup(
 		goto out;
 	}
 
-	if (nd->intent.open.flags & O_CREAT) {
+	if (nd->lookup.intent.open.flags & O_CREAT) {
 		nfs_begin_data_update(dir);
 		res = nfs4_atomic_open(dir, dentry, nd);
 		nfs_end_data_update(dir);
@@ -1055,7 +1055,7 @@ static struct dentry *nfs_atomic_lookup(
 			case -ENOTDIR:
 				goto no_open;
 			case -ELOOP:
-				if (!(nd->intent.open.flags & O_NOFOLLOW))
+				if (!(nd->lookup.intent.open.flags & O_NOFOLLOW))
 					goto no_open;
 			/* case -EINVAL: */
 			default:
@@ -1091,7 +1091,7 @@ static int nfs_open_revalidate(struct de
 	/* NFS only supports OPEN on regular files */
 	if (!S_ISREG(inode->i_mode))
 		goto no_open;
-	openflags = nd->intent.open.flags;
+	openflags = nd->lookup.intent.open.flags;
 	/* We cannot do exclusive creation on a positive dentry */
 	if ((openflags & (O_CREAT|O_EXCL)) == (O_CREAT|O_EXCL))
 		goto no_open;
@@ -1243,8 +1243,8 @@ static int nfs_create(struct inode *dir,
 	attr.ia_mode = mode;
 	attr.ia_valid = ATTR_MODE;
 
-	if ((nd->flags & LOOKUP_CREATE) != 0)
-		open_flags = nd->intent.open.flags;
+	if ((nd->lookup.flags & LOOKUP_CREATE) != 0)
+		open_flags = nd->lookup.intent.open.flags;
 
 	lock_kernel();
 	nfs_begin_data_update(dir);
@@ -1965,7 +1965,7 @@ int nfs_permission(struct inode *inode, 
 	if (mask == 0)
 		goto out;
 	/* Is this sys_access() ? */
-	if (nd != NULL && (nd->flags & LOOKUP_ACCESS))
+	if (nd != NULL && (nd->lookup.flags & LOOKUP_ACCESS))
 		goto force_lookup;
 
 	switch (inode->i_mode & S_IFMT) {
@@ -1975,7 +1975,7 @@ int nfs_permission(struct inode *inode, 
 			/* NFSv4 has atomic_open... */
 			if (nfs_server_capable(inode, NFS_CAP_ATOMIC_OPEN)
 					&& nd != NULL
-					&& (nd->flags & LOOKUP_OPEN))
+					&& (nd->lookup.flags & LOOKUP_OPEN))
 				goto out;
 			break;
 		case S_IFDIR:
--- a/fs/nfs/namespace.c
+++ b/fs/nfs/namespace.c
@@ -107,38 +107,38 @@ static void * nfs_follow_mountpoint(stru
 
 	BUG_ON(IS_ROOT(dentry));
 	dprintk("%s: enter\n", __FUNCTION__);
-	dput(nd->dentry);
-	nd->dentry = dget(dentry);
+	dput(nd->lookup.path.dentry);
+	nd->lookup.path.dentry = dget(dentry);
 
 	/* Look it up again */
-	parent = dget_parent(nd->dentry);
+	parent = dget_parent(nd->lookup.path.dentry);
 	err = server->nfs_client->rpc_ops->lookup(parent->d_inode,
-						  &nd->dentry->d_name,
+						  &nd->lookup.path.dentry->d_name,
 						  &fh, &fattr);
 	dput(parent);
 	if (err != 0)
 		goto out_err;
 
 	if (fattr.valid & NFS_ATTR_FATTR_V4_REFERRAL)
-		mnt = nfs_do_refmount(nd->mnt, nd->dentry);
+		mnt = nfs_do_refmount(nd->lookup.path.mnt, nd->lookup.path.dentry);
 	else
-		mnt = nfs_do_submount(nd->mnt, nd->dentry, &fh, &fattr);
+		mnt = nfs_do_submount(nd->lookup.path.mnt, nd->lookup.path.dentry, &fh, &fattr);
 	err = PTR_ERR(mnt);
 	if (IS_ERR(mnt))
 		goto out_err;
 
 	mntget(mnt);
-	err = do_add_mount(mnt, nd, nd->mnt->mnt_flags|MNT_SHRINKABLE, &nfs_automount_list);
+	err = do_add_mount(mnt, nd, nd->lookup.path.mnt->mnt_flags|MNT_SHRINKABLE, &nfs_automount_list);
 	if (err < 0) {
 		mntput(mnt);
 		if (err == -EBUSY)
 			goto out_follow;
 		goto out_err;
 	}
-	mntput(nd->mnt);
-	dput(nd->dentry);
-	nd->mnt = mnt;
-	nd->dentry = dget(mnt->mnt_root);
+	mntput(nd->lookup.path.mnt);
+	dput(nd->lookup.path.dentry);
+	nd->lookup.path.mnt = mnt;
+	nd->lookup.path.dentry = dget(mnt->mnt_root);
 	schedule_delayed_work(&nfs_automount_task, nfs_mountpoint_expiry_timeout);
 out:
 	dprintk("%s: done, returned %d\n", __FUNCTION__, err);
@@ -149,7 +149,7 @@ out_err:
 	path_release(nd);
 	goto out;
 out_follow:
-	while(d_mountpoint(nd->dentry) && follow_down(&nd->mnt, &nd->dentry))
+	while(d_mountpoint(nd->lookup.path.dentry) && follow_down(&nd->lookup.path.mnt, &nd->lookup.path.dentry))
 		;
 	err = 0;
 	goto out;
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -1382,10 +1382,10 @@ static int nfs4_intent_set_file(struct n
 	int ret;
 
 	/* If the open_intent is for execute, we have an extra check to make */
-	if (nd->intent.open.flags & FMODE_EXEC) {
+	if (nd->lookup.intent.open.flags & FMODE_EXEC) {
 		ret = _nfs4_do_access(state->inode,
 				state->owner->so_cred,
-				nd->intent.open.flags);
+				nd->lookup.intent.open.flags);
 		if (ret < 0)
 			goto out_close;
 	}
@@ -1398,7 +1398,7 @@ static int nfs4_intent_set_file(struct n
 	}
 	ret = PTR_ERR(filp);
 out_close:
-	nfs4_close_state(path, state, nd->intent.open.flags);
+	nfs4_close_state(path, state, nd->lookup.intent.open.flags);
 	return ret;
 }
 
@@ -1406,7 +1406,7 @@ struct dentry *
 nfs4_atomic_open(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
 {
 	struct path path = {
-		.mnt = nd->mnt,
+		.mnt = nd->lookup.path.mnt,
 		.dentry = dentry,
 	};
 	struct iattr attr;
@@ -1414,20 +1414,20 @@ nfs4_atomic_open(struct inode *dir, stru
 	struct nfs4_state *state;
 	struct dentry *res;
 
-	if (nd->flags & LOOKUP_CREATE) {
-		attr.ia_mode = nd->intent.open.create_mode;
+	if (nd->lookup.flags & LOOKUP_CREATE) {
+		attr.ia_mode = nd->lookup.intent.open.create_mode;
 		attr.ia_valid = ATTR_MODE;
 		if (!IS_POSIXACL(dir))
 			attr.ia_mode &= ~current->fs->umask;
 	} else {
 		attr.ia_valid = 0;
-		BUG_ON(nd->intent.open.flags & O_CREAT);
+		BUG_ON(nd->lookup.intent.open.flags & O_CREAT);
 	}
 
 	cred = rpcauth_lookupcred(NFS_CLIENT(dir)->cl_auth, 0);
 	if (IS_ERR(cred))
 		return (struct dentry *)cred;
-	state = nfs4_do_open(dir, &path, nd->intent.open.flags, &attr, cred);
+	state = nfs4_do_open(dir, &path, nd->lookup.intent.open.flags, &attr, cred);
 	put_rpccred(cred);
 	if (IS_ERR(state)) {
 		if (PTR_ERR(state) == -ENOENT)
@@ -1445,7 +1445,7 @@ int
 nfs4_open_revalidate(struct inode *dir, struct dentry *dentry, int openflags, struct nameidata *nd)
 {
 	struct path path = {
-		.mnt = nd->mnt,
+		.mnt = nd->lookup.path.mnt,
 		.dentry = dentry,
 	};
 	struct rpc_cred *cred;
@@ -1888,7 +1888,7 @@ nfs4_proc_create(struct inode *dir, stru
                  int flags, struct nameidata *nd)
 {
 	struct path path = {
-		.mnt = nd->mnt,
+		.mnt = nd->lookup.path.mnt,
 		.dentry = dentry,
 	};
 	struct nfs4_state *state;
@@ -1914,7 +1914,7 @@ nfs4_proc_create(struct inode *dir, stru
 			nfs_setattr_update_inode(state->inode, sattr);
 		nfs_post_op_update_inode(state->inode, &fattr);
 	}
-	if (status == 0 && (nd->flags & LOOKUP_OPEN) != 0)
+	if (status == 0 && (nd->lookup.flags & LOOKUP_OPEN) != 0)
 		status = nfs4_intent_set_file(nd, &path, state);
 	else
 		nfs4_close_state(&path, state, flags);
--- a/fs/nfsctl.c
+++ b/fs/nfsctl.c
@@ -41,7 +41,7 @@ static struct file *do_open(char *name, 
 		error = may_open(&nd, MAY_WRITE, FMODE_WRITE);
 
 	if (!error)
-		return dentry_open(nd.dentry, nd.mnt, flags);
+		return dentry_open(nd.lookup.path.dentry, nd.lookup.path.mnt, flags);
 
 	path_release(&nd);
 	return ERR_PTR(error);
--- a/fs/nfsd/export.c
+++ b/fs/nfsd/export.c
@@ -169,8 +169,8 @@ static int expkey_parse(struct cache_det
 			goto out;
 
 		dprintk("Found the path %s\n", buf);
-		key.ek_mnt = nd.mnt;
-		key.ek_dentry = nd.dentry;
+		key.ek_mnt = nd.lookup.path.mnt;
+		key.ek_dentry = nd.lookup.path.dentry;
 		
 		ek = svc_expkey_update(&key, ek);
 		if (ek)
@@ -509,7 +509,7 @@ static int svc_export_parse(struct cache
 	struct svc_export exp, *expp;
 	int an_int;
 
-	nd.dentry = NULL;
+	nd.lookup.path.dentry = NULL;
 	exp.ex_path = NULL;
 
 	/* fs locations */
@@ -549,8 +549,8 @@ static int svc_export_parse(struct cache
 
 	exp.h.flags = 0;
 	exp.ex_client = dom;
-	exp.ex_mnt = nd.mnt;
-	exp.ex_dentry = nd.dentry;
+	exp.ex_mnt = nd.lookup.path.mnt;
+	exp.ex_dentry = nd.lookup.path.dentry;
 	exp.ex_path = kstrdup(buf, GFP_KERNEL);
 	err = -ENOMEM;
 	if (!exp.ex_path)
@@ -612,7 +612,7 @@ static int svc_export_parse(struct cache
 				goto out;
 		}
 
-		err = check_export(nd.dentry->d_inode, exp.ex_flags,
+		err = check_export(nd.lookup.path.dentry->d_inode, exp.ex_flags,
 				   exp.ex_uuid);
 		if (err) goto out;
 	}
@@ -631,7 +631,7 @@ static int svc_export_parse(struct cache
 	nfsd4_fslocs_free(&exp.ex_fslocs);
 	kfree(exp.ex_uuid);
  	kfree(exp.ex_path);
-	if (nd.dentry)
+	if (nd.lookup.path.dentry)
 		path_release(&nd);
  out_no_path:
 	if (dom)
@@ -1032,7 +1032,7 @@ exp_export(struct nfsctl_export *nxp)
 		goto out_unlock;
 	err = -EINVAL;
 
-	exp = exp_get_by_name(clp, nd.mnt, nd.dentry, NULL);
+	exp = exp_get_by_name(clp, nd.lookup.path.mnt, nd.lookup.path.dentry, NULL);
 
 	memset(&new, 0, sizeof(new));
 
@@ -1040,7 +1040,7 @@ exp_export(struct nfsctl_export *nxp)
 	if ((nxp->ex_flags & NFSEXP_FSID) &&
 	    (!IS_ERR(fsid_key = exp_get_fsid_key(clp, nxp->ex_dev))) &&
 	    fsid_key->ek_mnt &&
-	    (fsid_key->ek_mnt != nd.mnt || fsid_key->ek_dentry != nd.dentry) )
+	    (fsid_key->ek_mnt != nd.lookup.path.mnt || fsid_key->ek_dentry != nd.lookup.path.dentry) )
 		goto finish;
 
 	if (!IS_ERR(exp)) {
@@ -1056,7 +1056,7 @@ exp_export(struct nfsctl_export *nxp)
 		goto finish;
 	}
 
-	err = check_export(nd.dentry->d_inode, nxp->ex_flags, NULL);
+	err = check_export(nd.lookup.path.dentry->d_inode, nxp->ex_flags, NULL);
 	if (err) goto finish;
 
 	err = -ENOMEM;
@@ -1069,8 +1069,8 @@ exp_export(struct nfsctl_export *nxp)
 	if (!new.ex_path)
 		goto finish;
 	new.ex_client = clp;
-	new.ex_mnt = nd.mnt;
-	new.ex_dentry = nd.dentry;
+	new.ex_mnt = nd.lookup.path.mnt;
+	new.ex_dentry = nd.lookup.path.dentry;
 	new.ex_flags = nxp->ex_flags;
 	new.ex_anon_uid = nxp->ex_anon_uid;
 	new.ex_anon_gid = nxp->ex_anon_gid;
@@ -1150,7 +1150,7 @@ exp_unexport(struct nfsctl_export *nxp)
 		goto out_domain;
 
 	err = -EINVAL;
-	exp = exp_get_by_name(dom, nd.mnt, nd.dentry, NULL);
+	exp = exp_get_by_name(dom, nd.lookup.path.mnt, nd.lookup.path.dentry, NULL);
 	path_release(&nd);
 	if (IS_ERR(exp))
 		goto out_domain;
@@ -1187,12 +1187,12 @@ exp_rootfh(svc_client *clp, char *path, 
 		printk("nfsd: exp_rootfh path not found %s", path);
 		return err;
 	}
-	inode = nd.dentry->d_inode;
+	inode = nd.lookup.path.dentry->d_inode;
 
 	dprintk("nfsd: exp_rootfh(%s [%p] %s:%s/%ld)\n",
-		 path, nd.dentry, clp->name,
+		 path, nd.lookup.path.dentry, clp->name,
 		 inode->i_sb->s_id, inode->i_ino);
-	exp = exp_parent(clp, nd.mnt, nd.dentry, NULL);
+	exp = exp_parent(clp, nd.lookup.path.mnt, nd.lookup.path.dentry, NULL);
 	if (IS_ERR(exp)) {
 		err = PTR_ERR(exp);
 		goto out;
@@ -1202,7 +1202,7 @@ exp_rootfh(svc_client *clp, char *path, 
 	 * fh must be initialized before calling fh_compose
 	 */
 	fh_init(&fh, maxsize);
-	if (fh_compose(&fh, exp, nd.dentry, NULL))
+	if (fh_compose(&fh, exp, nd.lookup.path.dentry, NULL))
 		err = -EINVAL;
 	else
 		err = 0;
--- a/fs/nfsd/nfs4recover.c
+++ b/fs/nfsd/nfs4recover.c
@@ -122,9 +122,9 @@ out_no_tfm:
 static void
 nfsd4_sync_rec_dir(void)
 {
-	mutex_lock(&rec_dir.dentry->d_inode->i_mutex);
-	nfsd_sync_dir(rec_dir.dentry);
-	mutex_unlock(&rec_dir.dentry->d_inode->i_mutex);
+	mutex_lock(&rec_dir.lookup.path.dentry->d_inode->i_mutex);
+	nfsd_sync_dir(rec_dir.lookup.path.dentry);
+	mutex_unlock(&rec_dir.lookup.path.dentry->d_inode->i_mutex);
 }
 
 int
@@ -144,9 +144,9 @@ nfsd4_create_clid_dir(struct nfs4_client
 	nfs4_save_user(&uid, &gid);
 
 	/* lock the parent */
-	mutex_lock(&rec_dir.dentry->d_inode->i_mutex);
+	mutex_lock(&rec_dir.lookup.path.dentry->d_inode->i_mutex);
 
-	dentry = lookup_one_len(dname, rec_dir.dentry, HEXDIR_LEN-1);
+	dentry = lookup_one_len(dname, rec_dir.lookup.path.dentry, HEXDIR_LEN-1);
 	if (IS_ERR(dentry)) {
 		status = PTR_ERR(dentry);
 		goto out_unlock;
@@ -156,11 +156,11 @@ nfsd4_create_clid_dir(struct nfs4_client
 		dprintk("NFSD: nfsd4_create_clid_dir: DIRECTORY EXISTS\n");
 		goto out_put;
 	}
-	status = vfs_mkdir(rec_dir.dentry->d_inode, dentry, S_IRWXU);
+	status = vfs_mkdir(rec_dir.lookup.path.dentry->d_inode, dentry, S_IRWXU);
 out_put:
 	dput(dentry);
 out_unlock:
-	mutex_unlock(&rec_dir.dentry->d_inode->i_mutex);
+	mutex_unlock(&rec_dir.lookup.path.dentry->d_inode->i_mutex);
 	if (status == 0) {
 		clp->cl_firststate = 1;
 		nfsd4_sync_rec_dir();
@@ -223,7 +223,7 @@ nfsd4_list_rec_dir(struct dentry *dir, r
 
 	nfs4_save_user(&uid, &gid);
 
-	filp = dentry_open(dget(dir), mntget(rec_dir.mnt), O_RDONLY);
+	filp = dentry_open(dget(dir), mntget(rec_dir.lookup.path.mnt), O_RDONLY);
 	status = PTR_ERR(filp);
 	if (IS_ERR(filp))
 		goto out;
@@ -288,9 +288,9 @@ nfsd4_unlink_clid_dir(char *name, int na
 
 	dprintk("NFSD: nfsd4_unlink_clid_dir. name %.*s\n", namlen, name);
 
-	mutex_lock(&rec_dir.dentry->d_inode->i_mutex);
-	dentry = lookup_one_len(name, rec_dir.dentry, namlen);
-	mutex_unlock(&rec_dir.dentry->d_inode->i_mutex);
+	mutex_lock(&rec_dir.lookup.path.dentry->d_inode->i_mutex);
+	dentry = lookup_one_len(name, rec_dir.lookup.path.dentry, namlen);
+	mutex_unlock(&rec_dir.lookup.path.dentry->d_inode->i_mutex);
 	if (IS_ERR(dentry)) {
 		status = PTR_ERR(dentry);
 		return status;
@@ -299,7 +299,7 @@ nfsd4_unlink_clid_dir(char *name, int na
 	if (!dentry->d_inode)
 		goto out;
 
-	status = nfsd4_clear_clid_dir(rec_dir.dentry, dentry);
+	status = nfsd4_clear_clid_dir(rec_dir.lookup.path.dentry, dentry);
 out:
 	dput(dentry);
 	return status;
@@ -349,12 +349,12 @@ nfsd4_recdir_purge_old(void) {
 
 	if (!rec_dir_init)
 		return;
-	status = nfsd4_list_rec_dir(rec_dir.dentry, purge_old);
+	status = nfsd4_list_rec_dir(rec_dir.lookup.path.dentry, purge_old);
 	if (status == 0)
 		nfsd4_sync_rec_dir();
 	if (status)
 		printk("nfsd4: failed to purge old clients from recovery"
-			" directory %s\n", rec_dir.dentry->d_name.name);
+			" directory %s\n", rec_dir.lookup.path.dentry->d_name.name);
 	return;
 }
 
@@ -375,10 +375,10 @@ int
 nfsd4_recdir_load(void) {
 	int status;
 
-	status = nfsd4_list_rec_dir(rec_dir.dentry, load_recdir);
+	status = nfsd4_list_rec_dir(rec_dir.lookup.path.dentry, load_recdir);
 	if (status)
 		printk("nfsd4: failed loading clients from recovery"
-			" directory %s\n", rec_dir.dentry->d_name.name);
+			" directory %s\n", rec_dir.lookup.path.dentry->d_name.name);
 	return status;
 }
 
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -3338,7 +3338,7 @@ nfs4_reset_recoverydir(char *recdir)
 	if (status)
 		return status;
 	status = -ENOTDIR;
-	if (S_ISDIR(nd.dentry->d_inode->i_mode)) {
+	if (S_ISDIR(nd.lookup.path.dentry->d_inode->i_mode)) {
 		nfs4_set_recdir(recdir);
 		status = 0;
 	}
--- a/fs/open.c
+++ b/fs/open.c
@@ -127,7 +127,7 @@ asmlinkage long sys_statfs(const char __
 	error = user_path_walk(path, &nd);
 	if (!error) {
 		struct statfs tmp;
-		error = vfs_statfs_native(nd.dentry, &tmp);
+		error = vfs_statfs_native(nd.lookup.path.dentry, &tmp);
 		if (!error && copy_to_user(buf, &tmp, sizeof(tmp)))
 			error = -EFAULT;
 		path_release(&nd);
@@ -146,7 +146,7 @@ asmlinkage long sys_statfs64(const char 
 	error = user_path_walk(path, &nd);
 	if (!error) {
 		struct statfs64 tmp;
-		error = vfs_statfs64(nd.dentry, &tmp);
+		error = vfs_statfs64(nd.lookup.path.dentry, &tmp);
 		if (!error && copy_to_user(buf, &tmp, sizeof(tmp)))
 			error = -EFAULT;
 		path_release(&nd);
@@ -233,7 +233,7 @@ static long do_sys_truncate(const char _
 	error = user_path_walk(path, &nd);
 	if (error)
 		goto out;
-	inode = nd.dentry->d_inode;
+	inode = nd.lookup.path.dentry->d_inode;
 
 	/* For directories it's -EISDIR, for other non-regulars - -EINVAL */
 	error = -EISDIR;
@@ -271,7 +271,7 @@ static long do_sys_truncate(const char _
 	error = locks_verify_truncate(inode, NULL, length);
 	if (!error) {
 		DQUOT_INIT(inode);
-		error = do_truncate(nd.dentry, length, 0, NULL);
+		error = do_truncate(nd.lookup.path.dentry, length, 0, NULL);
 	}
 
 put_write_and_out:
@@ -455,10 +455,10 @@ asmlinkage long sys_faccessat(int dfd, c
 	res = vfs_permission(&nd, mode);
 	/* SuS v2 requires we report a read only fs too */
 	if(res || !(mode & S_IWOTH) ||
-	   special_file(nd.dentry->d_inode->i_mode))
+	   special_file(nd.lookup.path.dentry->d_inode->i_mode))
 		goto out_path_release;
 
-	if(IS_RDONLY(nd.dentry->d_inode))
+	if(IS_RDONLY(nd.lookup.path.dentry->d_inode))
 		res = -EROFS;
 
 out_path_release:
@@ -490,7 +490,7 @@ asmlinkage long sys_chdir(const char __u
 	if (error)
 		goto dput_and_out;
 
-	set_fs_pwd(current->fs, nd.mnt, nd.dentry);
+	set_fs_pwd(current->fs, nd.lookup.path.mnt, nd.lookup.path.dentry);
 
 dput_and_out:
 	path_release(&nd);
@@ -545,7 +545,7 @@ asmlinkage long sys_chroot(const char __
 	if (!capable(CAP_SYS_CHROOT))
 		goto dput_and_out;
 
-	set_fs_root(current->fs, nd.mnt, nd.dentry);
+	set_fs_root(current->fs, nd.lookup.path.mnt, nd.lookup.path.dentry);
 	set_fs_altroot();
 	error = 0;
 dput_and_out:
@@ -602,7 +602,7 @@ asmlinkage long sys_fchmodat(int dfd, co
 	error = __user_walk_fd(dfd, filename, LOOKUP_FOLLOW, &nd);
 	if (error)
 		goto out;
-	inode = nd.dentry->d_inode;
+	inode = nd.lookup.path.dentry->d_inode;
 
 	error = -EROFS;
 	if (IS_RDONLY(inode))
@@ -617,7 +617,7 @@ asmlinkage long sys_fchmodat(int dfd, co
 		mode = inode->i_mode;
 	newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
 	newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
-	error = notify_change(nd.dentry, &newattrs);
+	error = notify_change(nd.lookup.path.dentry, &newattrs);
 	mutex_unlock(&inode->i_mutex);
 
 dput_and_out:
@@ -674,7 +674,7 @@ asmlinkage long sys_chown(const char __u
 	error = user_path_walk(filename, &nd);
 	if (error)
 		goto out;
-	error = chown_common(nd.dentry, user, group);
+	error = chown_common(nd.lookup.path.dentry, user, group);
 	path_release(&nd);
 out:
 	return error;
@@ -694,7 +694,7 @@ asmlinkage long sys_fchownat(int dfd, co
 	error = __user_walk_fd(dfd, filename, follow, &nd);
 	if (error)
 		goto out;
-	error = chown_common(nd.dentry, user, group);
+	error = chown_common(nd.lookup.path.dentry, user, group);
 	path_release(&nd);
 out:
 	return error;
@@ -708,7 +708,7 @@ asmlinkage long sys_lchown(const char __
 	error = user_path_walk_link(filename, &nd);
 	if (error)
 		goto out;
-	error = chown_common(nd.dentry, user, group);
+	error = chown_common(nd.lookup.path.dentry, user, group);
 	path_release(&nd);
 out:
 	return error;
@@ -846,7 +846,7 @@ EXPORT_SYMBOL(filp_open);
  * (e.g. in fifo_open), leaving you with parent locked (and in case of fifo,
  * leading to a deadlock, as nobody can open that fifo anymore, because
  * another process to open fifo will block on locked parent when doing lookup).
- * Note that in case of error, nd->intent.open.file is destroyed, but the
+ * Note that in case of error, nd->lookup.intent.open.file is destroyed, but the
  * path information remains valid.
  * If the open callback is set to NULL, then the standard f_op->open()
  * filesystem callback is substituted.
@@ -854,19 +854,19 @@ EXPORT_SYMBOL(filp_open);
 struct file *lookup_instantiate_filp(struct nameidata *nd, struct dentry *dentry,
 		int (*open)(struct inode *, struct file *))
 {
-	if (IS_ERR(nd->intent.open.file))
+	if (IS_ERR(nd->lookup.intent.open.file))
 		goto out;
 	if (IS_ERR(dentry))
 		goto out_err;
-	nd->intent.open.file = __dentry_open(dget(dentry), mntget(nd->mnt),
-					     nd->intent.open.flags - 1,
-					     nd->intent.open.file,
+	nd->lookup.intent.open.file = __dentry_open(dget(dentry), mntget(nd->lookup.path.mnt),
+					     nd->lookup.intent.open.flags - 1,
+					     nd->lookup.intent.open.file,
 					     open);
 out:
-	return nd->intent.open.file;
+	return nd->lookup.intent.open.file;
 out_err:
 	release_open_intent(nd);
-	nd->intent.open.file = (struct file *)dentry;
+	nd->lookup.intent.open.file = (struct file *)dentry;
 	goto out;
 }
 EXPORT_SYMBOL_GPL(lookup_instantiate_filp);
@@ -883,10 +883,10 @@ struct file *nameidata_to_filp(struct na
 	struct file *filp;
 
 	/* Pick up the filp from the open intent */
-	filp = nd->intent.open.file;
+	filp = nd->lookup.intent.open.file;
 	/* Has the filesystem initialised the file for us? */
 	if (filp->f_path.dentry == NULL)
-		filp = __dentry_open(nd->dentry, nd->mnt, flags, filp, NULL);
+		filp = __dentry_open(nd->lookup.path.dentry, nd->lookup.path.mnt, flags, filp, NULL);
 	else
 		path_release(nd);
 	return filp;
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -944,7 +944,7 @@ static void *proc_pid_follow_link(struct
 	if (!proc_fd_access_allowed(inode))
 		goto out;
 
-	error = PROC_I(inode)->op.proc_get_link(inode, &nd->dentry, &nd->mnt);
+	error = PROC_I(inode)->op.proc_get_link(inode, &nd->lookup.path.dentry, &nd->lookup.path.mnt);
 	nd->last_type = LAST_BIND;
 out:
 	return ERR_PTR(error);
--- a/fs/proc/proc_sysctl.c
+++ b/fs/proc/proc_sysctl.c
@@ -405,7 +405,7 @@ static int proc_sys_permission(struct in
 	if (!nd || !depth)
 		goto out;
 
-	dentry = nd->dentry;
+	dentry = nd->lookup.path.dentry;
 	table = do_proc_sys_lookup(dentry->d_parent, &dentry->d_name, &head);
 
 	/* If the entry does not exist deny permission */
--- a/fs/reiserfs/super.c
+++ b/fs/reiserfs/super.c
@@ -1982,12 +1982,12 @@ static int reiserfs_quota_on(struct supe
 	if (err)
 		return err;
 	/* Quotafile not on the same filesystem? */
-	if (nd.mnt->mnt_sb != sb) {
+	if (nd.lookup.path.mnt->mnt_sb != sb) {
 		path_release(&nd);
 		return -EXDEV;
 	}
 	/* We must not pack tails for quota files on reiserfs for quota IO to work */
-	if (!REISERFS_I(nd.dentry->d_inode)->i_flags & i_nopack_mask) {
+	if (!REISERFS_I(nd.lookup.path.dentry->d_inode)->i_flags & i_nopack_mask) {
 		reiserfs_warning(sb,
 				 "reiserfs: Quota file must have tail packing disabled.");
 		path_release(&nd);
@@ -2000,7 +2000,7 @@ static int reiserfs_quota_on(struct supe
 		return vfs_quota_on(sb, type, format_id, path);
 	}
 	/* Quotafile not of fs root? */
-	if (nd.dentry->d_parent->d_inode != sb->s_root->d_inode)
+	if (nd.lookup.path.dentry->d_parent->d_inode != sb->s_root->d_inode)
 		reiserfs_warning(sb,
 				 "reiserfs: Quota file not on filesystem root. "
 				 "Journalled quota will not work.");
--- a/fs/stat.c
+++ b/fs/stat.c
@@ -62,7 +62,7 @@ int vfs_stat_fd(int dfd, char __user *na
 
 	error = __user_walk_fd(dfd, name, LOOKUP_FOLLOW, &nd);
 	if (!error) {
-		error = vfs_getattr(nd.mnt, nd.dentry, stat);
+		error = vfs_getattr(nd.lookup.path.mnt, nd.lookup.path.dentry, stat);
 		path_release(&nd);
 	}
 	return error;
@@ -82,7 +82,7 @@ int vfs_lstat_fd(int dfd, char __user *n
 
 	error = __user_walk_fd(dfd, name, 0, &nd);
 	if (!error) {
-		error = vfs_getattr(nd.mnt, nd.dentry, stat);
+		error = vfs_getattr(nd.lookup.path.mnt, nd.lookup.path.dentry, stat);
 		path_release(&nd);
 	}
 	return error;
@@ -302,14 +302,14 @@ asmlinkage long sys_readlinkat(int dfd, 
 
 	error = __user_walk_fd(dfd, path, 0, &nd);
 	if (!error) {
-		struct inode * inode = nd.dentry->d_inode;
+		struct inode * inode = nd.lookup.path.dentry->d_inode;
 
 		error = -EINVAL;
 		if (inode->i_op && inode->i_op->readlink) {
-			error = security_inode_readlink(nd.dentry);
+			error = security_inode_readlink(nd.lookup.path.dentry);
 			if (!error) {
-				touch_atime(nd.mnt, nd.dentry);
-				error = inode->i_op->readlink(nd.dentry, buf, bufsiz);
+				touch_atime(nd.lookup.path.mnt, nd.lookup.path.dentry);
+				error = inode->i_op->readlink(nd.lookup.path.dentry, buf, bufsiz);
 			}
 		}
 		path_release(&nd);
--- a/fs/utimes.c
+++ b/fs/utimes.c
@@ -70,7 +70,7 @@ long do_utimes(int dfd, char __user *fil
 		if (error)
 			goto out;
 
-		dentry = nd.dentry;
+		dentry = nd.lookup.path.dentry;
 	}
 
 	inode = dentry->d_inode;
--- a/fs/vfat/namei.c
+++ b/fs/vfat/namei.c
@@ -30,7 +30,7 @@ static int vfat_revalidate(struct dentry
 	int ret = 1;
 
 	if (!dentry->d_inode &&
-	    nd && !(nd->flags & LOOKUP_CONTINUE) && (nd->flags & LOOKUP_CREATE))
+	    nd && !(nd->lookup.flags & LOOKUP_CONTINUE) && (nd->lookup.flags & LOOKUP_CREATE))
 		/*
 		 * negative dentry is dropped, in order to make sure
 		 * to use the name which a user desires if this is
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -235,7 +235,7 @@ sys_setxattr(char __user *path, char __u
 	error = user_path_walk(path, &nd);
 	if (error)
 		return error;
-	error = setxattr(nd.dentry, name, value, size, flags);
+	error = setxattr(nd.lookup.path.dentry, name, value, size, flags);
 	path_release(&nd);
 	return error;
 }
@@ -250,7 +250,7 @@ sys_lsetxattr(char __user *path, char __
 	error = user_path_walk_link(path, &nd);
 	if (error)
 		return error;
-	error = setxattr(nd.dentry, name, value, size, flags);
+	error = setxattr(nd.lookup.path.dentry, name, value, size, flags);
 	path_release(&nd);
 	return error;
 }
@@ -320,7 +320,7 @@ sys_getxattr(char __user *path, char __u
 	error = user_path_walk(path, &nd);
 	if (error)
 		return error;
-	error = getxattr(nd.dentry, name, value, size);
+	error = getxattr(nd.lookup.path.dentry, name, value, size);
 	path_release(&nd);
 	return error;
 }
@@ -335,7 +335,7 @@ sys_lgetxattr(char __user *path, char __
 	error = user_path_walk_link(path, &nd);
 	if (error)
 		return error;
-	error = getxattr(nd.dentry, name, value, size);
+	error = getxattr(nd.lookup.path.dentry, name, value, size);
 	path_release(&nd);
 	return error;
 }
@@ -394,7 +394,7 @@ sys_listxattr(char __user *path, char __
 	error = user_path_walk(path, &nd);
 	if (error)
 		return error;
-	error = listxattr(nd.dentry, list, size);
+	error = listxattr(nd.lookup.path.dentry, list, size);
 	path_release(&nd);
 	return error;
 }
@@ -408,7 +408,7 @@ sys_llistxattr(char __user *path, char _
 	error = user_path_walk_link(path, &nd);
 	if (error)
 		return error;
-	error = listxattr(nd.dentry, list, size);
+	error = listxattr(nd.lookup.path.dentry, list, size);
 	path_release(&nd);
 	return error;
 }
@@ -455,7 +455,7 @@ sys_removexattr(char __user *path, char 
 	error = user_path_walk(path, &nd);
 	if (error)
 		return error;
-	error = removexattr(nd.dentry, name);
+	error = removexattr(nd.lookup.path.dentry, name);
 	path_release(&nd);
 	return error;
 }
@@ -469,7 +469,7 @@ sys_lremovexattr(char __user *path, char
 	error = user_path_walk_link(path, &nd);
 	if (error)
 		return error;
-	error = removexattr(nd.dentry, name);
+	error = removexattr(nd.lookup.path.dentry, name);
 	path_release(&nd);
 	return error;
 }
--- a/fs/xfs/linux-2.6/xfs_ioctl.c
+++ b/fs/xfs/linux-2.6/xfs_ioctl.c
@@ -91,9 +91,9 @@ xfs_find_handle(
 		if (error)
 			return error;
 
-		ASSERT(nd.dentry);
-		ASSERT(nd.dentry->d_inode);
-		inode = igrab(nd.dentry->d_inode);
+		ASSERT(nd.lookup.path.dentry);
+		ASSERT(nd.lookup.path.dentry->d_inode);
+		inode = igrab(nd.lookup.path.dentry->d_inode);
 		path_release(&nd);
 		break;
 	}
--- a/kernel/auditfilter.c
+++ b/kernel/auditfilter.c
@@ -167,7 +167,7 @@ static struct audit_parent *audit_init_p
 	inotify_init_watch(&parent->wdata);
 	/* grab a ref so inotify watch hangs around until we take audit_filter_mutex */
 	get_inotify_watch(&parent->wdata);
-	wd = inotify_add_watch(audit_ih, &parent->wdata, ndp->dentry->d_inode,
+	wd = inotify_add_watch(audit_ih, &parent->wdata, ndp->lookup.path.dentry->d_inode,
 			       AUDIT_IN_WATCH);
 	if (wd < 0) {
 		audit_free_parent(&parent->wdata);
@@ -1176,8 +1176,8 @@ static int audit_add_watch(struct audit_
 
 	/* update watch filter fields */
 	if (ndw) {
-		watch->dev = ndw->dentry->d_inode->i_sb->s_dev;
-		watch->ino = ndw->dentry->d_inode->i_ino;
+		watch->dev = ndw->lookup.path.dentry->d_inode->i_sb->s_dev;
+		watch->ino = ndw->lookup.path.dentry->d_inode->i_ino;
 	}
 
 	/* The audit_filter_mutex must not be held during inotify calls because
@@ -1187,7 +1187,7 @@ static int audit_add_watch(struct audit_
 	 */
 	mutex_unlock(&audit_filter_mutex);
 
-	if (inotify_find_watch(audit_ih, ndp->dentry->d_inode, &i_watch) < 0) {
+	if (inotify_find_watch(audit_ih, ndp->lookup.path.dentry->d_inode, &i_watch) < 0) {
 		parent = audit_init_parent(ndp);
 		if (IS_ERR(parent)) {
 			/* caller expects mutex locked */
--- a/net/sunrpc/rpc_pipe.c
+++ b/net/sunrpc/rpc_pipe.c
@@ -656,7 +656,7 @@ rpc_lookup_negative(char *path, struct n
 
 	if ((error = rpc_lookup_parent(path, nd)) != 0)
 		return ERR_PTR(error);
-	dentry = rpc_lookup_create(nd->dentry, nd->last.name, nd->last.len, 1);
+	dentry = rpc_lookup_create(nd->lookup.path.dentry, nd->last.name, nd->last.len, 1);
 	if (IS_ERR(dentry))
 		rpc_release_path(nd);
 	return dentry;
@@ -674,7 +674,7 @@ rpc_mkdir(char *path, struct rpc_clnt *r
 	dentry = rpc_lookup_negative(path, &nd);
 	if (IS_ERR(dentry))
 		return dentry;
-	dir = nd.dentry->d_inode;
+	dir = nd.lookup.path.dentry->d_inode;
 	if ((error = __rpc_mkdir(dir, dentry)) != 0)
 		goto err_dput;
 	RPC_I(dentry->d_inode)->private = rpc_client;
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -734,14 +734,14 @@ static struct sock *unix_find_other(stru
 			goto put_fail;
 
 		err = -ECONNREFUSED;
-		if (!S_ISSOCK(nd.dentry->d_inode->i_mode))
+		if (!S_ISSOCK(nd.lookup.path.dentry->d_inode->i_mode))
 			goto put_fail;
-		u=unix_find_socket_byinode(nd.dentry->d_inode);
+		u=unix_find_socket_byinode(nd.lookup.path.dentry->d_inode);
 		if (!u)
 			goto put_fail;
 
 		if (u->sk_type == type)
-			touch_atime(nd.mnt, nd.dentry);
+			touch_atime(nd.lookup.path.mnt, nd.lookup.path.dentry);
 
 		path_release(&nd);
 
@@ -834,12 +834,12 @@ static int unix_bind(struct socket *sock
 		 */
 		mode = S_IFSOCK |
 		       (SOCK_INODE(sock)->i_mode & ~current->fs->umask);
-		err = vfs_mknod(nd.dentry->d_inode, dentry, mode, 0);
+		err = vfs_mknod(nd.lookup.path.dentry->d_inode, dentry, mode, 0);
 		if (err)
 			goto out_mknod_dput;
-		mutex_unlock(&nd.dentry->d_inode->i_mutex);
-		dput(nd.dentry);
-		nd.dentry = dentry;
+		mutex_unlock(&nd.lookup.path.dentry->d_inode->i_mutex);
+		dput(nd.lookup.path.dentry);
+		nd.lookup.path.dentry = dentry;
 
 		addr->hash = UNIX_HASH_SIZE;
 	}
@@ -857,8 +857,8 @@ static int unix_bind(struct socket *sock
 		list = &unix_socket_table[addr->hash];
 	} else {
 		list = &unix_socket_table[dentry->d_inode->i_ino & (UNIX_HASH_SIZE-1)];
-		u->dentry = nd.dentry;
-		u->mnt    = nd.mnt;
+		u->dentry = nd.lookup.path.dentry;
+		u->mnt    = nd.lookup.path.mnt;
 	}
 
 	err = 0;
@@ -876,7 +876,7 @@ out:
 out_mknod_dput:
 	dput(dentry);
 out_mknod_unlock:
-	mutex_unlock(&nd.dentry->d_inode->i_mutex);
+	mutex_unlock(&nd.lookup.path.dentry->d_inode->i_mutex);
 	path_release(&nd);
 out_mknod_parent:
 	if (err==-EEXIST)
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -2084,10 +2084,10 @@ static int selinux_mount(char * dev_name
 		return rc;
 
 	if (flags & MS_REMOUNT)
-		return superblock_has_perm(current, nd->mnt->mnt_sb,
+		return superblock_has_perm(current, nd->lookup.path.mnt->mnt_sb,
 		                           FILESYSTEM__REMOUNT, NULL);
 	else
-		return dentry_has_perm(current, nd->mnt, nd->dentry,
+		return dentry_has_perm(current, nd->lookup.path.mnt, nd->lookup.path.dentry,
 		                       FILE__MOUNTON);
 }
 


^ permalink raw reply	[flat|nested] 35+ messages in thread

* [RFC 03/10] Pass no unnecessary information to iop->permission
  2007-08-08 17:16 [RFC 00/10] Split up struct nameidata (take 3) Andreas Gruenbacher
  2007-08-08 17:16 ` [RFC 01/10] Split up struct nameidata Andreas Gruenbacher
  2007-08-08 17:16 ` [RFC 02/10] Switch from nd->{mnt,dentry} to nd->lookup.path.{mnt,dentry} Andreas Gruenbacher
@ 2007-08-08 17:16 ` Andreas Gruenbacher
  2007-08-08 17:16 ` [RFC 04/10] Temporary struct vfs_lookup in file_permission Andreas Gruenbacher
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 35+ messages in thread
From: Andreas Gruenbacher @ 2007-08-08 17:16 UTC (permalink / raw)
  To: linux-kernel
  Cc: John Johansen, Jan Blunck, Erez Zadok, Josef 'Jeff' Sipek

[-- Attachment #1: permission-args.diff --]
[-- Type: text/plain, Size: 29196 bytes --]

The various permission functions and the permission inode operation do
not need a full nameidata. Pass a struct vfs_lookup instead.

Signed-off-by: Andreas Gruenbacher <ag@bestbits.at>

---
 fs/afs/internal.h              |    4 +---
 fs/afs/security.c              |    2 +-
 fs/bad_inode.c                 |    2 +-
 fs/cifs/cifsfs.c               |    3 ++-
 fs/coda/dir.c                  |    2 +-
 fs/coda/pioctl.c               |    4 ++--
 fs/ecryptfs/inode.c            |   20 ++++++++++----------
 fs/exec.c                      |    4 ++--
 fs/ext2/acl.c                  |    2 +-
 fs/ext2/acl.h                  |    2 +-
 fs/ext3/acl.c                  |    2 +-
 fs/ext3/acl.h                  |    2 +-
 fs/ext4/acl.c                  |    2 +-
 fs/ext4/acl.h                  |    2 +-
 fs/fuse/dir.c                  |    4 ++--
 fs/gfs2/ops_inode.c            |    4 ++--
 fs/hfs/inode.c                 |    2 +-
 fs/hfsplus/inode.c             |    2 +-
 fs/inotify_user.c              |    2 +-
 fs/jffs2/acl.c                 |    2 +-
 fs/jffs2/acl.h                 |    2 +-
 fs/jfs/acl.c                   |    2 +-
 fs/jfs/jfs_acl.h               |    2 +-
 fs/namei.c                     |   34 +++++++++++++++++-----------------
 fs/nfs/dir.c                   |    8 ++++----
 fs/ocfs2/file.c                |    2 +-
 fs/ocfs2/file.h                |    3 +--
 fs/open.c                      |    8 ++++----
 fs/proc/base.c                 |    2 +-
 fs/proc/proc_sysctl.c          |    7 ++++---
 fs/reiserfs/xattr.c            |    3 ++-
 fs/smbfs/file.c                |    2 +-
 fs/utimes.c                    |    2 +-
 fs/xfs/linux-2.6/xfs_iops.c    |    2 +-
 include/linux/coda_linux.h     |    2 +-
 include/linux/fs.h             |    6 +++---
 include/linux/nfs_fs.h         |    2 +-
 include/linux/reiserfs_xattr.h |    4 ++--
 include/linux/security.h       |   10 +++++-----
 include/linux/shmem_fs.h       |    2 +-
 mm/shmem_acl.c                 |    2 +-
 net/unix/af_unix.c             |    2 +-
 security/dummy.c               |    2 +-
 security/selinux/hooks.c       |    4 ++--
 44 files changed, 92 insertions(+), 92 deletions(-)

--- a/fs/afs/internal.h
+++ b/fs/afs/internal.h
@@ -469,8 +469,6 @@ extern bool afs_cm_incoming_call(struct 
 extern const struct inode_operations afs_dir_inode_operations;
 extern const struct file_operations afs_dir_file_operations;
 
-extern int afs_permission(struct inode *, int, struct nameidata *);
-
 /*
  * file.c
  */
@@ -607,7 +605,7 @@ extern void afs_clear_permits(struct afs
 extern void afs_cache_permit(struct afs_vnode *, struct key *, long);
 extern void afs_zap_permits(struct rcu_head *);
 extern struct key *afs_request_key(struct afs_cell *);
-extern int afs_permission(struct inode *, int, struct nameidata *);
+extern int afs_permission(struct inode *, int, struct vfs_lookup *);
 
 /*
  * server.c
--- a/fs/afs/security.c
+++ b/fs/afs/security.c
@@ -284,7 +284,7 @@ static int afs_check_permit(struct afs_v
  * - AFS ACLs are attached to directories only, and a file is controlled by its
  *   parent directory's ACL
  */
-int afs_permission(struct inode *inode, int mask, struct nameidata *nd)
+int afs_permission(struct inode *inode, int mask, struct vfs_lookup *lookup)
 {
 	struct afs_vnode *vnode = AFS_FS_I(inode);
 	afs_access_t access;
--- a/fs/bad_inode.c
+++ b/fs/bad_inode.c
@@ -244,7 +244,7 @@ static int bad_inode_readlink(struct den
 }
 
 static int bad_inode_permission(struct inode *inode, int mask,
-			struct nameidata *nd)
+			struct vfs_lookup *lookup)
 {
 	return -EIO;
 }
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -234,7 +234,8 @@ cifs_statfs(struct dentry *dentry, struc
 				   longer available? */
 }
 
-static int cifs_permission(struct inode *inode, int mask, struct nameidata *nd)
+static int cifs_permission(struct inode *inode, int mask,
+		struct vfs_lookup *lookup)
 {
 	struct cifs_sb_info *cifs_sb;
 
--- a/fs/coda/dir.c
+++ b/fs/coda/dir.c
@@ -137,7 +137,7 @@ exit:
 }
 
 
-int coda_permission(struct inode *inode, int mask, struct nameidata *nd)
+int coda_permission(struct inode *inode, int mask, struct vfs_lookup *lookup)
 {
         int error = 0;
  
--- a/fs/coda/pioctl.c
+++ b/fs/coda/pioctl.c
@@ -25,7 +25,7 @@
 
 /* pioctl ops */
 static int coda_ioctl_permission(struct inode *inode, int mask,
-				 struct nameidata *nd);
+				 struct vfs_lookup *lookup);
 static int coda_pioctl(struct inode * inode, struct file * filp, 
                        unsigned int cmd, unsigned long user_data);
 
@@ -43,7 +43,7 @@ const struct file_operations coda_ioctl_
 
 /* the coda pioctl inode ops */
 static int coda_ioctl_permission(struct inode *inode, int mask,
-				 struct nameidata *nd)
+				 struct vfs_lookup *lookup)
 {
         return 0;
 }
--- a/fs/ecryptfs/inode.c
+++ b/fs/ecryptfs/inode.c
@@ -855,19 +855,19 @@ out:
 }
 
 static int
-ecryptfs_permission(struct inode *inode, int mask, struct nameidata *nd)
+ecryptfs_permission(struct inode *inode, int mask, struct vfs_lookup *lookup)
 {
 	int rc;
 
-        if (nd) {
-		struct vfsmount *vfsmnt_save = nd->lookup.path.mnt;
-		struct dentry *dentry_save = nd->lookup.path.dentry;
-
-		nd->lookup.path.mnt = ecryptfs_dentry_to_lower_mnt(nd->lookup.path.dentry);
-		nd->lookup.path.dentry = ecryptfs_dentry_to_lower(nd->lookup.path.dentry);
-		rc = permission(ecryptfs_inode_to_lower(inode), mask, nd);
-		nd->lookup.path.mnt = vfsmnt_save;
-		nd->lookup.path.dentry = dentry_save;
+        if (lookup) {
+		struct vfsmount *vfsmnt_save = lookup->path.mnt;
+		struct dentry *dentry_save = lookup->path.dentry;
+
+		lookup->path.mnt = ecryptfs_dentry_to_lower_mnt(lookup->path.dentry);
+		lookup->path.dentry = ecryptfs_dentry_to_lower(lookup->path.dentry);
+		rc = permission(ecryptfs_inode_to_lower(inode), mask, lookup);
+		lookup->path.mnt = vfsmnt_save;
+		lookup->path.dentry = dentry_save;
         } else
 		rc = permission(ecryptfs_inode_to_lower(inode), mask, NULL);
         return rc;
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -142,7 +142,7 @@ asmlinkage long sys_uselib(const char __
 	if (!S_ISREG(nd.lookup.path.dentry->d_inode->i_mode))
 		goto exit;
 
-	error = vfs_permission(&nd, MAY_READ | MAY_EXEC);
+	error = vfs_permission(&nd.lookup, MAY_READ | MAY_EXEC);
 	if (error)
 		goto exit;
 
@@ -683,7 +683,7 @@ struct file *open_exec(const char *name)
 		file = ERR_PTR(-EACCES);
 		if (!(nd.lookup.path.mnt->mnt_flags & MNT_NOEXEC) &&
 		    S_ISREG(inode->i_mode)) {
-			int err = vfs_permission(&nd, MAY_EXEC);
+			int err = vfs_permission(&nd.lookup, MAY_EXEC);
 			file = ERR_PTR(err);
 			if (!err) {
 				file = nameidata_to_filp(&nd, O_RDONLY);
--- a/fs/ext2/acl.c
+++ b/fs/ext2/acl.c
@@ -294,7 +294,7 @@ ext2_check_acl(struct inode *inode, int 
 }
 
 int
-ext2_permission(struct inode *inode, int mask, struct nameidata *nd)
+ext2_permission(struct inode *inode, int mask, struct vfs_lookup *lookup)
 {
 	return generic_permission(inode, mask, ext2_check_acl);
 }
--- a/fs/ext2/acl.h
+++ b/fs/ext2/acl.h
@@ -58,7 +58,7 @@ static inline int ext2_acl_count(size_t 
 #define EXT2_ACL_NOT_CACHED ((void *)-1)
 
 /* acl.c */
-extern int ext2_permission (struct inode *, int, struct nameidata *);
+extern int ext2_permission (struct inode *, int, struct vfs_lookup *);
 extern int ext2_acl_chmod (struct inode *);
 extern int ext2_init_acl (struct inode *, struct inode *);
 
--- a/fs/ext3/acl.c
+++ b/fs/ext3/acl.c
@@ -299,7 +299,7 @@ ext3_check_acl(struct inode *inode, int 
 }
 
 int
-ext3_permission(struct inode *inode, int mask, struct nameidata *nd)
+ext3_permission(struct inode *inode, int mask, struct vfs_lookup *lookup)
 {
 	return generic_permission(inode, mask, ext3_check_acl);
 }
--- a/fs/ext3/acl.h
+++ b/fs/ext3/acl.h
@@ -58,7 +58,7 @@ static inline int ext3_acl_count(size_t 
 #define EXT3_ACL_NOT_CACHED ((void *)-1)
 
 /* acl.c */
-extern int ext3_permission (struct inode *, int, struct nameidata *);
+extern int ext3_permission (struct inode *, int, struct vfs_lookup *);
 extern int ext3_acl_chmod (struct inode *);
 extern int ext3_init_acl (handle_t *, struct inode *, struct inode *);
 
--- a/fs/ext4/acl.c
+++ b/fs/ext4/acl.c
@@ -299,7 +299,7 @@ ext4_check_acl(struct inode *inode, int 
 }
 
 int
-ext4_permission(struct inode *inode, int mask, struct nameidata *nd)
+ext4_permission(struct inode *inode, int mask, struct vfs_lookup *lookup)
 {
 	return generic_permission(inode, mask, ext4_check_acl);
 }
--- a/fs/ext4/acl.h
+++ b/fs/ext4/acl.h
@@ -58,7 +58,7 @@ static inline int ext4_acl_count(size_t 
 #define EXT4_ACL_NOT_CACHED ((void *)-1)
 
 /* acl.c */
-extern int ext4_permission (struct inode *, int, struct nameidata *);
+extern int ext4_permission (struct inode *, int, struct vfs_lookup *);
 extern int ext4_acl_chmod (struct inode *);
 extern int ext4_init_acl (handle_t *, struct inode *, struct inode *);
 
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -792,7 +792,7 @@ static int fuse_access(struct inode *ino
  * access request is sent.  Execute permission is still checked
  * locally based on file mode.
  */
-static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd)
+static int fuse_permission(struct inode *inode, int mask, struct vfs_lookup *lookup)
 {
 	struct fuse_conn *fc = get_fuse_conn(inode);
 
@@ -821,7 +821,7 @@ static int fuse_permission(struct inode 
 		if ((mask & MAY_EXEC) && !S_ISDIR(mode) && !(mode & S_IXUGO))
 			return -EACCES;
 
-		if (nd && (nd->lookup.flags & (LOOKUP_ACCESS | LOOKUP_CHDIR)))
+		if (lookup && (lookup->flags & (LOOKUP_ACCESS | LOOKUP_CHDIR)))
 			return fuse_access(inode, mask);
 		return 0;
 	}
--- a/fs/gfs2/ops_inode.c
+++ b/fs/gfs2/ops_inode.c
@@ -861,7 +861,7 @@ static void *gfs2_follow_link(struct den
  * gfs2_permission -
  * @inode:
  * @mask:
- * @nd: passed from Linux VFS, ignored by us
+ * @lookup: passed from Linux VFS, ignored by us
  *
  * This may be called from the VFS directly, or from within GFS2 with the
  * inode locked, so we look to see if the glock is already locked and only
@@ -870,7 +870,7 @@ static void *gfs2_follow_link(struct den
  * Returns: errno
  */
 
-static int gfs2_permission(struct inode *inode, int mask, struct nameidata *nd)
+static int gfs2_permission(struct inode *inode, int mask, struct vfs_lookup *lookup)
 {
 	struct gfs2_inode *ip = GFS2_I(inode);
 	struct gfs2_holder i_gh;
--- a/fs/hfs/inode.c
+++ b/fs/hfs/inode.c
@@ -508,7 +508,7 @@ void hfs_clear_inode(struct inode *inode
 }
 
 static int hfs_permission(struct inode *inode, int mask,
-			  struct nameidata *nd)
+			  struct vfs_lookup *lookup)
 {
 	if (S_ISREG(inode->i_mode) && mask & MAY_EXEC)
 		return 0;
--- a/fs/hfsplus/inode.c
+++ b/fs/hfsplus/inode.c
@@ -232,7 +232,7 @@ static void hfsplus_set_perms(struct ino
 	perms->dev = cpu_to_be32(HFSPLUS_I(inode).dev);
 }
 
-static int hfsplus_permission(struct inode *inode, int mask, struct nameidata *nd)
+static int hfsplus_permission(struct inode *inode, int mask, struct vfs_lookup *lookup)
 {
 	/* MAY_EXEC is also used for lookup, if no x bit is set allow lookup,
 	 * open_exec has the same test, so it's still not executable, if a x bit
--- a/fs/inotify_user.c
+++ b/fs/inotify_user.c
@@ -349,7 +349,7 @@ static int find_inode(const char __user 
 	if (error)
 		return error;
 	/* you can only watch an inode if you have read permissions on it */
-	error = vfs_permission(nd, MAY_READ);
+	error = vfs_permission(nd.lookup, MAY_READ);
 	if (error)
 		path_release(nd);
 	return error;
--- a/fs/jffs2/acl.c
+++ b/fs/jffs2/acl.c
@@ -302,7 +302,7 @@ static int jffs2_check_acl(struct inode 
 	return -EAGAIN;
 }
 
-int jffs2_permission(struct inode *inode, int mask, struct nameidata *nd)
+int jffs2_permission(struct inode *inode, int mask, struct vfs_lookup *lookup)
 {
 	return generic_permission(inode, mask, jffs2_check_acl);
 }
--- a/fs/jffs2/acl.h
+++ b/fs/jffs2/acl.h
@@ -28,7 +28,7 @@ struct jffs2_acl_header {
 
 #define JFFS2_ACL_NOT_CACHED ((void *)-1)
 
-extern int jffs2_permission(struct inode *, int, struct nameidata *);
+extern int jffs2_permission(struct inode *, int, struct vfs_lookup *);
 extern int jffs2_acl_chmod(struct inode *);
 extern int jffs2_init_acl(struct inode *, struct inode *);
 extern void jffs2_clear_acl(struct jffs2_inode_info *);
--- a/fs/jfs/acl.c
+++ b/fs/jfs/acl.c
@@ -140,7 +140,7 @@ static int jfs_check_acl(struct inode *i
 	return -EAGAIN;
 }
 
-int jfs_permission(struct inode *inode, int mask, struct nameidata *nd)
+int jfs_permission(struct inode *inode, int mask, struct vfs_lookup *lookup)
 {
 	return generic_permission(inode, mask, jfs_check_acl);
 }
--- a/fs/jfs/jfs_acl.h
+++ b/fs/jfs/jfs_acl.h
@@ -20,7 +20,7 @@
 
 #ifdef CONFIG_JFS_POSIX_ACL
 
-int jfs_permission(struct inode *, int, struct nameidata *);
+int jfs_permission(struct inode *, int, struct vfs_lookup *);
 int jfs_init_acl(tid_t, struct inode *, struct inode *);
 int jfs_setattr(struct dentry *, struct iattr *);
 
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -226,7 +226,7 @@ int generic_permission(struct inode *ino
 	return -EACCES;
 }
 
-int permission(struct inode *inode, int mask, struct nameidata *nd)
+int permission(struct inode *inode, int mask, struct vfs_lookup *lookup)
 {
 	umode_t mode = inode->i_mode;
 	int retval, submask;
@@ -254,24 +254,25 @@ int permission(struct inode *inode, int 
 	 * the fs is mounted with the "noexec" flag.
 	 */
 	if ((mask & MAY_EXEC) && S_ISREG(mode) && (!(mode & S_IXUGO) ||
-			(nd && nd->lookup.path.mnt && (nd->lookup.path.mnt->mnt_flags & MNT_NOEXEC))))
+			(lookup && lookup->path.mnt &&
+			 (lookup->path.mnt->mnt_flags & MNT_NOEXEC))))
 		return -EACCES;
 
 	/* Ordinary permission routines do not understand MAY_APPEND. */
 	submask = mask & ~MAY_APPEND;
 	if (inode->i_op && inode->i_op->permission)
-		retval = inode->i_op->permission(inode, submask, nd);
+		retval = inode->i_op->permission(inode, submask, lookup);
 	else
 		retval = generic_permission(inode, submask, NULL);
 	if (retval)
 		return retval;
 
-	return security_inode_permission(inode, mask, nd);
+	return security_inode_permission(inode, mask, lookup);
 }
 
 /**
  * vfs_permission  -  check for access rights to a given path
- * @nd:		lookup result that describes the path
+ * @lookup:	lookup result that describes the path
  * @mask:	right to check for (%MAY_READ, %MAY_WRITE, %MAY_EXEC)
  *
  * Used to check for read/write/execute permissions on a path.
@@ -279,9 +280,9 @@ int permission(struct inode *inode, int 
  * for filesystem access without changing the "normal" uids which
  * are used for other things.
  */
-int vfs_permission(struct nameidata *nd, int mask)
+int vfs_permission(struct vfs_lookup *lookup, int mask)
 {
-	return permission(nd->lookup.path.dentry->d_inode, mask, nd);
+	return permission(lookup->path.dentry->d_inode, mask, lookup);
 }
 
 /**
@@ -429,8 +430,7 @@ static struct dentry * cached_lookup(str
  * short-cut DAC fails, then call permission() to do more
  * complete permission check.
  */
-static int exec_permission_lite(struct inode *inode,
-				       struct nameidata *nd)
+static int exec_permission_lite(struct inode *inode, struct vfs_lookup *lookup)
 {
 	umode_t	mode = inode->i_mode;
 
@@ -456,7 +456,7 @@ static int exec_permission_lite(struct i
 
 	return -EACCES;
 ok:
-	return security_inode_permission(inode, MAY_EXEC, nd);
+	return security_inode_permission(inode, MAY_EXEC, lookup);
 }
 
 /*
@@ -831,9 +831,9 @@ static fastcall int __link_path_walk(con
 		unsigned int c;
 
 		nd->lookup.flags |= LOOKUP_CONTINUE;
-		err = exec_permission_lite(inode, nd);
+		err = exec_permission_lite(inode, &nd->lookup);
 		if (err == -EAGAIN)
-			err = vfs_permission(nd, MAY_EXEC);
+			err = vfs_permission(&nd->lookup, MAY_EXEC);
  		if (err)
 			break;
 
@@ -1321,7 +1321,7 @@ static inline struct dentry * __lookup_h
 
 	inode = base->d_inode;
 
-	err = permission(inode, MAY_EXEC, nd);
+	err = permission(inode, MAY_EXEC, &nd->lookup);
 	dentry = ERR_PTR(err);
 	if (err)
 		goto out;
@@ -1473,13 +1473,13 @@ static int may_delete(struct inode *dir,
  *  4. We can't do it if dir is immutable (done in permission())
  */
 static inline int may_create(struct inode *dir, struct dentry *child,
-			     struct nameidata *nd)
+			     struct vfs_lookup *lookup)
 {
 	if (child->d_inode)
 		return -EEXIST;
 	if (IS_DEADDIR(dir))
 		return -ENOENT;
-	return permission(dir,MAY_WRITE | MAY_EXEC, nd);
+	return permission(dir,MAY_WRITE | MAY_EXEC, lookup);
 }
 
 /* 
@@ -1545,7 +1545,7 @@ void unlock_rename(struct dentry *p1, st
 int vfs_create(struct inode *dir, struct dentry *dentry, int mode,
 		struct nameidata *nd)
 {
-	int error = may_create(dir, dentry, nd);
+	int error = may_create(dir, dentry, &nd->lookup);
 
 	if (error)
 		return error;
@@ -1579,7 +1579,7 @@ int may_open(struct nameidata *nd, int a
 	if (S_ISDIR(inode->i_mode) && (flag & FMODE_WRITE))
 		return -EISDIR;
 
-	error = vfs_permission(nd, acc_mode);
+	error = vfs_permission(&nd->lookup, acc_mode);
 	if (error)
 		return error;
 
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -1955,7 +1955,7 @@ out:
 	return -EACCES;
 }
 
-int nfs_permission(struct inode *inode, int mask, struct nameidata *nd)
+int nfs_permission(struct inode *inode, int mask, struct vfs_lookup *lookup)
 {
 	struct rpc_cred *cred;
 	int res = 0;
@@ -1965,7 +1965,7 @@ int nfs_permission(struct inode *inode, 
 	if (mask == 0)
 		goto out;
 	/* Is this sys_access() ? */
-	if (nd != NULL && (nd->lookup.flags & LOOKUP_ACCESS))
+	if (lookup && (lookup->flags & LOOKUP_ACCESS))
 		goto force_lookup;
 
 	switch (inode->i_mode & S_IFMT) {
@@ -1974,8 +1974,8 @@ int nfs_permission(struct inode *inode, 
 		case S_IFREG:
 			/* NFSv4 has atomic_open... */
 			if (nfs_server_capable(inode, NFS_CAP_ATOMIC_OPEN)
-					&& nd != NULL
-					&& (nd->lookup.flags & LOOKUP_OPEN))
+					&& lookup
+					&& (lookup->flags & LOOKUP_OPEN))
 				goto out;
 			break;
 		case S_IFDIR:
--- a/fs/ocfs2/file.c
+++ b/fs/ocfs2/file.c
@@ -1091,7 +1091,7 @@ bail:
 	return err;
 }
 
-int ocfs2_permission(struct inode *inode, int mask, struct nameidata *nd)
+int ocfs2_permission(struct inode *inode, int mask, struct vfs_lookup *lookup)
 {
 	int ret;
 
--- a/fs/ocfs2/file.h
+++ b/fs/ocfs2/file.h
@@ -54,8 +54,7 @@ int ocfs2_lock_allocators(struct inode *
 int ocfs2_setattr(struct dentry *dentry, struct iattr *attr);
 int ocfs2_getattr(struct vfsmount *mnt, struct dentry *dentry,
 		  struct kstat *stat);
-int ocfs2_permission(struct inode *inode, int mask,
-		     struct nameidata *nd);
+int ocfs2_permission(struct inode *inode, int mask, struct vfs_lookup *lookup);
 
 int ocfs2_should_update_atime(struct inode *inode,
 			      struct vfsmount *vfsmnt);
--- a/fs/open.c
+++ b/fs/open.c
@@ -244,7 +244,7 @@ static long do_sys_truncate(const char _
 	if (!S_ISREG(inode->i_mode))
 		goto dput_and_out;
 
-	error = vfs_permission(&nd, MAY_WRITE);
+	error = vfs_permission(&nd.lookup, MAY_WRITE);
 	if (error)
 		goto dput_and_out;
 
@@ -452,7 +452,7 @@ asmlinkage long sys_faccessat(int dfd, c
 	if (res)
 		goto out;
 
-	res = vfs_permission(&nd, mode);
+	res = vfs_permission(&nd.lookup, mode);
 	/* SuS v2 requires we report a read only fs too */
 	if(res || !(mode & S_IWOTH) ||
 	   special_file(nd.lookup.path.dentry->d_inode->i_mode))
@@ -486,7 +486,7 @@ asmlinkage long sys_chdir(const char __u
 	if (error)
 		goto out;
 
-	error = vfs_permission(&nd, MAY_EXEC);
+	error = vfs_permission(&nd.lookup, MAY_EXEC);
 	if (error)
 		goto dput_and_out;
 
@@ -537,7 +537,7 @@ asmlinkage long sys_chroot(const char __
 	if (error)
 		goto out;
 
-	error = vfs_permission(&nd, MAY_EXEC);
+	error = vfs_permission(&nd.lookup, MAY_EXEC);
 	if (error)
 		goto dput_and_out;
 
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -1479,7 +1479,7 @@ static const struct file_operations proc
  * access /proc/self/fd after it has executed a setuid().
  */
 static int proc_fd_permission(struct inode *inode, int mask,
-				struct nameidata *nd)
+				struct vfs_lookup *lookup)
 {
 	int rv;
 
--- a/fs/proc/proc_sysctl.c
+++ b/fs/proc/proc_sysctl.c
@@ -369,7 +369,8 @@ out:
 	return ret;
 }
 
-static int proc_sys_permission(struct inode *inode, int mask, struct nameidata *nd)
+static int proc_sys_permission(struct inode *inode, int mask,
+			       struct vfs_lookup *lookup)
 {
 	/*
 	 * sysctl entries that are not writeable,
@@ -402,10 +403,10 @@ static int proc_sys_permission(struct in
 	/* If we can't get a sysctl table entry the permission
 	 * checks on the cached mode will have to be enough.
 	 */
-	if (!nd || !depth)
+	if (!lookup || !depth)
 		goto out;
 
-	dentry = nd->lookup.path.dentry;
+	dentry = lookup->path.dentry;
 	table = do_proc_sys_lookup(dentry->d_parent, &dentry->d_name, &head);
 
 	/* If the entry does not exist deny permission */
--- a/fs/reiserfs/xattr.c
+++ b/fs/reiserfs/xattr.c
@@ -1294,7 +1294,8 @@ static int reiserfs_check_acl(struct ino
 	return error;
 }
 
-int reiserfs_permission(struct inode *inode, int mask, struct nameidata *nd)
+int reiserfs_permission(struct inode *inode, int mask,
+			struct vfs_lookup *lookup)
 {
 	/*
 	 * We don't do permission checks on the internal objects.
--- a/fs/smbfs/file.c
+++ b/fs/smbfs/file.c
@@ -391,7 +391,7 @@ smb_file_release(struct inode *inode, st
  * privileges, so we need our own check for this.
  */
 static int
-smb_file_permission(struct inode *inode, int mask, struct nameidata *nd)
+smb_file_permission(struct inode *inode, int mask, struct vfs_lookup *lookup)
 {
 	int mode = inode->i_mode;
 	int error = 0;
--- a/fs/utimes.c
+++ b/fs/utimes.c
@@ -111,7 +111,7 @@ long do_utimes(int dfd, char __user *fil
 				if (!(f->f_mode & FMODE_WRITE))
 					goto dput_and_out;
 			} else {
-				error = vfs_permission(&nd, MAY_WRITE);
+				error = vfs_permission(&nd.lookup, MAY_WRITE);
 				if (error)
 					goto dput_and_out;
 			}
--- a/fs/xfs/linux-2.6/xfs_iops.c
+++ b/fs/xfs/linux-2.6/xfs_iops.c
@@ -605,7 +605,7 @@ STATIC int
 xfs_vn_permission(
 	struct inode	*inode,
 	int		mode,
-	struct nameidata *nd)
+	struct vfs_lookup *lookup)
 {
 	return -bhv_vop_access(vn_from_inode(inode), mode << 6, NULL);
 }
--- a/include/linux/coda_linux.h
+++ b/include/linux/coda_linux.h
@@ -37,7 +37,7 @@ extern const struct file_operations coda
 /* operations shared over more than one file */
 int coda_open(struct inode *i, struct file *f);
 int coda_release(struct inode *i, struct file *f);
-int coda_permission(struct inode *inode, int mask, struct nameidata *nd);
+int coda_permission(struct inode *inode, int mask, struct vfs_lookup *lookup);
 int coda_revalidate_inode(struct dentry *);
 int coda_getattr(struct vfsmount *, struct dentry *, struct kstat *);
 int coda_setattr(struct dentry *, struct iattr *);
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1008,7 +1008,7 @@ extern void unlock_super(struct super_bl
 /*
  * VFS helper functions..
  */
-extern int vfs_permission(struct nameidata *, int);
+extern int vfs_permission(struct vfs_lookup *, int);
 extern int vfs_create(struct inode *, struct dentry *, int, struct nameidata *);
 extern int vfs_mkdir(struct inode *, struct dentry *, int);
 extern int vfs_mknod(struct inode *, struct dentry *, int, dev_t);
@@ -1147,7 +1147,7 @@ struct inode_operations {
 	void * (*follow_link) (struct dentry *, struct nameidata *);
 	void (*put_link) (struct dentry *, struct nameidata *, void *);
 	void (*truncate) (struct inode *);
-	int (*permission) (struct inode *, int, struct nameidata *);
+	int (*permission) (struct inode *, int, struct vfs_lookup *);
 	int (*setattr) (struct dentry *, struct iattr *);
 	int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *);
 	int (*setxattr) (struct dentry *, const char *,const void *,size_t,int);
@@ -1562,7 +1562,7 @@ extern int do_remount_sb(struct super_bl
 extern sector_t bmap(struct inode *, sector_t);
 #endif
 extern int notify_change(struct dentry *, struct iattr *);
-extern int permission(struct inode *, int, struct nameidata *);
+extern int permission(struct inode *, int, struct vfs_lookup *);
 extern int generic_permission(struct inode *, int,
 		int (*check_acl)(struct inode *, int));
 
--- a/include/linux/nfs_fs.h
+++ b/include/linux/nfs_fs.h
@@ -288,7 +288,7 @@ extern struct inode *nfs_fhget(struct su
 extern int nfs_refresh_inode(struct inode *, struct nfs_fattr *);
 extern int nfs_post_op_update_inode(struct inode *inode, struct nfs_fattr *fattr);
 extern int nfs_getattr(struct vfsmount *, struct dentry *, struct kstat *);
-extern int nfs_permission(struct inode *, int, struct nameidata *);
+extern int nfs_permission(struct inode *, int, struct vfs_lookup *);
 extern int nfs_access_get_cached(struct inode *, struct rpc_cred *, struct nfs_access_entry *);
 extern void nfs_access_add_cache(struct inode *, struct nfs_access_entry *);
 extern void nfs_access_zap_cache(struct inode *inode);
--- a/include/linux/reiserfs_xattr.h
+++ b/include/linux/reiserfs_xattr.h
@@ -55,8 +55,8 @@ int reiserfs_removexattr(struct dentry *
 int reiserfs_delete_xattrs(struct inode *inode);
 int reiserfs_chown_xattrs(struct inode *inode, struct iattr *attrs);
 int reiserfs_xattr_init(struct super_block *sb, int mount_flags);
-int reiserfs_permission(struct inode *inode, int mask, struct nameidata *nd);
-
+int reiserfs_permission(struct inode *inode, int mask,
+			struct vfs_lookup *lookup);
 int reiserfs_xattr_del(struct inode *, const char *);
 int reiserfs_xattr_get(const struct inode *, const char *, void *, size_t);
 int reiserfs_xattr_set(struct inode *, const char *, const void *, size_t, int);
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -350,7 +350,7 @@ struct request_sock;
  *	called when the actual read/write operations are performed.
  *	@inode contains the inode structure to check.
  *	@mask contains the permission mask.
- *     @nd contains the nameidata (may be NULL).
+ *     @lookup contains the vfs_lookup (may be NULL).
  *	Return 0 if permission is granted.
  * @inode_setattr:
  *	Check permission before setting file attributes.  Note that the kernel
@@ -1220,7 +1220,7 @@ struct security_operations {
 	                     struct inode *new_dir, struct dentry *new_dentry);
 	int (*inode_readlink) (struct dentry *dentry);
 	int (*inode_follow_link) (struct dentry *dentry, struct nameidata *nd);
-	int (*inode_permission) (struct inode *inode, int mask, struct nameidata *nd);
+	int (*inode_permission) (struct inode *inode, int mask, struct vfs_lookup *lookup);
 	int (*inode_setattr)	(struct dentry *dentry, struct iattr *attr);
 	int (*inode_getattr) (struct vfsmount *mnt, struct dentry *dentry);
         void (*inode_delete) (struct inode *inode);
@@ -1700,11 +1700,11 @@ static inline int security_inode_follow_
 }
 
 static inline int security_inode_permission (struct inode *inode, int mask,
-					     struct nameidata *nd)
+					     struct vfs_lookup *lookup)
 {
 	if (unlikely (IS_PRIVATE (inode)))
 		return 0;
-	return security_ops->inode_permission (inode, mask, nd);
+	return security_ops->inode_permission (inode, mask, lookup);
 }
 
 static inline int security_inode_setattr (struct dentry *dentry,
@@ -2408,7 +2408,7 @@ static inline int security_inode_follow_
 }
 
 static inline int security_inode_permission (struct inode *inode, int mask,
-					     struct nameidata *nd)
+					     struct vfs_lookup *lookup)
 {
 	return 0;
 }
--- a/include/linux/shmem_fs.h
+++ b/include/linux/shmem_fs.h
@@ -41,7 +41,7 @@ static inline struct shmem_inode_info *S
 }
 
 #ifdef CONFIG_TMPFS_POSIX_ACL
-int shmem_permission(struct inode *, int, struct nameidata *);
+int shmem_permission(struct inode *, int, struct vfs_lookup *);
 int shmem_acl_init(struct inode *, struct inode *);
 void shmem_acl_destroy_inode(struct inode *);
 
--- a/mm/shmem_acl.c
+++ b/mm/shmem_acl.c
@@ -191,7 +191,7 @@ shmem_check_acl(struct inode *inode, int
  * shmem_permission  -  permission() inode operation
  */
 int
-shmem_permission(struct inode *inode, int mask, struct nameidata *nd)
+shmem_permission(struct inode *inode, int mask, struct vfs_lookup *lookup)
 {
 	return generic_permission(inode, mask, shmem_check_acl);
 }
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -729,7 +729,7 @@ static struct sock *unix_find_other(stru
 		err = path_lookup(sunname->sun_path, LOOKUP_FOLLOW, &nd);
 		if (err)
 			goto fail;
-		err = vfs_permission(&nd, MAY_WRITE);
+		err = vfs_permission(&nd.lookup, MAY_WRITE);
 		if (err)
 			goto put_fail;
 
--- a/security/dummy.c
+++ b/security/dummy.c
@@ -323,7 +323,7 @@ static int dummy_inode_follow_link (stru
 	return 0;
 }
 
-static int dummy_inode_permission (struct inode *inode, int mask, struct nameidata *nd)
+static int dummy_inode_permission (struct inode *inode, int mask, struct vfs_lookup *lookup)
 {
 	return 0;
 }
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -2250,11 +2250,11 @@ static int selinux_inode_follow_link(str
 }
 
 static int selinux_inode_permission(struct inode *inode, int mask,
-				    struct nameidata *nd)
+				    struct vfs_lookup *lookup)
 {
 	int rc;
 
-	rc = secondary_ops->inode_permission(inode, mask, nd);
+	rc = secondary_ops->inode_permission(inode, mask, lookup);
 	if (rc)
 		return rc;
 


^ permalink raw reply	[flat|nested] 35+ messages in thread

* [RFC 04/10] Temporary struct vfs_lookup in file_permission
  2007-08-08 17:16 [RFC 00/10] Split up struct nameidata (take 3) Andreas Gruenbacher
                   ` (2 preceding siblings ...)
  2007-08-08 17:16 ` [RFC 03/10] Pass no unnecessary information to iop->permission Andreas Gruenbacher
@ 2007-08-08 17:16 ` Andreas Gruenbacher
  2007-08-08 17:58   ` Josef Sipek
  2007-08-08 19:25   ` Christoph Hellwig
  2007-08-08 17:16 ` [RFC 05/10] Use vfs_permission instead of file_permission in sys_fchdir Andreas Gruenbacher
                   ` (5 subsequent siblings)
  9 siblings, 2 replies; 35+ messages in thread
From: Andreas Gruenbacher @ 2007-08-08 17:16 UTC (permalink / raw)
  To: linux-kernel
  Cc: John Johansen, Jan Blunck, Erez Zadok, Josef 'Jeff' Sipek

[-- Attachment #1: file_permission.diff --]
[-- Type: text/plain, Size: 812 bytes --]

Create a temporary struct vfs_lookup in file_permission() instead of
passing a NULL value.

Signed-off-by: Andreas Gruenbacher <ag@bestbits.at>

---
 fs/namei.c |   11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

--- a/fs/namei.c
+++ b/fs/namei.c
@@ -292,14 +292,15 @@ int vfs_permission(struct vfs_lookup *lo
  *
  * Used to check for read/write/execute permissions on an already opened
  * file.
- *
- * Note:
- *	Do not use this function in new code.  All access checks should
- *	be done using vfs_permission().
  */
 int file_permission(struct file *file, int mask)
 {
-	return permission(file->f_path.dentry->d_inode, mask, NULL);
+	struct vfs_lookup lookup;
+
+	lookup.path = file->f_path;
+	lookup.flags = 0;
+
+	return permission(file->f_path.dentry->d_inode, mask, &lookup);
 }
 
 /*


^ permalink raw reply	[flat|nested] 35+ messages in thread

* [RFC 05/10] Use vfs_permission instead of file_permission in sys_fchdir
  2007-08-08 17:16 [RFC 00/10] Split up struct nameidata (take 3) Andreas Gruenbacher
                   ` (3 preceding siblings ...)
  2007-08-08 17:16 ` [RFC 04/10] Temporary struct vfs_lookup in file_permission Andreas Gruenbacher
@ 2007-08-08 17:16 ` Andreas Gruenbacher
  2007-08-08 19:26   ` Christoph Hellwig
  2007-08-08 17:16 ` [RFC 06/10] Use vfs_permission instead of file_permission in do_path_lookup Andreas Gruenbacher
                   ` (4 subsequent siblings)
  9 siblings, 1 reply; 35+ messages in thread
From: Andreas Gruenbacher @ 2007-08-08 17:16 UTC (permalink / raw)
  To: linux-kernel
  Cc: John Johansen, Jan Blunck, Erez Zadok, Josef 'Jeff' Sipek

[-- Attachment #1: sys_fchdir.diff --]
[-- Type: text/plain, Size: 1100 bytes --]

Create a temporary vfs_lookup object, and use vfs_permission instead
of file_permission() in sys_fchdir().

Signed-off-by: Andreas Gruenbacher <ag@bestbits.at>

---
 fs/open.c |   15 ++++++---------
 1 file changed, 6 insertions(+), 9 deletions(-)

--- a/fs/open.c
+++ b/fs/open.c
@@ -501,9 +501,7 @@ out:
 asmlinkage long sys_fchdir(unsigned int fd)
 {
 	struct file *file;
-	struct dentry *dentry;
-	struct inode *inode;
-	struct vfsmount *mnt;
+	struct vfs_lookup lookup;
 	int error;
 
 	error = -EBADF;
@@ -511,17 +509,16 @@ asmlinkage long sys_fchdir(unsigned int 
 	if (!file)
 		goto out;
 
-	dentry = file->f_path.dentry;
-	mnt = file->f_path.mnt;
-	inode = dentry->d_inode;
+	lookup.path = file->f_path;
+	lookup.flags = 0;
 
 	error = -ENOTDIR;
-	if (!S_ISDIR(inode->i_mode))
+	if (!S_ISDIR(lookup.path.dentry->d_inode->i_mode))
 		goto out_putf;
 
-	error = file_permission(file, MAY_EXEC);
+	error = vfs_permission(&lookup, MAY_EXEC);
 	if (!error)
-		set_fs_pwd(current->fs, mnt, dentry);
+		set_fs_pwd(current->fs, lookup.path.mnt, lookup.path.dentry);
 out_putf:
 	fput(file);
 out:


^ permalink raw reply	[flat|nested] 35+ messages in thread

* [RFC 06/10] Use vfs_permission instead of file_permission in do_path_lookup
  2007-08-08 17:16 [RFC 00/10] Split up struct nameidata (take 3) Andreas Gruenbacher
                   ` (4 preceding siblings ...)
  2007-08-08 17:16 ` [RFC 05/10] Use vfs_permission instead of file_permission in sys_fchdir Andreas Gruenbacher
@ 2007-08-08 17:16 ` Andreas Gruenbacher
  2007-08-08 19:27   ` Christoph Hellwig
  2007-08-08 17:16 ` [RFC 07/10] Pass no unnecessary information to iop->create Andreas Gruenbacher
                   ` (3 subsequent siblings)
  9 siblings, 1 reply; 35+ messages in thread
From: Andreas Gruenbacher @ 2007-08-08 17:16 UTC (permalink / raw)
  To: linux-kernel
  Cc: John Johansen, Jan Blunck, Erez Zadok, Josef 'Jeff' Sipek

[-- Attachment #1: do_path_lookup.diff --]
[-- Type: text/plain, Size: 1113 bytes --]

Switch from file_permission() to vfs_permission() in do_path_lookup()
by filling in the vfs_lookup in nd slightly earlier.

Signed-off-by: Andreas Gruenbacher <ag@bestbits.at>

---
 fs/namei.c |   12 +++++-------
 1 file changed, 5 insertions(+), 7 deletions(-)

--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1133,25 +1133,23 @@ static int fastcall do_path_lookup(int d
 		nd->lookup.path.dentry = dget(fs->pwd);
 		read_unlock(&fs->lock);
 	} else {
-		struct dentry *dentry;
-
 		file = fget_light(dfd, &fput_needed);
 		retval = -EBADF;
 		if (!file)
 			goto out_fail;
 
-		dentry = file->f_path.dentry;
+		nd->lookup.path = file->f_path;
 
 		retval = -ENOTDIR;
-		if (!S_ISDIR(dentry->d_inode->i_mode))
+		if (!S_ISDIR(nd->lookup.path.dentry->d_inode->i_mode))
 			goto fput_fail;
 
-		retval = file_permission(file, MAY_EXEC);
+		retval = vfs_permission(&nd->lookup, MAY_EXEC);
 		if (retval)
 			goto fput_fail;
 
-		nd->lookup.path.mnt = mntget(file->f_path.mnt);
-		nd->lookup.path.dentry = dget(dentry);
+		mntget(nd->lookup.path.mnt);
+		dget(nd->lookup.path.dentry);
 
 		fput_light(file, fput_needed);
 	}


^ permalink raw reply	[flat|nested] 35+ messages in thread

* [RFC 07/10] Pass no unnecessary information to iop->create
  2007-08-08 17:16 [RFC 00/10] Split up struct nameidata (take 3) Andreas Gruenbacher
                   ` (5 preceding siblings ...)
  2007-08-08 17:16 ` [RFC 06/10] Use vfs_permission instead of file_permission in do_path_lookup Andreas Gruenbacher
@ 2007-08-08 17:16 ` Andreas Gruenbacher
  2007-08-08 17:16 ` [RFC 08/10] Pass no NULL vfs_lookup to vfs_create Andreas Gruenbacher
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 35+ messages in thread
From: Andreas Gruenbacher @ 2007-08-08 17:16 UTC (permalink / raw)
  To: linux-kernel
  Cc: John Johansen, Jan Blunck, Erez Zadok, Josef 'Jeff' Sipek

[-- Attachment #1: create-args.diff --]
[-- Type: text/plain, Size: 39375 bytes --]

vfs_create() and the create inode operation do not need a full nameidata.
Pass a struct vfs_lookup instead.

Signed-off-by: Andreas Gruenbacher <ag@bestbits.at>

---
 fs/9p/vfs_inode.c           |   13 +++++++------
 fs/affs/affs.h              |    2 +-
 fs/affs/namei.c             |    2 +-
 fs/afs/dir.c                |    4 ++--
 fs/bad_inode.c              |    2 +-
 fs/bfs/dir.c                |    2 +-
 fs/cifs/cifsfs.h            |    2 +-
 fs/cifs/dir.c               |   10 +++++-----
 fs/coda/dir.c               |    4 ++--
 fs/ecryptfs/inode.c         |   24 ++++++++++++------------
 fs/exec.c                   |    4 ++--
 fs/ext2/namei.c             |    2 +-
 fs/ext3/namei.c             |    2 +-
 fs/ext4/namei.c             |    2 +-
 fs/fuse/dir.c               |   12 ++++++------
 fs/gfs2/inode.c             |    2 +-
 fs/gfs2/inode.h             |    2 +-
 fs/gfs2/ops_inode.c         |    8 ++++----
 fs/hfs/dir.c                |    2 +-
 fs/hfsplus/dir.c            |    2 +-
 fs/hpfs/namei.c             |    2 +-
 fs/hugetlbfs/inode.c        |    2 +-
 fs/inotify_user.c           |    2 +-
 fs/jffs2/dir.c              |    4 ++--
 fs/jfs/namei.c              |    2 +-
 fs/minix/namei.c            |    2 +-
 fs/msdos/namei.c            |    2 +-
 fs/namei.c                  |   27 +++++++++++++++------------
 fs/ncpfs/dir.c              |    4 ++--
 fs/nfs/dir.c                |   30 +++++++++++++++---------------
 fs/nfs/nfs3proc.c           |    2 +-
 fs/nfs/nfs4proc.c           |   24 ++++++++++++------------
 fs/nfs/proc.c               |    2 +-
 fs/ocfs2/dlm/dlmfs.c        |    2 +-
 fs/ocfs2/namei.c            |    2 +-
 fs/open.c                   |   22 ++++++++++++----------
 fs/qnx4/namei.c             |    2 +-
 fs/ramfs/inode.c            |    2 +-
 fs/reiserfs/namei.c         |    2 +-
 fs/smbfs/dir.c              |    4 ++--
 fs/sysv/namei.c             |    2 +-
 fs/udf/namei.c              |    2 +-
 fs/ufs/namei.c              |    2 +-
 fs/vfat/namei.c             |    2 +-
 fs/xfs/linux-2.6/xfs_iops.c |    2 +-
 include/linux/fs.h          |    4 ++--
 include/linux/namei.h       |    5 +++--
 include/linux/nfs_xdr.h     |    2 +-
 include/linux/qnx4_fs.h     |    2 +-
 ipc/mqueue.c                |    2 +-
 mm/shmem.c                  |    2 +-
 51 files changed, 139 insertions(+), 132 deletions(-)

--- a/fs/9p/vfs_inode.c
+++ b/fs/9p/vfs_inode.c
@@ -459,13 +459,13 @@ error:
  * @inode: directory inode that is being created
  * @dentry:  dentry that is being deleted
  * @mode: create permissions
- * @nd: path information
+ * @lookup: path information
  *
  */
 
 static int
 v9fs_vfs_create(struct inode *dir, struct dentry *dentry, int mode,
-		struct nameidata *nd)
+		struct vfs_lookup *lookup)
 {
 	int err;
 	u32 perm;
@@ -478,8 +478,8 @@ v9fs_vfs_create(struct inode *dir, struc
 	fid = NULL;
 	v9ses = v9fs_inode2v9ses(dir);
 	perm = unixmode2p9mode(v9ses, mode);
-	if (nd && nd->lookup.flags & LOOKUP_OPEN)
-		flags = nd->lookup.intent.open.flags - 1;
+	if (lookup && lookup->flags & LOOKUP_OPEN)
+		flags = lookup->intent.open.flags - 1;
 	else
 		flags = O_RDWR;
 
@@ -492,8 +492,9 @@ v9fs_vfs_create(struct inode *dir, struc
 	}
 
 	/* if we are opening a file, assign the open fid to the file */
-	if (nd && nd->lookup.flags & LOOKUP_OPEN) {
-		filp = lookup_instantiate_filp(nd, dentry, v9fs_open_created);
+	if (lookup && lookup->flags & LOOKUP_OPEN) {
+		filp = lookup_instantiate_filp(lookup, dentry,
+					       v9fs_open_created);
 		if (IS_ERR(filp)) {
 			err = PTR_ERR(filp);
 			goto error;
--- a/fs/affs/affs.h
+++ b/fs/affs/affs.h
@@ -155,7 +155,7 @@ extern void	affs_free_bitmap(struct supe
 extern int	affs_hash_name(struct super_block *sb, const u8 *name, unsigned int len);
 extern struct dentry *affs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *);
 extern int	affs_unlink(struct inode *dir, struct dentry *dentry);
-extern int	affs_create(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *);
+extern int	affs_create(struct inode *dir, struct dentry *dentry, int mode, struct vfs_lookup *);
 extern int	affs_mkdir(struct inode *dir, struct dentry *dentry, int mode);
 extern int	affs_rmdir(struct inode *dir, struct dentry *dentry);
 extern int	affs_link(struct dentry *olddentry, struct inode *dir,
--- a/fs/affs/namei.c
+++ b/fs/affs/namei.c
@@ -243,7 +243,7 @@ affs_unlink(struct inode *dir, struct de
 }
 
 int
-affs_create(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *nd)
+affs_create(struct inode *dir, struct dentry *dentry, int mode, struct vfs_lookup *lookup)
 {
 	struct super_block *sb = dir->i_sb;
 	struct inode	*inode;
--- a/fs/afs/dir.c
+++ b/fs/afs/dir.c
@@ -29,7 +29,7 @@ static void afs_d_release(struct dentry 
 static int afs_lookup_filldir(void *_cookie, const char *name, int nlen,
 				  loff_t fpos, u64 ino, unsigned dtype);
 static int afs_create(struct inode *dir, struct dentry *dentry, int mode,
-		      struct nameidata *nd);
+		      struct vfs_lookup *lookup);
 static int afs_mkdir(struct inode *dir, struct dentry *dentry, int mode);
 static int afs_rmdir(struct inode *dir, struct dentry *dentry);
 static int afs_unlink(struct inode *dir, struct dentry *dentry);
@@ -906,7 +906,7 @@ error:
  * create a regular file on an AFS filesystem
  */
 static int afs_create(struct inode *dir, struct dentry *dentry, int mode,
-		      struct nameidata *nd)
+		      struct vfs_lookup *lookup)
 {
 	struct afs_file_status status;
 	struct afs_callback cb;
--- a/fs/bad_inode.c
+++ b/fs/bad_inode.c
@@ -186,7 +186,7 @@ static const struct file_operations bad_
 };
 
 static int bad_inode_create (struct inode *dir, struct dentry *dentry,
-		int mode, struct nameidata *nd)
+		int mode, struct vfs_lookup *lookup)
 {
 	return -EIO;
 }
--- a/fs/bfs/dir.c
+++ b/fs/bfs/dir.c
@@ -79,7 +79,7 @@ const struct file_operations bfs_dir_ope
 extern void dump_imap(const char *, struct super_block *);
 
 static int bfs_create(struct inode * dir, struct dentry * dentry, int mode,
-		struct nameidata *nd)
+		struct vfs_lookup *lookup)
 {
 	int err;
 	struct inode * inode;
--- a/fs/cifs/cifsfs.h
+++ b/fs/cifs/cifsfs.h
@@ -44,7 +44,7 @@ extern void cifs_read_inode(struct inode
 /* Functions related to inodes */
 extern const struct inode_operations cifs_dir_inode_ops;
 extern int cifs_create(struct inode *, struct dentry *, int,
-		       struct nameidata *);
+		       struct vfs_lookup *);
 extern struct dentry *cifs_lookup(struct inode *, struct dentry *,
 				  struct nameidata *);
 extern int cifs_unlink(struct inode *, struct dentry *);
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -125,7 +125,7 @@ BB remove above eight lines BB */
 
 int
 cifs_create(struct inode *inode, struct dentry *direntry, int mode,
-		struct nameidata *nd)
+		struct vfs_lookup *lookup)
 {
 	int rc = -ENOENT;
 	int xid;
@@ -153,8 +153,8 @@ cifs_create(struct inode *inode, struct 
 		return -ENOMEM;
 	}
 
-	if (nd && (nd->lookup.flags & LOOKUP_OPEN)) {
-		int oflags = nd->lookup.intent.open.flags;
+	if (lookup && (lookup->flags & LOOKUP_OPEN)) {
+		int oflags = lookup->intent.open.flags;
 
 		desiredAccess = 0;
 		if (oflags & FMODE_READ)
@@ -263,8 +263,8 @@ cifs_create(struct inode *inode, struct 
 				direntry->d_op = &cifs_dentry_ops;
 			d_instantiate(direntry, newinode);
 		}
-		if ((nd == NULL /* nfsd case - nfs srv does not set nd */) ||
-			((nd->lookup.flags & LOOKUP_OPEN) == FALSE)) {
+		if ((!lookup /* nfsd case - nfs srv does not set lookup */) ||
+			((lookup->flags & LOOKUP_OPEN) == FALSE)) {
 			/* mknod case - do not leave file open */
 			CIFSSMBClose(xid, pTcon, fileHandle);
 		} else if (newinode) {
--- a/fs/coda/dir.c
+++ b/fs/coda/dir.c
@@ -29,7 +29,7 @@
 #include "coda_int.h"
 
 /* dir inode-ops */
-static int coda_create(struct inode *dir, struct dentry *new, int mode, struct nameidata *nd);
+static int coda_create(struct inode *dir, struct dentry *new, int mode, struct vfs_lookup *lookup);
 static struct dentry *coda_lookup(struct inode *dir, struct dentry *target, struct nameidata *nd);
 static int coda_link(struct dentry *old_dentry, struct inode *dir_inode, 
 		     struct dentry *entry);
@@ -192,7 +192,7 @@ static inline void coda_dir_drop_nlink(s
 }
 
 /* creation routines: create, mknod, mkdir, link, symlink */
-static int coda_create(struct inode *dir, struct dentry *de, int mode, struct nameidata *nd)
+static int coda_create(struct inode *dir, struct dentry *de, int mode, struct vfs_lookup *lookup)
 {
         int error=0;
 	const char *name=de->d_name.name;
--- a/fs/ecryptfs/inode.c
+++ b/fs/ecryptfs/inode.c
@@ -69,7 +69,7 @@ static void unlock_dir(struct dentry *di
 static int
 ecryptfs_create_underlying_file(struct inode *lower_dir_inode,
 				struct dentry *dentry, int mode,
-				struct nameidata *nd)
+				struct vfs_lookup *lookup)
 {
 	struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry);
 	struct vfsmount *lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry);
@@ -77,13 +77,13 @@ ecryptfs_create_underlying_file(struct i
 	struct vfsmount *vfsmount_save;
 	int rc;
 
-	dentry_save = nd->lookup.path.dentry;
-	vfsmount_save = nd->lookup.path.mnt;
-	nd->lookup.path.dentry = lower_dentry;
-	nd->lookup.path.mnt = lower_mnt;
-	rc = vfs_create(lower_dir_inode, lower_dentry, mode, nd);
-	nd->lookup.path.dentry = dentry_save;
-	nd->lookup.path.mnt = vfsmount_save;
+	dentry_save = lookup->path.dentry;
+	vfsmount_save = lookup->path.mnt;
+	lookup->path.dentry = lower_dentry;
+	lookup->path.mnt = lower_mnt;
+	rc = vfs_create(lower_dir_inode, lower_dentry, mode, lookup);
+	lookup->path.dentry = dentry_save;
+	lookup->path.mnt = vfsmount_save;
 	return rc;
 }
 
@@ -103,7 +103,7 @@ ecryptfs_create_underlying_file(struct i
 static int
 ecryptfs_do_create(struct inode *directory_inode,
 		   struct dentry *ecryptfs_dentry, int mode,
-		   struct nameidata *nd)
+		   struct vfs_lookup *lookup)
 {
 	int rc;
 	struct dentry *lower_dentry;
@@ -118,7 +118,7 @@ ecryptfs_do_create(struct inode *directo
 		goto out;
 	}
 	rc = ecryptfs_create_underlying_file(lower_dir_dentry->d_inode,
-					     ecryptfs_dentry, mode, nd);
+					     ecryptfs_dentry, mode, lookup);
 	if (unlikely(rc)) {
 		ecryptfs_printk(KERN_ERR,
 				"Failure to create underlying file\n");
@@ -248,11 +248,11 @@ out:
  */
 static int
 ecryptfs_create(struct inode *directory_inode, struct dentry *ecryptfs_dentry,
-		int mode, struct nameidata *nd)
+		int mode, struct vfs_lookup *lookup)
 {
 	int rc;
 
-	rc = ecryptfs_do_create(directory_inode, ecryptfs_dentry, mode, nd);
+	rc = ecryptfs_do_create(directory_inode, ecryptfs_dentry, mode, lookup);
 	if (unlikely(rc)) {
 		ecryptfs_printk(KERN_WARNING, "Failed to create file in"
 				"lower filesystem\n");
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -174,7 +174,7 @@ asmlinkage long sys_uselib(const char __
 out:
   	return error;
 exit:
-	release_open_intent(&nd);
+	release_open_intent(&nd.lookup.intent.open);
 	path_release(&nd);
 	goto out;
 }
@@ -698,7 +698,7 @@ out:
 				return file;
 			}
 		}
-		release_open_intent(&nd);
+		release_open_intent(&nd.lookup.intent.open);
 		path_release(&nd);
 	}
 	goto out;
--- a/fs/ext2/namei.c
+++ b/fs/ext2/namei.c
@@ -103,7 +103,7 @@ struct dentry *ext2_get_parent(struct de
  * If the create succeeds, we fill in the inode information
  * with d_instantiate(). 
  */
-static int ext2_create (struct inode * dir, struct dentry * dentry, int mode, struct nameidata *nd)
+static int ext2_create (struct inode * dir, struct dentry * dentry, int mode, struct vfs_lookup *lookup)
 {
 	struct inode * inode = ext2_new_inode (dir, mode);
 	int err = PTR_ERR(inode);
--- a/fs/ext3/namei.c
+++ b/fs/ext3/namei.c
@@ -1654,7 +1654,7 @@ static int ext3_add_nondir(handle_t *han
  * with d_instantiate().
  */
 static int ext3_create (struct inode * dir, struct dentry * dentry, int mode,
-		struct nameidata *nd)
+		struct vfs_lookup *lookup)
 {
 	handle_t *handle;
 	struct inode * inode;
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -1681,7 +1681,7 @@ static int ext4_add_nondir(handle_t *han
  * with d_instantiate().
  */
 static int ext4_create (struct inode * dir, struct dentry * dentry, int mode,
-		struct nameidata *nd)
+		struct vfs_lookup *lookup)
 {
 	handle_t *handle;
 	struct inode * inode;
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -303,7 +303,7 @@ static void fuse_sync_release(struct fus
  * 'mknod' + 'open' requests.
  */
 static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode,
-			    struct nameidata *nd)
+			    struct vfs_lookup *lookup)
 {
 	int err;
 	struct inode *inode;
@@ -315,7 +315,7 @@ static int fuse_create_open(struct inode
 	struct fuse_entry_out outentry;
 	struct fuse_file *ff;
 	struct file *file;
-	int flags = nd->lookup.intent.open.flags - 1;
+	int flags = lookup->intent.open.flags - 1;
 
 	if (fc->no_create)
 		return -ENOSYS;
@@ -375,7 +375,7 @@ static int fuse_create_open(struct inode
 	fuse_put_request(fc, forget_req);
 	d_instantiate(entry, inode);
 	fuse_change_timeout(entry, &outentry);
-	file = lookup_instantiate_filp(nd, entry, generic_file_open);
+	file = lookup_instantiate_filp(lookup, entry, generic_file_open);
 	if (IS_ERR(file)) {
 		ff->fh = outopen.fh;
 		fuse_sync_release(fc, ff, outentry.nodeid, flags);
@@ -483,10 +483,10 @@ static int fuse_mknod(struct inode *dir,
 }
 
 static int fuse_create(struct inode *dir, struct dentry *entry, int mode,
-		       struct nameidata *nd)
+		       struct vfs_lookup *lookup)
 {
-	if (nd && (nd->lookup.flags & LOOKUP_OPEN)) {
-		int err = fuse_create_open(dir, entry, mode, nd);
+	if (lookup && (lookup->flags & LOOKUP_OPEN)) {
+		int err = fuse_create_open(dir, entry, mode, lookup);
 		if (err != -ENOSYS)
 			return err;
 		/* Fall back on mknod */
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -409,7 +409,7 @@ struct inode *gfs2_lookup_simple(struct 
  */
 
 struct inode *gfs2_lookupi(struct inode *dir, const struct qstr *name,
-			   int is_root, struct nameidata *nd)
+			   int is_root, struct vfs_lookup *lookup)
 {
 	struct super_block *sb = dir->i_sb;
 	struct gfs2_inode *dip = GFS2_I(dir);
--- a/fs/gfs2/inode.h
+++ b/fs/gfs2/inode.h
@@ -57,7 +57,7 @@ int gfs2_inode_refresh(struct gfs2_inode
 int gfs2_dinode_dealloc(struct gfs2_inode *inode);
 int gfs2_change_nlink(struct gfs2_inode *ip, int diff);
 struct inode *gfs2_lookupi(struct inode *dir, const struct qstr *name,
-			   int is_root, struct nameidata *nd);
+			   int is_root, struct vfs_lookup *lookup);
 struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name,
 			   unsigned int mode, dev_t dev);
 int gfs2_rmdiri(struct gfs2_inode *dip, const struct qstr *name,
--- a/fs/gfs2/ops_inode.c
+++ b/fs/gfs2/ops_inode.c
@@ -48,7 +48,7 @@
  */
 
 static int gfs2_create(struct inode *dir, struct dentry *dentry,
-		       int mode, struct nameidata *nd)
+		       int mode, struct vfs_lookup *lookup)
 {
 	struct gfs2_inode *dip = GFS2_I(dir);
 	struct gfs2_sbd *sdp = GFS2_SB(dir);
@@ -69,12 +69,12 @@ static int gfs2_create(struct inode *dir
 			mark_inode_dirty(inode);
 			break;
 		} else if (PTR_ERR(inode) != -EEXIST ||
-			   (nd->lookup.intent.open.flags & O_EXCL)) {
+			   (lookup->intent.open.flags & O_EXCL)) {
 			gfs2_holder_uninit(ghs);
 			return PTR_ERR(inode);
 		}
 
-		inode = gfs2_lookupi(dir, &dentry->d_name, 0, nd);
+		inode = gfs2_lookupi(dir, &dentry->d_name, 0, lookup);
 		if (inode) {
 			if (!IS_ERR(inode)) {
 				gfs2_holder_uninit(ghs);
@@ -109,7 +109,7 @@ static struct dentry *gfs2_lookup(struct
 
 	dentry->d_op = &gfs2_dops;
 
-	inode = gfs2_lookupi(dir, &dentry->d_name, 0, nd);
+	inode = gfs2_lookupi(dir, &dentry->d_name, 0, &nd->lookup);
 	if (inode && IS_ERR(inode))
 		return ERR_PTR(PTR_ERR(inode));
 
--- a/fs/hfs/dir.c
+++ b/fs/hfs/dir.c
@@ -178,7 +178,7 @@ static int hfs_dir_release(struct inode 
  * the directory and the name (and its length) of the new file.
  */
 static int hfs_create(struct inode *dir, struct dentry *dentry, int mode,
-		      struct nameidata *nd)
+		      struct vfs_lookup *lookup)
 {
 	struct inode *inode;
 	int res;
--- a/fs/hfsplus/dir.c
+++ b/fs/hfsplus/dir.c
@@ -236,7 +236,7 @@ static int hfsplus_dir_release(struct in
 }
 
 static int hfsplus_create(struct inode *dir, struct dentry *dentry, int mode,
-			  struct nameidata *nd)
+			  struct vfs_lookup *lookup)
 {
 	struct inode *inode;
 	int res;
--- a/fs/hpfs/namei.c
+++ b/fs/hpfs/namei.c
@@ -118,7 +118,7 @@ bail:
 	return err;
 }
 
-static int hpfs_create(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *nd)
+static int hpfs_create(struct inode *dir, struct dentry *dentry, int mode, struct vfs_lookup *lookup)
 {
 	const char *name = dentry->d_name.name;
 	unsigned len = dentry->d_name.len;
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -437,7 +437,7 @@ static int hugetlbfs_mkdir(struct inode 
 	return retval;
 }
 
-static int hugetlbfs_create(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *nd)
+static int hugetlbfs_create(struct inode *dir, struct dentry *dentry, int mode, struct vfs_lookup *lookup)
 {
 	return hugetlbfs_mknod(dir, dentry, mode | S_IFREG, 0);
 }
--- a/fs/inotify_user.c
+++ b/fs/inotify_user.c
@@ -349,7 +349,7 @@ static int find_inode(const char __user 
 	if (error)
 		return error;
 	/* you can only watch an inode if you have read permissions on it */
-	error = vfs_permission(nd.lookup, MAY_READ);
+	error = vfs_permission(&nd->lookup, MAY_READ);
 	if (error)
 		path_release(nd);
 	return error;
--- a/fs/jffs2/dir.c
+++ b/fs/jffs2/dir.c
@@ -22,7 +22,7 @@
 static int jffs2_readdir (struct file *, void *, filldir_t);
 
 static int jffs2_create (struct inode *,struct dentry *,int,
-			 struct nameidata *);
+			 struct vfs_lookup *);
 static struct dentry *jffs2_lookup (struct inode *,struct dentry *,
 				    struct nameidata *);
 static int jffs2_link (struct dentry *,struct inode *,struct dentry *);
@@ -176,7 +176,7 @@ static int jffs2_readdir(struct file *fi
 
 
 static int jffs2_create(struct inode *dir_i, struct dentry *dentry, int mode,
-			struct nameidata *nd)
+			struct vfs_lookup *lookup)
 {
 	struct jffs2_raw_inode *ri;
 	struct jffs2_inode_info *f, *dir_f;
--- a/fs/jfs/namei.c
+++ b/fs/jfs/namei.c
@@ -71,7 +71,7 @@ static inline void free_ea_wmap(struct i
  *
  */
 static int jfs_create(struct inode *dip, struct dentry *dentry, int mode,
-		struct nameidata *nd)
+		struct vfs_lookup *lookup)
 {
 	int rc = 0;
 	tid_t tid;		/* transaction id */
--- a/fs/minix/namei.c
+++ b/fs/minix/namei.c
@@ -83,7 +83,7 @@ static int minix_mknod(struct inode * di
 }
 
 static int minix_create(struct inode * dir, struct dentry *dentry, int mode,
-		struct nameidata *nd)
+		struct vfs_lookup *lookup)
 {
 	return minix_mknod(dir, dentry, mode, 0);
 }
--- a/fs/msdos/namei.c
+++ b/fs/msdos/namei.c
@@ -277,7 +277,7 @@ static int msdos_add_entry(struct inode 
 
 /***** Create a file */
 static int msdos_create(struct inode *dir, struct dentry *dentry, int mode,
-			struct nameidata *nd)
+			struct vfs_lookup *lookup)
 {
 	struct super_block *sb = dir->i_sb;
 	struct inode *inode = NULL;
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -369,12 +369,14 @@ void path_release_on_umount(struct namei
  * release_open_intent - free up open intent resources
  * @nd: pointer to nameidata
  */
-void release_open_intent(struct nameidata *nd)
+void release_open_intent(struct open_intent *intent)
 {
-	if (nd->lookup.intent.open.file->f_path.dentry == NULL)
-		put_filp(nd->lookup.intent.open.file);
+	struct file *file = intent->file;
+
+	if (file->f_path.dentry == NULL)
+		put_filp(file);
 	else
-		fput(nd->lookup.intent.open.file);
+		fput(file);
 }
 
 static inline struct dentry *
@@ -1223,7 +1225,7 @@ static int __path_lookup_intent_open(int
 			path_release(nd);
 		}
 	} else if (err != 0)
-		release_open_intent(nd);
+		release_open_intent(&nd->lookup.intent.open);
 	return err;
 }
 
@@ -1542,9 +1544,9 @@ void unlock_rename(struct dentry *p1, st
 }
 
 int vfs_create(struct inode *dir, struct dentry *dentry, int mode,
-		struct nameidata *nd)
+	       struct vfs_lookup *lookup)
 {
-	int error = may_create(dir, dentry, &nd->lookup);
+	int error = may_create(dir, dentry, lookup);
 
 	if (error)
 		return error;
@@ -1557,7 +1559,7 @@ int vfs_create(struct inode *dir, struct
 	if (error)
 		return error;
 	DQUOT_INIT(dir);
-	error = dir->i_op->create(dir, dentry, mode, nd);
+	error = dir->i_op->create(dir, dentry, mode, lookup);
 	if (!error)
 		fsnotify_create(dir, dentry);
 	return error;
@@ -1650,7 +1652,7 @@ static int open_namei_create(struct name
 
 	if (!IS_POSIXACL(dir->d_inode))
 		mode &= ~current->fs->umask;
-	error = vfs_create(dir->d_inode, path->dentry, mode, nd);
+	error = vfs_create(dir->d_inode, path->dentry, mode, &nd->lookup);
 	mutex_unlock(&dir->d_inode->i_mutex);
 	dput(nd->lookup.path.dentry);
 	nd->lookup.path.dentry = path->dentry;
@@ -1783,7 +1785,7 @@ exit_dput:
 	dput_path(&path, nd);
 exit:
 	if (!IS_ERR(nd->lookup.intent.open.file))
-		release_open_intent(nd);
+		release_open_intent(&nd->lookup.intent.open);
 	path_release(nd);
 	return error;
 
@@ -1811,7 +1813,7 @@ do_link:
 		 * me so stupid? Anathema to whoever designed this non-sense
 		 * with "intent.open".
 		 */
-		release_open_intent(nd);
+		release_open_intent(&nd->lookup.intent.open);
 		return error;
 	}
 	nd->lookup.flags &= ~LOOKUP_PARENT;
@@ -1935,7 +1937,8 @@ asmlinkage long sys_mknodat(int dfd, con
 	if (!IS_ERR(dentry)) {
 		switch (mode & S_IFMT) {
 		case 0: case S_IFREG:
-			error = vfs_create(nd.lookup.path.dentry->d_inode,dentry,mode,&nd);
+			error = vfs_create(nd.lookup.path.dentry->d_inode,
+					   dentry, mode, &nd.lookup);
 			break;
 		case S_IFCHR: case S_IFBLK:
 			error = vfs_mknod(nd.lookup.path.dentry->d_inode,dentry,mode,
--- a/fs/ncpfs/dir.c
+++ b/fs/ncpfs/dir.c
@@ -33,7 +33,7 @@ static void ncp_do_readdir(struct file *
 
 static int ncp_readdir(struct file *, void *, filldir_t);
 
-static int ncp_create(struct inode *, struct dentry *, int, struct nameidata *);
+static int ncp_create(struct inode *, struct dentry *, int, struct vfs_lookup *);
 static struct dentry *ncp_lookup(struct inode *, struct dentry *, struct nameidata *);
 static int ncp_unlink(struct inode *, struct dentry *);
 static int ncp_mkdir(struct inode *, struct dentry *, int);
@@ -940,7 +940,7 @@ out:
 }
 
 static int ncp_create(struct inode *dir, struct dentry *dentry, int mode,
-		struct nameidata *nd)
+		struct vfs_lookup *lookup)
 {
 	return ncp_create_new(dir, dentry, mode, 0, 0);
 }
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -44,7 +44,7 @@
 static int nfs_opendir(struct inode *, struct file *);
 static int nfs_readdir(struct file *, void *, filldir_t);
 static struct dentry *nfs_lookup(struct inode *, struct dentry *, struct nameidata *);
-static int nfs_create(struct inode *, struct dentry *, int, struct nameidata *);
+static int nfs_create(struct inode *, struct dentry *, int, struct vfs_lookup *);
 static int nfs_mkdir(struct inode *, struct dentry *, int);
 static int nfs_rmdir(struct inode *, struct dentry *);
 static int nfs_unlink(struct inode *, struct dentry *);
@@ -687,11 +687,11 @@ static inline void nfs_renew_times(struc
  * component of the path.
  * We check for this using LOOKUP_CONTINUE and LOOKUP_PARENT.
  */
-static inline unsigned int nfs_lookup_check_intent(struct nameidata *nd, unsigned int mask)
+static inline unsigned int nfs_lookup_check_intent(struct vfs_lookup *lookup, unsigned int mask)
 {
-	if (nd->lookup.flags & (LOOKUP_CONTINUE|LOOKUP_PARENT))
+	if (lookup->flags & (LOOKUP_CONTINUE|LOOKUP_PARENT))
 		return 0;
-	return nd->lookup.flags & mask;
+	return lookup->flags & mask;
 }
 
 /*
@@ -712,7 +712,7 @@ int nfs_lookup_verify_inode(struct inode
 		if (nd->lookup.flags & LOOKUP_REVAL)
 			goto out_force;
 		/* This is an open(2) */
-		if (nfs_lookup_check_intent(nd, LOOKUP_OPEN) != 0 &&
+		if (nfs_lookup_check_intent(&nd->lookup, LOOKUP_OPEN) != 0 &&
 				!(server->flags & NFS_MOUNT_NOCTO) &&
 				(S_ISREG(inode->i_mode) ||
 				 S_ISDIR(inode->i_mode)))
@@ -735,7 +735,7 @@ int nfs_neg_need_reval(struct inode *dir
 		       struct nameidata *nd)
 {
 	/* Don't revalidate a negative dentry if we're creating a new file */
-	if (nd != NULL && nfs_lookup_check_intent(nd, LOOKUP_CREATE) != 0)
+	if (nd != NULL && nfs_lookup_check_intent(&nd->lookup, LOOKUP_CREATE) != 0)
 		return 0;
 	return !nfs_check_verifier(dir, dentry);
 }
@@ -888,13 +888,13 @@ struct dentry_operations nfs_dentry_oper
  * an O_EXCL create using this path component.
  */
 static inline
-int nfs_is_exclusive_create(struct inode *dir, struct nameidata *nd)
+int nfs_is_exclusive_create(struct inode *dir, struct vfs_lookup *lookup)
 {
 	if (NFS_PROTO(dir)->version == 2)
 		return 0;
-	if (nd == NULL || nfs_lookup_check_intent(nd, LOOKUP_CREATE) == 0)
+	if (!lookup || nfs_lookup_check_intent(lookup, LOOKUP_CREATE) == 0)
 		return 0;
-	return (nd->lookup.intent.open.flags & O_EXCL) != 0;
+	return (lookup->intent.open.flags & O_EXCL) != 0;
 }
 
 static inline int nfs_reval_fsid(struct inode *dir, const struct nfs_fattr *fattr)
@@ -932,7 +932,7 @@ static struct dentry *nfs_lookup(struct 
 	 * If we're doing an exclusive create, optimize away the lookup
 	 * but don't hash the dentry.
 	 */
-	if (nfs_is_exclusive_create(dir, nd)) {
+	if (nfs_is_exclusive_create(dir, &nd->lookup)) {
 		d_instantiate(dentry, NULL);
 		res = NULL;
 		goto out_unlock;
@@ -991,7 +991,7 @@ struct dentry_operations nfs4_dentry_ope
  */
 static int is_atomic_open(struct inode *dir, struct nameidata *nd)
 {
-	if (nd == NULL || nfs_lookup_check_intent(nd, LOOKUP_OPEN) == 0)
+	if (nd == NULL || nfs_lookup_check_intent(&nd->lookup, LOOKUP_OPEN) == 0)
 		return 0;
 	/* NFS does not (yet) have a stateful open for directories */
 	if (nd->lookup.flags & LOOKUP_DIRECTORY)
@@ -1231,7 +1231,7 @@ int nfs_instantiate(struct dentry *dentr
  * reply path made it appear to have failed.
  */
 static int nfs_create(struct inode *dir, struct dentry *dentry, int mode,
-		struct nameidata *nd)
+		struct vfs_lookup *lookup)
 {
 	struct iattr attr;
 	int error;
@@ -1243,12 +1243,12 @@ static int nfs_create(struct inode *dir,
 	attr.ia_mode = mode;
 	attr.ia_valid = ATTR_MODE;
 
-	if ((nd->lookup.flags & LOOKUP_CREATE) != 0)
-		open_flags = nd->lookup.intent.open.flags;
+	if ((lookup->flags & LOOKUP_CREATE) != 0)
+		open_flags = lookup->intent.open.flags;
 
 	lock_kernel();
 	nfs_begin_data_update(dir);
-	error = NFS_PROTO(dir)->create(dir, dentry, &attr, open_flags, nd);
+	error = NFS_PROTO(dir)->create(dir, dentry, &attr, open_flags, lookup);
 	nfs_end_data_update(dir);
 	if (error != 0)
 		goto out_err;
--- a/fs/nfs/nfs3proc.c
+++ b/fs/nfs/nfs3proc.c
@@ -258,7 +258,7 @@ static int nfs3_proc_readlink(struct ino
  */
 static int
 nfs3_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
-		 int flags, struct nameidata *nd)
+		 int flags, struct vfs_lookup *lookup)
 {
 	struct nfs_fh		fhandle;
 	struct nfs_fattr	fattr;
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -1376,20 +1376,20 @@ out:
 	return status;
 }
 
-static int nfs4_intent_set_file(struct nameidata *nd, struct path *path, struct nfs4_state *state)
+static int nfs4_intent_set_file(struct vfs_lookup *lookup, struct path *path, struct nfs4_state *state)
 {
 	struct file *filp;
 	int ret;
 
 	/* If the open_intent is for execute, we have an extra check to make */
-	if (nd->lookup.intent.open.flags & FMODE_EXEC) {
+	if (lookup->intent.open.flags & FMODE_EXEC) {
 		ret = _nfs4_do_access(state->inode,
 				state->owner->so_cred,
-				nd->lookup.intent.open.flags);
+				lookup->intent.open.flags);
 		if (ret < 0)
 			goto out_close;
 	}
-	filp = lookup_instantiate_filp(nd, path->dentry, NULL);
+	filp = lookup_instantiate_filp(lookup, path->dentry, NULL);
 	if (!IS_ERR(filp)) {
 		struct nfs_open_context *ctx;
 		ctx = (struct nfs_open_context *)filp->private_data;
@@ -1398,7 +1398,7 @@ static int nfs4_intent_set_file(struct n
 	}
 	ret = PTR_ERR(filp);
 out_close:
-	nfs4_close_state(path, state, nd->lookup.intent.open.flags);
+	nfs4_close_state(path, state, lookup->intent.open.flags);
 	return ret;
 }
 
@@ -1437,7 +1437,7 @@ nfs4_atomic_open(struct inode *dir, stru
 	res = d_add_unique(dentry, igrab(state->inode));
 	if (res != NULL)
 		dentry = res;
-	nfs4_intent_set_file(nd, &path, state);
+	nfs4_intent_set_file(&nd->lookup, &path, state);
 	return res;
 }
 
@@ -1463,14 +1463,14 @@ nfs4_open_revalidate(struct inode *dir, 
 			case -EDQUOT:
 			case -ENOSPC:
 			case -EROFS:
-				lookup_instantiate_filp(nd, (struct dentry *)state, NULL);
+				lookup_instantiate_filp(&nd->lookup, (struct dentry *)state, NULL);
 				return 1;
 			default:
 				goto out_drop;
 		}
 	}
 	if (state->inode == dentry->d_inode) {
-		nfs4_intent_set_file(nd, &path, state);
+		nfs4_intent_set_file(&nd->lookup, &path, state);
 		return 1;
 	}
 	nfs4_close_state(&path, state, openflags);
@@ -1885,10 +1885,10 @@ static int nfs4_proc_readlink(struct ino
 
 static int
 nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
-                 int flags, struct nameidata *nd)
+                 int flags, struct vfs_lookup *lookup)
 {
 	struct path path = {
-		.mnt = nd->lookup.path.mnt,
+		.mnt = lookup->path.mnt,
 		.dentry = dentry,
 	};
 	struct nfs4_state *state;
@@ -1914,8 +1914,8 @@ nfs4_proc_create(struct inode *dir, stru
 			nfs_setattr_update_inode(state->inode, sattr);
 		nfs_post_op_update_inode(state->inode, &fattr);
 	}
-	if (status == 0 && (nd->lookup.flags & LOOKUP_OPEN) != 0)
-		status = nfs4_intent_set_file(nd, &path, state);
+	if (status == 0 && (lookup->flags & LOOKUP_OPEN) != 0)
+		status = nfs4_intent_set_file(lookup, &path, state);
 	else
 		nfs4_close_state(&path, state, flags);
 out:
--- a/fs/nfs/proc.c
+++ b/fs/nfs/proc.c
@@ -187,7 +187,7 @@ static int nfs_proc_readlink(struct inod
 
 static int
 nfs_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
-		int flags, struct nameidata *nd)
+		int flags, struct vfs_lookup *lookup)
 {
 	struct nfs_fh		fhandle;
 	struct nfs_fattr	fattr;
--- a/fs/ocfs2/dlm/dlmfs.c
+++ b/fs/ocfs2/dlm/dlmfs.c
@@ -459,7 +459,7 @@ bail:
 static int dlmfs_create(struct inode *dir,
 			struct dentry *dentry,
 			int mode,
-			struct nameidata *nd)
+			struct vfs_lookup *lookup)
 {
 	int status = 0;
 	struct inode *inode;
--- a/fs/ocfs2/namei.c
+++ b/fs/ocfs2/namei.c
@@ -626,7 +626,7 @@ static int ocfs2_mkdir(struct inode *dir
 static int ocfs2_create(struct inode *dir,
 			struct dentry *dentry,
 			int mode,
-			struct nameidata *nd)
+			struct vfs_lookup *lookup)
 {
 	int ret;
 
--- a/fs/open.c
+++ b/fs/open.c
@@ -831,7 +831,7 @@ EXPORT_SYMBOL(filp_open);
 
 /**
  * lookup_instantiate_filp - instantiates the open intent filp
- * @nd: pointer to nameidata
+ * @lookup: pointer to vfs_lookup
  * @dentry: pointer to dentry
  * @open: open callback
  *
@@ -848,22 +848,24 @@ EXPORT_SYMBOL(filp_open);
  * If the open callback is set to NULL, then the standard f_op->open()
  * filesystem callback is substituted.
  */
-struct file *lookup_instantiate_filp(struct nameidata *nd, struct dentry *dentry,
+struct file *lookup_instantiate_filp(struct vfs_lookup *lookup,
+		struct dentry *dentry,
 		int (*open)(struct inode *, struct file *))
 {
-	if (IS_ERR(nd->lookup.intent.open.file))
+	if (IS_ERR(lookup->intent.open.file))
 		goto out;
 	if (IS_ERR(dentry))
 		goto out_err;
-	nd->lookup.intent.open.file = __dentry_open(dget(dentry), mntget(nd->lookup.path.mnt),
-					     nd->lookup.intent.open.flags - 1,
-					     nd->lookup.intent.open.file,
-					     open);
+	lookup->intent.open.file = __dentry_open(dget(dentry),
+						 mntget(lookup->path.mnt),
+						 lookup->intent.open.flags - 1,
+						 lookup->intent.open.file,
+						 open);
 out:
-	return nd->lookup.intent.open.file;
+	return lookup->intent.open.file;
 out_err:
-	release_open_intent(nd);
-	nd->lookup.intent.open.file = (struct file *)dentry;
+	release_open_intent(&lookup->intent.open);
+	lookup->intent.open.file = (struct file *)dentry;
 	goto out;
 }
 EXPORT_SYMBOL_GPL(lookup_instantiate_filp);
--- a/fs/qnx4/namei.c
+++ b/fs/qnx4/namei.c
@@ -142,7 +142,7 @@ out:
 
 #ifdef CONFIG_QNX4FS_RW
 int qnx4_create(struct inode *dir, struct dentry *dentry, int mode,
-		struct nameidata *nd)
+		struct vfs_lookup *lookup)
 {
 	QNX4DEBUG(("qnx4: qnx4_create\n"));
 	if (dir == NULL) {
--- a/fs/ramfs/inode.c
+++ b/fs/ramfs/inode.c
@@ -117,7 +117,7 @@ static int ramfs_mkdir(struct inode * di
 	return retval;
 }
 
-static int ramfs_create(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *nd)
+static int ramfs_create(struct inode *dir, struct dentry *dentry, int mode, struct vfs_lookup *lookup)
 {
 	return ramfs_mknod(dir, dentry, mode | S_IFREG, 0);
 }
--- a/fs/reiserfs/namei.c
+++ b/fs/reiserfs/namei.c
@@ -600,7 +600,7 @@ static int new_inode_init(struct inode *
 }
 
 static int reiserfs_create(struct inode *dir, struct dentry *dentry, int mode,
-			   struct nameidata *nd)
+			   struct vfs_lookup *lookup)
 {
 	int retval;
 	struct inode *inode;
--- a/fs/smbfs/dir.c
+++ b/fs/smbfs/dir.c
@@ -26,7 +26,7 @@ static int smb_readdir(struct file *, vo
 static int smb_dir_open(struct inode *, struct file *);
 
 static struct dentry *smb_lookup(struct inode *, struct dentry *, struct nameidata *);
-static int smb_create(struct inode *, struct dentry *, int, struct nameidata *);
+static int smb_create(struct inode *, struct dentry *, int, struct vfs_lookup *);
 static int smb_mkdir(struct inode *, struct dentry *, int);
 static int smb_rmdir(struct inode *, struct dentry *);
 static int smb_unlink(struct inode *, struct dentry *);
@@ -520,7 +520,7 @@ out_close:
 /* N.B. How should the mode argument be used? */
 static int
 smb_create(struct inode *dir, struct dentry *dentry, int mode,
-		struct nameidata *nd)
+		struct vfs_lookup *lookup)
 {
 	struct smb_sb_info *server = server_from_dentry(dentry);
 	__u16 fileid;
--- a/fs/sysv/namei.c
+++ b/fs/sysv/namei.c
@@ -80,7 +80,7 @@ static int sysv_mknod(struct inode * dir
 	return err;
 }
 
-static int sysv_create(struct inode * dir, struct dentry * dentry, int mode, struct nameidata *nd)
+static int sysv_create(struct inode * dir, struct dentry * dentry, int mode, struct vfs_lookup *lookup)
 {
 	return sysv_mknod(dir, dentry, mode, 0);
 }
--- a/fs/udf/namei.c
+++ b/fs/udf/namei.c
@@ -572,7 +572,7 @@ static int udf_delete_entry(struct inode
 }
 
 static int udf_create(struct inode *dir, struct dentry *dentry, int mode,
-		      struct nameidata *nd)
+		      struct vfs_lookup *lookup)
 {
 	struct udf_fileident_bh fibh;
 	struct inode *inode;
--- a/fs/ufs/namei.c
+++ b/fs/ufs/namei.c
@@ -77,7 +77,7 @@ static struct dentry *ufs_lookup(struct 
  * with d_instantiate(). 
  */
 static int ufs_create (struct inode * dir, struct dentry * dentry, int mode,
-		struct nameidata *nd)
+		struct vfs_lookup *lookup)
 {
 	struct inode *inode;
 	int err;
--- a/fs/vfat/namei.c
+++ b/fs/vfat/namei.c
@@ -731,7 +731,7 @@ error:
 }
 
 static int vfat_create(struct inode *dir, struct dentry *dentry, int mode,
-		       struct nameidata *nd)
+		       struct vfs_lookup *lookup)
 {
 	struct super_block *sb = dir->i_sb;
 	struct inode *inode;
--- a/fs/xfs/linux-2.6/xfs_iops.c
+++ b/fs/xfs/linux-2.6/xfs_iops.c
@@ -367,7 +367,7 @@ xfs_vn_create(
 	struct inode	*dir,
 	struct dentry	*dentry,
 	int		mode,
-	struct nameidata *nd)
+	struct vfs_lookup *lookup)
 {
 	return xfs_vn_mknod(dir, dentry, mode, 0);
 }
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1009,7 +1009,7 @@ extern void unlock_super(struct super_bl
  * VFS helper functions..
  */
 extern int vfs_permission(struct vfs_lookup *, int);
-extern int vfs_create(struct inode *, struct dentry *, int, struct nameidata *);
+extern int vfs_create(struct inode *, struct dentry *, int, struct vfs_lookup *);
 extern int vfs_mkdir(struct inode *, struct dentry *, int);
 extern int vfs_mknod(struct inode *, struct dentry *, int, dev_t);
 extern int vfs_symlink(struct inode *, struct dentry *, const char *, int);
@@ -1133,7 +1133,7 @@ struct file_operations {
 };
 
 struct inode_operations {
-	int (*create) (struct inode *,struct dentry *,int, struct nameidata *);
+	int (*create) (struct inode *,struct dentry *,int, struct vfs_lookup *);
 	struct dentry * (*lookup) (struct inode *,struct dentry *, struct nameidata *);
 	int (*link) (struct dentry *,struct inode *,struct dentry *);
 	int (*unlink) (struct inode *,struct dentry *);
--- a/include/linux/namei.h
+++ b/include/linux/namei.h
@@ -79,10 +79,11 @@ extern void path_release_on_umount(struc
 
 extern int __user_path_lookup_open(const char __user *, unsigned lookup_flags, struct nameidata *nd, int open_flags);
 extern int path_lookup_open(int dfd, const char *name, unsigned lookup_flags, struct nameidata *, int open_flags);
-extern struct file *lookup_instantiate_filp(struct nameidata *nd, struct dentry *dentry,
+extern struct file *lookup_instantiate_filp(struct vfs_lookup *lookup,
+		struct dentry *dentry,
 		int (*open)(struct inode *, struct file *));
 extern struct file *nameidata_to_filp(struct nameidata *nd, int flags);
-extern void release_open_intent(struct nameidata *);
+extern void release_open_intent(struct open_intent *);
 
 extern struct dentry * lookup_one_len(const char *, struct dentry *, int);
 extern struct dentry *lookup_one_len_kern(const char *, struct dentry *, int);
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -789,7 +789,7 @@ struct nfs_rpc_ops {
 	int	(*readlink)(struct inode *, struct page *, unsigned int,
 			    unsigned int);
 	int	(*create)  (struct inode *, struct dentry *,
-			    struct iattr *, int, struct nameidata *);
+			    struct iattr *, int, struct vfs_lookup *);
 	int	(*remove)  (struct inode *, struct qstr *);
 	void	(*unlink_setup)  (struct rpc_message *, struct inode *dir);
 	int	(*unlink_done) (struct rpc_task *, struct inode *);
--- a/include/linux/qnx4_fs.h
+++ b/include/linux/qnx4_fs.h
@@ -122,7 +122,7 @@ extern const struct file_operations qnx4
 extern const struct file_operations qnx4_dir_operations;
 extern int qnx4_is_free(struct super_block *sb, long block);
 extern int qnx4_set_bitmap(struct super_block *sb, long block, int busy);
-extern int qnx4_create(struct inode *inode, struct dentry *dentry, int mode, struct nameidata *nd);
+extern int qnx4_create(struct inode *inode, struct dentry *dentry, int mode, struct vfs_lookup *lookup);
 extern void qnx4_truncate(struct inode *inode);
 extern void qnx4_free_inode(struct inode *inode);
 extern int qnx4_unlink(struct inode *dir, struct dentry *dentry);
--- a/ipc/mqueue.c
+++ b/ipc/mqueue.c
@@ -266,7 +266,7 @@ static void mqueue_delete_inode(struct i
 }
 
 static int mqueue_create(struct inode *dir, struct dentry *dentry,
-				int mode, struct nameidata *nd)
+				int mode, struct vfs_lookup *lookup)
 {
 	struct inode *inode;
 	struct mq_attr *attr = dentry->d_fsdata;
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -1749,7 +1749,7 @@ static int shmem_mkdir(struct inode *dir
 }
 
 static int shmem_create(struct inode *dir, struct dentry *dentry, int mode,
-		struct nameidata *nd)
+		struct vfs_lookup *lookup)
 {
 	return shmem_mknod(dir, dentry, mode | S_IFREG, 0);
 }


^ permalink raw reply	[flat|nested] 35+ messages in thread

* [RFC 08/10] Pass no NULL vfs_lookup to vfs_create
  2007-08-08 17:16 [RFC 00/10] Split up struct nameidata (take 3) Andreas Gruenbacher
                   ` (6 preceding siblings ...)
  2007-08-08 17:16 ` [RFC 07/10] Pass no unnecessary information to iop->create Andreas Gruenbacher
@ 2007-08-08 17:16 ` Andreas Gruenbacher
  2007-08-08 19:36   ` Christoph Hellwig
  2007-08-08 17:16 ` [RFC 09/10] Pass no unnecessary information to dop->d_revalidate Andreas Gruenbacher
  2007-08-08 17:16 ` [RFC 10/10] Pass no unnecessary information to iop->lookup Andreas Gruenbacher
  9 siblings, 1 reply; 35+ messages in thread
From: Andreas Gruenbacher @ 2007-08-08 17:16 UTC (permalink / raw)
  To: linux-kernel
  Cc: John Johansen, Jan Blunck, Erez Zadok, Josef 'Jeff' Sipek

[-- Attachment #1: vfs_create-nameidata.diff --]
[-- Type: text/plain, Size: 7865 bytes --]

Never pass a NULL vfs_lookup to vfs_create() or iop->create by creating
temporary vfs_lookup objects where needed. Remove the obsolete NULL
checks.

Signed-off-by: Andreas Gruenbacher <ag@bestbits.at>

---
 fs/9p/vfs_inode.c |    4 ++--
 fs/cifs/dir.c     |    5 ++---
 fs/nfsd/vfs.c     |   36 +++++++++++++++++++++---------------
 ipc/mqueue.c      |   23 ++++++++++++++---------
 4 files changed, 39 insertions(+), 29 deletions(-)

--- a/fs/9p/vfs_inode.c
+++ b/fs/9p/vfs_inode.c
@@ -478,7 +478,7 @@ v9fs_vfs_create(struct inode *dir, struc
 	fid = NULL;
 	v9ses = v9fs_inode2v9ses(dir);
 	perm = unixmode2p9mode(v9ses, mode);
-	if (lookup && lookup->flags & LOOKUP_OPEN)
+	if (lookup->flags & LOOKUP_OPEN)
 		flags = lookup->intent.open.flags - 1;
 	else
 		flags = O_RDWR;
@@ -492,7 +492,7 @@ v9fs_vfs_create(struct inode *dir, struc
 	}
 
 	/* if we are opening a file, assign the open fid to the file */
-	if (lookup && lookup->flags & LOOKUP_OPEN) {
+	if (lookup->flags & LOOKUP_OPEN) {
 		filp = lookup_instantiate_filp(lookup, dentry,
 					       v9fs_open_created);
 		if (IS_ERR(filp)) {
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -153,7 +153,7 @@ cifs_create(struct inode *inode, struct 
 		return -ENOMEM;
 	}
 
-	if (lookup && (lookup->flags & LOOKUP_OPEN)) {
+	if (lookup->flags & LOOKUP_OPEN) {
 		int oflags = lookup->intent.open.flags;
 
 		desiredAccess = 0;
@@ -263,8 +263,7 @@ cifs_create(struct inode *inode, struct 
 				direntry->d_op = &cifs_dentry_ops;
 			d_instantiate(direntry, newinode);
 		}
-		if ((!lookup /* nfsd case - nfs srv does not set lookup */) ||
-			((lookup->flags & LOOKUP_OPEN) == FALSE)) {
+		if (!(lookup->flags & LOOKUP_OPEN)) {
 			/* mknod case - do not leave file open */
 			CIFSSMBClose(xid, pTcon, fileHandle);
 		} else if (newinode) {
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -1139,7 +1139,8 @@ nfsd_create(struct svc_rqst *rqstp, stru
 		char *fname, int flen, struct iattr *iap,
 		int type, dev_t rdev, struct svc_fh *resfhp)
 {
-	struct dentry	*dentry, *dchild = NULL;
+	struct vfs_lookup lookup;
+	struct dentry	*dchild = NULL;
 	struct inode	*dirp;
 	__be32		err;
 	int		host_err;
@@ -1155,8 +1156,10 @@ nfsd_create(struct svc_rqst *rqstp, stru
 	if (err)
 		goto out;
 
-	dentry = fhp->fh_dentry;
-	dirp = dentry->d_inode;
+	lookup.path.dentry = fhp->fh_dentry;
+	lookup.path.mnt = fhp->fh_export->ex_mnt;
+	lookup.flags = 0;
+	dirp = lookup.path.dentry->d_inode;
 
 	err = nfserr_notdir;
 	if(!dirp->i_op || !dirp->i_op->lookup)
@@ -1168,7 +1171,7 @@ nfsd_create(struct svc_rqst *rqstp, stru
 	if (!resfhp->fh_dentry) {
 		/* called from nfsd_proc_mkdir, or possibly nfsd3_proc_create */
 		fh_lock_nested(fhp, I_MUTEX_PARENT);
-		dchild = lookup_one_len(fname, dentry, flen);
+		dchild = lookup_one_len(fname, lookup.path.dentry, flen);
 		host_err = PTR_ERR(dchild);
 		if (IS_ERR(dchild))
 			goto out_nfserr;
@@ -1182,8 +1185,8 @@ nfsd_create(struct svc_rqst *rqstp, stru
 			/* not actually possible */
 			printk(KERN_ERR
 				"nfsd_create: parent %s/%s not locked!\n",
-				dentry->d_parent->d_name.name,
-				dentry->d_name.name);
+				lookup.path.dentry->d_parent->d_name.name,
+				lookup.path.dentry->d_name.name);
 			err = nfserr_io;
 			goto out;
 		}
@@ -1194,7 +1197,7 @@ nfsd_create(struct svc_rqst *rqstp, stru
 	err = nfserr_exist;
 	if (dchild->d_inode) {
 		dprintk("nfsd_create: dentry %s/%s not negative!\n",
-			dentry->d_name.name, dchild->d_name.name);
+			lookup.path.dentry->d_name.name, dchild->d_name.name);
 		goto out; 
 	}
 
@@ -1208,7 +1211,7 @@ nfsd_create(struct svc_rqst *rqstp, stru
 	err = 0;
 	switch (type) {
 	case S_IFREG:
-		host_err = vfs_create(dirp, dchild, iap->ia_mode, NULL);
+		host_err = vfs_create(dirp, dchild, iap->ia_mode, &lookup);
 		break;
 	case S_IFDIR:
 		host_err = vfs_mkdir(dirp, dchild, iap->ia_mode);
@@ -1227,7 +1230,7 @@ nfsd_create(struct svc_rqst *rqstp, stru
 		goto out_nfserr;
 
 	if (EX_ISSYNC(fhp->fh_export)) {
-		err = nfserrno(nfsd_sync_dir(dentry));
+		err = nfserrno(nfsd_sync_dir(lookup.path.dentry));
 		write_inode_now(dchild->d_inode, 1);
 	}
 
@@ -1267,7 +1270,8 @@ nfsd_create_v3(struct svc_rqst *rqstp, s
 		struct svc_fh *resfhp, int createmode, u32 *verifier,
 	        int *truncp, int *created)
 {
-	struct dentry	*dentry, *dchild = NULL;
+	struct vfs_lookup lookup;
+	struct dentry	*dchild = NULL;
 	struct inode	*dirp;
 	__be32		err;
 	int		host_err;
@@ -1285,8 +1289,10 @@ nfsd_create_v3(struct svc_rqst *rqstp, s
 	if (err)
 		goto out;
 
-	dentry = fhp->fh_dentry;
-	dirp = dentry->d_inode;
+	lookup.path.dentry = fhp->fh_dentry;
+	lookup.path.mnt = fhp->fh_export->ex_mnt;
+	lookup.flags = 0;
+	dirp = lookup.path.dentry->d_inode;
 
 	/* Get all the sanity checks out of the way before
 	 * we lock the parent. */
@@ -1298,7 +1304,7 @@ nfsd_create_v3(struct svc_rqst *rqstp, s
 	/*
 	 * Compose the response file handle.
 	 */
-	dchild = lookup_one_len(fname, dentry, flen);
+	dchild = lookup_one_len(fname, lookup.path.dentry, flen);
 	host_err = PTR_ERR(dchild);
 	if (IS_ERR(dchild))
 		goto out_nfserr;
@@ -1352,14 +1358,14 @@ nfsd_create_v3(struct svc_rqst *rqstp, s
 		goto out;
 	}
 
-	host_err = vfs_create(dirp, dchild, iap->ia_mode, NULL);
+	host_err = vfs_create(dirp, dchild, iap->ia_mode, &lookup);
 	if (host_err < 0)
 		goto out_nfserr;
 	if (created)
 		*created = 1;
 
 	if (EX_ISSYNC(fhp->fh_export)) {
-		err = nfserrno(nfsd_sync_dir(dentry));
+		err = nfserrno(nfsd_sync_dir(lookup.path.dentry));
 		/* setattr will sync the child (or not) */
 	}
 
--- a/ipc/mqueue.c
+++ b/ipc/mqueue.c
@@ -599,9 +599,11 @@ static int mq_attr_ok(struct mq_attr *at
 /*
  * Invoked when creating a new queue via sys_mq_open
  */
-static struct file *do_create(struct dentry *dir, struct dentry *dentry,
-			int oflag, mode_t mode, struct mq_attr __user *u_attr)
+static struct file *do_create(struct vfs_lookup *lookup, int oflag, mode_t mode,
+			      struct mq_attr __user *u_attr)
 {
+	struct dentry *dir = mqueue_mnt->mnt_root;
+	struct dentry *dentry = lookup->path.dentry;
 	struct mq_attr attr;
 	int ret;
 
@@ -617,7 +619,7 @@ static struct file *do_create(struct den
 	}
 
 	mode &= ~current->fs->umask;
-	ret = vfs_create(dir->d_inode, dentry, mode, NULL);
+	ret = vfs_create(dir->d_inode, dentry, mode, lookup);
 	dentry->d_fsdata = NULL;
 	if (ret)
 		goto out;
@@ -631,10 +633,11 @@ out:
 }
 
 /* Opens existing queue */
-static struct file *do_open(struct dentry *dentry, int oflag)
+static struct file *do_open(struct vfs_lookup *lookup, int oflag)
 {
 static int oflag2acc[O_ACCMODE] = { MAY_READ, MAY_WRITE,
 					MAY_READ | MAY_WRITE };
+	struct dentry *dentry = lookup->path.dentry;
 
 	if ((oflag & O_ACCMODE) == (O_RDWR | O_WRONLY)) {
 		dput(dentry);
@@ -654,6 +657,7 @@ static int oflag2acc[O_ACCMODE] = { MAY_
 asmlinkage long sys_mq_open(const char __user *u_name, int oflag, mode_t mode,
 				struct mq_attr __user *u_attr)
 {
+	struct vfs_lookup lookup;
 	struct dentry *dentry;
 	struct file *filp;
 	char *name;
@@ -676,7 +680,9 @@ asmlinkage long sys_mq_open(const char _
 		error = PTR_ERR(dentry);
 		goto out_err;
 	}
-	mntget(mqueue_mnt);
+	lookup.path.mnt = mntget(mqueue_mnt);
+	lookup.path.dentry = dentry;
+	lookup.flags = 0;
 
 	if (oflag & O_CREAT) {
 		if (dentry->d_inode) {	/* entry already exists */
@@ -684,17 +690,16 @@ asmlinkage long sys_mq_open(const char _
 			error = -EEXIST;
 			if (oflag & O_EXCL)
 				goto out;
-			filp = do_open(dentry, oflag);
+			filp = do_open(&lookup, oflag);
 		} else {
-			filp = do_create(mqueue_mnt->mnt_root, dentry,
-						oflag, mode, u_attr);
+			filp = do_create(&lookup, oflag, mode, u_attr);
 		}
 	} else {
 		error = -ENOENT;
 		if (!dentry->d_inode)
 			goto out;
 		audit_inode(name, dentry->d_inode);
-		filp = do_open(dentry, oflag);
+		filp = do_open(&lookup, oflag);
 	}
 
 	if (IS_ERR(filp)) {


^ permalink raw reply	[flat|nested] 35+ messages in thread

* [RFC 09/10] Pass no unnecessary information to dop->d_revalidate
  2007-08-08 17:16 [RFC 00/10] Split up struct nameidata (take 3) Andreas Gruenbacher
                   ` (7 preceding siblings ...)
  2007-08-08 17:16 ` [RFC 08/10] Pass no NULL vfs_lookup to vfs_create Andreas Gruenbacher
@ 2007-08-08 17:16 ` Andreas Gruenbacher
  2007-08-08 17:16 ` [RFC 10/10] Pass no unnecessary information to iop->lookup Andreas Gruenbacher
  9 siblings, 0 replies; 35+ messages in thread
From: Andreas Gruenbacher @ 2007-08-08 17:16 UTC (permalink / raw)
  To: linux-kernel
  Cc: John Johansen, Jan Blunck, Erez Zadok, Josef 'Jeff' Sipek

[-- Attachment #1: d_revalidate-args.diff --]
[-- Type: text/plain, Size: 21651 bytes --]

dop->d_revalidate does not need a full nameidata. Pass a struct vfs_lookup
instead.

Signed-off-by: Andreas Gruenbacher <ag@bestbits.at>

---
 fs/afs/dir.c           |    4 ++--
 fs/autofs/root.c       |    4 ++--
 fs/autofs4/root.c      |   12 ++++++------
 fs/cifs/dir.c          |    2 +-
 fs/coda/dir.c          |    4 ++--
 fs/ecryptfs/dentry.c   |   20 +++++++++-----------
 fs/fuse/dir.c          |    3 ++-
 fs/gfs2/ops_dentry.c   |    4 ++--
 fs/hfs/sysdep.c        |    3 ++-
 fs/namei.c             |   13 +++++++------
 fs/ncpfs/dir.c         |    8 ++++----
 fs/nfs/dir.c           |   42 ++++++++++++++++++++++--------------------
 fs/nfs/nfs4_fs.h       |    2 +-
 fs/nfs/nfs4proc.c      |    8 ++++----
 fs/ocfs2/dcache.c      |    2 +-
 fs/proc/base.c         |    7 ++++---
 fs/proc/proc_sysctl.c  |    2 +-
 fs/smbfs/dir.c         |    4 ++--
 fs/vfat/namei.c        |    6 +++---
 include/linux/dcache.h |    3 ++-
 20 files changed, 79 insertions(+), 74 deletions(-)

--- a/fs/afs/dir.c
+++ b/fs/afs/dir.c
@@ -23,7 +23,7 @@ static struct dentry *afs_lookup(struct 
 				 struct nameidata *nd);
 static int afs_dir_open(struct inode *inode, struct file *file);
 static int afs_readdir(struct file *file, void *dirent, filldir_t filldir);
-static int afs_d_revalidate(struct dentry *dentry, struct nameidata *nd);
+static int afs_d_revalidate(struct dentry *dentry, struct vfs_lookup *lookup);
 static int afs_d_delete(struct dentry *dentry);
 static void afs_d_release(struct dentry *dentry);
 static int afs_lookup_filldir(void *_cookie, const char *name, int nlen,
@@ -560,7 +560,7 @@ static struct dentry *afs_lookup(struct 
  * - NOTE! the hit can be a negative hit too, so we can't assume we have an
  *   inode
  */
-static int afs_d_revalidate(struct dentry *dentry, struct nameidata *nd)
+static int afs_d_revalidate(struct dentry *dentry, struct vfs_lookup *lookup)
 {
 	struct afs_vnode *vnode, *dir;
 	struct afs_fid fid;
--- a/fs/autofs/root.c
+++ b/fs/autofs/root.c
@@ -145,7 +145,7 @@ static int try_to_fill_dentry(struct den
  * yet completely filled in, and revalidate has to delay such
  * lookups..
  */
-static int autofs_revalidate(struct dentry * dentry, struct nameidata *nd)
+static int autofs_revalidate(struct dentry * dentry, struct vfs_lookup *lookup)
 {
 	struct inode * dir;
 	struct autofs_sb_info *sbi;
@@ -233,7 +233,7 @@ static struct dentry *autofs_root_lookup
 	d_add(dentry, NULL);
 
 	mutex_unlock(&dir->i_mutex);
-	autofs_revalidate(dentry, nd);
+	autofs_revalidate(dentry, &nd->lookup);
 	mutex_lock(&dir->i_mutex);
 
 	/*
--- a/fs/autofs4/root.c
+++ b/fs/autofs4/root.c
@@ -122,7 +122,7 @@ static int autofs4_dir_open(struct inode
 
 	status = -ENOENT;
 	if (!d_mountpoint(dentry) && dentry->d_op && dentry->d_op->d_revalidate) {
-		struct nameidata nd;
+		struct vfs_lookup lookup;
 		int empty, ret;
 
 		/* In case there are stale directory dentrys from a failed mount */
@@ -133,8 +133,8 @@ static int autofs4_dir_open(struct inode
 		if (!empty)
 			d_invalidate(dentry);
 
-		nd.lookup.flags = LOOKUP_DIRECTORY;
-		ret = (dentry->d_op->d_revalidate)(dentry, &nd);
+		lookup.flags = LOOKUP_DIRECTORY;
+		ret = (dentry->d_op->d_revalidate)(dentry, &lookup);
 
 		if (ret <= 0) {
 			if (ret < 0)
@@ -392,12 +392,12 @@ out_error:
  * yet completely filled in, and revalidate has to delay such
  * lookups..
  */
-static int autofs4_revalidate(struct dentry *dentry, struct nameidata *nd)
+static int autofs4_revalidate(struct dentry *dentry, struct vfs_lookup *lookup)
 {
 	struct inode *dir = dentry->d_parent->d_inode;
 	struct autofs_sb_info *sbi = autofs4_sbi(dir->i_sb);
 	int oz_mode = autofs4_oz_mode(sbi);
-	int flags = nd ? nd->lookup.flags : 0;
+	int flags = lookup ? lookup->flags : 0;
 	int status = 1;
 
 	/* Pending dentry */
@@ -627,7 +627,7 @@ static struct dentry *autofs4_lookup(str
 
 	if (dentry->d_op && dentry->d_op->d_revalidate) {
 		mutex_unlock(&dir->i_mutex);
-		(dentry->d_op->d_revalidate)(dentry, nd);
+		(dentry->d_op->d_revalidate)(dentry, &nd->lookup);
 		mutex_lock(&dir->i_mutex);
 	}
 
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -531,7 +531,7 @@ cifs_lookup(struct inode *parent_dir_ino
 }
 
 static int
-cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd)
+cifs_d_revalidate(struct dentry *direntry, struct vfs_lookup *lookup)
 {
 	int isValid = 1;
 
--- a/fs/coda/dir.c
+++ b/fs/coda/dir.c
@@ -45,7 +45,7 @@ static int coda_rename(struct inode *old
 static int coda_readdir(struct file *file, void *buf, filldir_t filldir);
 
 /* dentry ops */
-static int coda_dentry_revalidate(struct dentry *de, struct nameidata *nd);
+static int coda_dentry_revalidate(struct dentry *de, struct vfs_lookup *lookup);
 static int coda_dentry_delete(struct dentry *);
 
 /* support routines */
@@ -583,7 +583,7 @@ out:
 }
 
 /* called when a cache lookup succeeds */
-static int coda_dentry_revalidate(struct dentry *de, struct nameidata *nd)
+static int coda_dentry_revalidate(struct dentry *de, struct vfs_lookup *lookup)
 {
 	struct inode *inode = de->d_inode;
 	struct coda_inode_info *cii;
--- a/fs/ecryptfs/dentry.c
+++ b/fs/ecryptfs/dentry.c
@@ -31,7 +31,7 @@
 /**
  * ecryptfs_d_revalidate - revalidate an ecryptfs dentry
  * @dentry: The ecryptfs dentry
- * @nd: The associated nameidata
+ * @lookup: The associated vfs_lookup
  *
  * Called when the VFS needs to revalidate a dentry. This
  * is called whenever a name lookup finds a dentry in the
@@ -41,23 +41,21 @@
  * Returns 1 if valid, 0 otherwise.
  *
  */
-static int ecryptfs_d_revalidate(struct dentry *dentry, struct nameidata *nd)
+static int ecryptfs_d_revalidate(struct dentry *dentry,
+				 struct vfs_lookup *lookup)
 {
 	struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry);
 	struct vfsmount *lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry);
-	struct dentry *dentry_save;
-	struct vfsmount *vfsmount_save;
+	struct path path_save;
 	int rc = 1;
 
 	if (!lower_dentry->d_op || !lower_dentry->d_op->d_revalidate)
 		goto out;
-	dentry_save = nd->lookup.path.dentry;
-	vfsmount_save = nd->lookup.path.mnt;
-	nd->lookup.path.dentry = lower_dentry;
-	nd->lookup.path.mnt = lower_mnt;
-	rc = lower_dentry->d_op->d_revalidate(lower_dentry, nd);
-	nd->lookup.path.dentry = dentry_save;
-	nd->lookup.path.mnt = vfsmount_save;
+	path_save = lookup->path;
+	lookup->path.dentry = lower_dentry;
+	lookup->path.mnt = lower_mnt;
+	rc = lower_dentry->d_op->d_revalidate(lower_dentry, lookup);
+	lookup->path = path_save;
 	if (dentry->d_inode) {
 		struct inode *lower_inode =
 			ecryptfs_inode_to_lower(dentry->d_inode);
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -127,7 +127,8 @@ static void fuse_lookup_init(struct fuse
  * the lookup once more.  If the lookup results in the same inode,
  * then refresh the attributes, timeouts and mark the dentry valid.
  */
-static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd)
+static int fuse_dentry_revalidate(struct dentry *entry,
+				  struct vfs_lookup *lookup)
 {
 	struct inode *inode = entry->d_inode;
 
--- a/fs/gfs2/ops_dentry.c
+++ b/fs/gfs2/ops_dentry.c
@@ -26,7 +26,7 @@
 /**
  * gfs2_drevalidate - Check directory lookup consistency
  * @dentry: the mapping to check
- * @nd:
+ * @lookup:
  *
  * Check to make sure the lookup necessary to arrive at this inode from its
  * parent is still good.
@@ -34,7 +34,7 @@
  * Returns: 1 if the dentry is ok, 0 if it isn't
  */
 
-static int gfs2_drevalidate(struct dentry *dentry, struct nameidata *nd)
+static int gfs2_drevalidate(struct dentry *dentry, struct vfs_lookup *lookup)
 {
 	struct dentry *parent = dget_parent(dentry);
 	struct gfs2_sbd *sdp = GFS2_SB(parent->d_inode);
--- a/fs/hfs/sysdep.c
+++ b/fs/hfs/sysdep.c
@@ -12,7 +12,8 @@
 
 /* dentry case-handling: just lowercase everything */
 
-static int hfs_revalidate_dentry(struct dentry *dentry, struct nameidata *nd)
+static int hfs_revalidate_dentry(struct dentry *dentry,
+				 struct vfs_lookup *lookup)
 {
 	struct inode *inode = dentry->d_inode;
 	int diff;
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -380,9 +380,9 @@ void release_open_intent(struct open_int
 }
 
 static inline struct dentry *
-do_revalidate(struct dentry *dentry, struct nameidata *nd)
+do_revalidate(struct dentry *dentry, struct vfs_lookup *lookup)
 {
-	int status = dentry->d_op->d_revalidate(dentry, nd);
+	int status = dentry->d_op->d_revalidate(dentry, lookup);
 	if (unlikely(status <= 0)) {
 		/*
 		 * The dentry failed validation.
@@ -418,7 +418,7 @@ static struct dentry * cached_lookup(str
 		dentry = d_lookup(parent, name);
 
 	if (dentry && dentry->d_op && dentry->d_op->d_revalidate)
-		dentry = do_revalidate(dentry, nd);
+		dentry = do_revalidate(dentry, &nd->lookup);
 
 	return dentry;
 }
@@ -511,7 +511,7 @@ static struct dentry * real_lookup(struc
 	 */
 	mutex_unlock(&dir->i_mutex);
 	if (result->d_op && result->d_op->d_revalidate) {
-		result = do_revalidate(result, nd);
+		result = do_revalidate(result, &nd->lookup);
 		if (!result)
 			result = ERR_PTR(-ENOENT);
 	}
@@ -792,7 +792,7 @@ need_lookup:
 	goto done;
 
 need_revalidate:
-	dentry = do_revalidate(dentry, nd);
+	dentry = do_revalidate(dentry, &nd->lookup);
 	if (!dentry)
 		goto need_lookup;
 	if (IS_ERR(dentry))
@@ -982,7 +982,8 @@ return_reval:
 		    (nd->lookup.path.dentry->d_sb->s_type->fs_flags & FS_REVAL_DOT)) {
 			err = -ESTALE;
 			/* Note: we do not d_invalidate() */
-			if (!nd->lookup.path.dentry->d_op->d_revalidate(nd->lookup.path.dentry, nd))
+			if (!nd->lookup.path.dentry->d_op->d_revalidate(
+					nd->lookup.path.dentry, &nd->lookup))
 				break;
 		}
 return_base:
--- a/fs/ncpfs/dir.c
+++ b/fs/ncpfs/dir.c
@@ -74,7 +74,7 @@ const struct inode_operations ncp_dir_in
 /*
  * Dentry operations routines
  */
-static int ncp_lookup_validate(struct dentry *, struct nameidata *);
+static int ncp_lookup_validate(struct dentry *, struct vfs_lookup *);
 static int ncp_hash_dentry(struct dentry *, struct qstr *);
 static int ncp_compare_dentry (struct dentry *, struct qstr *, struct qstr *);
 static int ncp_delete_dentry(struct dentry *);
@@ -266,7 +266,7 @@ leave_me:;
 
 
 static int
-__ncp_lookup_validate(struct dentry * dentry, struct nameidata *nd)
+__ncp_lookup_validate(struct dentry * dentry, struct vfs_lookup *lookup)
 {
 	struct ncp_server *server;
 	struct dentry *parent;
@@ -336,11 +336,11 @@ finished:
 }
 
 static int
-ncp_lookup_validate(struct dentry * dentry, struct nameidata *nd)
+ncp_lookup_validate(struct dentry * dentry, struct vfs_lookup *lookup)
 {
 	int res;
 	lock_kernel();
-	res = __ncp_lookup_validate(dentry, nd);
+	res = __ncp_lookup_validate(dentry, lookup);
 	unlock_kernel();
 	return res;
 }
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -703,16 +703,16 @@ static inline unsigned int nfs_lookup_ch
  *
  */
 static inline
-int nfs_lookup_verify_inode(struct inode *inode, struct nameidata *nd)
+int nfs_lookup_verify_inode(struct inode *inode, struct vfs_lookup *lookup)
 {
 	struct nfs_server *server = NFS_SERVER(inode);
 
-	if (nd != NULL) {
+	if (lookup) {
 		/* VFS wants an on-the-wire revalidation */
-		if (nd->lookup.flags & LOOKUP_REVAL)
+		if (lookup->flags & LOOKUP_REVAL)
 			goto out_force;
 		/* This is an open(2) */
-		if (nfs_lookup_check_intent(&nd->lookup, LOOKUP_OPEN) != 0 &&
+		if (nfs_lookup_check_intent(lookup, LOOKUP_OPEN) != 0 &&
 				!(server->flags & NFS_MOUNT_NOCTO) &&
 				(S_ISREG(inode->i_mode) ||
 				 S_ISDIR(inode->i_mode)))
@@ -732,10 +732,10 @@ out_force:
  */
 static inline
 int nfs_neg_need_reval(struct inode *dir, struct dentry *dentry,
-		       struct nameidata *nd)
+		       struct vfs_lookup *lookup)
 {
 	/* Don't revalidate a negative dentry if we're creating a new file */
-	if (nd != NULL && nfs_lookup_check_intent(&nd->lookup, LOOKUP_CREATE) != 0)
+	if (lookup && nfs_lookup_check_intent(lookup, LOOKUP_CREATE) != 0)
 		return 0;
 	return !nfs_check_verifier(dir, dentry);
 }
@@ -751,7 +751,8 @@ int nfs_neg_need_reval(struct inode *dir
  * If the parent directory is seen to have changed, we throw out the
  * cached dentry and do a new lookup.
  */
-static int nfs_lookup_revalidate(struct dentry * dentry, struct nameidata *nd)
+static int nfs_lookup_revalidate(struct dentry *dentry,
+				 struct vfs_lookup *lookup)
 {
 	struct inode *dir;
 	struct inode *inode;
@@ -772,7 +773,7 @@ static int nfs_lookup_revalidate(struct 
 		goto out_zap_parent;
 
 	if (!inode) {
-		if (nfs_neg_need_reval(dir, dentry, nd))
+		if (nfs_neg_need_reval(dir, dentry, lookup))
 			goto out_bad;
 		goto out_valid;
 	}
@@ -786,7 +787,7 @@ static int nfs_lookup_revalidate(struct 
 
 	/* Force a full look up iff the parent directory has changed */
 	if (nfs_check_verifier(dir, dentry)) {
-		if (nfs_lookup_verify_inode(inode, nd))
+		if (nfs_lookup_verify_inode(inode, lookup))
 			goto out_zap_parent;
 		goto out_valid;
 	}
@@ -977,7 +978,7 @@ out:
 }
 
 #ifdef CONFIG_NFS_V4
-static int nfs_open_revalidate(struct dentry *, struct nameidata *);
+static int nfs_open_revalidate(struct dentry *, struct vfs_lookup *);
 
 struct dentry_operations nfs4_dentry_operations = {
 	.d_revalidate	= nfs_open_revalidate,
@@ -989,15 +990,16 @@ struct dentry_operations nfs4_dentry_ope
  * Use intent information to determine whether we need to substitute
  * the NFSv4-style stateful OPEN for the LOOKUP call
  */
-static int is_atomic_open(struct inode *dir, struct nameidata *nd)
+static int is_atomic_open(struct inode *dir, struct vfs_lookup *lookup)
 {
-	if (nd == NULL || nfs_lookup_check_intent(&nd->lookup, LOOKUP_OPEN) == 0)
+	if (!lookup || nfs_lookup_check_intent(lookup, LOOKUP_OPEN) == 0)
 		return 0;
 	/* NFS does not (yet) have a stateful open for directories */
-	if (nd->lookup.flags & LOOKUP_DIRECTORY)
+	if (lookup->flags & LOOKUP_DIRECTORY)
 		return 0;
 	/* Are we trying to write to a read only partition? */
-	if (IS_RDONLY(dir) && (nd->lookup.intent.open.flags & (O_CREAT|O_TRUNC|FMODE_WRITE)))
+	if (IS_RDONLY(dir) && (lookup->intent.open.flags &
+			       (O_CREAT|O_TRUNC|FMODE_WRITE)))
 		return 0;
 	return 1;
 }
@@ -1011,7 +1013,7 @@ static struct dentry *nfs_atomic_lookup(
 			dir->i_sb->s_id, dir->i_ino, dentry->d_name.name);
 
 	/* Check that we are indeed trying to open this file */
-	if (!is_atomic_open(dir, nd))
+	if (!is_atomic_open(dir, &nd->lookup))
 		goto no_open;
 
 	if (dentry->d_name.len > NFS_SERVER(dir)->namelen) {
@@ -1071,7 +1073,7 @@ no_open:
 	return nfs_lookup(dir, dentry, nd);
 }
 
-static int nfs_open_revalidate(struct dentry *dentry, struct nameidata *nd)
+static int nfs_open_revalidate(struct dentry *dentry, struct vfs_lookup *lookup)
 {
 	struct dentry *parent = NULL;
 	struct inode *inode = dentry->d_inode;
@@ -1081,7 +1083,7 @@ static int nfs_open_revalidate(struct de
 
 	parent = dget_parent(dentry);
 	dir = parent->d_inode;
-	if (!is_atomic_open(dir, nd))
+	if (!is_atomic_open(dir, lookup))
 		goto no_open;
 	/* We can't create new files in nfs_open_revalidate(), so we
 	 * optimize away revalidation of negative dentries.
@@ -1091,7 +1093,7 @@ static int nfs_open_revalidate(struct de
 	/* NFS only supports OPEN on regular files */
 	if (!S_ISREG(inode->i_mode))
 		goto no_open;
-	openflags = nd->lookup.intent.open.flags;
+	openflags = lookup->intent.open.flags;
 	/* We cannot do exclusive creation on a positive dentry */
 	if ((openflags & (O_CREAT|O_EXCL)) == (O_CREAT|O_EXCL))
 		goto no_open;
@@ -1105,7 +1107,7 @@ static int nfs_open_revalidate(struct de
 	 */
 	lock_kernel();
 	verifier = nfs_save_change_attribute(dir);
-	ret = nfs4_open_revalidate(dir, dentry, openflags, nd);
+	ret = nfs4_open_revalidate(dir, dentry, openflags, lookup);
 	if (!ret)
 		nfs_refresh_verifier(dentry, verifier);
 	unlock_kernel();
@@ -1118,7 +1120,7 @@ no_open:
 	dput(parent);
 	if (inode != NULL && nfs_have_delegation(inode, FMODE_READ))
 		return 1;
-	return nfs_lookup_revalidate(dentry, nd);
+	return nfs_lookup_revalidate(dentry, lookup);
 }
 #endif /* CONFIG_NFSV4 */
 
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -180,7 +180,7 @@ extern int nfs4_proc_async_renew(struct 
 extern int nfs4_proc_renew(struct nfs_client *, struct rpc_cred *);
 extern int nfs4_do_close(struct path *path, struct nfs4_state *state);
 extern struct dentry *nfs4_atomic_open(struct inode *, struct dentry *, struct nameidata *);
-extern int nfs4_open_revalidate(struct inode *, struct dentry *, int, struct nameidata *);
+extern int nfs4_open_revalidate(struct inode *, struct dentry *, int, struct vfs_lookup *);
 extern int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle);
 extern int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name,
 		struct nfs4_fs_locations *fs_locations, struct page *page);
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -1442,10 +1442,10 @@ nfs4_atomic_open(struct inode *dir, stru
 }
 
 int
-nfs4_open_revalidate(struct inode *dir, struct dentry *dentry, int openflags, struct nameidata *nd)
+nfs4_open_revalidate(struct inode *dir, struct dentry *dentry, int openflags, struct vfs_lookup *lookup)
 {
 	struct path path = {
-		.mnt = nd->lookup.path.mnt,
+		.mnt = lookup->path.mnt,
 		.dentry = dentry,
 	};
 	struct rpc_cred *cred;
@@ -1463,14 +1463,14 @@ nfs4_open_revalidate(struct inode *dir, 
 			case -EDQUOT:
 			case -ENOSPC:
 			case -EROFS:
-				lookup_instantiate_filp(&nd->lookup, (struct dentry *)state, NULL);
+				lookup_instantiate_filp(lookup, (struct dentry *)state, NULL);
 				return 1;
 			default:
 				goto out_drop;
 		}
 	}
 	if (state->inode == dentry->d_inode) {
-		nfs4_intent_set_file(&nd->lookup, &path, state);
+		nfs4_intent_set_file(lookup, &path, state);
 		return 1;
 	}
 	nfs4_close_state(&path, state, openflags);
--- a/fs/ocfs2/dcache.c
+++ b/fs/ocfs2/dcache.c
@@ -41,7 +41,7 @@
 
 
 static int ocfs2_dentry_revalidate(struct dentry *dentry,
-				   struct nameidata *nd)
+				   struct vfs_lookup *lookup)
 {
 	struct inode *inode = dentry->d_inode;
 	int ret = 0;    /* if all else fails, just return false */
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -1100,7 +1100,7 @@ static int pid_getattr(struct vfsmount *
  * made this apply to all per process world readable and executable
  * directories.
  */
-static int pid_revalidate(struct dentry *dentry, struct nameidata *nd)
+static int pid_revalidate(struct dentry *dentry, struct vfs_lookup *lookup)
 {
 	struct inode *inode = dentry->d_inode;
 	struct task_struct *task = get_proc_task(inode);
@@ -1266,7 +1266,7 @@ static int proc_fd_link(struct inode *in
 	return proc_fd_info(inode, dentry, mnt, NULL);
 }
 
-static int tid_fd_revalidate(struct dentry *dentry, struct nameidata *nd)
+static int tid_fd_revalidate(struct dentry *dentry, struct vfs_lookup *lookup)
 {
 	struct inode *inode = dentry->d_inode;
 	struct task_struct *task = get_proc_task(inode);
@@ -1911,7 +1911,8 @@ static const struct pid_entry proc_base_
  * directory. In this case, however, we can do it - no aliasing problems
  * due to the way we treat inodes.
  */
-static int proc_base_revalidate(struct dentry *dentry, struct nameidata *nd)
+static int proc_base_revalidate(struct dentry *dentry,
+				struct vfs_lookup *lookup)
 {
 	struct inode *inode = dentry->d_inode;
 	struct task_struct *task = get_proc_task(inode);
--- a/fs/proc/proc_sysctl.c
+++ b/fs/proc/proc_sysctl.c
@@ -451,7 +451,7 @@ static struct inode_operations proc_sys_
 	.setattr	= proc_sys_setattr,
 };
 
-static int proc_sys_revalidate(struct dentry *dentry, struct nameidata *nd)
+static int proc_sys_revalidate(struct dentry *dentry, struct vfs_lookup *lookup)
 {
 	struct ctl_table_header *head;
 	struct ctl_table *table;
--- a/fs/smbfs/dir.c
+++ b/fs/smbfs/dir.c
@@ -272,7 +272,7 @@ smb_dir_open(struct inode *dir, struct f
 /*
  * Dentry operations routines
  */
-static int smb_lookup_validate(struct dentry *, struct nameidata *);
+static int smb_lookup_validate(struct dentry *, struct vfs_lookup *);
 static int smb_hash_dentry(struct dentry *, struct qstr *);
 static int smb_compare_dentry(struct dentry *, struct qstr *, struct qstr *);
 static int smb_delete_dentry(struct dentry *);
@@ -296,7 +296,7 @@ static struct dentry_operations smbfs_de
  * This is the callback when the dcache has a lookup hit.
  */
 static int
-smb_lookup_validate(struct dentry * dentry, struct nameidata *nd)
+smb_lookup_validate(struct dentry * dentry, struct vfs_lookup *lookup)
 {
 	struct smb_sb_info *server = server_from_dentry(dentry);
 	struct inode * inode = dentry->d_inode;
--- a/fs/vfat/namei.c
+++ b/fs/vfat/namei.c
@@ -25,12 +25,12 @@
 #include <linux/buffer_head.h>
 #include <linux/namei.h>
 
-static int vfat_revalidate(struct dentry *dentry, struct nameidata *nd)
+static int vfat_revalidate(struct dentry *dentry, struct vfs_lookup *lookup)
 {
 	int ret = 1;
 
-	if (!dentry->d_inode &&
-	    nd && !(nd->lookup.flags & LOOKUP_CONTINUE) && (nd->lookup.flags & LOOKUP_CREATE))
+	if (!dentry->d_inode && lookup && !(lookup->flags & LOOKUP_CONTINUE) &&
+	    (lookup->flags & LOOKUP_CREATE))
 		/*
 		 * negative dentry is dropped, in order to make sure
 		 * to use the name which a user desires if this is
--- a/include/linux/dcache.h
+++ b/include/linux/dcache.h
@@ -11,6 +11,7 @@
 
 struct nameidata;
 struct vfsmount;
+struct vfs_lookup;
 
 /*
  * linux/include/linux/dcache.h
@@ -127,7 +128,7 @@ enum dentry_d_lock_class
 };
 
 struct dentry_operations {
-	int (*d_revalidate)(struct dentry *, struct nameidata *);
+	int (*d_revalidate)(struct dentry *, struct vfs_lookup *);
 	int (*d_hash) (struct dentry *, struct qstr *);
 	int (*d_compare) (struct dentry *, struct qstr *, struct qstr *);
 	int (*d_delete)(struct dentry *);


^ permalink raw reply	[flat|nested] 35+ messages in thread

* [RFC 10/10] Pass no unnecessary information to iop->lookup
  2007-08-08 17:16 [RFC 00/10] Split up struct nameidata (take 3) Andreas Gruenbacher
                   ` (8 preceding siblings ...)
  2007-08-08 17:16 ` [RFC 09/10] Pass no unnecessary information to dop->d_revalidate Andreas Gruenbacher
@ 2007-08-08 17:16 ` Andreas Gruenbacher
  9 siblings, 0 replies; 35+ messages in thread
From: Andreas Gruenbacher @ 2007-08-08 17:16 UTC (permalink / raw)
  To: linux-kernel
  Cc: John Johansen, Jan Blunck, Erez Zadok, Josef 'Jeff' Sipek

[-- Attachment #1: lookup-args.diff --]
[-- Type: text/plain, Size: 42801 bytes --]

iop->lookup does not need a full nameidata. Pass a struct vfs_lookup
instead.

Signed-off-by: Andreas Gruenbacher <ag@bestbits.at>

---
 fs/9p/vfs_inode.c           |    6 +++---
 fs/adfs/dir.c               |    2 +-
 fs/affs/affs.h              |    2 +-
 fs/affs/namei.c             |    2 +-
 fs/afs/dir.c                |    4 ++--
 fs/afs/mntpt.c              |    4 ++--
 fs/autofs/root.c            |    6 +++---
 fs/autofs4/root.c           |    6 +++---
 fs/bad_inode.c              |    2 +-
 fs/befs/linuxvfs.c          |    4 ++--
 fs/bfs/dir.c                |    2 +-
 fs/cifs/cifsfs.h            |    2 +-
 fs/cifs/dir.c               |    2 +-
 fs/coda/dir.c               |    4 ++--
 fs/configfs/dir.c           |    4 ++--
 fs/cramfs/inode.c           |    3 ++-
 fs/ecryptfs/inode.c         |   10 +++++-----
 fs/efs/namei.c              |    2 +-
 fs/ext2/namei.c             |    2 +-
 fs/ext3/namei.c             |    2 +-
 fs/ext4/namei.c             |    2 +-
 fs/freevxfs/vxfs_lookup.c   |    4 ++--
 fs/fuse/dir.c               |    2 +-
 fs/gfs2/ops_inode.c         |    6 +++---
 fs/hfs/dir.c                |    2 +-
 fs/hfs/inode.c              |    2 +-
 fs/hfsplus/dir.c            |    2 +-
 fs/hfsplus/inode.c          |    2 +-
 fs/hpfs/dir.c               |    3 ++-
 fs/hpfs/hpfs_fn.h           |    2 +-
 fs/isofs/isofs.h            |    2 +-
 fs/isofs/namei.c            |    2 +-
 fs/jffs2/dir.c              |    4 ++--
 fs/jfs/namei.c              |    2 +-
 fs/libfs.c                  |    2 +-
 fs/minix/namei.c            |    2 +-
 fs/msdos/namei.c            |    2 +-
 fs/namei.c                  |    4 ++--
 fs/ncpfs/dir.c              |    4 ++--
 fs/nfs/dir.c                |   24 ++++++++++++------------
 fs/nfs/nfs4_fs.h            |    2 +-
 fs/nfs/nfs4proc.c           |   16 +++++++++-------
 fs/ntfs/namei.c             |    4 ++--
 fs/ocfs2/namei.c            |    2 +-
 fs/proc/base.c              |   15 ++++++++-------
 fs/proc/generic.c           |    2 +-
 fs/proc/proc_sysctl.c       |    2 +-
 fs/proc/root.c              |    6 +++---
 fs/qnx4/namei.c             |    2 +-
 fs/reiserfs/namei.c         |    2 +-
 fs/romfs/inode.c            |    3 ++-
 fs/smbfs/dir.c              |    4 ++--
 fs/sysfs/dir.c              |    2 +-
 fs/sysv/namei.c             |    2 +-
 fs/udf/namei.c              |    2 +-
 fs/ufs/namei.c              |    2 +-
 fs/vfat/namei.c             |    2 +-
 fs/xfs/linux-2.6/xfs_iops.c |    2 +-
 include/linux/efs_fs.h      |    2 +-
 include/linux/fs.h          |    4 ++--
 include/linux/proc_fs.h     |    4 ++--
 include/linux/qnx4_fs.h     |    2 +-
 62 files changed, 118 insertions(+), 112 deletions(-)

--- a/fs/9p/vfs_inode.c
+++ b/fs/9p/vfs_inode.c
@@ -553,7 +553,7 @@ static int v9fs_vfs_mkdir(struct inode *
  */
 
 static struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
-				      struct nameidata *nameidata)
+				      struct vfs_lookup *lookup)
 {
 	struct super_block *sb;
 	struct v9fs_session_info *v9ses;
@@ -562,8 +562,8 @@ static struct dentry *v9fs_vfs_lookup(st
 	char *name;
 	int result = 0;
 
-	P9_DPRINTK(P9_DEBUG_VFS, "dir: %p dentry: (%s) %p nameidata: %p\n",
-		dir, dentry->d_name.name, dentry, nameidata);
+	P9_DPRINTK(P9_DEBUG_VFS, "dir: %p dentry: (%s) %p lookup: %p\n",
+		dir, dentry->d_name.name, dentry, lookup);
 
 	sb = dir->i_sb;
 	v9ses = v9fs_inode2v9ses(dir);
--- a/fs/adfs/dir.c
+++ b/fs/adfs/dir.c
@@ -268,7 +268,7 @@ struct dentry_operations adfs_dentry_ope
 };
 
 static struct dentry *
-adfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
+adfs_lookup(struct inode *dir, struct dentry *dentry, struct vfs_lookup *lookup)
 {
 	struct inode *inode = NULL;
 	struct object_info obj;
--- a/fs/affs/affs.h
+++ b/fs/affs/affs.h
@@ -153,7 +153,7 @@ extern void	affs_free_bitmap(struct supe
 /* namei.c */
 
 extern int	affs_hash_name(struct super_block *sb, const u8 *name, unsigned int len);
-extern struct dentry *affs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *);
+extern struct dentry *affs_lookup(struct inode *dir, struct dentry *dentry, struct vfs_lookup *);
 extern int	affs_unlink(struct inode *dir, struct dentry *dentry);
 extern int	affs_create(struct inode *dir, struct dentry *dentry, int mode, struct vfs_lookup *);
 extern int	affs_mkdir(struct inode *dir, struct dentry *dentry, int mode);
--- a/fs/affs/namei.c
+++ b/fs/affs/namei.c
@@ -197,7 +197,7 @@ affs_find_entry(struct inode *dir, struc
 }
 
 struct dentry *
-affs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
+affs_lookup(struct inode *dir, struct dentry *dentry, struct vfs_lookup *lookup)
 {
 	struct super_block *sb = dir->i_sb;
 	struct buffer_head *bh;
--- a/fs/afs/dir.c
+++ b/fs/afs/dir.c
@@ -20,7 +20,7 @@
 #include "internal.h"
 
 static struct dentry *afs_lookup(struct inode *dir, struct dentry *dentry,
-				 struct nameidata *nd);
+				 struct vfs_lookup *lookup);
 static int afs_dir_open(struct inode *inode, struct file *file);
 static int afs_readdir(struct file *file, void *dirent, filldir_t filldir);
 static int afs_d_revalidate(struct dentry *dentry, struct vfs_lookup *lookup);
@@ -484,7 +484,7 @@ static int afs_do_lookup(struct inode *d
  * look up an entry in a directory
  */
 static struct dentry *afs_lookup(struct inode *dir, struct dentry *dentry,
-				 struct nameidata *nd)
+				 struct vfs_lookup *lookup)
 {
 	struct afs_vnode *vnode;
 	struct afs_fid fid;
--- a/fs/afs/mntpt.c
+++ b/fs/afs/mntpt.c
@@ -23,7 +23,7 @@
 
 static struct dentry *afs_mntpt_lookup(struct inode *dir,
 				       struct dentry *dentry,
-				       struct nameidata *nd);
+				       struct vfs_lookup *lookup);
 static int afs_mntpt_open(struct inode *inode, struct file *file);
 static void *afs_mntpt_follow_link(struct dentry *dentry, struct nameidata *nd);
 static void afs_mntpt_expiry_timed_out(struct work_struct *work);
@@ -103,7 +103,7 @@ out:
  */
 static struct dentry *afs_mntpt_lookup(struct inode *dir,
 				       struct dentry *dentry,
-				       struct nameidata *nd)
+				       struct vfs_lookup *lookup)
 {
 	_enter("%p,%p{%p{%s},%s}",
 	       dir,
--- a/fs/autofs/root.c
+++ b/fs/autofs/root.c
@@ -19,7 +19,7 @@
 #include "autofs_i.h"
 
 static int autofs_root_readdir(struct file *,void *,filldir_t);
-static struct dentry *autofs_root_lookup(struct inode *,struct dentry *, struct nameidata *);
+static struct dentry *autofs_root_lookup(struct inode *,struct dentry *, struct vfs_lookup *);
 static int autofs_root_symlink(struct inode *,struct dentry *,const char *);
 static int autofs_root_unlink(struct inode *,struct dentry *);
 static int autofs_root_rmdir(struct inode *,struct dentry *);
@@ -196,7 +196,7 @@ static struct dentry_operations autofs_d
 	.d_revalidate	= autofs_revalidate,
 };
 
-static struct dentry *autofs_root_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
+static struct dentry *autofs_root_lookup(struct inode *dir, struct dentry *dentry, struct vfs_lookup *lookup)
 {
 	struct autofs_sb_info *sbi;
 	int oz_mode;
@@ -233,7 +233,7 @@ static struct dentry *autofs_root_lookup
 	d_add(dentry, NULL);
 
 	mutex_unlock(&dir->i_mutex);
-	autofs_revalidate(dentry, &nd->lookup);
+	autofs_revalidate(dentry, lookup);
 	mutex_lock(&dir->i_mutex);
 
 	/*
--- a/fs/autofs4/root.c
+++ b/fs/autofs4/root.c
@@ -28,7 +28,7 @@ static int autofs4_dir_open(struct inode
 static int autofs4_dir_close(struct inode *inode, struct file *file);
 static int autofs4_dir_readdir(struct file * filp, void * dirent, filldir_t filldir);
 static int autofs4_root_readdir(struct file * filp, void * dirent, filldir_t filldir);
-static struct dentry *autofs4_lookup(struct inode *,struct dentry *, struct nameidata *);
+static struct dentry *autofs4_lookup(struct inode *,struct dentry *, struct vfs_lookup *);
 static void *autofs4_follow_link(struct dentry *, struct nameidata *);
 
 const struct file_operations autofs4_root_operations = {
@@ -565,7 +565,7 @@ next:
 }
 
 /* Lookups in the root directory */
-static struct dentry *autofs4_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
+static struct dentry *autofs4_lookup(struct inode *dir, struct dentry *dentry, struct vfs_lookup *lookup)
 {
 	struct autofs_sb_info *sbi;
 	struct dentry *unhashed;
@@ -627,7 +627,7 @@ static struct dentry *autofs4_lookup(str
 
 	if (dentry->d_op && dentry->d_op->d_revalidate) {
 		mutex_unlock(&dir->i_mutex);
-		(dentry->d_op->d_revalidate)(dentry, &nd->lookup);
+		(dentry->d_op->d_revalidate)(dentry, lookup);
 		mutex_lock(&dir->i_mutex);
 	}
 
--- a/fs/bad_inode.c
+++ b/fs/bad_inode.c
@@ -192,7 +192,7 @@ static int bad_inode_create (struct inod
 }
 
 static struct dentry *bad_inode_lookup(struct inode *dir,
-			struct dentry *dentry, struct nameidata *nd)
+			struct dentry *dentry, struct vfs_lookup *lookup)
 {
 	return ERR_PTR(-EIO);
 }
--- a/fs/befs/linuxvfs.c
+++ b/fs/befs/linuxvfs.c
@@ -34,7 +34,7 @@ static int befs_readdir(struct file *, v
 static int befs_get_block(struct inode *, sector_t, struct buffer_head *, int);
 static int befs_readpage(struct file *file, struct page *page);
 static sector_t befs_bmap(struct address_space *mapping, sector_t block);
-static struct dentry *befs_lookup(struct inode *, struct dentry *, struct nameidata *);
+static struct dentry *befs_lookup(struct inode *, struct dentry *, struct vfs_lookup *);
 static void befs_read_inode(struct inode *ino);
 static struct inode *befs_alloc_inode(struct super_block *sb);
 static void befs_destroy_inode(struct inode *inode);
@@ -159,7 +159,7 @@ befs_get_block(struct inode *inode, sect
 }
 
 static struct dentry *
-befs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
+befs_lookup(struct inode *dir, struct dentry *dentry, struct vfs_lookup *lookup)
 {
 	struct inode *inode = NULL;
 	struct super_block *sb = dir->i_sb;
--- a/fs/bfs/dir.c
+++ b/fs/bfs/dir.c
@@ -127,7 +127,7 @@ static int bfs_create(struct inode * dir
 	return 0;
 }
 
-static struct dentry * bfs_lookup(struct inode * dir, struct dentry * dentry, struct nameidata *nd)
+static struct dentry * bfs_lookup(struct inode * dir, struct dentry * dentry, struct vfs_lookup *lookup)
 {
 	struct inode * inode = NULL;
 	struct buffer_head * bh;
--- a/fs/cifs/cifsfs.h
+++ b/fs/cifs/cifsfs.h
@@ -46,7 +46,7 @@ extern const struct inode_operations cif
 extern int cifs_create(struct inode *, struct dentry *, int,
 		       struct vfs_lookup *);
 extern struct dentry *cifs_lookup(struct inode *, struct dentry *,
-				  struct nameidata *);
+				  struct vfs_lookup *);
 extern int cifs_unlink(struct inode *, struct dentry *);
 extern int cifs_hardlink(struct dentry *, struct inode *, struct dentry *);
 extern int cifs_mknod(struct inode *, struct dentry *, int, dev_t);
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -438,7 +438,7 @@ int cifs_mknod(struct inode *inode, stru
 
 struct dentry *
 cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
-	    struct nameidata *nd)
+	    struct vfs_lookup *lookup)
 {
 	int xid;
 	int rc = 0; /* to get around spurious gcc warning, set to zero here */
--- a/fs/coda/dir.c
+++ b/fs/coda/dir.c
@@ -30,7 +30,7 @@
 
 /* dir inode-ops */
 static int coda_create(struct inode *dir, struct dentry *new, int mode, struct vfs_lookup *lookup);
-static struct dentry *coda_lookup(struct inode *dir, struct dentry *target, struct nameidata *nd);
+static struct dentry *coda_lookup(struct inode *dir, struct dentry *target, struct vfs_lookup *lookup);
 static int coda_link(struct dentry *old_dentry, struct inode *dir_inode, 
 		     struct dentry *entry);
 static int coda_unlink(struct inode *dir_inode, struct dentry *entry);
@@ -93,7 +93,7 @@ const struct file_operations coda_dir_op
 
 /* inode operations for directories */
 /* access routines: lookup, readlink, permission */
-static struct dentry *coda_lookup(struct inode *dir, struct dentry *entry, struct nameidata *nd)
+static struct dentry *coda_lookup(struct inode *dir, struct dentry *entry, struct vfs_lookup *lookup)
 {
 	struct inode *inode = NULL;
 	struct CodaFid resfid = { { 0, } };
--- a/fs/configfs/dir.c
+++ b/fs/configfs/dir.c
@@ -297,7 +297,7 @@ static int configfs_attach_attr(struct c
 
 static struct dentry * configfs_lookup(struct inode *dir,
 				       struct dentry *dentry,
-				       struct nameidata *nd)
+				       struct vfs_lookup *lookup)
 {
 	struct configfs_dirent * parent_sd = dentry->d_parent->d_fsdata;
 	struct configfs_dirent * sd;
@@ -322,7 +322,7 @@ static struct dentry * configfs_lookup(s
 		 * If it doesn't exist and it isn't a NOT_PINNED item,
 		 * it must be negative.
 		 */
-		return simple_lookup(dir, dentry, nd);
+		return simple_lookup(dir, dentry, lookup);
 	}
 
 	return ERR_PTR(err);
--- a/fs/cramfs/inode.c
+++ b/fs/cramfs/inode.c
@@ -405,7 +405,8 @@ static int cramfs_readdir(struct file *f
 /*
  * Lookup and fill in the inode data..
  */
-static struct dentry * cramfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
+static struct dentry * cramfs_lookup(struct inode *dir, struct dentry *dentry,
+				     struct vfs_lookup *lookup)
 {
 	unsigned int offset = 0;
 	int sorted;
--- a/fs/ecryptfs/inode.c
+++ b/fs/ecryptfs/inode.c
@@ -275,7 +275,7 @@ out:
  * dentry cache and continue on to read it from the disk.
  */
 static struct dentry *ecryptfs_lookup(struct inode *dir, struct dentry *dentry,
-				      struct nameidata *nd)
+				      struct vfs_lookup *lookup)
 {
 	int rc = 0;
 	struct dentry *lower_dir_dentry;
@@ -353,9 +353,9 @@ static struct dentry *ecryptfs_lookup(st
 		ecryptfs_printk(KERN_DEBUG, "Is a symlink; returning\n");
 		goto out;
 	}
-	if (!nd) {
-		ecryptfs_printk(KERN_DEBUG, "We have a NULL nd, just leave"
-				"as we *think* we are about to unlink\n");
+	if (!lookup) {
+		ecryptfs_printk(KERN_DEBUG, "We have a NULL vfs_lookup, just "
+				"leave as we *think* we are about to unlink\n");
 		goto out;
 	}
 	/* Released in this function */
@@ -371,7 +371,7 @@ static struct dentry *ecryptfs_lookup(st
 	if (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED))
 		ecryptfs_set_default_sizes(crypt_stat);
 	rc = ecryptfs_read_and_validate_header_region(page_virt, lower_dentry,
-						      nd->lookup.path.mnt);
+						      lookup->path.mnt);
 	if (rc) {
 		rc = ecryptfs_read_and_validate_xattr_region(page_virt, dentry);
 		if (rc) {
--- a/fs/efs/namei.c
+++ b/fs/efs/namei.c
@@ -57,7 +57,7 @@ static efs_ino_t efs_find_entry(struct i
 	return(0);
 }
 
-struct dentry *efs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) {
+struct dentry *efs_lookup(struct inode *dir, struct dentry *dentry, struct vfs_lookup *lookup) {
 	efs_ino_t inodenum;
 	struct inode * inode = NULL;
 
--- a/fs/ext2/namei.c
+++ b/fs/ext2/namei.c
@@ -52,7 +52,7 @@ static inline int ext2_add_nondir(struct
  * Methods themselves.
  */
 
-static struct dentry *ext2_lookup(struct inode * dir, struct dentry *dentry, struct nameidata *nd)
+static struct dentry *ext2_lookup(struct inode * dir, struct dentry *dentry, struct vfs_lookup *lookup)
 {
 	struct inode * inode;
 	ino_t ino;
--- a/fs/ext3/namei.c
+++ b/fs/ext3/namei.c
@@ -996,7 +996,7 @@ errout:
 }
 #endif
 
-static struct dentry *ext3_lookup(struct inode * dir, struct dentry *dentry, struct nameidata *nd)
+static struct dentry *ext3_lookup(struct inode * dir, struct dentry *dentry, struct vfs_lookup *lookup)
 {
 	struct inode * inode;
 	struct ext3_dir_entry_2 * de;
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -994,7 +994,7 @@ errout:
 }
 #endif
 
-static struct dentry *ext4_lookup(struct inode * dir, struct dentry *dentry, struct nameidata *nd)
+static struct dentry *ext4_lookup(struct inode * dir, struct dentry *dentry, struct vfs_lookup *lookup)
 {
 	struct inode * inode;
 	struct ext4_dir_entry_2 * de;
--- a/fs/freevxfs/vxfs_lookup.c
+++ b/fs/freevxfs/vxfs_lookup.c
@@ -49,7 +49,7 @@
 #define VXFS_BLOCK_PER_PAGE(sbp)  ((PAGE_CACHE_SIZE / (sbp)->s_blocksize))
 
 
-static struct dentry *	vxfs_lookup(struct inode *, struct dentry *, struct nameidata *);
+static struct dentry *	vxfs_lookup(struct inode *, struct dentry *, struct vfs_lookup *);
 static int		vxfs_readdir(struct file *, void *, filldir_t);
 
 const struct inode_operations vxfs_dir_inode_ops = {
@@ -202,7 +202,7 @@ vxfs_inode_by_name(struct inode *dip, st
  *   in the return pointer.
  */
 static struct dentry *
-vxfs_lookup(struct inode *dip, struct dentry *dp, struct nameidata *nd)
+vxfs_lookup(struct inode *dip, struct dentry *dp, struct vfs_lookup *lookup)
 {
 	struct inode		*ip = NULL;
 	ino_t			ino;
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -221,7 +221,7 @@ static int fuse_d_add_directory(struct d
 }
 
 static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
-				  struct nameidata *nd)
+				  struct vfs_lookup *lookup)
 {
 	int err;
 	struct fuse_entry_out outarg;
--- a/fs/gfs2/ops_inode.c
+++ b/fs/gfs2/ops_inode.c
@@ -95,7 +95,7 @@ static int gfs2_create(struct inode *dir
  * gfs2_lookup - Look up a filename in a directory and return its inode
  * @dir: The directory inode
  * @dentry: The dentry of the new inode
- * @nd: passed from Linux VFS, ignored by us
+ * @lookup: passed from Linux VFS, ignored by us
  *
  * Called by the VFS layer. Lock dir and call gfs2_lookupi()
  *
@@ -103,13 +103,13 @@ static int gfs2_create(struct inode *dir
  */
 
 static struct dentry *gfs2_lookup(struct inode *dir, struct dentry *dentry,
-				  struct nameidata *nd)
+				  struct vfs_lookup *lookup)
 {
 	struct inode *inode = NULL;
 
 	dentry->d_op = &gfs2_dops;
 
-	inode = gfs2_lookupi(dir, &dentry->d_name, 0, &nd->lookup);
+	inode = gfs2_lookupi(dir, &dentry->d_name, 0, lookup);
 	if (inode && IS_ERR(inode))
 		return ERR_PTR(PTR_ERR(inode));
 
--- a/fs/hfs/dir.c
+++ b/fs/hfs/dir.c
@@ -18,7 +18,7 @@
  * hfs_lookup()
  */
 static struct dentry *hfs_lookup(struct inode *dir, struct dentry *dentry,
-				 struct nameidata *nd)
+				 struct vfs_lookup *lookup)
 {
 	hfs_cat_rec rec;
 	struct hfs_find_data fd;
--- a/fs/hfs/inode.c
+++ b/fs/hfs/inode.c
@@ -459,7 +459,7 @@ out:
 }
 
 static struct dentry *hfs_file_lookup(struct inode *dir, struct dentry *dentry,
-				      struct nameidata *nd)
+				      struct vfs_lookup *lookup)
 {
 	struct inode *inode = NULL;
 	hfs_cat_rec rec;
--- a/fs/hfsplus/dir.c
+++ b/fs/hfsplus/dir.c
@@ -25,7 +25,7 @@ static inline void hfsplus_instantiate(s
 
 /* Find the entry inside dir named dentry->d_name */
 static struct dentry *hfsplus_lookup(struct inode *dir, struct dentry *dentry,
-				     struct nameidata *nd)
+				     struct vfs_lookup *lookup)
 {
 	struct inode *inode = NULL;
 	struct hfs_find_data fd;
--- a/fs/hfsplus/inode.c
+++ b/fs/hfsplus/inode.c
@@ -137,7 +137,7 @@ struct dentry_operations hfsplus_dentry_
 };
 
 static struct dentry *hfsplus_file_lookup(struct inode *dir, struct dentry *dentry,
-					  struct nameidata *nd)
+					  struct vfs_lookup *lookup)
 {
 	struct hfs_find_data fd;
 	struct super_block *sb = dir->i_sb;
--- a/fs/hpfs/dir.c
+++ b/fs/hpfs/dir.c
@@ -184,7 +184,8 @@ out:
  *	      to tell read_inode to read fnode or not.
  */
 
-struct dentry *hpfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
+struct dentry *hpfs_lookup(struct inode *dir, struct dentry *dentry,
+			   struct vfs_lookup *lookup)
 {
 	const char *name = dentry->d_name.name;
 	unsigned len = dentry->d_name.len;
--- a/fs/hpfs/hpfs_fn.h
+++ b/fs/hpfs/hpfs_fn.h
@@ -238,7 +238,7 @@ void hpfs_set_dentry_operations(struct d
 
 /* dir.c */
 
-struct dentry *hpfs_lookup(struct inode *, struct dentry *, struct nameidata *);
+struct dentry *hpfs_lookup(struct inode *, struct dentry *, struct vfs_lookup *);
 extern const struct file_operations hpfs_dir_ops;
 
 /* dnode.c */
--- a/fs/isofs/isofs.h
+++ b/fs/isofs/isofs.h
@@ -112,7 +112,7 @@ extern int isofs_name_translate(struct i
 int get_joliet_filename(struct iso_directory_record *, unsigned char *, struct inode *);
 int get_acorn_filename(struct iso_directory_record *, char *, struct inode *);
 
-extern struct dentry *isofs_lookup(struct inode *, struct dentry *, struct nameidata *);
+extern struct dentry *isofs_lookup(struct inode *, struct dentry *, struct vfs_lookup *);
 extern struct buffer_head *isofs_bread(struct inode *, sector_t);
 extern int isofs_get_blocks(struct inode *, sector_t, struct buffer_head **, unsigned long);
 
--- a/fs/isofs/namei.c
+++ b/fs/isofs/namei.c
@@ -155,7 +155,7 @@ isofs_find_entry(struct inode *dir, stru
 	return 0;
 }
 
-struct dentry *isofs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
+struct dentry *isofs_lookup(struct inode *dir, struct dentry *dentry, struct vfs_lookup *lookup)
 {
 	int found;
 	unsigned long block, offset;
--- a/fs/jffs2/dir.c
+++ b/fs/jffs2/dir.c
@@ -24,7 +24,7 @@ static int jffs2_readdir (struct file *,
 static int jffs2_create (struct inode *,struct dentry *,int,
 			 struct vfs_lookup *);
 static struct dentry *jffs2_lookup (struct inode *,struct dentry *,
-				    struct nameidata *);
+				    struct vfs_lookup *);
 static int jffs2_link (struct dentry *,struct inode *,struct dentry *);
 static int jffs2_unlink (struct inode *,struct dentry *);
 static int jffs2_symlink (struct inode *,struct dentry *,const char *);
@@ -70,7 +70,7 @@ const struct inode_operations jffs2_dir_
    nice and simple
 */
 static struct dentry *jffs2_lookup(struct inode *dir_i, struct dentry *target,
-				   struct nameidata *nd)
+				   struct vfs_lookup *lookup)
 {
 	struct jffs2_inode_info *dir_f;
 	struct jffs2_sb_info *c;
--- a/fs/jfs/namei.c
+++ b/fs/jfs/namei.c
@@ -1428,7 +1428,7 @@ static int jfs_mknod(struct inode *dir, 
 	return rc;
 }
 
-static struct dentry *jfs_lookup(struct inode *dip, struct dentry *dentry, struct nameidata *nd)
+static struct dentry *jfs_lookup(struct inode *dip, struct dentry *dentry, struct vfs_lookup *lookup)
 {
 	struct btstack btstack;
 	ino_t inum;
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -41,7 +41,7 @@ static int simple_delete_dentry(struct d
  * Lookup the data. This is trivial - if the dentry didn't already
  * exist, we know it is negative.  Set d_op to delete negative dentries.
  */
-struct dentry *simple_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
+struct dentry *simple_lookup(struct inode *dir, struct dentry *dentry, struct vfs_lookup *lookup)
 {
 	static struct dentry_operations simple_dentry_operations = {
 		.d_delete = simple_delete_dentry,
--- a/fs/minix/namei.c
+++ b/fs/minix/namei.c
@@ -42,7 +42,7 @@ struct dentry_operations minix_dentry_op
 	.d_hash		= minix_hash,
 };
 
-static struct dentry *minix_lookup(struct inode * dir, struct dentry *dentry, struct nameidata *nd)
+static struct dentry *minix_lookup(struct inode * dir, struct dentry *dentry, struct vfs_lookup *lookup)
 {
 	struct inode * inode = NULL;
 	ino_t ino;
--- a/fs/msdos/namei.c
+++ b/fs/msdos/namei.c
@@ -205,7 +205,7 @@ static struct dentry_operations msdos_de
 
 /***** Get inode using directory and name */
 static struct dentry *msdos_lookup(struct inode *dir, struct dentry *dentry,
-				   struct nameidata *nd)
+				   struct vfs_lookup *lookup)
 {
 	struct super_block *sb = dir->i_sb;
 	struct fat_slot_info sinfo;
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -495,7 +495,7 @@ static struct dentry * real_lookup(struc
 		struct dentry * dentry = d_alloc(parent, name);
 		result = ERR_PTR(-ENOMEM);
 		if (dentry) {
-			result = dir->i_op->lookup(dir, dentry, nd);
+			result = dir->i_op->lookup(dir, dentry, &nd->lookup);
 			if (result)
 				dput(dentry);
 			else
@@ -1300,7 +1300,7 @@ static inline struct dentry *__lookup_ha
 		dentry = ERR_PTR(-ENOMEM);
 		if (!new)
 			goto out;
-		dentry = inode->i_op->lookup(inode, new, nd);
+		dentry = inode->i_op->lookup(inode, new, &nd->lookup);
 		if (!dentry)
 			dentry = new;
 		else
--- a/fs/ncpfs/dir.c
+++ b/fs/ncpfs/dir.c
@@ -34,7 +34,7 @@ static void ncp_do_readdir(struct file *
 static int ncp_readdir(struct file *, void *, filldir_t);
 
 static int ncp_create(struct inode *, struct dentry *, int, struct vfs_lookup *);
-static struct dentry *ncp_lookup(struct inode *, struct dentry *, struct nameidata *);
+static struct dentry *ncp_lookup(struct inode *, struct dentry *, struct vfs_lookup *);
 static int ncp_unlink(struct inode *, struct dentry *);
 static int ncp_mkdir(struct inode *, struct dentry *, int);
 static int ncp_rmdir(struct inode *, struct dentry *);
@@ -791,7 +791,7 @@ out:
 	return result;
 }
 
-static struct dentry *ncp_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
+static struct dentry *ncp_lookup(struct inode *dir, struct dentry *dentry, struct vfs_lookup *lookup)
 {
 	struct ncp_server *server = NCP_SERVER(dir);
 	struct inode *inode = NULL;
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -43,7 +43,7 @@
 
 static int nfs_opendir(struct inode *, struct file *);
 static int nfs_readdir(struct file *, void *, filldir_t);
-static struct dentry *nfs_lookup(struct inode *, struct dentry *, struct nameidata *);
+static struct dentry *nfs_lookup(struct inode *, struct dentry *, struct vfs_lookup *);
 static int nfs_create(struct inode *, struct dentry *, int, struct vfs_lookup *);
 static int nfs_mkdir(struct inode *, struct dentry *, int);
 static int nfs_rmdir(struct inode *, struct dentry *);
@@ -103,7 +103,7 @@ const struct inode_operations nfs3_dir_i
 
 #ifdef CONFIG_NFS_V4
 
-static struct dentry *nfs_atomic_lookup(struct inode *, struct dentry *, struct nameidata *);
+static struct dentry *nfs_atomic_lookup(struct inode *, struct dentry *, struct vfs_lookup *);
 const struct inode_operations nfs4_dir_inode_operations = {
 	.create		= nfs_create,
 	.lookup		= nfs_atomic_lookup,
@@ -908,7 +908,7 @@ static inline int nfs_reval_fsid(struct 
 	return 0;
 }
 
-static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd)
+static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, struct vfs_lookup *lookup)
 {
 	struct dentry *res;
 	struct inode *inode = NULL;
@@ -933,7 +933,7 @@ static struct dentry *nfs_lookup(struct 
 	 * If we're doing an exclusive create, optimize away the lookup
 	 * but don't hash the dentry.
 	 */
-	if (nfs_is_exclusive_create(dir, &nd->lookup)) {
+	if (nfs_is_exclusive_create(dir, lookup)) {
 		d_instantiate(dentry, NULL);
 		res = NULL;
 		goto out_unlock;
@@ -1004,7 +1004,7 @@ static int is_atomic_open(struct inode *
 	return 1;
 }
 
-static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
+static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry, struct vfs_lookup *lookup)
 {
 	struct dentry *res = NULL;
 	int error;
@@ -1013,7 +1013,7 @@ static struct dentry *nfs_atomic_lookup(
 			dir->i_sb->s_id, dir->i_ino, dentry->d_name.name);
 
 	/* Check that we are indeed trying to open this file */
-	if (!is_atomic_open(dir, &nd->lookup))
+	if (!is_atomic_open(dir, lookup))
 		goto no_open;
 
 	if (dentry->d_name.len > NFS_SERVER(dir)->namelen) {
@@ -1023,7 +1023,7 @@ static struct dentry *nfs_atomic_lookup(
 	dentry->d_op = NFS_PROTO(dir)->dentry_ops;
 
 	/* Let vfs_create() deal with O_EXCL */
-	if (nd->lookup.intent.open.flags & O_EXCL) {
+	if (lookup->intent.open.flags & O_EXCL) {
 		d_add(dentry, NULL);
 		goto out;
 	}
@@ -1038,12 +1038,12 @@ static struct dentry *nfs_atomic_lookup(
 		goto out;
 	}
 
-	if (nd->lookup.intent.open.flags & O_CREAT) {
+	if (lookup->intent.open.flags & O_CREAT) {
 		nfs_begin_data_update(dir);
-		res = nfs4_atomic_open(dir, dentry, nd);
+		res = nfs4_atomic_open(dir, dentry, lookup);
 		nfs_end_data_update(dir);
 	} else
-		res = nfs4_atomic_open(dir, dentry, nd);
+		res = nfs4_atomic_open(dir, dentry, lookup);
 	unlock_kernel();
 	if (IS_ERR(res)) {
 		error = PTR_ERR(res);
@@ -1057,7 +1057,7 @@ static struct dentry *nfs_atomic_lookup(
 			case -ENOTDIR:
 				goto no_open;
 			case -ELOOP:
-				if (!(nd->lookup.intent.open.flags & O_NOFOLLOW))
+				if (!(lookup->intent.open.flags & O_NOFOLLOW))
 					goto no_open;
 			/* case -EINVAL: */
 			default:
@@ -1070,7 +1070,7 @@ static struct dentry *nfs_atomic_lookup(
 out:
 	return res;
 no_open:
-	return nfs_lookup(dir, dentry, nd);
+	return nfs_lookup(dir, dentry, lookup);
 }
 
 static int nfs_open_revalidate(struct dentry *dentry, struct vfs_lookup *lookup)
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -179,7 +179,7 @@ extern int nfs4_proc_setclientid_confirm
 extern int nfs4_proc_async_renew(struct nfs_client *, struct rpc_cred *);
 extern int nfs4_proc_renew(struct nfs_client *, struct rpc_cred *);
 extern int nfs4_do_close(struct path *path, struct nfs4_state *state);
-extern struct dentry *nfs4_atomic_open(struct inode *, struct dentry *, struct nameidata *);
+extern struct dentry *nfs4_atomic_open(struct inode *, struct dentry *, struct vfs_lookup *);
 extern int nfs4_open_revalidate(struct inode *, struct dentry *, int, struct vfs_lookup *);
 extern int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle);
 extern int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name,
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -1403,10 +1403,11 @@ out_close:
 }
 
 struct dentry *
-nfs4_atomic_open(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
+nfs4_atomic_open(struct inode *dir, struct dentry *dentry,
+		 struct vfs_lookup *lookup)
 {
 	struct path path = {
-		.mnt = nd->lookup.path.mnt,
+		.mnt = lookup->path.mnt,
 		.dentry = dentry,
 	};
 	struct iattr attr;
@@ -1414,20 +1415,21 @@ nfs4_atomic_open(struct inode *dir, stru
 	struct nfs4_state *state;
 	struct dentry *res;
 
-	if (nd->lookup.flags & LOOKUP_CREATE) {
-		attr.ia_mode = nd->lookup.intent.open.create_mode;
+	if (lookup->flags & LOOKUP_CREATE) {
+		attr.ia_mode = lookup->intent.open.create_mode;
 		attr.ia_valid = ATTR_MODE;
 		if (!IS_POSIXACL(dir))
 			attr.ia_mode &= ~current->fs->umask;
 	} else {
 		attr.ia_valid = 0;
-		BUG_ON(nd->lookup.intent.open.flags & O_CREAT);
+		BUG_ON(lookup->intent.open.flags & O_CREAT);
 	}
 
 	cred = rpcauth_lookupcred(NFS_CLIENT(dir)->cl_auth, 0);
 	if (IS_ERR(cred))
 		return (struct dentry *)cred;
-	state = nfs4_do_open(dir, &path, nd->lookup.intent.open.flags, &attr, cred);
+	state = nfs4_do_open(dir, &path, lookup->intent.open.flags, &attr,
+			     cred);
 	put_rpccred(cred);
 	if (IS_ERR(state)) {
 		if (PTR_ERR(state) == -ENOENT)
@@ -1437,7 +1439,7 @@ nfs4_atomic_open(struct inode *dir, stru
 	res = d_add_unique(dentry, igrab(state->inode));
 	if (res != NULL)
 		dentry = res;
-	nfs4_intent_set_file(&nd->lookup, &path, state);
+	nfs4_intent_set_file(lookup, &path, state);
 	return res;
 }
 
--- a/fs/ntfs/namei.c
+++ b/fs/ntfs/namei.c
@@ -34,7 +34,7 @@
  * ntfs_lookup - find the inode represented by a dentry in a directory inode
  * @dir_ino:	directory inode in which to look for the inode
  * @dent:	dentry representing the inode to look for
- * @nd:		lookup nameidata
+ * @lookup:		lookup nameidata
  *
  * In short, ntfs_lookup() looks for the inode represented by the dentry @dent
  * in the directory inode @dir_ino and if found attaches the inode to the
@@ -100,7 +100,7 @@
  * Locking: Caller must hold i_mutex on the directory.
  */
 static struct dentry *ntfs_lookup(struct inode *dir_ino, struct dentry *dent,
-		struct nameidata *nd)
+		struct vfs_lookup *lookup)
 {
 	ntfs_volume *vol = NTFS_SB(dir_ino->i_sb);
 	struct inode *dent_inode;
--- a/fs/ocfs2/namei.c
+++ b/fs/ocfs2/namei.c
@@ -138,7 +138,7 @@ static inline int ocfs2_add_entry(handle
 #define OCFS2_ORPHAN_NAMELEN ((int)(2 * sizeof(u64)))
 
 static struct dentry *ocfs2_lookup(struct inode *dir, struct dentry *dentry,
-				   struct nameidata *nd)
+				   struct vfs_lookup *lookup)
 {
 	int status;
 	u64 blkno;
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -1444,7 +1444,7 @@ out_no_task:
 }
 
 static struct dentry *proc_lookupfd(struct inode *dir, struct dentry *dentry,
-				    struct nameidata *nd)
+				    struct vfs_lookup *lookup)
 {
 	return proc_lookupfd_common(dir, dentry, proc_fd_instantiate);
 }
@@ -1527,7 +1527,7 @@ static struct dentry *proc_fdinfo_instan
 
 static struct dentry *proc_lookupfdinfo(struct inode *dir,
 					struct dentry *dentry,
-					struct nameidata *nd)
+					struct vfs_lookup *lookup)
 {
 	return proc_lookupfd_common(dir, dentry, proc_fdinfo_instantiate);
 }
@@ -1772,7 +1772,8 @@ static const struct file_operations proc
 };
 
 static struct dentry *proc_attr_dir_lookup(struct inode *dir,
-				struct dentry *dentry, struct nameidata *nd)
+				struct dentry *dentry,
+				struct vfs_lookup *lookup)
 {
 	return proc_pident_lookup(dir, dentry,
 				  attr_dir_stuff, ARRAY_SIZE(attr_dir_stuff));
@@ -2112,7 +2113,7 @@ static const struct file_operations proc
 	.readdir	= proc_tgid_base_readdir,
 };
 
-static struct dentry *proc_tgid_base_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd){
+static struct dentry *proc_tgid_base_lookup(struct inode *dir, struct dentry *dentry, struct vfs_lookup *lookup){
 	return proc_pident_lookup(dir, dentry,
 				  tgid_base_stuff, ARRAY_SIZE(tgid_base_stuff));
 }
@@ -2220,7 +2221,7 @@ out:
 	return error;
 }
 
-struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd)
+struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, struct vfs_lookup *lookup)
 {
 	struct dentry *result = ERR_PTR(-ENOENT);
 	struct task_struct *task;
@@ -2387,7 +2388,7 @@ static int proc_tid_base_readdir(struct 
 				   tid_base_stuff,ARRAY_SIZE(tid_base_stuff));
 }
 
-static struct dentry *proc_tid_base_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd){
+static struct dentry *proc_tid_base_lookup(struct inode *dir, struct dentry *dentry, struct vfs_lookup *lookup){
 	return proc_pident_lookup(dir, dentry,
 				  tid_base_stuff, ARRAY_SIZE(tid_base_stuff));
 }
@@ -2431,7 +2432,7 @@ out:
 	return error;
 }
 
-static struct dentry *proc_task_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd)
+static struct dentry *proc_task_lookup(struct inode *dir, struct dentry * dentry, struct vfs_lookup *lookup)
 {
 	struct dentry *result = ERR_PTR(-ENOENT);
 	struct task_struct *task;
--- a/fs/proc/generic.c
+++ b/fs/proc/generic.c
@@ -383,7 +383,7 @@ static struct dentry_operations proc_den
  * Don't create negative dentries here, return -ENOENT by hand
  * instead.
  */
-struct dentry *proc_lookup(struct inode * dir, struct dentry *dentry, struct nameidata *nd)
+struct dentry *proc_lookup(struct inode * dir, struct dentry *dentry, struct vfs_lookup *lookup)
 {
 	struct inode *inode = NULL;
 	struct proc_dir_entry * de;
--- a/fs/proc/proc_sysctl.c
+++ b/fs/proc/proc_sysctl.c
@@ -139,7 +139,7 @@ static struct ctl_table *do_proc_sys_loo
 }
 
 static struct dentry *proc_sys_lookup(struct inode *dir, struct dentry *dentry,
-					struct nameidata *nd)
+					struct vfs_lookup *lookup)
 {
 	struct ctl_table_header *head;
 	struct inode *inode;
--- a/fs/proc/root.c
+++ b/fs/proc/root.c
@@ -90,13 +90,13 @@ static int proc_root_getattr(struct vfsm
 	return 0;
 }
 
-static struct dentry *proc_root_lookup(struct inode * dir, struct dentry * dentry, struct nameidata *nd)
+static struct dentry *proc_root_lookup(struct inode * dir, struct dentry * dentry, struct vfs_lookup *lookup)
 {
-	if (!proc_lookup(dir, dentry, nd)) {
+	if (!proc_lookup(dir, dentry, lookup)) {
 		return NULL;
 	}
 	
-	return proc_pid_lookup(dir, dentry, nd);
+	return proc_pid_lookup(dir, dentry, lookup);
 }
 
 static int proc_root_readdir(struct file * filp,
--- a/fs/qnx4/namei.c
+++ b/fs/qnx4/namei.c
@@ -106,7 +106,7 @@ static struct buffer_head *qnx4_find_ent
 	return NULL;
 }
 
-struct dentry * qnx4_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
+struct dentry * qnx4_lookup(struct inode *dir, struct dentry *dentry, struct vfs_lookup *lookup)
 {
 	int ino;
 	struct qnx4_inode_entry *de;
--- a/fs/reiserfs/namei.c
+++ b/fs/reiserfs/namei.c
@@ -324,7 +324,7 @@ static int reiserfs_find_entry(struct in
 }
 
 static struct dentry *reiserfs_lookup(struct inode *dir, struct dentry *dentry,
-				      struct nameidata *nd)
+				      struct vfs_lookup *lookup)
 {
 	int retval;
 	struct inode *inode = NULL;
--- a/fs/romfs/inode.c
+++ b/fs/romfs/inode.c
@@ -332,7 +332,8 @@ out:
 }
 
 static struct dentry *
-romfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
+romfs_lookup(struct inode *dir, struct dentry *dentry,
+	     struct vfs_lookup *lookup)
 {
 	unsigned long offset, maxoff;
 	int fslen, res;
--- a/fs/smbfs/dir.c
+++ b/fs/smbfs/dir.c
@@ -25,7 +25,7 @@
 static int smb_readdir(struct file *, void *, filldir_t);
 static int smb_dir_open(struct inode *, struct file *);
 
-static struct dentry *smb_lookup(struct inode *, struct dentry *, struct nameidata *);
+static struct dentry *smb_lookup(struct inode *, struct dentry *, struct vfs_lookup *);
 static int smb_create(struct inode *, struct dentry *, int, struct vfs_lookup *);
 static int smb_mkdir(struct inode *, struct dentry *, int);
 static int smb_rmdir(struct inode *, struct dentry *);
@@ -424,7 +424,7 @@ smb_renew_times(struct dentry * dentry)
 }
 
 static struct dentry *
-smb_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
+smb_lookup(struct inode *dir, struct dentry *dentry, struct vfs_lookup *lookup)
 {
 	struct smb_fattr finfo;
 	struct inode *inode;
--- a/fs/sysfs/dir.c
+++ b/fs/sysfs/dir.c
@@ -760,7 +760,7 @@ static int sysfs_count_nlink(struct sysf
 }
 
 static struct dentry * sysfs_lookup(struct inode *dir, struct dentry *dentry,
-				struct nameidata *nd)
+				struct vfs_lookup *lookup)
 {
 	struct sysfs_dirent * parent_sd = dentry->d_parent->d_fsdata;
 	struct sysfs_dirent * sd;
--- a/fs/sysv/namei.c
+++ b/fs/sysv/namei.c
@@ -42,7 +42,7 @@ struct dentry_operations sysv_dentry_ope
 	.d_hash		= sysv_hash,
 };
 
-static struct dentry *sysv_lookup(struct inode * dir, struct dentry * dentry, struct nameidata *nd)
+static struct dentry *sysv_lookup(struct inode * dir, struct dentry * dentry, struct vfs_lookup *lookup)
 {
 	struct inode * inode = NULL;
 	ino_t ino;
--- a/fs/udf/namei.c
+++ b/fs/udf/namei.c
@@ -276,7 +276,7 @@ static struct fileIdentDesc *udf_find_en
  */
 
 static struct dentry *udf_lookup(struct inode *dir, struct dentry *dentry,
-				 struct nameidata *nd)
+				 struct vfs_lookup *lookup)
 {
 	struct inode *inode = NULL;
 	struct fileIdentDesc cfi;
--- a/fs/ufs/namei.c
+++ b/fs/ufs/namei.c
@@ -46,7 +46,7 @@ static inline int ufs_add_nondir(struct 
 	return err;
 }
 
-static struct dentry *ufs_lookup(struct inode * dir, struct dentry *dentry, struct nameidata *nd)
+static struct dentry *ufs_lookup(struct inode * dir, struct dentry *dentry, struct vfs_lookup *lookup)
 {
 	struct inode * inode = NULL;
 	ino_t ino;
--- a/fs/vfat/namei.c
+++ b/fs/vfat/namei.c
@@ -684,7 +684,7 @@ static int vfat_find(struct inode *dir, 
 }
 
 static struct dentry *vfat_lookup(struct inode *dir, struct dentry *dentry,
-				  struct nameidata *nd)
+				  struct vfs_lookup *lookup)
 {
 	struct super_block *sb = dir->i_sb;
 	struct fat_slot_info sinfo;
--- a/fs/xfs/linux-2.6/xfs_iops.c
+++ b/fs/xfs/linux-2.6/xfs_iops.c
@@ -385,7 +385,7 @@ STATIC struct dentry *
 xfs_vn_lookup(
 	struct inode	*dir,
 	struct dentry	*dentry,
-	struct nameidata *nd)
+	struct vfs_lookup *lookup)
 {
 	bhv_vnode_t	*vp = vn_from_inode(dir), *cvp;
 	int		error;
--- a/include/linux/efs_fs.h
+++ b/include/linux/efs_fs.h
@@ -44,7 +44,7 @@ extern void efs_read_inode(struct inode 
 extern efs_block_t efs_map_block(struct inode *, efs_block_t);
 extern int efs_get_block(struct inode *, sector_t, struct buffer_head *, int);
 
-extern struct dentry *efs_lookup(struct inode *, struct dentry *, struct nameidata *);
+extern struct dentry *efs_lookup(struct inode *, struct dentry *, struct vfs_lookup *);
 extern struct dentry *efs_get_dentry(struct super_block *sb, void *vobjp);
 extern struct dentry *efs_get_parent(struct dentry *);
 extern int efs_bmap(struct inode *, int);
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1134,7 +1134,7 @@ struct file_operations {
 
 struct inode_operations {
 	int (*create) (struct inode *,struct dentry *,int, struct vfs_lookup *);
-	struct dentry * (*lookup) (struct inode *,struct dentry *, struct nameidata *);
+	struct dentry * (*lookup) (struct inode *,struct dentry *, struct vfs_lookup *);
 	int (*link) (struct dentry *,struct inode *,struct dentry *);
 	int (*unlink) (struct inode *,struct dentry *);
 	int (*symlink) (struct inode *,struct dentry *,const char *);
@@ -1817,7 +1817,7 @@ extern int simple_prepare_write(struct f
 extern int simple_commit_write(struct file *file, struct page *page,
 				unsigned offset, unsigned to);
 
-extern struct dentry *simple_lookup(struct inode *, struct dentry *, struct nameidata *);
+extern struct dentry *simple_lookup(struct inode *, struct dentry *, struct vfs_lookup *);
 extern ssize_t generic_read_dir(struct file *, char __user *, size_t, loff_t *);
 extern const struct file_operations simple_dir_operations;
 extern const struct inode_operations simple_dir_inode_operations;
--- a/include/linux/proc_fs.h
+++ b/include/linux/proc_fs.h
@@ -112,7 +112,7 @@ extern void proc_misc_init(void);
 struct mm_struct;
 
 void proc_flush_task(struct task_struct *task);
-struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *);
+struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, struct vfs_lookup *);
 int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir);
 unsigned long task_vsize(struct mm_struct *);
 int task_statm(struct mm_struct *, int *, int *, int *, int *);
@@ -138,7 +138,7 @@ extern struct inode *proc_get_inode(stru
  * of the /proc/<pid> subdirectories.
  */
 extern int proc_readdir(struct file *, void *, filldir_t);
-extern struct dentry *proc_lookup(struct inode *, struct dentry *, struct nameidata *);
+extern struct dentry *proc_lookup(struct inode *, struct dentry *, struct vfs_lookup *);
 
 extern const struct file_operations proc_kcore_operations;
 extern const struct file_operations proc_kmsg_operations;
--- a/include/linux/qnx4_fs.h
+++ b/include/linux/qnx4_fs.h
@@ -110,7 +110,7 @@ struct qnx4_inode_info {
 	struct inode vfs_inode;
 };
 
-extern struct dentry *qnx4_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd);
+extern struct dentry *qnx4_lookup(struct inode *dir, struct dentry *dentry, struct vfs_lookup *lookup);
 extern unsigned long qnx4_count_free_blocks(struct super_block *sb);
 extern unsigned long qnx4_block_map(struct inode *inode, long iblock);
 


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [RFC 04/10] Temporary struct vfs_lookup in file_permission
  2007-08-08 17:16 ` [RFC 04/10] Temporary struct vfs_lookup in file_permission Andreas Gruenbacher
@ 2007-08-08 17:58   ` Josef Sipek
  2007-08-08 18:56     ` Andreas Gruenbacher
  2007-08-08 19:25   ` Christoph Hellwig
  1 sibling, 1 reply; 35+ messages in thread
From: Josef Sipek @ 2007-08-08 17:58 UTC (permalink / raw)
  To: Andreas Gruenbacher
  Cc: linux-kernel, John Johansen, Jan Blunck, Erez Zadok,
	Josef 'Jeff' Sipek

On Wed, Aug 08, 2007 at 07:16:26PM +0200, Andreas Gruenbacher wrote:
> Create a temporary struct vfs_lookup in file_permission() instead of
> passing a NULL value.
> 
> Signed-off-by: Andreas Gruenbacher <ag@bestbits.at>
> 
> ---
>  fs/namei.c |   11 ++++++-----
>  1 file changed, 6 insertions(+), 5 deletions(-)
> 
> --- a/fs/namei.c
> +++ b/fs/namei.c
> @@ -292,14 +292,15 @@ int vfs_permission(struct vfs_lookup *lo
>   *
>   * Used to check for read/write/execute permissions on an already opened
>   * file.
> - *
> - * Note:
> - *	Do not use this function in new code.  All access checks should
> - *	be done using vfs_permission().

Should this comment be removed?

>   */
>  int file_permission(struct file *file, int mask)
>  {
> -	return permission(file->f_path.dentry->d_inode, mask, NULL);
> +	struct vfs_lookup lookup;
> +
> +	lookup.path = file->f_path;
> +	lookup.flags = 0;

I tend to find this little bit cleaner:

struct vfs_lookup lookup = {
	.path	= file->f_path,
	.flags	= 0,
};

> +
> +	return permission(file->f_path.dentry->d_inode, mask, &lookup);
>  }
>  
>  /*

-- 
Humans were created by water to transport it upward.

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [RFC 04/10] Temporary struct vfs_lookup in file_permission
  2007-08-08 17:58   ` Josef Sipek
@ 2007-08-08 18:56     ` Andreas Gruenbacher
  0 siblings, 0 replies; 35+ messages in thread
From: Andreas Gruenbacher @ 2007-08-08 18:56 UTC (permalink / raw)
  To: Josef Sipek
  Cc: linux-kernel, John Johansen, Jan Blunck, Erez Zadok,
	Josef 'Jeff' Sipek

On Wednesday 08 August 2007 19:58, Josef Sipek wrote:
> On Wed, Aug 08, 2007 at 07:16:26PM +0200, Andreas Gruenbacher wrote:
> > Create a temporary struct vfs_lookup in file_permission() instead of
> > passing a NULL value.
> > 
> > Signed-off-by: Andreas Gruenbacher <ag@bestbits.at>
> > 
> > ---
> >  fs/namei.c |   11 ++++++-----
> >  1 file changed, 6 insertions(+), 5 deletions(-)
> > 
> > --- a/fs/namei.c
> > +++ b/fs/namei.c
> > @@ -292,14 +292,15 @@ int vfs_permission(struct vfs_lookup *lo
> >   *
> >   * Used to check for read/write/execute permissions on an already opened
> >   * file.
> > - *
> > - * Note:
> > - *	Do not use this function in new code.  All access checks should
> > - *	be done using vfs_permission().
> 
> Should this comment be removed?

IMO yes. If vfs_permission() works for a piece of code it's the obvious 
preference. If on the other hand you really need to check permissions on a 
file, then why not use this function?

> >   */
> >  int file_permission(struct file *file, int mask)
> >  {
> > -	return permission(file->f_path.dentry->d_inode, mask, NULL);
> > +	struct vfs_lookup lookup;
> > +
> > +	lookup.path = file->f_path;
> > +	lookup.flags = 0;
> 
> I tend to find this little bit cleaner:
> 
> struct vfs_lookup lookup = {
> 	.path	= file->f_path,
> 	.flags	= 0,
> };

I didn't use initializers because they initialize the entire data structure. 
In case of struct vfs_lookup, unless the LOOKUP_OPEN flag is set, then the 
open_intent doesn't need initialization. We could use a DEFINE_... macro; not 
sure this would improve anything though.

> > +
> > +	return permission(file->f_path.dentry->d_inode, mask, &lookup);
> >  }
> >  
> >  /*

Thanks,
Andreas

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [RFC 04/10] Temporary struct vfs_lookup in file_permission
  2007-08-08 17:16 ` [RFC 04/10] Temporary struct vfs_lookup in file_permission Andreas Gruenbacher
  2007-08-08 17:58   ` Josef Sipek
@ 2007-08-08 19:25   ` Christoph Hellwig
  2007-08-08 21:41     ` Andreas Gruenbacher
  1 sibling, 1 reply; 35+ messages in thread
From: Christoph Hellwig @ 2007-08-08 19:25 UTC (permalink / raw)
  To: Andreas Gruenbacher
  Cc: linux-kernel, John Johansen, Jan Blunck, Erez Zadok,
	Josef 'Jeff' Sipek

On Wed, Aug 08, 2007 at 07:16:26PM +0200, Andreas Gruenbacher wrote:
> Create a temporary struct vfs_lookup in file_permission() instead of
> passing a NULL value.

NACK.  file_permission is special in that it doesn't happen in the
context of any kind of lookup operation, and the nd/intent paramater
to ->permission should be NULL in that case instead of faking up some crap.


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [RFC 05/10] Use vfs_permission instead of file_permission in sys_fchdir
  2007-08-08 17:16 ` [RFC 05/10] Use vfs_permission instead of file_permission in sys_fchdir Andreas Gruenbacher
@ 2007-08-08 19:26   ` Christoph Hellwig
  0 siblings, 0 replies; 35+ messages in thread
From: Christoph Hellwig @ 2007-08-08 19:26 UTC (permalink / raw)
  To: Andreas Gruenbacher
  Cc: linux-kernel, John Johansen, Jan Blunck, Erez Zadok,
	Josef 'Jeff' Sipek

On Wed, Aug 08, 2007 at 07:16:27PM +0200, Andreas Gruenbacher wrote:
> Create a temporary vfs_lookup object, and use vfs_permission instead
> of file_permission() in sys_fchdir().

NACK for the same reason as the previous one.


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [RFC 06/10] Use vfs_permission instead of file_permission in do_path_lookup
  2007-08-08 17:16 ` [RFC 06/10] Use vfs_permission instead of file_permission in do_path_lookup Andreas Gruenbacher
@ 2007-08-08 19:27   ` Christoph Hellwig
  0 siblings, 0 replies; 35+ messages in thread
From: Christoph Hellwig @ 2007-08-08 19:27 UTC (permalink / raw)
  To: Andreas Gruenbacher
  Cc: linux-kernel, John Johansen, Jan Blunck, Erez Zadok,
	Josef 'Jeff' Sipek

On Wed, Aug 08, 2007 at 07:16:28PM +0200, Andreas Gruenbacher wrote:
> Switch from file_permission() to vfs_permission() in do_path_lookup()
> by filling in the vfs_lookup in nd slightly earlier.

While this one is okay because it is part of a lookup operation.

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [RFC 01/10] Split up struct nameidata
  2007-08-08 17:16 ` [RFC 01/10] Split up struct nameidata Andreas Gruenbacher
@ 2007-08-08 19:32   ` Christoph Hellwig
  2007-08-09  8:26     ` atomic open (was Re: [RFC 01/10] Split up struct nameidata) Miklos Szeredi
  2007-08-10 14:42     ` [RFC 01/10] Split up struct nameidata Andreas Gruenbacher
  0 siblings, 2 replies; 35+ messages in thread
From: Christoph Hellwig @ 2007-08-08 19:32 UTC (permalink / raw)
  To: Andreas Gruenbacher
  Cc: linux-kernel, John Johansen, Jan Blunck, Erez Zadok,
	Josef 'Jeff' Sipek

On Wed, Aug 08, 2007 at 07:16:23PM +0200, Andreas Gruenbacher wrote:
> Split up struct nameidata into struct vfs_lookup with the lookup result
> and intent and the remaining fields for performing an actual lookup.

Looks good as a start, but please don't put a struct path in there,
as the vfsmount will go away from the lookup intent as soon as we have
a new inode operation for atomic create + open, and not having it in the
struct path will make that removal a lot less painfull.


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [RFC 08/10] Pass no NULL vfs_lookup to vfs_create
  2007-08-08 17:16 ` [RFC 08/10] Pass no NULL vfs_lookup to vfs_create Andreas Gruenbacher
@ 2007-08-08 19:36   ` Christoph Hellwig
  0 siblings, 0 replies; 35+ messages in thread
From: Christoph Hellwig @ 2007-08-08 19:36 UTC (permalink / raw)
  To: Andreas Gruenbacher
  Cc: linux-kernel, John Johansen, Jan Blunck, Erez Zadok,
	Josef 'Jeff' Sipek

On Wed, Aug 08, 2007 at 07:16:30PM +0200, Andreas Gruenbacher wrote:
> Never pass a NULL vfs_lookup to vfs_create() or iop->create by creating
> temporary vfs_lookup objects where needed. Remove the obsolete NULL
> checks.

ipc/mqueue.c should be rewritten to use vfs_path_lookup instead.

nfsd is special - people need to deal with the !nameidata or !intent
case anyway because the fs/exportfs/expfs.c code uses lookup_one_len
all over when the filesystem is mared nfs exportable, but fortunately
the filesystem that are nfs exportable are usually not those using
intents.  We might eventually fix this one day by having some kind
open by handle intent, but that should come as part of a large
patch series where we qualify the type of lookup for every single
lookup.

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [RFC 04/10] Temporary struct vfs_lookup in file_permission
  2007-08-08 19:25   ` Christoph Hellwig
@ 2007-08-08 21:41     ` Andreas Gruenbacher
  2007-08-08 23:24       ` Christoph Hellwig
  0 siblings, 1 reply; 35+ messages in thread
From: Andreas Gruenbacher @ 2007-08-08 21:41 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: linux-kernel, John Johansen, Jan Blunck, Erez Zadok,
	Josef 'Jeff' Sipek

On Wednesday 08 August 2007 21:25, Christoph Hellwig wrote:
> On Wed, Aug 08, 2007 at 07:16:26PM +0200, Andreas Gruenbacher wrote:
> > Create a temporary struct vfs_lookup in file_permission() instead of
> > passing a NULL value.
> 
> NACK.  file_permission is special in that it doesn't happen in the
> context of any kind of lookup operation, and the nd/intent paramater
> to ->permission should be NULL in that case instead of faking up some crap.

Lookup or not doesn't actually matter. Think of fchdir(2): it does a 
permission check, and it should also pass down the LOOKUP_CHDIR flag. (Yes I 
know, it doesn't do that right now. Bug.) I can't think of a better example 
right now, but the intent does not only make sense in lookup context.

It's true that filesystems should never touch vfsmnts -- except for a few rare 
exceptions. Filesystem stacking is one. NFS silly-rename is another: if the 
vfsmnt of the object being silly-renamed were passed down to the file system, 
we would mntget() it. Right now there is a reference counting bug that allows 
to blow up the kernel by unmounting that mount point before the silly-renamed 
file is closed. (It's client-side only of course, but still.) The vfsmnt that 
this patch passes down in file_permission() is not some crap as you chose to 
call it, it's the appropriate vfsmnt.

Last but not least, file_permission() is a vfs function not a filesystem 
operation. It indirectly calls into security_inode_permission(). We need the 
vfsmnt there for path-based LSMs, for operations like fchmod(2). But that's a 
different set of patches, and a different discussion.

Thanks,
Andreas

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [RFC 04/10] Temporary struct vfs_lookup in file_permission
  2007-08-08 21:41     ` Andreas Gruenbacher
@ 2007-08-08 23:24       ` Christoph Hellwig
  2007-08-09 17:23         ` Andreas Gruenbacher
  0 siblings, 1 reply; 35+ messages in thread
From: Christoph Hellwig @ 2007-08-08 23:24 UTC (permalink / raw)
  To: Andreas Gruenbacher
  Cc: Christoph Hellwig, linux-kernel, John Johansen, Jan Blunck,
	Erez Zadok, Josef 'Jeff' Sipek

On Wed, Aug 08, 2007 at 11:41:06PM +0200, Andreas Gruenbacher wrote:
> Lookup or not doesn't actually matter. Think of fchdir(2): it does a 
> permission check, and it should also pass down the LOOKUP_CHDIR flag.

fchdir per defintion doesn't do any lookup, and it should not pretend to be
doing one.

> It's true that filesystems should never touch vfsmnts -- except for a few rare 
> exceptions. Filesystem stacking is one. NFS silly-rename is another: if the 
> vfsmnt of the object being silly-renamed were passed down to the file system, 
> we would mntget() it. Right now there is a reference counting bug that allows 
> to blow up the kernel by unmounting that mount point before the silly-renamed 
> file is closed. (It's client-side only of course, but still.)

Wrong. Remember what we call unmount is two underlying operations:

 - detach the subtree from the namespace, this is the vfsmount-based operation.
   this one couldn't care less about an in-progress silly-rename
 - actually teard down the filesystem.  this is a superblock-related
   operation, and you want your reference counting for the above case
   to be on the superblock level if at all.  A good explanation of
   the bug you're seeing and how you intend to fix it outside of this
   slightly heated thread might help, though..

Remember that passing down the vfsmount to the filesystem for namespace
operations is actually harmful, because all the namespace operations must
operate independent of the actual view (aka vfsmount) it's coming from - 
all vfsmounts shared a single dentry subtree and operation on either of
them must give the same results.

> The vfsmnt that 
> this patch passes down in file_permission() is not some crap as you chose to 
> call it, it's the appropriate vfsmnt.

No, it's wrong.  There is no path except for informal purposes attached to
a struct file.  I created file_permission to document that clearly and
people don't try things like this.  There's lots of chances where fs passing
has happened, were into a lazily detached tree, after a pviot_root, etc where
trying to do anything that remotely looks like pathname based operation just
doesn't make any sense in this case.


^ permalink raw reply	[flat|nested] 35+ messages in thread

* atomic open (was Re: [RFC 01/10] Split up struct nameidata)
  2007-08-08 19:32   ` Christoph Hellwig
@ 2007-08-09  8:26     ` Miklos Szeredi
  2007-08-10 14:42     ` [RFC 01/10] Split up struct nameidata Andreas Gruenbacher
  1 sibling, 0 replies; 35+ messages in thread
From: Miklos Szeredi @ 2007-08-09  8:26 UTC (permalink / raw)
  To: hch; +Cc: agruen, linux-kernel, jjohansen, jblunck, ezk, jsipek

> On Wed, Aug 08, 2007 at 07:16:23PM +0200, Andreas Gruenbacher wrote:
> > Split up struct nameidata into struct vfs_lookup with the lookup result
> > and intent and the remaining fields for performing an actual lookup.
> 
> Looks good as a start, but please don't put a struct path in there,
> as the vfsmount will go away from the lookup intent as soon as we have
> a new inode operation for atomic create + open, and not having it in the
> struct path will make that removal a lot less painfull.

Btw, is the atomic open/create/truncate operation any further than
conceptual phase?  Have we worked out what to do with the ugly "create
follows symlink" case?

I'm just about to add another hack to the VFS to enable atomic
open+truncate for fuse, and have a feeling that it will provoke some
not so positive reactions ;)

Miklos

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [RFC 04/10] Temporary struct vfs_lookup in file_permission
  2007-08-08 23:24       ` Christoph Hellwig
@ 2007-08-09 17:23         ` Andreas Gruenbacher
  0 siblings, 0 replies; 35+ messages in thread
From: Andreas Gruenbacher @ 2007-08-09 17:23 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: linux-kernel, John Johansen, Jan Blunck, Erez Zadok,
	Josef 'Jeff' Sipek

On Thursday 09 August 2007 01:24, Christoph Hellwig wrote:
> On Wed, Aug 08, 2007 at 11:41:06PM +0200, Andreas Gruenbacher wrote:
> > Lookup or not doesn't actually matter. Think of fchdir(2): it does a 
> > permission check, and it should also pass down the LOOKUP_CHDIR flag.
> 
> fchdir per defintion doesn't do any lookup, and it should not pretend to be
> doing one.

fchdir doesn't pretend to do a lookup by passing the LOOKUP_CHDIR flag, it 
indicates that a chdir is being done. The lookup happened earlier at a time 
at which the kernel didn't know that a chdir would follow. If fchdir doesn't 
pass down the LOOKUP_CHDIR flag, then that flag is pretty pointless: it could 
be bypassed any time by an open followed by fchdir.

> > The vfsmnt that this patch passes down in file_permission() is not some
> > crap as you chose to call it, it's the appropriate vfsmnt.
> 
> No, it's wrong.  There is no path except for informal purposes attached to
> a struct file.

I'm sorry, but the dentry and vfsmnt in struct file is *not* only used for 
informational purposes: openat does a lookup relative to a file's dentry and 
vfsmnt, and there are other examples as well.

The dentry and vfsmnt identify a particular object in the filesystem 
hierarchy. As long as the file hasn't been deleted, they can be used to 
compute a pathname that leads to the file (if the file is reachable at all). 
You can used that pathname for more than informational purposes. It is real, 
and canonical too.

> I created file_permission to document that clearly and people don't try
> things like this. There's lots of chances where fs passing has happened,

						  ^ you must mean fd passing

> were into a lazily detached tree, after a pviot_root, etc where trying to do
> anything that remotely looks like pathname based operation just doesn't make
> any sense in this case.

What you are saying doesn't make sense. It makes perfect sense to compute the 
pathname of an open file in some situations. Obviously it does not make sense 
when the file has been deleted, and you really do want to detect when a file 
has become unreachable (lazily unmounted, other namespace, whatever). You 
will always find that out when trying to compute its pathname, so that's not 
an issue. (Caveat: this requires the d_path fixes I have posted earlier.)

Thanks,
Andreas

^ permalink raw reply	[flat|nested] 35+ messages in thread

* [patch 1/4] Introduce pathput
  2007-08-10 14:42     ` [RFC 01/10] Split up struct nameidata Andreas Gruenbacher
@ 2007-08-10 14:22       ` Andreas Gruenbacher
  2007-08-29 19:07         ` Christoph Hellwig
  2007-08-10 14:22       ` [patch 2/4] Use pathput in a few more places Andreas Gruenbacher
                         ` (2 subsequent siblings)
  3 siblings, 1 reply; 35+ messages in thread
From: Andreas Gruenbacher @ 2007-08-10 14:22 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: linux-kernel, John Johansen, Jan Blunck, Erez Zadok,
	Josef 'Jeff' Sipek

[-- Attachment #1: pathput.diff --]
[-- Type: text/plain, Size: 28829 bytes --]

* Add pathput() for releasing a reference to the dentry and vfsmount of a
  struct path.

* Switch from path_release(nd) to pathget(&nd->path).

* Switch from path_release_on_umount(nd) to pathput_on_umount(&nd->path).

* Rename dput_path() to pathput_conditional().

Signed-off-by: Jan Blunck <jblunck@suse.de>
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>

---
 arch/alpha/kernel/osf_sys.c                  |    2 
 arch/mips/kernel/sysirix.c                   |    6 +-
 arch/parisc/hpux/sys_hpux.c                  |    2 
 arch/powerpc/platforms/cell/spufs/syscalls.c |    2 
 arch/sparc64/solaris/fs.c                    |    4 -
 drivers/md/dm-table.c                        |    2 
 drivers/mtd/mtdsuper.c                       |    4 -
 fs/afs/mntpt.c                               |    2 
 fs/autofs4/root.c                            |    2 
 fs/block_dev.c                               |    2 
 fs/coda/pioctl.c                             |    4 -
 fs/compat.c                                  |    4 -
 fs/configfs/symlink.c                        |    4 -
 fs/dquot.c                                   |    2 
 fs/ecryptfs/main.c                           |    2 
 fs/exec.c                                    |    4 -
 fs/ext3/super.c                              |    4 -
 fs/ext4/super.c                              |    4 -
 fs/gfs2/ops_fstype.c                         |    2 
 fs/inotify_user.c                            |    4 -
 fs/namei.c                                   |   57 +++++++++++----------------
 fs/namespace.c                               |   22 +++++-----
 fs/nfs/namespace.c                           |    2 
 fs/nfsctl.c                                  |    2 
 fs/nfsd/export.c                             |   10 ++--
 fs/nfsd/nfs4recover.c                        |    2 
 fs/nfsd/nfs4state.c                          |    2 
 fs/open.c                                    |   26 ++++++------
 fs/proc/base.c                               |    2 
 fs/reiserfs/super.c                          |    8 +--
 fs/stat.c                                    |    6 +-
 fs/utimes.c                                  |    2 
 fs/xattr.c                                   |   16 +++----
 fs/xfs/linux-2.6/xfs_ioctl.c                 |    2 
 include/linux/namei.h                        |   12 +++--
 kernel/auditfilter.c                         |    4 -
 net/sunrpc/rpc_pipe.c                        |    2 
 net/unix/af_unix.c                           |    6 +-
 38 files changed, 121 insertions(+), 124 deletions(-)

--- a/arch/alpha/kernel/osf_sys.c
+++ b/arch/alpha/kernel/osf_sys.c
@@ -261,7 +261,7 @@ osf_statfs(char __user *path, struct osf
 	retval = user_path_walk(path, &nd);
 	if (!retval) {
 		retval = do_osf_statfs(nd.dentry, buffer, bufsiz);
-		path_release(&nd);
+		pathput(&nd.lookup.path);
 	}
 	return retval;
 }
--- a/arch/mips/kernel/sysirix.c
+++ b/arch/mips/kernel/sysirix.c
@@ -711,7 +711,7 @@ asmlinkage int irix_statfs(const char __
 	}
 
 dput_and_out:
-	path_release(&nd);
+	pathput(&nd.lookup.path);
 out:
 	return error;
 }
@@ -1385,7 +1385,7 @@ asmlinkage int irix_statvfs(char __user 
 		error |= __put_user(0, &buf->f_fstr[i]);
 
 dput_and_out:
-	path_release(&nd);
+	pathput(&nd.lookup.path);
 out:
 	return error;
 }
@@ -1636,7 +1636,7 @@ asmlinkage int irix_statvfs64(char __use
 		error |= __put_user(0, &buf->f_fstr[i]);
 
 dput_and_out:
-	path_release(&nd);
+	pathput(&nd.lookup.path);
 out:
 	return error;
 }
--- a/arch/parisc/hpux/sys_hpux.c
+++ b/arch/parisc/hpux/sys_hpux.c
@@ -222,7 +222,7 @@ asmlinkage long hpux_statfs(const char _
 		error = vfs_statfs_hpux(nd.dentry, &tmp);
 		if (!error && copy_to_user(buf, &tmp, sizeof(tmp)))
 			error = -EFAULT;
-		path_release(&nd);
+		pathput(&nd.lookup.path);
 	}
 	return error;
 }
--- a/arch/powerpc/platforms/cell/spufs/syscalls.c
+++ b/arch/powerpc/platforms/cell/spufs/syscalls.c
@@ -91,7 +91,7 @@ asmlinkage long do_spu_create(const char
 				LOOKUP_OPEN|LOOKUP_CREATE, &nd);
 		if (!ret) {
 			ret = spufs_create(&nd, flags, mode, neighbor);
-			path_release(&nd);
+			pathput(&nd.lookup.path);
 		}
 		putname(tmp);
 	}
--- a/arch/sparc64/solaris/fs.c
+++ b/arch/sparc64/solaris/fs.c
@@ -436,7 +436,7 @@ asmlinkage int solaris_statvfs(u32 path,
 	if (!error) {
 		struct inode * inode = nd.dentry->d_inode;
 		error = report_statvfs(nd.mnt, inode, buf);
-		path_release(&nd);
+		pathput(&nd.lookup.path);
 	}
 	return error;
 }
@@ -466,7 +466,7 @@ asmlinkage int solaris_statvfs64(u32 pat
 	if (!error) {
 		struct inode * inode = nd.dentry->d_inode;
 		error = report_statvfs64(nd.mnt, inode, buf);
-		path_release(&nd);
+		pathput(&nd.lookup.path);
 	}
 	unlock_kernel();
 	return error;
--- a/drivers/md/dm-table.c
+++ b/drivers/md/dm-table.c
@@ -370,7 +370,7 @@ static int lookup_device(const char *pat
 	*dev = inode->i_rdev;
 
  out:
-	path_release(&nd);
+	pathput(&nd.lookup.path);
 	return r;
 }
 
--- a/drivers/mtd/mtdsuper.c
+++ b/drivers/mtd/mtdsuper.c
@@ -201,7 +201,7 @@ int get_sb_mtd(struct file_system_type *
 		goto not_an_MTD_device;
 
 	mtdnr = iminor(nd.lookup.path.dentry->d_inode);
-	path_release(&nd);
+	pathput(&nd.lookup.path);
 
 	return get_sb_mtd_nr(fs_type, flags, dev_name, data, mtdnr, fill_super,
 			     mnt);
@@ -212,7 +212,7 @@ not_an_MTD_device:
 		       "MTD: Attempt to mount non-MTD device \"%s\"\n",
 		       dev_name);
 out:
-	path_release(&nd);
+	pathput(&nd.lookup.path);
 	return ret;
 
 }
--- a/fs/afs/mntpt.c
+++ b/fs/afs/mntpt.c
@@ -227,7 +227,7 @@ static void *afs_mntpt_follow_link(struc
 
 	newmnt = afs_mntpt_do_automount(nd->lookup.path.dentry);
 	if (IS_ERR(newmnt)) {
-		path_release(nd);
+		pathput(&nd->lookup.path);
 		return (void *)newmnt;
 	}
 
--- a/fs/autofs4/root.c
+++ b/fs/autofs4/root.c
@@ -382,7 +382,7 @@ done:
 	return NULL;
 
 out_error:
-	path_release(nd);
+	pathput(&nd->lookup.path);
 	return ERR_PTR(status);
 }
 
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -1398,7 +1398,7 @@ struct block_device *lookup_bdev(const c
 	if (!bdev)
 		goto fail;
 out:
-	path_release(&nd);
+	pathput(&nd.lookup.path);
 	return bdev;
 fail:
 	bdev = ERR_PTR(error);
--- a/fs/coda/pioctl.c
+++ b/fs/coda/pioctl.c
@@ -80,7 +80,7 @@ static int coda_pioctl(struct inode * in
 	
 	/* return if it is not a Coda inode */
 	if ( target_inode->i_sb != inode->i_sb ) {
-		path_release(&nd);
+		pathput(&nd.lookup.path);
 	        return  -EINVAL;
 	}
 
@@ -89,7 +89,7 @@ static int coda_pioctl(struct inode * in
 
 	error = venus_pioctl(inode->i_sb, &(cnp->c_fid), cmd, &data);
 
-	path_release(&nd);
+	pathput(&nd.lookup.path);
         return error;
 }
 
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -244,7 +244,7 @@ asmlinkage long compat_sys_statfs(const 
 		error = vfs_statfs(nd.lookup.path.dentry, &tmp);
 		if (!error)
 			error = put_compat_statfs(buf, &tmp);
-		path_release(&nd);
+		pathput(&nd.lookup.path);
 	}
 	return error;
 }
@@ -312,7 +312,7 @@ asmlinkage long compat_sys_statfs64(cons
 		error = vfs_statfs(nd.lookup.path.dentry, &tmp);
 		if (!error)
 			error = put_compat_statfs64(buf, &tmp);
-		path_release(&nd);
+		pathput(&nd.lookup.path);
 	}
 	return error;
 }
--- a/fs/configfs/symlink.c
+++ b/fs/configfs/symlink.c
@@ -103,7 +103,7 @@ static int get_target(const char *symnam
 			*target = configfs_get_config_item(nd->lookup.path.dentry);
 			if (!*target) {
 				ret = -ENOENT;
-				path_release(nd);
+				pathput(&nd->lookup.path);
 			}
 		} else
 			ret = -EPERM;
@@ -141,7 +141,7 @@ int configfs_symlink(struct inode *dir, 
 		ret = create_link(parent_item, target_item, dentry);
 
 	config_item_put(target_item);
-	path_release(&nd);
+	pathput(&nd.lookup.path);
 
 out_put:
 	config_item_put(parent_item);
--- a/fs/dquot.c
+++ b/fs/dquot.c
@@ -1552,7 +1552,7 @@ int vfs_quota_on(struct super_block *sb,
 	else
 		error = vfs_quota_on_inode(nd.lookup.path.dentry->d_inode, type, format_id);
 out_path:
-	path_release(&nd);
+	pathput(&nd.lookup.path);
 	return error;
 }
 
--- a/fs/ecryptfs/main.c
+++ b/fs/ecryptfs/main.c
@@ -500,7 +500,7 @@ static int ecryptfs_read_super(struct su
 	rc = 0;
 	goto out;
 out_free:
-	path_release(&nd);
+	pathput(&nd.lookup.path);
 out:
 	return rc;
 }
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -175,7 +175,7 @@ out:
   	return error;
 exit:
 	release_open_intent(&nd.lookup.intent.open);
-	path_release(&nd);
+	pathput(&nd.lookup.path);
 	goto out;
 }
 
@@ -699,7 +699,7 @@ out:
 			}
 		}
 		release_open_intent(&nd.lookup.intent.open);
-		path_release(&nd);
+		pathput(&nd.lookup.path);
 	}
 	goto out;
 }
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -2645,7 +2645,7 @@ static int ext3_quota_on(struct super_bl
 		return err;
 	/* Quotafile not on the same filesystem? */
 	if (nd.lookup.path.mnt->mnt_sb != sb) {
-		path_release(&nd);
+		pathput(&nd.lookup.path);
 		return -EXDEV;
 	}
 	/* Quotafile not of fs root? */
@@ -2653,7 +2653,7 @@ static int ext3_quota_on(struct super_bl
 		printk(KERN_WARNING
 			"EXT3-fs: Quota file not on filesystem root. "
 			"Journalled quota will not work.\n");
-	path_release(&nd);
+	pathput(&nd.lookup.path);
 	return vfs_quota_on(sb, type, format_id, path);
 }
 
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -2765,7 +2765,7 @@ static int ext4_quota_on(struct super_bl
 		return err;
 	/* Quotafile not on the same filesystem? */
 	if (nd.lookup.path.mnt->mnt_sb != sb) {
-		path_release(&nd);
+		pathput(&nd.lookup.path);
 		return -EXDEV;
 	}
 	/* Quotafile not of fs root? */
@@ -2773,7 +2773,7 @@ static int ext4_quota_on(struct super_bl
 		printk(KERN_WARNING
 			"EXT4-fs: Quota file not on filesystem root. "
 			"Journalled quota will not work.\n");
-	path_release(&nd);
+	pathput(&nd.lookup.path);
 	return vfs_quota_on(sb, type, format_id, path);
 }
 
--- a/fs/gfs2/ops_fstype.c
+++ b/fs/gfs2/ops_fstype.c
@@ -843,7 +843,7 @@ static struct super_block* get_gfs2_sb(c
 	       "mount point %s\n", dev_name);
 
 free_nd:
-	path_release(&nd);
+	pathput(&nd.lookup.path);
 out:
 	return sb;
 }
--- a/fs/inotify_user.c
+++ b/fs/inotify_user.c
@@ -351,7 +351,7 @@ static int find_inode(const char __user 
 	/* you can only watch an inode if you have read permissions on it */
 	error = vfs_permission(&nd->lookup, MAY_READ);
 	if (error)
-		path_release(nd);
+		pathput(&nd->lookup.path);
 	return error;
 }
 
@@ -648,7 +648,7 @@ asmlinkage long sys_inotify_add_watch(in
 		ret = create_watch(dev, inode, mask);
 	mutex_unlock(&dev->up_mutex);
 
-	path_release(&nd);
+	pathput(&nd.lookup.path);
 fput_and_out:
 	fput_light(filp, fput_needed);
 	return ret;
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -349,20 +349,14 @@ int deny_write_access(struct file * file
 	return 0;
 }
 
-void path_release(struct nameidata *nd)
-{
-	dput(nd->lookup.path.dentry);
-	mntput(nd->lookup.path.mnt);
-}
-
 /*
- * umount() mustn't call path_release()/mntput() as that would clear
+ * umount() mustn't call pathput()/mntput() as that would clear
  * mnt_expiry_mark
  */
-void path_release_on_umount(struct nameidata *nd)
+void pathput_on_umount(struct path *path)
 {
-	dput(nd->lookup.path.dentry);
-	mntput_no_expire(nd->lookup.path.mnt);
+	dput(path->dentry);
+	mntput_no_expire(path->mnt);
 }
 
 /**
@@ -549,7 +543,7 @@ static __always_inline int __vfs_follow_
 		goto fail;
 
 	if (*link == '/') {
-		path_release(nd);
+		pathput(&nd->lookup.path);
 		if (!walk_init_root(link, nd))
 			/* weird __emul_prefix() stuff did it */
 			goto out;
@@ -565,18 +559,18 @@ out:
 	 */
 	name = __getname();
 	if (unlikely(!name)) {
-		path_release(nd);
+		pathput(&nd->lookup.path);
 		return -ENOMEM;
 	}
 	strcpy(name, nd->last.name);
 	nd->last.name = name;
 	return 0;
 fail:
-	path_release(nd);
+	pathput(&nd->lookup.path);
 	return PTR_ERR(link);
 }
 
-static inline void dput_path(struct path *path, struct nameidata *nd)
+static inline void pathput_conditional(struct path *path, struct nameidata *nd)
 {
 	dput(path->dentry);
 	if (path->mnt != nd->lookup.path.mnt)
@@ -649,8 +643,8 @@ static inline int do_follow_link(struct 
 	nd->depth--;
 	return err;
 loop:
-	dput_path(path, nd);
-	path_release(nd);
+	pathput_conditional(path, nd);
+	pathput(&nd->lookup.path);
 	return err;
 }
 
@@ -989,10 +983,10 @@ return_reval:
 return_base:
 		return 0;
 out_dput:
-		dput_path(&next, nd);
+		pathput_conditional(&next, nd);
 		break;
 	}
-	path_release(nd);
+	pathput(&nd->lookup.path);
 return_err:
 	return err;
 }
@@ -1065,7 +1059,7 @@ static int __emul_lookup_dentry(const ch
 				mntput(old_mnt);
 				return 1;
 			}
-			path_release(nd);
+			pathput(&nd->lookup.path);
 		}
 		nd->lookup.path.dentry = old_dentry;
 		nd->lookup.path.mnt = old_mnt;
@@ -1223,7 +1217,7 @@ static int __path_lookup_intent_open(int
 	if (IS_ERR(nd->lookup.intent.open.file)) {
 		if (err == 0) {
 			err = PTR_ERR(nd->lookup.intent.open.file);
-			path_release(nd);
+			pathput(&nd->lookup.path);
 		}
 	} else if (err != 0)
 		release_open_intent(&nd->lookup.intent.open);
@@ -1783,11 +1777,11 @@ ok:
 	return 0;
 
 exit_dput:
-	dput_path(&path, nd);
+	pathput_conditional(&path, nd);
 exit:
 	if (!IS_ERR(nd->lookup.intent.open.file))
 		release_open_intent(&nd->lookup.intent.open);
-	path_release(nd);
+	pathput(&nd->lookup.path);
 	return error;
 
 do_link:
@@ -1957,7 +1951,7 @@ asmlinkage long sys_mknodat(int dfd, con
 		dput(dentry);
 	}
 	mutex_unlock(&nd.lookup.path.dentry->d_inode->i_mutex);
-	path_release(&nd);
+	pathput(&nd.lookup.path);
 out:
 	putname(tmp);
 
@@ -2017,7 +2011,7 @@ asmlinkage long sys_mkdirat(int dfd, con
 	dput(dentry);
 out_unlock:
 	mutex_unlock(&nd.lookup.path.dentry->d_inode->i_mutex);
-	path_release(&nd);
+	pathput(&nd.lookup.path);
 out:
 	putname(tmp);
 out_err:
@@ -2125,7 +2119,7 @@ static long do_rmdir(int dfd, const char
 exit2:
 	mutex_unlock(&nd.lookup.path.dentry->d_inode->i_mutex);
 exit1:
-	path_release(&nd);
+	pathput(&nd.lookup.path);
 exit:
 	putname(name);
 	return error;
@@ -2208,7 +2202,7 @@ static long do_unlinkat(int dfd, const c
 	if (inode)
 		iput(inode);	/* truncate the inode here */
 exit1:
-	path_release(&nd);
+	pathput(&nd.lookup.path);
 exit:
 	putname(name);
 	return error;
@@ -2285,7 +2279,7 @@ asmlinkage long sys_symlinkat(const char
 	dput(dentry);
 out_unlock:
 	mutex_unlock(&nd.lookup.path.dentry->d_inode->i_mutex);
-	path_release(&nd);
+	pathput(&nd.lookup.path);
 out:
 	putname(to);
 out_putname:
@@ -2381,9 +2375,9 @@ asmlinkage long sys_linkat(int olddfd, c
 out_unlock:
 	mutex_unlock(&nd.lookup.path.dentry->d_inode->i_mutex);
 out_release:
-	path_release(&nd);
+	pathput(&nd.lookup.path);
 out:
-	path_release(&old_nd);
+	pathput(&old_nd.lookup.path);
 exit:
 	putname(to);
 
@@ -2611,9 +2605,9 @@ exit4:
 exit3:
 	unlock_rename(new_dir, old_dir);
 exit2:
-	path_release(&newnd);
+	pathput(&newnd.lookup.path);
 exit1:
-	path_release(&oldnd);
+	pathput(&oldnd.lookup.path);
 exit:
 	return error;
 }
@@ -2811,7 +2805,6 @@ EXPORT_SYMBOL(page_symlink);
 EXPORT_SYMBOL(page_symlink_inode_operations);
 EXPORT_SYMBOL(path_lookup);
 EXPORT_SYMBOL(vfs_path_lookup);
-EXPORT_SYMBOL(path_release);
 EXPORT_SYMBOL(permission);
 EXPORT_SYMBOL(vfs_permission);
 EXPORT_SYMBOL(file_permission);
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -648,7 +648,7 @@ asmlinkage long sys_umount(char __user *
 
 	retval = do_umount(nd.lookup.path.mnt, flags);
 dput_and_out:
-	path_release_on_umount(&nd);
+	pathput_on_umount(&nd.lookup.path);
 out:
 	return retval;
 }
@@ -940,7 +940,7 @@ static int do_loopback(struct nameidata 
 
 out:
 	up_write(&namespace_sem);
-	path_release(&old_nd);
+	pathput(&old_nd.lookup.path);
 	return err;
 }
 
@@ -1051,8 +1051,8 @@ out1:
 out:
 	up_write(&namespace_sem);
 	if (!err)
-		path_release(&parent_nd);
-	path_release(&old_nd);
+		pathput(&parent_nd.lookup.path);
+	pathput(&old_nd.lookup.path);
 	return err;
 }
 
@@ -1435,7 +1435,7 @@ long do_mount(char *dev_name, char *dir_
 		retval = do_new_mount(&nd, type_page, flags, mnt_flags,
 				      dev_name, data_page);
 dput_out:
-	path_release(&nd);
+	pathput(&nd.lookup.path);
 	return retval;
 }
 
@@ -1689,7 +1689,7 @@ asmlinkage long sys_pivot_root(const cha
 
 	error = security_sb_pivotroot(&old_nd, &new_nd);
 	if (error) {
-		path_release(&old_nd);
+		pathput(&old_nd.lookup.path);
 		goto out1;
 	}
 
@@ -1748,15 +1748,15 @@ asmlinkage long sys_pivot_root(const cha
 	chroot_fs_refs(&user_nd, &new_nd);
 	security_sb_post_pivotroot(&user_nd, &new_nd);
 	error = 0;
-	path_release(&root_parent);
-	path_release(&parent_nd);
+	pathput(&root_parent.lookup.path);
+	pathput(&parent_nd.lookup.path);
 out2:
 	mutex_unlock(&old_nd.lookup.path.dentry->d_inode->i_mutex);
 	up_write(&namespace_sem);
-	path_release(&user_nd);
-	path_release(&old_nd);
+	pathput(&user_nd.lookup.path);
+	pathput(&old_nd.lookup.path);
 out1:
-	path_release(&new_nd);
+	pathput(&new_nd.lookup.path);
 out0:
 	unlock_kernel();
 	return error;
--- a/fs/nfs/namespace.c
+++ b/fs/nfs/namespace.c
@@ -146,7 +146,7 @@ out:
 	dprintk("<-- nfs_follow_mountpoint() = %d\n", err);
 	return ERR_PTR(err);
 out_err:
-	path_release(nd);
+	pathput(&nd->lookup.path);
 	goto out;
 out_follow:
 	while(d_mountpoint(nd->lookup.path.dentry) && follow_down(&nd->lookup.path.mnt, &nd->lookup.path.dentry))
--- a/fs/nfsctl.c
+++ b/fs/nfsctl.c
@@ -43,7 +43,7 @@ static struct file *do_open(char *name, 
 	if (!error)
 		return dentry_open(nd.lookup.path.dentry, nd.lookup.path.mnt, flags);
 
-	path_release(&nd);
+	pathput(&nd.lookup.path);
 	return ERR_PTR(error);
 }
 
--- a/fs/nfsd/export.c
+++ b/fs/nfsd/export.c
@@ -177,7 +177,7 @@ static int expkey_parse(struct cache_det
 			cache_put(&ek->h, &svc_expkey_cache);
 		else
 			err = -ENOMEM;
-		path_release(&nd);
+		pathput(&nd.lookup.path);
 	}
 	cache_flush();
  out:
@@ -632,7 +632,7 @@ static int svc_export_parse(struct cache
 	kfree(exp.ex_uuid);
  	kfree(exp.ex_path);
 	if (nd.lookup.path.dentry)
-		path_release(&nd);
+		pathput(&nd.lookup.path);
  out_no_path:
 	if (dom)
 		auth_domain_put(dom);
@@ -1099,7 +1099,7 @@ finish:
 		cache_put(&fsid_key->h, &svc_expkey_cache);
 	if (clp)
 		auth_domain_put(clp);
-	path_release(&nd);
+	pathput(&nd.lookup.path);
 out_unlock:
 	exp_writeunlock();
 out:
@@ -1151,7 +1151,7 @@ exp_unexport(struct nfsctl_export *nxp)
 
 	err = -EINVAL;
 	exp = exp_get_by_name(dom, nd.lookup.path.mnt, nd.lookup.path.dentry, NULL);
-	path_release(&nd);
+	pathput(&nd.lookup.path);
 	if (IS_ERR(exp))
 		goto out_domain;
 
@@ -1210,7 +1210,7 @@ exp_rootfh(svc_client *clp, char *path, 
 	fh_put(&fh);
 	exp_put(exp);
 out:
-	path_release(&nd);
+	pathput(&nd.lookup.path);
 	return err;
 }
 
--- a/fs/nfsd/nfs4recover.c
+++ b/fs/nfsd/nfs4recover.c
@@ -417,5 +417,5 @@ nfsd4_shutdown_recdir(void)
 	if (!rec_dir_init)
 		return;
 	rec_dir_init = 0;
-	path_release(&rec_dir);
+	pathput(&rec_dir.lookup.path);
 }
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -3342,7 +3342,7 @@ nfs4_reset_recoverydir(char *recdir)
 		nfs4_set_recdir(recdir);
 		status = 0;
 	}
-	path_release(&nd);
+	pathput(&nd.lookup.path);
 	return status;
 }
 
--- a/fs/open.c
+++ b/fs/open.c
@@ -130,7 +130,7 @@ asmlinkage long sys_statfs(const char __
 		error = vfs_statfs_native(nd.lookup.path.dentry, &tmp);
 		if (!error && copy_to_user(buf, &tmp, sizeof(tmp)))
 			error = -EFAULT;
-		path_release(&nd);
+		pathput(&nd.lookup.path);
 	}
 	return error;
 }
@@ -149,7 +149,7 @@ asmlinkage long sys_statfs64(const char 
 		error = vfs_statfs64(nd.lookup.path.dentry, &tmp);
 		if (!error && copy_to_user(buf, &tmp, sizeof(tmp)))
 			error = -EFAULT;
-		path_release(&nd);
+		pathput(&nd.lookup.path);
 	}
 	return error;
 }
@@ -277,7 +277,7 @@ static long do_sys_truncate(const char _
 put_write_and_out:
 	put_write_access(inode);
 dput_and_out:
-	path_release(&nd);
+	pathput(&nd.lookup.path);
 out:
 	return error;
 }
@@ -456,13 +456,13 @@ asmlinkage long sys_faccessat(int dfd, c
 	/* SuS v2 requires we report a read only fs too */
 	if(res || !(mode & S_IWOTH) ||
 	   special_file(nd.lookup.path.dentry->d_inode->i_mode))
-		goto out_path_release;
+		goto out_pathput;
 
 	if(IS_RDONLY(nd.lookup.path.dentry->d_inode))
 		res = -EROFS;
 
-out_path_release:
-	path_release(&nd);
+out_pathput:
+	pathput(&nd.lookup.path);
 out:
 	current->fsuid = old_fsuid;
 	current->fsgid = old_fsgid;
@@ -493,7 +493,7 @@ asmlinkage long sys_chdir(const char __u
 	set_fs_pwd(current->fs, nd.lookup.path.mnt, nd.lookup.path.dentry);
 
 dput_and_out:
-	path_release(&nd);
+	pathput(&nd.lookup.path);
 out:
 	return error;
 }
@@ -546,7 +546,7 @@ asmlinkage long sys_chroot(const char __
 	set_fs_altroot();
 	error = 0;
 dput_and_out:
-	path_release(&nd);
+	pathput(&nd.lookup.path);
 out:
 	return error;
 }
@@ -618,7 +618,7 @@ asmlinkage long sys_fchmodat(int dfd, co
 	mutex_unlock(&inode->i_mutex);
 
 dput_and_out:
-	path_release(&nd);
+	pathput(&nd.lookup.path);
 out:
 	return error;
 }
@@ -672,7 +672,7 @@ asmlinkage long sys_chown(const char __u
 	if (error)
 		goto out;
 	error = chown_common(nd.lookup.path.dentry, user, group);
-	path_release(&nd);
+	pathput(&nd.lookup.path);
 out:
 	return error;
 }
@@ -692,7 +692,7 @@ asmlinkage long sys_fchownat(int dfd, co
 	if (error)
 		goto out;
 	error = chown_common(nd.lookup.path.dentry, user, group);
-	path_release(&nd);
+	pathput(&nd.lookup.path);
 out:
 	return error;
 }
@@ -706,7 +706,7 @@ asmlinkage long sys_lchown(const char __
 	if (error)
 		goto out;
 	error = chown_common(nd.lookup.path.dentry, user, group);
-	path_release(&nd);
+	pathput(&nd.lookup.path);
 out:
 	return error;
 }
@@ -887,7 +887,7 @@ struct file *nameidata_to_filp(struct na
 	if (filp->f_path.dentry == NULL)
 		filp = __dentry_open(nd->lookup.path.dentry, nd->lookup.path.mnt, flags, filp, NULL);
 	else
-		path_release(nd);
+		pathput(&nd->lookup.path);
 	return filp;
 }
 
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -938,7 +938,7 @@ static void *proc_pid_follow_link(struct
 	int error = -EACCES;
 
 	/* We don't need a base pointer in the /proc filesystem */
-	path_release(nd);
+	pathput(&nd->lookup.path);
 
 	/* Are we allowed to snoop on the tasks file descriptors? */
 	if (!proc_fd_access_allowed(inode))
--- a/fs/reiserfs/super.c
+++ b/fs/reiserfs/super.c
@@ -1983,20 +1983,20 @@ static int reiserfs_quota_on(struct supe
 		return err;
 	/* Quotafile not on the same filesystem? */
 	if (nd.lookup.path.mnt->mnt_sb != sb) {
-		path_release(&nd);
+		pathput(&nd.lookup.path);
 		return -EXDEV;
 	}
 	/* We must not pack tails for quota files on reiserfs for quota IO to work */
 	if (!REISERFS_I(nd.lookup.path.dentry->d_inode)->i_flags & i_nopack_mask) {
 		reiserfs_warning(sb,
 				 "reiserfs: Quota file must have tail packing disabled.");
-		path_release(&nd);
+		pathput(&nd.lookup.path);
 		return -EINVAL;
 	}
 	/* Not journalling quota? No more tests needed... */
 	if (!REISERFS_SB(sb)->s_qf_names[USRQUOTA] &&
 	    !REISERFS_SB(sb)->s_qf_names[GRPQUOTA]) {
-		path_release(&nd);
+		pathput(&nd.lookup.path);
 		return vfs_quota_on(sb, type, format_id, path);
 	}
 	/* Quotafile not of fs root? */
@@ -2004,7 +2004,7 @@ static int reiserfs_quota_on(struct supe
 		reiserfs_warning(sb,
 				 "reiserfs: Quota file not on filesystem root. "
 				 "Journalled quota will not work.");
-	path_release(&nd);
+	pathput(&nd.lookup.path);
 	return vfs_quota_on(sb, type, format_id, path);
 }
 
--- a/fs/stat.c
+++ b/fs/stat.c
@@ -63,7 +63,7 @@ int vfs_stat_fd(int dfd, char __user *na
 	error = __user_walk_fd(dfd, name, LOOKUP_FOLLOW, &nd);
 	if (!error) {
 		error = vfs_getattr(nd.lookup.path.mnt, nd.lookup.path.dentry, stat);
-		path_release(&nd);
+		pathput(&nd.lookup.path);
 	}
 	return error;
 }
@@ -83,7 +83,7 @@ int vfs_lstat_fd(int dfd, char __user *n
 	error = __user_walk_fd(dfd, name, 0, &nd);
 	if (!error) {
 		error = vfs_getattr(nd.lookup.path.mnt, nd.lookup.path.dentry, stat);
-		path_release(&nd);
+		pathput(&nd.lookup.path);
 	}
 	return error;
 }
@@ -312,7 +312,7 @@ asmlinkage long sys_readlinkat(int dfd, 
 				error = inode->i_op->readlink(nd.lookup.path.dentry, buf, bufsiz);
 			}
 		}
-		path_release(&nd);
+		pathput(&nd.lookup.path);
 	}
 	return error;
 }
--- a/fs/utimes.c
+++ b/fs/utimes.c
@@ -124,7 +124,7 @@ dput_and_out:
 	if (f)
 		fput(f);
 	else
-		path_release(&nd);
+		pathput(&nd.lookup.path);
 out:
 	return error;
 }
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -236,7 +236,7 @@ sys_setxattr(char __user *path, char __u
 	if (error)
 		return error;
 	error = setxattr(nd.lookup.path.dentry, name, value, size, flags);
-	path_release(&nd);
+	pathput(&nd.lookup.path);
 	return error;
 }
 
@@ -251,7 +251,7 @@ sys_lsetxattr(char __user *path, char __
 	if (error)
 		return error;
 	error = setxattr(nd.lookup.path.dentry, name, value, size, flags);
-	path_release(&nd);
+	pathput(&nd.lookup.path);
 	return error;
 }
 
@@ -321,7 +321,7 @@ sys_getxattr(char __user *path, char __u
 	if (error)
 		return error;
 	error = getxattr(nd.lookup.path.dentry, name, value, size);
-	path_release(&nd);
+	pathput(&nd.lookup.path);
 	return error;
 }
 
@@ -336,7 +336,7 @@ sys_lgetxattr(char __user *path, char __
 	if (error)
 		return error;
 	error = getxattr(nd.lookup.path.dentry, name, value, size);
-	path_release(&nd);
+	pathput(&nd.lookup.path);
 	return error;
 }
 
@@ -395,7 +395,7 @@ sys_listxattr(char __user *path, char __
 	if (error)
 		return error;
 	error = listxattr(nd.lookup.path.dentry, list, size);
-	path_release(&nd);
+	pathput(&nd.lookup.path);
 	return error;
 }
 
@@ -409,7 +409,7 @@ sys_llistxattr(char __user *path, char _
 	if (error)
 		return error;
 	error = listxattr(nd.lookup.path.dentry, list, size);
-	path_release(&nd);
+	pathput(&nd.lookup.path);
 	return error;
 }
 
@@ -456,7 +456,7 @@ sys_removexattr(char __user *path, char 
 	if (error)
 		return error;
 	error = removexattr(nd.lookup.path.dentry, name);
-	path_release(&nd);
+	pathput(&nd.lookup.path);
 	return error;
 }
 
@@ -470,7 +470,7 @@ sys_lremovexattr(char __user *path, char
 	if (error)
 		return error;
 	error = removexattr(nd.lookup.path.dentry, name);
-	path_release(&nd);
+	pathput(&nd.lookup.path);
 	return error;
 }
 
--- a/fs/xfs/linux-2.6/xfs_ioctl.c
+++ b/fs/xfs/linux-2.6/xfs_ioctl.c
@@ -94,7 +94,7 @@ xfs_find_handle(
 		ASSERT(nd.lookup.path.dentry);
 		ASSERT(nd.lookup.path.dentry->d_inode);
 		inode = igrab(nd.lookup.path.dentry->d_inode);
-		path_release(&nd);
+		pathput(&nd.lookup.path);
 		break;
 	}
 
--- a/include/linux/namei.h
+++ b/include/linux/namei.h
@@ -2,10 +2,9 @@
 #define _LINUX_NAMEI_H
 
 #include <linux/dcache.h>
+#include <linux/mount.h>
 #include <linux/linkage.h>
 
-struct vfsmount;
-
 struct open_intent {
 	int	flags;
 	int	create_mode;
@@ -74,8 +73,7 @@ extern int FASTCALL(__user_walk_fd(int d
 extern int FASTCALL(path_lookup(const char *, unsigned, struct nameidata *));
 extern int vfs_path_lookup(struct dentry *, struct vfsmount *,
 			   const char *, unsigned int, struct nameidata *);
-extern void path_release(struct nameidata *);
-extern void path_release_on_umount(struct nameidata *);
+extern void pathput_on_umount(struct path *);
 
 extern int __user_path_lookup_open(const char __user *, unsigned lookup_flags, struct nameidata *nd, int open_flags);
 extern int path_lookup_open(int dfd, const char *name, unsigned lookup_flags, struct nameidata *, int open_flags);
@@ -104,4 +102,10 @@ static inline char *nd_get_link(struct n
 	return nd->saved_names[nd->depth];
 }
 
+static inline void pathput(struct path *path)
+{
+	dput(path->dentry);
+	mntput(path->mnt);
+}
+
 #endif /* _LINUX_NAMEI_H */
--- a/kernel/auditfilter.c
+++ b/kernel/auditfilter.c
@@ -1123,11 +1123,11 @@ static int audit_get_nd(char *path, stru
 static void audit_put_nd(struct nameidata *ndp, struct nameidata *ndw)
 {
 	if (ndp) {
-		path_release(ndp);
+		pathput(&ndp->lookup.path);
 		kfree(ndp);
 	}
 	if (ndw) {
-		path_release(ndw);
+		pathput(&ndw->lookup.path);
 		kfree(ndw);
 	}
 }
--- a/net/sunrpc/rpc_pipe.c
+++ b/net/sunrpc/rpc_pipe.c
@@ -484,7 +484,7 @@ rpc_lookup_parent(char *path, struct nam
 static void
 rpc_release_path(struct nameidata *nd)
 {
-	path_release(nd);
+	pathput(&nd->lookup.path);
 	rpc_put_mount();
 }
 
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -743,7 +743,7 @@ static struct sock *unix_find_other(stru
 		if (u->sk_type == type)
 			touch_atime(nd.lookup.path.mnt, nd.lookup.path.dentry);
 
-		path_release(&nd);
+		pathput(&nd.lookup.path);
 
 		err=-EPROTOTYPE;
 		if (u->sk_type != type) {
@@ -764,7 +764,7 @@ static struct sock *unix_find_other(stru
 	return u;
 
 put_fail:
-	path_release(&nd);
+	pathput(&nd.lookup.path);
 fail:
 	*error=err;
 	return NULL;
@@ -877,7 +877,7 @@ out_mknod_dput:
 	dput(dentry);
 out_mknod_unlock:
 	mutex_unlock(&nd.lookup.path.dentry->d_inode->i_mutex);
-	path_release(&nd);
+	pathput(&nd.lookup.path);
 out_mknod_parent:
 	if (err==-EEXIST)
 		err=-EADDRINUSE;


^ permalink raw reply	[flat|nested] 35+ messages in thread

* [patch 2/4] Use pathput in a few more places
  2007-08-10 14:42     ` [RFC 01/10] Split up struct nameidata Andreas Gruenbacher
  2007-08-10 14:22       ` [patch 1/4] Introduce pathput Andreas Gruenbacher
@ 2007-08-10 14:22       ` Andreas Gruenbacher
  2007-08-29 19:08         ` Christoph Hellwig
  2007-08-10 14:22       ` [patch 3/4] Introduce pathget Andreas Gruenbacher
  2007-08-10 14:22       ` [patch 4/4] Switch to struct path in fs_struct Andreas Gruenbacher
  3 siblings, 1 reply; 35+ messages in thread
From: Andreas Gruenbacher @ 2007-08-10 14:22 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: linux-kernel, John Johansen, Jan Blunck, Erez Zadok,
	Josef 'Jeff' Sipek

[-- Attachment #1: more-pathput.diff --]
[-- Type: text/plain, Size: 2131 bytes --]

afs_mntpt_follow_link() actually does mntput before dput, which is wrong.

Signed-off-by: Jan Blunck <jblunck@suse.de>
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>

---
 fs/afs/mntpt.c |    3 +--
 fs/namei.c     |   15 +++++----------
 2 files changed, 6 insertions(+), 12 deletions(-)

--- a/fs/afs/mntpt.c
+++ b/fs/afs/mntpt.c
@@ -235,8 +235,7 @@ static void *afs_mntpt_follow_link(struc
 	err = do_add_mount(newmnt, nd, MNT_SHRINKABLE, &afs_vfsmounts);
 	switch (err) {
 	case 0:
-		mntput(nd->lookup.path.mnt);
-		dput(nd->lookup.path.dentry);
+		pathput(&nd->lookup.path);
 		nd->lookup.path.mnt = newmnt;
 		nd->lookup.path.dentry = dget(newmnt->mnt_root);
 		schedule_delayed_work(&afs_mntpt_expiry_timer,
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -610,8 +610,7 @@ static __always_inline int __do_follow_l
 		if (dentry->d_inode->i_op->put_link)
 			dentry->d_inode->i_op->put_link(dentry, nd, cookie);
 	}
-	dput(dentry);
-	mntput(path->mnt);
+	pathput(path);
 
 	return error;
 }
@@ -1016,8 +1015,7 @@ static int fastcall link_path_walk(const
 		result = __link_path_walk(name, nd);
 	}
 
-	dput(save.lookup.path.dentry);
-	mntput(save.lookup.path.mnt);
+	pathput(&save.lookup.path);
 
 	return result;
 }
@@ -1038,8 +1036,7 @@ static int __emul_lookup_dentry(const ch
 		return 0;		/* something went wrong... */
 
 	if (!nd->lookup.path.dentry->d_inode || S_ISDIR(nd->lookup.path.dentry->d_inode->i_mode)) {
-		struct dentry *old_dentry = nd->lookup.path.dentry;
-		struct vfsmount *old_mnt = nd->lookup.path.mnt;
+		struct path old_path = nd->lookup.path;
 		struct qstr last = nd->last;
 		int last_type = nd->last_type;
 		struct fs_struct *fs = current->fs;
@@ -1055,14 +1052,12 @@ static int __emul_lookup_dentry(const ch
 		read_unlock(&fs->lock);
 		if (path_walk(name, nd) == 0) {
 			if (nd->lookup.path.dentry->d_inode) {
-				dput(old_dentry);
-				mntput(old_mnt);
+				pathput(&old_path);
 				return 1;
 			}
 			pathput(&nd->lookup.path);
 		}
-		nd->lookup.path.dentry = old_dentry;
-		nd->lookup.path.mnt = old_mnt;
+		nd->lookup.path = old_path;
 		nd->last = last;
 		nd->last_type = last_type;
 	}


^ permalink raw reply	[flat|nested] 35+ messages in thread

* [patch 3/4] Introduce pathget
  2007-08-10 14:42     ` [RFC 01/10] Split up struct nameidata Andreas Gruenbacher
  2007-08-10 14:22       ` [patch 1/4] Introduce pathput Andreas Gruenbacher
  2007-08-10 14:22       ` [patch 2/4] Use pathput in a few more places Andreas Gruenbacher
@ 2007-08-10 14:22       ` Andreas Gruenbacher
  2007-08-29 19:09         ` Christoph Hellwig
  2007-08-10 14:22       ` [patch 4/4] Switch to struct path in fs_struct Andreas Gruenbacher
  3 siblings, 1 reply; 35+ messages in thread
From: Andreas Gruenbacher @ 2007-08-10 14:22 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: linux-kernel, John Johansen, Jan Blunck, Erez Zadok,
	Josef 'Jeff' Sipek

[-- Attachment #1: pathget.diff --]
[-- Type: text/plain, Size: 1390 bytes --]

This is the symmetric operation to pathput.

Signed-off-by: Jan Blunck <jblunck@suse.de>
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>

---
 fs/namei.c            |    9 +++------
 include/linux/namei.h |    8 --------
 2 files changed, 3 insertions(+), 14 deletions(-)

--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1003,14 +1003,12 @@ static int fastcall link_path_walk(const
 	int result;
 
 	/* make sure the stuff we saved doesn't go away */
-	dget(save.lookup.path.dentry);
-	mntget(save.lookup.path.mnt);
+	pathget(&save.lookup.path);
 
 	result = __link_path_walk(name, nd);
 	if (result == -ESTALE) {
 		*nd = save;
-		dget(nd->lookup.path.dentry);
-		mntget(nd->lookup.path.mnt);
+		pathget(&nd->lookup.path);
 		nd->lookup.flags |= LOOKUP_REVAL;
 		result = __link_path_walk(name, nd);
 	}
@@ -1140,8 +1138,7 @@ static int fastcall do_path_lookup(int d
 		if (retval)
 			goto fput_fail;
 
-		mntget(nd->lookup.path.mnt);
-		dget(nd->lookup.path.dentry);
+		pathget(&nd->lookup.path);
 
 		fput_light(file, fput_needed);
 	}
--- a/include/linux/namei.h
+++ b/include/linux/namei.h
@@ -102,6 +102,14 @@ static inline char *nd_get_link(struct n
 	return nd->saved_names[nd->depth];
 }
 
+static inline struct path *pathget(struct path *path)
+{
+	mntget(path->mnt);
+	dget(path->dentry);
+
+	return path;
+}
+
 static inline void pathput(struct path *path)
 {
 	dput(path->dentry);


^ permalink raw reply	[flat|nested] 35+ messages in thread

* [patch 4/4] Switch to struct path in fs_struct
  2007-08-10 14:42     ` [RFC 01/10] Split up struct nameidata Andreas Gruenbacher
                         ` (2 preceding siblings ...)
  2007-08-10 14:22       ` [patch 3/4] Introduce pathget Andreas Gruenbacher
@ 2007-08-10 14:22       ` Andreas Gruenbacher
  2007-08-29 19:12         ` Christoph Hellwig
  3 siblings, 1 reply; 35+ messages in thread
From: Andreas Gruenbacher @ 2007-08-10 14:22 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: linux-kernel, John Johansen, Jan Blunck, Erez Zadok,
	Josef 'Jeff' Sipek

[-- Attachment #1: paths-in-fs_struct.diff --]
[-- Type: text/plain, Size: 18743 bytes --]

* Move the definition of struct path into <linux/path.h>.

* Use struct path in fs_struct. This allows to use pathget and
  pathput on a fs_struct.

Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
Signed-off-by: Jan Blunck <jblunck@suse.de>

---
 drivers/pnp/pnpbios/core.c     |    2 -
 fs/dcache.c                    |   31 ++++++++------------
 fs/namei.c                     |   47 +++++++++++--------------------
 fs/namespace.c                 |   61 ++++++++++++++++++-----------------------
 fs/proc/base.c                 |    8 ++---
 include/linux/fs_struct.h      |    6 +---
 include/linux/namei.h          |    6 ----
 include/linux/path.h           |   12 ++++++++
 init/do_mounts.c               |    6 ++--
 kernel/auditsc.c               |   27 ++++++++----------
 kernel/exit.c                  |   12 ++------
 kernel/fork.c                  |   17 ++++-------
 kernel/kmod.c                  |    2 -
 sound/core/seq/seq_clientmgr.c |    5 ++-
 sound/core/seq/seq_device.c    |    2 -
 sound/core/sound.c             |    4 +-
 sound/core/timer.c             |    2 -
 17 files changed, 110 insertions(+), 140 deletions(-)

--- a/drivers/pnp/pnpbios/core.c
+++ b/drivers/pnp/pnpbios/core.c
@@ -105,7 +105,7 @@ static int pnp_dock_event(int dock, stru
 	char *argv[3], **envp, *buf, *scratch;
 	int i = 0, value;
 
-	if (!current->fs->root)
+	if (!current->fs->root.dentry)
 		return -EAGAIN;
 	if (!(envp = kcalloc(20, sizeof(char *), GFP_KERNEL)))
 		return -ENOMEM;
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -1854,8 +1854,7 @@ char * d_path(struct dentry *dentry, str
 				char *buf, int buflen)
 {
 	char *res;
-	struct vfsmount *rootmnt;
-	struct dentry *root;
+	struct path root;
 
 	/*
 	 * We have various synthetic filesystems that never get mounted.  On
@@ -1868,14 +1867,12 @@ char * d_path(struct dentry *dentry, str
 		return dentry->d_op->d_dname(dentry, buf, buflen);
 
 	read_lock(&current->fs->lock);
-	rootmnt = mntget(current->fs->rootmnt);
-	root = dget(current->fs->root);
+	root = *pathget(&current->fs->root);
 	read_unlock(&current->fs->lock);
 	spin_lock(&dcache_lock);
-	res = __d_path(dentry, vfsmnt, root, rootmnt, buf, buflen);
+	res = __d_path(dentry, vfsmnt, root.dentry, root.mnt, buf, buflen);
 	spin_unlock(&dcache_lock);
-	dput(root);
-	mntput(rootmnt);
+	pathput(&root);
 	return res;
 }
 
@@ -1921,28 +1918,26 @@ char *dynamic_dname(struct dentry *dentr
 asmlinkage long sys_getcwd(char __user *buf, unsigned long size)
 {
 	int error;
-	struct vfsmount *pwdmnt, *rootmnt;
-	struct dentry *pwd, *root;
+	struct path pwd, root;
 	char *page = (char *) __get_free_page(GFP_USER);
 
 	if (!page)
 		return -ENOMEM;
 
 	read_lock(&current->fs->lock);
-	pwdmnt = mntget(current->fs->pwdmnt);
-	pwd = dget(current->fs->pwd);
-	rootmnt = mntget(current->fs->rootmnt);
-	root = dget(current->fs->root);
+	pwd = *pathget(&current->fs->pwd);
+	root = *pathget(&current->fs->root);
 	read_unlock(&current->fs->lock);
 
 	error = -ENOENT;
 	/* Has the current directory has been unlinked? */
 	spin_lock(&dcache_lock);
-	if (pwd->d_parent == pwd || !d_unhashed(pwd)) {
+	if (pwd.dentry->d_parent == pwd.dentry || !d_unhashed(pwd.dentry)) {
 		unsigned long len;
 		char * cwd;
 
-		cwd = __d_path(pwd, pwdmnt, root, rootmnt, page, PAGE_SIZE);
+		cwd = __d_path(pwd.dentry, pwd.mnt, root.dentry, root.mnt,
+			       page, PAGE_SIZE);
 		spin_unlock(&dcache_lock);
 
 		error = PTR_ERR(cwd);
@@ -1960,10 +1955,8 @@ asmlinkage long sys_getcwd(char __user *
 		spin_unlock(&dcache_lock);
 
 out:
-	dput(pwd);
-	mntput(pwdmnt);
-	dput(root);
-	mntput(rootmnt);
+	pathput(&pwd);
+	pathput(&root);
 	free_page((unsigned long) page);
 	return error;
 }
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -521,16 +521,14 @@ walk_init_root(const char *name, struct 
 	struct fs_struct *fs = current->fs;
 
 	read_lock(&fs->lock);
-	if (fs->altroot && !(nd->lookup.flags & LOOKUP_NOALT)) {
-		nd->lookup.path.mnt = mntget(fs->altrootmnt);
-		nd->lookup.path.dentry = dget(fs->altroot);
+	if (fs->altroot.dentry && !(nd->lookup.flags & LOOKUP_NOALT)) {
+		nd->lookup.path = *pathget(&fs->altroot);
 		read_unlock(&fs->lock);
 		if (__emul_lookup_dentry(name,nd))
 			return 0;
 		read_lock(&fs->lock);
 	}
-	nd->lookup.path.mnt = mntget(fs->rootmnt);
-	nd->lookup.path.dentry = dget(fs->root);
+	nd->lookup.path = *pathget(&fs->root);
 	read_unlock(&fs->lock);
 	return 1;
 }
@@ -727,8 +725,8 @@ static __always_inline void follow_dotdo
 		struct dentry *old = nd->lookup.path.dentry;
 
                 read_lock(&fs->lock);
-		if (nd->lookup.path.dentry == fs->root &&
-		    nd->lookup.path.mnt == fs->rootmnt) {
+		if (nd->lookup.path.dentry == fs->root.dentry &&
+		    nd->lookup.path.mnt == fs->root.mnt) {
                         read_unlock(&fs->lock);
 			break;
 		}
@@ -1045,8 +1043,7 @@ static int __emul_lookup_dentry(const ch
 		 */
 		nd->last_type = LAST_ROOT;
 		read_lock(&fs->lock);
-		nd->lookup.path.mnt = mntget(fs->rootmnt);
-		nd->lookup.path.dentry = dget(fs->root);
+		nd->lookup.path = *pathget(&fs->root);
 		read_unlock(&fs->lock);
 		if (path_walk(name, nd) == 0) {
 			if (nd->lookup.path.dentry->d_inode) {
@@ -1066,29 +1063,22 @@ void set_fs_altroot(void)
 {
 	char *emul = __emul_prefix();
 	struct nameidata nd;
-	struct vfsmount *mnt = NULL, *oldmnt;
-	struct dentry *dentry = NULL, *olddentry;
+	struct path path = { }, old_path;
 	int err;
 	struct fs_struct *fs = current->fs;
 
 	if (!emul)
 		goto set_it;
 	err = path_lookup(emul, LOOKUP_FOLLOW|LOOKUP_DIRECTORY|LOOKUP_NOALT, &nd);
-	if (!err) {
-		mnt = nd.lookup.path.mnt;
-		dentry = nd.lookup.path.dentry;
-	}
+	if (!err)
+		path = nd.lookup.path;
 set_it:
 	write_lock(&fs->lock);
-	oldmnt = fs->altrootmnt;
-	olddentry = fs->altroot;
-	fs->altrootmnt = mnt;
-	fs->altroot = dentry;
+	old_path = fs->altroot;
+	fs->altroot = path;
 	write_unlock(&fs->lock);
-	if (olddentry) {
-		dput(olddentry);
-		mntput(oldmnt);
-	}
+	if (old_path.dentry)
+		pathput(&old_path);
 }
 
 /* Returns 0 and nd will be valid on success; Retuns error, otherwise. */
@@ -1106,21 +1096,18 @@ static int fastcall do_path_lookup(int d
 
 	if (*name=='/') {
 		read_lock(&fs->lock);
-		if (fs->altroot && !(nd->lookup.flags & LOOKUP_NOALT)) {
-			nd->lookup.path.mnt = mntget(fs->altrootmnt);
-			nd->lookup.path.dentry = dget(fs->altroot);
+		if (fs->altroot.dentry && !(nd->lookup.flags & LOOKUP_NOALT)) {
+			nd->lookup.path = *pathget(&fs->altroot);
 			read_unlock(&fs->lock);
 			if (__emul_lookup_dentry(name,nd))
 				goto out; /* found in altroot */
 			read_lock(&fs->lock);
 		}
-		nd->lookup.path.mnt = mntget(fs->rootmnt);
-		nd->lookup.path.dentry = dget(fs->root);
+		nd->lookup.path = *pathget(&fs->root);
 		read_unlock(&fs->lock);
 	} else if (dfd == AT_FDCWD) {
 		read_lock(&fs->lock);
-		nd->lookup.path.mnt = mntget(fs->pwdmnt);
-		nd->lookup.path.dentry = dget(fs->pwd);
+		nd->lookup.path = *pathget(&fs->pwd);
 		read_unlock(&fs->lock);
 	} else {
 		file = fget_light(dfd, &fput_needed);
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -551,7 +551,7 @@ static int do_umount(struct vfsmount *mn
 	 *  (2) the usage count == 1 [parent vfsmount] + 1 [sys_umount]
 	 */
 	if (flags & MNT_EXPIRE) {
-		if (mnt == current->fs->rootmnt ||
+		if (mnt == current->fs->root.mnt ||
 		    flags & (MNT_FORCE | MNT_DETACH))
 			return -EINVAL;
 
@@ -586,7 +586,7 @@ static int do_umount(struct vfsmount *mn
 	 * /reboot - static binary that would close all descriptors and
 	 * call reboot(9). Then init(8) could umount root and exec /reboot.
 	 */
-	if (mnt == current->fs->rootmnt && !(flags & MNT_DETACH)) {
+	if (mnt == current->fs->root.mnt && !(flags & MNT_DETACH)) {
 		/*
 		 * Special case for "unmounting" root ...
 		 * we just try to remount it readonly.
@@ -1482,17 +1482,17 @@ static struct mnt_namespace *dup_mnt_ns(
 	while (p) {
 		q->mnt_ns = new_ns;
 		if (fs) {
-			if (p == fs->rootmnt) {
+			if (p == fs->root.mnt) {
 				rootmnt = p;
-				fs->rootmnt = mntget(q);
+				fs->root.mnt = mntget(q);
 			}
-			if (p == fs->pwdmnt) {
+			if (p == fs->pwd.mnt) {
 				pwdmnt = p;
-				fs->pwdmnt = mntget(q);
+				fs->pwd.mnt = mntget(q);
 			}
-			if (p == fs->altrootmnt) {
+			if (p == fs->altroot.mnt) {
 				altrootmnt = p;
-				fs->altrootmnt = mntget(q);
+				fs->altroot.mnt = mntget(q);
 			}
 		}
 		p = next_mnt(p, mnt_ns->root);
@@ -1570,47 +1570,41 @@ out1:
 }
 
 /*
- * Replace the fs->{rootmnt,root} with {mnt,dentry}. Put the old values.
+ * Replace fs->root with {mnt,dentry}. Put the old values.
  * It can block. Requires the big lock held.
  */
 void set_fs_root(struct fs_struct *fs, struct vfsmount *mnt,
 		 struct dentry *dentry)
 {
-	struct dentry *old_root;
-	struct vfsmount *old_rootmnt;
+	struct path old_root;
+
 	write_lock(&fs->lock);
 	old_root = fs->root;
-	old_rootmnt = fs->rootmnt;
-	fs->rootmnt = mntget(mnt);
-	fs->root = dget(dentry);
+	fs->root.mnt = mntget(mnt);
+	fs->root.dentry = dget(dentry);
 	write_unlock(&fs->lock);
-	if (old_root) {
-		dput(old_root);
-		mntput(old_rootmnt);
-	}
+
+	if (old_root.dentry)
+		pathput(&old_root);
 }
 
 /*
- * Replace the fs->{pwdmnt,pwd} with {mnt,dentry}. Put the old values.
+ * Replace fs->pwd with {mnt,dentry}. Put the old values.
  * It can block. Requires the big lock held.
  */
 void set_fs_pwd(struct fs_struct *fs, struct vfsmount *mnt,
 		struct dentry *dentry)
 {
-	struct dentry *old_pwd;
-	struct vfsmount *old_pwdmnt;
+	struct path old_pwd;
 
 	write_lock(&fs->lock);
 	old_pwd = fs->pwd;
-	old_pwdmnt = fs->pwdmnt;
-	fs->pwdmnt = mntget(mnt);
-	fs->pwd = dget(dentry);
+	fs->pwd.mnt = mntget(mnt);
+	fs->pwd.dentry = dget(dentry);
 	write_unlock(&fs->lock);
 
-	if (old_pwd) {
-		dput(old_pwd);
-		mntput(old_pwdmnt);
-	}
+	if (old_pwd.dentry)
+		pathput(&old_pwd);
 }
 
 static void chroot_fs_refs(struct nameidata *old_nd, struct nameidata *new_nd)
@@ -1625,11 +1619,11 @@ static void chroot_fs_refs(struct nameid
 		if (fs) {
 			atomic_inc(&fs->count);
 			task_unlock(p);
-			if (fs->root == old_nd->lookup.path.dentry
-			    && fs->rootmnt == old_nd->lookup.path.mnt)
+			if (fs->root.dentry == old_nd->lookup.path.dentry
+			    && fs->root.mnt == old_nd->lookup.path.mnt)
 				set_fs_root(fs, new_nd->lookup.path.mnt, new_nd->lookup.path.dentry);
-			if (fs->pwd == old_nd->lookup.path.dentry
-			    && fs->pwdmnt == old_nd->lookup.path.mnt)
+			if (fs->pwd.dentry == old_nd->lookup.path.dentry
+			    && fs->pwd.mnt == old_nd->lookup.path.mnt)
 				set_fs_pwd(fs, new_nd->lookup.path.mnt, new_nd->lookup.path.dentry);
 			put_fs_struct(fs);
 		} else
@@ -1694,8 +1688,7 @@ asmlinkage long sys_pivot_root(const cha
 	}
 
 	read_lock(&current->fs->lock);
-	user_nd.lookup.path.mnt = mntget(current->fs->rootmnt);
-	user_nd.lookup.path.dentry = dget(current->fs->root);
+	user_nd.lookup.path = *pathget(&current->fs->root);
 	read_unlock(&current->fs->lock);
 	down_write(&namespace_sem);
 	mutex_lock(&old_nd.lookup.path.dentry->d_inode->i_mutex);
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -162,8 +162,8 @@ static int proc_cwd_link(struct inode *i
 	}
 	if (fs) {
 		read_lock(&fs->lock);
-		*mnt = mntget(fs->pwdmnt);
-		*dentry = dget(fs->pwd);
+		*mnt = mntget(fs->pwd.mnt);
+		*dentry = dget(fs->pwd.dentry);
 		read_unlock(&fs->lock);
 		result = 0;
 		put_fs_struct(fs);
@@ -183,8 +183,8 @@ static int proc_root_link(struct inode *
 	}
 	if (fs) {
 		read_lock(&fs->lock);
-		*mnt = mntget(fs->rootmnt);
-		*dentry = dget(fs->root);
+		*mnt = mntget(fs->root.mnt);
+		*dentry = dget(fs->root.dentry);
 		read_unlock(&fs->lock);
 		result = 0;
 		put_fs_struct(fs);
--- a/include/linux/fs_struct.h
+++ b/include/linux/fs_struct.h
@@ -1,15 +1,13 @@
 #ifndef _LINUX_FS_STRUCT_H
 #define _LINUX_FS_STRUCT_H
 
-struct dentry;
-struct vfsmount;
+#include <linux/path.h>
 
 struct fs_struct {
 	atomic_t count;
 	rwlock_t lock;
 	int umask;
-	struct dentry * root, * pwd, * altroot;
-	struct vfsmount * rootmnt, * pwdmnt, * altrootmnt;
+	struct path root, pwd, altroot;
 };
 
 #define INIT_FS {				\
--- a/include/linux/namei.h
+++ b/include/linux/namei.h
@@ -3,6 +3,7 @@
 
 #include <linux/dcache.h>
 #include <linux/mount.h>
+#include <linux/path.h>
 #include <linux/linkage.h>
 
 struct open_intent {
@@ -13,11 +14,6 @@ struct open_intent {
 
 enum { MAX_NESTED_LINKS = 8 };
 
-struct path {
-	struct vfsmount *mnt;
-	struct dentry *dentry;
-};
-
 struct vfs_lookup {
 	struct path	 path;
 	unsigned int	flags;
--- /dev/null
+++ b/include/linux/path.h
@@ -0,0 +1,12 @@
+#ifndef _LINUX_PATH_H
+#define _LINUX_PATH_H
+
+struct dentry;
+struct vfsmount;
+
+struct path {
+	struct vfsmount *mnt;
+	struct dentry *dentry;
+};
+
+#endif  /* _LINUX_PATH_H */
--- a/init/do_mounts.c
+++ b/init/do_mounts.c
@@ -286,10 +286,10 @@ static int __init do_mount_root(char *na
 		return err;
 
 	sys_chdir("/root");
-	ROOT_DEV = current->fs->pwdmnt->mnt_sb->s_dev;
+	ROOT_DEV = current->fs->pwd.mnt->mnt_sb->s_dev;
 	printk("VFS: Mounted root (%s filesystem)%s.\n",
-	       current->fs->pwdmnt->mnt_sb->s_type->name,
-	       current->fs->pwdmnt->mnt_sb->s_flags & MS_RDONLY ? 
+	       current->fs->pwd.mnt->mnt_sb->s_type->name,
+	       current->fs->pwd.mnt->mnt_sb->s_flags & MS_RDONLY ? 
 	       " readonly" : "");
 	return 0;
 }
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -196,8 +196,7 @@ struct audit_context {
 	int		    name_count;
 	struct audit_names  names[AUDIT_NAMES];
 	char *		    filterkey;	/* key for rule that triggered record */
-	struct dentry *	    pwd;
-	struct vfsmount *   pwdmnt;
+	struct path	    pwd;
 	struct audit_context *previous; /* For nested syscalls */
 	struct audit_aux_data *aux;
 	struct audit_aux_data *aux_pids;
@@ -635,12 +634,9 @@ static inline void audit_free_names(stru
 			__putname(context->names[i].name);
 	}
 	context->name_count = 0;
-	if (context->pwd)
-		dput(context->pwd);
-	if (context->pwdmnt)
-		mntput(context->pwdmnt);
-	context->pwd = NULL;
-	context->pwdmnt = NULL;
+	pathput(&context->pwd);
+	context->pwd.dentry = NULL;
+	context->pwd.mnt = NULL;
 }
 
 static inline void audit_free_aux(struct audit_context *context)
@@ -1052,10 +1048,11 @@ static void audit_log_exit(struct audit_
 				  context->target_sid))
 			call_panic = 1;
 
-	if (context->pwd && context->pwdmnt) {
+	if (context->pwd.dentry && context->pwd.mnt) {
 		ab = audit_log_start(context, GFP_KERNEL, AUDIT_CWD);
 		if (ab) {
-			audit_log_d_path(ab, "cwd=", context->pwd, context->pwdmnt);
+			audit_log_d_path(ab, "cwd=", context->pwd.dentry,
+					 context->pwd.mnt);
 			audit_log_end(ab);
 		}
 	}
@@ -1078,8 +1075,9 @@ static void audit_log_exit(struct audit_
 			case 0:
 				/* name was specified as a relative path and the
 				 * directory component is the cwd */
-				audit_log_d_path(ab, " name=", context->pwd,
-						 context->pwdmnt);
+				audit_log_d_path(ab, " name=",
+						 context->pwd.dentry,
+						 context->pwd.mnt);
 				break;
 			default:
 				/* log the name's directory component */
@@ -1311,10 +1309,9 @@ void __audit_getname(const char *name)
 	context->names[context->name_count].ino  = (unsigned long)-1;
 	context->names[context->name_count].osid = 0;
 	++context->name_count;
-	if (!context->pwd) {
+	if (!context->pwd.dentry) {
 		read_lock(&current->fs->lock);
-		context->pwd = dget(current->fs->pwd);
-		context->pwdmnt = mntget(current->fs->pwdmnt);
+		context->pwd = *pathget(&current->fs->pwd);
 		read_unlock(&current->fs->lock);
 	}
 		
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -523,14 +523,10 @@ static inline void __put_fs_struct(struc
 {
 	/* No need to hold fs->lock if we are killing it */
 	if (atomic_dec_and_test(&fs->count)) {
-		dput(fs->root);
-		mntput(fs->rootmnt);
-		dput(fs->pwd);
-		mntput(fs->pwdmnt);
-		if (fs->altroot) {
-			dput(fs->altroot);
-			mntput(fs->altrootmnt);
-		}
+		pathput(&fs->root);
+		pathput(&fs->pwd);
+		if (fs->altroot.dentry)
+			pathput(&fs->altroot);
 		kmem_cache_free(fs_cachep, fs);
 	}
 }
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -582,16 +582,13 @@ static inline struct fs_struct *__copy_f
 		rwlock_init(&fs->lock);
 		fs->umask = old->umask;
 		read_lock(&old->lock);
-		fs->rootmnt = mntget(old->rootmnt);
-		fs->root = dget(old->root);
-		fs->pwdmnt = mntget(old->pwdmnt);
-		fs->pwd = dget(old->pwd);
-		if (old->altroot) {
-			fs->altrootmnt = mntget(old->altrootmnt);
-			fs->altroot = dget(old->altroot);
-		} else {
-			fs->altrootmnt = NULL;
-			fs->altroot = NULL;
+		fs->root = *pathget(&old->root);
+		fs->pwd = *pathget(&old->pwd);
+		if (old->altroot.dentry)
+			fs->altroot = *pathget(&old->altroot);
+		else {
+			fs->altroot.mnt = NULL;
+			fs->altroot.dentry = NULL;
 		}
 		read_unlock(&old->lock);
 	}
--- a/kernel/kmod.c
+++ b/kernel/kmod.c
@@ -174,7 +174,7 @@ static int ____call_usermodehelper(void 
 	set_user_nice(current, 0);
 
 	retval = -EPERM;
-	if (current->fs->root)
+	if (current->fs->root.dentry)
 		retval = kernel_execve(sub_info->path,
 				sub_info->argv, sub_info->envp);
 
--- a/sound/core/seq/seq_clientmgr.c
+++ b/sound/core/seq/seq_clientmgr.c
@@ -152,13 +152,14 @@ struct snd_seq_client *snd_seq_client_us
 	}
 	spin_unlock_irqrestore(&clients_lock, flags);
 #ifdef CONFIG_KMOD
-	if (!in_interrupt() && current->fs->root) {
+	if (!in_interrupt() && current->fs->root.dentry) {
 		static char client_requested[SNDRV_SEQ_GLOBAL_CLIENTS];
 		static char card_requested[SNDRV_CARDS];
 		if (clientid < SNDRV_SEQ_GLOBAL_CLIENTS) {
 			int idx;
 			
-			if (! client_requested[clientid] && current->fs->root) {
+			if (!client_requested[clientid] &&
+			    current->fs->root.dentry) {
 				client_requested[clientid] = 1;
 				for (idx = 0; idx < 15; idx++) {
 					if (seq_client_load[idx] < 0)
--- a/sound/core/seq/seq_device.c
+++ b/sound/core/seq/seq_device.c
@@ -150,7 +150,7 @@ void snd_seq_device_load_drivers(void)
 	if (snd_seq_in_init)
 		return;
 
-	if (! current->fs->root)
+	if (! current->fs->root.dentry)
 		return;
 
 	mutex_lock(&ops_mutex);
--- a/sound/core/sound.c
+++ b/sound/core/sound.c
@@ -72,7 +72,7 @@ static DEFINE_MUTEX(sound_mutex);
  */
 void snd_request_card(int card)
 {
-	if (! current->fs->root)
+	if (! current->fs->root.dentry)
 		return;
 	if (snd_card_locked(card))
 		return;
@@ -87,7 +87,7 @@ static void snd_request_other(int minor)
 {
 	char *str;
 
-	if (! current->fs->root)
+	if (! current->fs->root.dentry)
 		return;
 	switch (minor) {
 	case SNDRV_MINOR_SEQUENCER:	str = "snd-seq";	break;
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -148,7 +148,7 @@ static struct snd_timer *snd_timer_find(
 
 static void snd_timer_request(struct snd_timer_id *tid)
 {
-	if (! current->fs->root)
+	if (! current->fs->root.dentry)
 		return;
 	switch (tid->dev_class) {
 	case SNDRV_TIMER_CLASS_GLOBAL:


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [RFC 01/10] Split up struct nameidata
  2007-08-08 19:32   ` Christoph Hellwig
  2007-08-09  8:26     ` atomic open (was Re: [RFC 01/10] Split up struct nameidata) Miklos Szeredi
@ 2007-08-10 14:42     ` Andreas Gruenbacher
  2007-08-10 14:22       ` [patch 1/4] Introduce pathput Andreas Gruenbacher
                         ` (3 more replies)
  1 sibling, 4 replies; 35+ messages in thread
From: Andreas Gruenbacher @ 2007-08-10 14:42 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: linux-kernel, John Johansen, Jan Blunck, Erez Zadok,
	Josef 'Jeff' Sipek

On Wed, 08 August 2007, Christoph Hellwig wrote:
> On Wed, Aug 08, 2007 at 07:16:23PM +0200, Andreas Gruenbacher wrote:
> > Split up struct nameidata into struct vfs_lookup with the lookup result
> > and intent and the remaining fields for performing an actual lookup.
> 
> Looks good as a start, but please don't put a struct path in there,
> as the vfsmount will go away from the lookup intent as soon as we have
> a new inode operation for atomic create + open, and not having it in the
> struct path will make that removal a lot less painfull.

Removing the vfsmount from struct vfs_intent sounds like a bad idea to
me. (dentry, vfsmount) pairs should be kept together; this makes it much
more obvious what's going on.

The idea of struct vfs_lookup is not a filesystem level abstraction and
information hiding mechanism, it is to be able to pass on a lookup
result to the vfs more easily. The vfsmount is definitely part of that
result. Cleaning up atomic create + open should be mostly independent of
that.

Attached are patches that introduce pathput() and pathget(). Those are
further cleanups which depend on the struct path in the nameidata /
vfs_lookup.

Thanks,
Andreas


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [patch 1/4] Introduce pathput
  2007-08-10 14:22       ` [patch 1/4] Introduce pathput Andreas Gruenbacher
@ 2007-08-29 19:07         ` Christoph Hellwig
  2007-09-14 16:36           ` Christoph Hellwig
  0 siblings, 1 reply; 35+ messages in thread
From: Christoph Hellwig @ 2007-08-29 19:07 UTC (permalink / raw)
  To: Andreas Gruenbacher
  Cc: Christoph Hellwig, linux-kernel, John Johansen, Jan Blunck,
	Erez Zadok, Josef 'Jeff' Sipek

On Fri, Aug 10, 2007 at 04:22:09PM +0200, Andreas Gruenbacher wrote:
> * Add pathput() for releasing a reference to the dentry and vfsmount of a
>   struct path.
> 
> * Switch from path_release(nd) to pathget(&nd->path).

				^^^^^^^^^^^^^ pathput

> 
> * Switch from path_release_on_umount(nd) to pathput_on_umount(&nd->path).
> 
> * Rename dput_path() to pathput_conditional().

The introduction of pathput is fine we me.  The removal of path_release
doesn't make much sense.  We have tons of invocations of exactly that
patter, and having keeping path_release for that makes a lot of sense.

I also think there rename from dput_path to pathput_conditional is
rather pointless.  Sure, that thing needs a better name, but
pathput_conditional is not a better name.

And all of the functions could use some kerneldoc comments describing them.

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [patch 2/4] Use pathput in a few more places
  2007-08-10 14:22       ` [patch 2/4] Use pathput in a few more places Andreas Gruenbacher
@ 2007-08-29 19:08         ` Christoph Hellwig
  2007-08-30 15:01           ` [FIX] mntput called before dput in afs Andreas Gruenbacher
                             ` (2 more replies)
  0 siblings, 3 replies; 35+ messages in thread
From: Christoph Hellwig @ 2007-08-29 19:08 UTC (permalink / raw)
  To: Andreas Gruenbacher
  Cc: Christoph Hellwig, linux-kernel, John Johansen, Jan Blunck,
	Erez Zadok, Josef 'Jeff' Sipek, dhowells

On Fri, Aug 10, 2007 at 04:22:10PM +0200, Andreas Gruenbacher wrote:
> afs_mntpt_follow_link() actually does mntput before dput, which is wrong.

Please send a fix to Dave to fix this for 2.6.24 and stable even without
introducing pathput just yet.

The actual patch is fine.

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [patch 3/4] Introduce pathget
  2007-08-10 14:22       ` [patch 3/4] Introduce pathget Andreas Gruenbacher
@ 2007-08-29 19:09         ` Christoph Hellwig
  0 siblings, 0 replies; 35+ messages in thread
From: Christoph Hellwig @ 2007-08-29 19:09 UTC (permalink / raw)
  To: Andreas Gruenbacher
  Cc: Christoph Hellwig, linux-kernel, John Johansen, Jan Blunck,
	Erez Zadok, Josef 'Jeff' Sipek

On Fri, Aug 10, 2007 at 04:22:11PM +0200, Andreas Gruenbacher wrote:
> This is the symmetric operation to pathput.

The primitive looks fine to me, but it needs a kerneldoc comment describing
it.  Also I think both this and pathput should not actually be inline.


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [patch 4/4] Switch to struct path in fs_struct
  2007-08-10 14:22       ` [patch 4/4] Switch to struct path in fs_struct Andreas Gruenbacher
@ 2007-08-29 19:12         ` Christoph Hellwig
  0 siblings, 0 replies; 35+ messages in thread
From: Christoph Hellwig @ 2007-08-29 19:12 UTC (permalink / raw)
  To: Andreas Gruenbacher
  Cc: Christoph Hellwig, linux-kernel, John Johansen, Jan Blunck,
	Erez Zadok, Josef 'Jeff' Sipek

On Fri, Aug 10, 2007 at 04:22:12PM +0200, Andreas Gruenbacher wrote:
> * Move the definition of struct path into <linux/path.h>.
> 
> * Use struct path in fs_struct. This allows to use pathget and
>   pathput on a fs_struct.

Looks good.

Btw, WTF are pnpbios and sound looking at fs_struct?  They have no
right to poke there at all.

> --- /dev/null
> +++ b/include/linux/path.h
> @@ -0,0 +1,12 @@
> +#ifndef _LINUX_PATH_H
> +#define _LINUX_PATH_H
> +
> +struct dentry;
> +struct vfsmount;
> +
> +struct path {
> +	struct vfsmount *mnt;
> +	struct dentry *dentry;
> +};
> +
> +#endif  /* _LINUX_PATH_H */

This header should probably also have the prototypes for pathget/pathput


^ permalink raw reply	[flat|nested] 35+ messages in thread

* [FIX] mntput called before dput in afs
  2007-08-29 19:08         ` Christoph Hellwig
@ 2007-08-30 15:01           ` Andreas Gruenbacher
  2007-08-30 15:15           ` David Howells
  2007-08-30 15:56           ` David Howells
  2 siblings, 0 replies; 35+ messages in thread
From: Andreas Gruenbacher @ 2007-08-30 15:01 UTC (permalink / raw)
  To: David Howells; +Cc: Christoph Hellwig, linux-kernel

David,

dput must be called before mntput here. Please consider for 2.6.24 and stable.

Signed-off-by: Andreas Gruenbacher <agruen@suse.de>

---
 fs/afs/mntpt.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/fs/afs/mntpt.c
+++ b/fs/afs/mntpt.c
@@ -235,8 +235,8 @@ static void *afs_mntpt_follow_link(struc
 	err = do_add_mount(newmnt, nd, MNT_SHRINKABLE, &afs_vfsmounts);
 	switch (err) {
 	case 0:
-		mntput(nd->mnt);
 		dput(nd->dentry);
+		mntput(nd->mnt);
 		nd->mnt = newmnt;
 		nd->dentry = dget(newmnt->mnt_root);
 		schedule_delayed_work(&afs_mntpt_expiry_timer,

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [FIX] mntput called before dput in afs
  2007-08-29 19:08         ` Christoph Hellwig
  2007-08-30 15:01           ` [FIX] mntput called before dput in afs Andreas Gruenbacher
@ 2007-08-30 15:15           ` David Howells
  2007-08-30 15:56           ` David Howells
  2 siblings, 0 replies; 35+ messages in thread
From: David Howells @ 2007-08-30 15:15 UTC (permalink / raw)
  To: Andreas Gruenbacher; +Cc: dhowells, Christoph Hellwig, linux-kernel

Andreas Gruenbacher <agruen@suse.de> wrote:

> dput must be called before mntput here. Please consider for 2.6.24 and stable.
> 
> Signed-off-by: Andreas Gruenbacher <agruen@suse.de>

Fine by me.

Acked-By: David Howells <dhowells@redhat.com>

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [FIX] mntput called before dput in afs
  2007-08-29 19:08         ` Christoph Hellwig
  2007-08-30 15:01           ` [FIX] mntput called before dput in afs Andreas Gruenbacher
  2007-08-30 15:15           ` David Howells
@ 2007-08-30 15:56           ` David Howells
  2 siblings, 0 replies; 35+ messages in thread
From: David Howells @ 2007-08-30 15:56 UTC (permalink / raw)
  To: akpm; +Cc: dhowells, Christoph Hellwig, linux-kernel, Andreas Gruenbacher


From: Andreas Gruenbacher <agruen@suse.de>

dput must be called before mntput here. Please consider for 2.6.24 and stable.

Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
Acked-By: David Howells <dhowells@redhat.com>

---
 fs/afs/mntpt.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/fs/afs/mntpt.c
+++ b/fs/afs/mntpt.c
@@ -235,8 +235,8 @@ static void *afs_mntpt_follow_link(struc
 	err = do_add_mount(newmnt, nd, MNT_SHRINKABLE, &afs_vfsmounts);
 	switch (err) {
 	case 0:
-		mntput(nd->mnt);
 		dput(nd->dentry);
+		mntput(nd->mnt);
 		nd->mnt = newmnt;
 		nd->dentry = dget(newmnt->mnt_root);
 		schedule_delayed_work(&afs_mntpt_expiry_timer,


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [patch 1/4] Introduce pathput
  2007-08-29 19:07         ` Christoph Hellwig
@ 2007-09-14 16:36           ` Christoph Hellwig
  0 siblings, 0 replies; 35+ messages in thread
From: Christoph Hellwig @ 2007-09-14 16:36 UTC (permalink / raw)
  To: Christoph Hellwig, Andreas Gruenbacher, linux-kernel,
	John Johansen, Jan Blunck, Erez Zadok,
	Josef 'Jeff' Sipek

On Wed, Aug 29, 2007 at 08:07:10PM +0100, Christoph Hellwig wrote:
> > * Switch from path_release_on_umount(nd) to pathput_on_umount(&nd->path).
> > 
> > * Rename dput_path() to pathput_conditional().
> 
> The introduction of pathput is fine we me.  The removal of path_release
> doesn't make much sense.  We have tons of invocations of exactly that
> patter, and having keeping path_release for that makes a lot of sense.

After some private discussion on this I think I was overruled, so feel
free to keep that change.  Al also suggested to rename the things
to path_get/path_put which makes sense.

Any chance you could respin the series with the review comments addressed
so that there is a chance to get it into 2.6.24?

^ permalink raw reply	[flat|nested] 35+ messages in thread

end of thread, other threads:[~2007-09-14 16:36 UTC | newest]

Thread overview: 35+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-08-08 17:16 [RFC 00/10] Split up struct nameidata (take 3) Andreas Gruenbacher
2007-08-08 17:16 ` [RFC 01/10] Split up struct nameidata Andreas Gruenbacher
2007-08-08 19:32   ` Christoph Hellwig
2007-08-09  8:26     ` atomic open (was Re: [RFC 01/10] Split up struct nameidata) Miklos Szeredi
2007-08-10 14:42     ` [RFC 01/10] Split up struct nameidata Andreas Gruenbacher
2007-08-10 14:22       ` [patch 1/4] Introduce pathput Andreas Gruenbacher
2007-08-29 19:07         ` Christoph Hellwig
2007-09-14 16:36           ` Christoph Hellwig
2007-08-10 14:22       ` [patch 2/4] Use pathput in a few more places Andreas Gruenbacher
2007-08-29 19:08         ` Christoph Hellwig
2007-08-30 15:01           ` [FIX] mntput called before dput in afs Andreas Gruenbacher
2007-08-30 15:15           ` David Howells
2007-08-30 15:56           ` David Howells
2007-08-10 14:22       ` [patch 3/4] Introduce pathget Andreas Gruenbacher
2007-08-29 19:09         ` Christoph Hellwig
2007-08-10 14:22       ` [patch 4/4] Switch to struct path in fs_struct Andreas Gruenbacher
2007-08-29 19:12         ` Christoph Hellwig
2007-08-08 17:16 ` [RFC 02/10] Switch from nd->{mnt,dentry} to nd->lookup.path.{mnt,dentry} Andreas Gruenbacher
2007-08-08 17:16 ` [RFC 03/10] Pass no unnecessary information to iop->permission Andreas Gruenbacher
2007-08-08 17:16 ` [RFC 04/10] Temporary struct vfs_lookup in file_permission Andreas Gruenbacher
2007-08-08 17:58   ` Josef Sipek
2007-08-08 18:56     ` Andreas Gruenbacher
2007-08-08 19:25   ` Christoph Hellwig
2007-08-08 21:41     ` Andreas Gruenbacher
2007-08-08 23:24       ` Christoph Hellwig
2007-08-09 17:23         ` Andreas Gruenbacher
2007-08-08 17:16 ` [RFC 05/10] Use vfs_permission instead of file_permission in sys_fchdir Andreas Gruenbacher
2007-08-08 19:26   ` Christoph Hellwig
2007-08-08 17:16 ` [RFC 06/10] Use vfs_permission instead of file_permission in do_path_lookup Andreas Gruenbacher
2007-08-08 19:27   ` Christoph Hellwig
2007-08-08 17:16 ` [RFC 07/10] Pass no unnecessary information to iop->create Andreas Gruenbacher
2007-08-08 17:16 ` [RFC 08/10] Pass no NULL vfs_lookup to vfs_create Andreas Gruenbacher
2007-08-08 19:36   ` Christoph Hellwig
2007-08-08 17:16 ` [RFC 09/10] Pass no unnecessary information to dop->d_revalidate Andreas Gruenbacher
2007-08-08 17:16 ` [RFC 10/10] Pass no unnecessary information to iop->lookup Andreas Gruenbacher

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).