Patches contributed by State University of New York at Stony Brook


commit 9afa2fb6c13501e5b3536d15344fce4e5442c469
Author: Erez Zadok <ezk@cs.sunysb.edu>
Date:   Wed Dec 2 19:51:54 2009 -0500

    fsstack/ecryptfs: remove unused get_nlinks param to fsstack_copy_attr_all
    
    This get_nlinks parameter was never used by the only mainline user,
    ecryptfs; and it has never been used by unionfs or wrapfs either.
    
    Acked-by: Dustin Kirkland <kirkland@canonical.com>
    Acked-by: Tyler Hicks <tyhicks@linux.vnet.ibm.com>
    Signed-off-by: Erez Zadok <ezk@cs.sunysb.edu>
    Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

diff --git a/fs/ecryptfs/dentry.c b/fs/ecryptfs/dentry.c
index 2dda5ade75bc..8f006a0d6076 100644
--- a/fs/ecryptfs/dentry.c
+++ b/fs/ecryptfs/dentry.c
@@ -62,7 +62,7 @@ static int ecryptfs_d_revalidate(struct dentry *dentry, struct nameidata *nd)
 		struct inode *lower_inode =
 			ecryptfs_inode_to_lower(dentry->d_inode);
 
-		fsstack_copy_attr_all(dentry->d_inode, lower_inode, NULL);
+		fsstack_copy_attr_all(dentry->d_inode, lower_inode);
 	}
 out:
 	return rc;
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c
index 056fed62d0de..429ca0b3ba08 100644
--- a/fs/ecryptfs/inode.c
+++ b/fs/ecryptfs/inode.c
@@ -626,9 +626,9 @@ ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry,
 			lower_new_dir_dentry->d_inode, lower_new_dentry);
 	if (rc)
 		goto out_lock;
-	fsstack_copy_attr_all(new_dir, lower_new_dir_dentry->d_inode, NULL);
+	fsstack_copy_attr_all(new_dir, lower_new_dir_dentry->d_inode);
 	if (new_dir != old_dir)
-		fsstack_copy_attr_all(old_dir, lower_old_dir_dentry->d_inode, NULL);
+		fsstack_copy_attr_all(old_dir, lower_old_dir_dentry->d_inode);
 out_lock:
 	unlock_rename(lower_old_dir_dentry, lower_new_dir_dentry);
 	dput(lower_new_dentry->d_parent);
@@ -967,7 +967,7 @@ static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia)
 	rc = notify_change(lower_dentry, ia);
 	mutex_unlock(&lower_dentry->d_inode->i_mutex);
 out:
-	fsstack_copy_attr_all(inode, lower_inode, NULL);
+	fsstack_copy_attr_all(inode, lower_inode);
 	return rc;
 }
 
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c
index 101fe4c7b1ee..567bc4b9f70a 100644
--- a/fs/ecryptfs/main.c
+++ b/fs/ecryptfs/main.c
@@ -189,7 +189,7 @@ int ecryptfs_interpose(struct dentry *lower_dentry, struct dentry *dentry,
 		init_special_inode(inode, lower_inode->i_mode,
 				   lower_inode->i_rdev);
 	dentry->d_op = &ecryptfs_dops;
-	fsstack_copy_attr_all(inode, lower_inode, NULL);
+	fsstack_copy_attr_all(inode, lower_inode);
 	/* This size will be overwritten for real files w/ headers and
 	 * other metadata */
 	fsstack_copy_inode_size(inode, lower_inode);
diff --git a/fs/stack.c b/fs/stack.c
index 67716f6a1a4a..0e20e43ad740 100644
--- a/fs/stack.c
+++ b/fs/stack.c
@@ -14,11 +14,8 @@ void fsstack_copy_inode_size(struct inode *dst, const struct inode *src)
 }
 EXPORT_SYMBOL_GPL(fsstack_copy_inode_size);
 
-/* copy all attributes; get_nlinks is optional way to override the i_nlink
- * copying
- */
-void fsstack_copy_attr_all(struct inode *dest, const struct inode *src,
-				int (*get_nlinks)(struct inode *))
+/* copy all attributes */
+void fsstack_copy_attr_all(struct inode *dest, const struct inode *src)
 {
 	dest->i_mode = src->i_mode;
 	dest->i_uid = src->i_uid;
@@ -29,14 +26,6 @@ void fsstack_copy_attr_all(struct inode *dest, const struct inode *src,
 	dest->i_ctime = src->i_ctime;
 	dest->i_blkbits = src->i_blkbits;
 	dest->i_flags = src->i_flags;
-
-	/*
-	 * Update the nlinks AFTER updating the above fields, because the
-	 * get_links callback may depend on them.
-	 */
-	if (!get_nlinks)
-		dest->i_nlink = src->i_nlink;
-	else
-		dest->i_nlink = (*get_nlinks)(dest);
+	dest->i_nlink = src->i_nlink;
 }
 EXPORT_SYMBOL_GPL(fsstack_copy_attr_all);
diff --git a/include/linux/fs_stack.h b/include/linux/fs_stack.h
index bb516ceeefc9..aa60311900dd 100644
--- a/include/linux/fs_stack.h
+++ b/include/linux/fs_stack.h
@@ -8,9 +8,7 @@
 #include <linux/fs.h>
 
 /* externs for fs/stack.c */
-extern void fsstack_copy_attr_all(struct inode *dest, const struct inode *src,
-				int (*get_nlinks)(struct inode *));
-
+extern void fsstack_copy_attr_all(struct inode *dest, const struct inode *src);
 extern void fsstack_copy_inode_size(struct inode *dst, const struct inode *src);
 
 /* inlines */

commit aa81a7c7120ad9a4f8b677b7c204bb12b2b0e145
Author: Erez Zadok <ezk@cs.sunysb.edu>
Date:   Thu Feb 7 00:13:25 2008 -0800

    VFS: factor out three helpers for FIBMAP/FIONBIO/FIOASYNC file ioctls
    
    Factor out file-specific ioctl code into smaller helper functions, away from
    file_ioctl().  This helps code readability and also reduces indentation inside
    case statements.
    
    Signed-off-by: Erez Zadok <ezk@cs.sunysb.edu>
    Cc: Christoph Hellwig <hch@lst.de>
    Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
    Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

diff --git a/fs/ioctl.c b/fs/ioctl.c
index e6500cd12258..683002fefa55 100644
--- a/fs/ioctl.c
+++ b/fs/ioctl.c
@@ -52,32 +52,34 @@ long vfs_ioctl(struct file *filp, unsigned int cmd,
 	return error;
 }
 
+static int ioctl_fibmap(struct file *filp, int __user *p)
+{
+	struct address_space *mapping = filp->f_mapping;
+	int res, block;
+
+	/* do we support this mess? */
+	if (!mapping->a_ops->bmap)
+		return -EINVAL;
+	if (!capable(CAP_SYS_RAWIO))
+		return -EPERM;
+	res = get_user(block, p);
+	if (res)
+		return res;
+	lock_kernel();
+	res = mapping->a_ops->bmap(mapping, block);
+	unlock_kernel();
+	return put_user(res, p);
+}
+
 static int file_ioctl(struct file *filp, unsigned int cmd,
 		unsigned long arg)
 {
-	int error;
-	int block;
 	struct inode *inode = filp->f_path.dentry->d_inode;
 	int __user *p = (int __user *)arg;
 
 	switch (cmd) {
 	case FIBMAP:
-	{
-		struct address_space *mapping = filp->f_mapping;
-		int res;
-		/* do we support this mess? */
-		if (!mapping->a_ops->bmap)
-			return -EINVAL;
-		if (!capable(CAP_SYS_RAWIO))
-			return -EPERM;
-		error = get_user(block, p);
-		if (error)
-			return error;
-		lock_kernel();
-		res = mapping->a_ops->bmap(mapping, block);
-		unlock_kernel();
-		return put_user(res, p);
-	}
+		return ioctl_fibmap(filp, p);
 	case FIGETBSZ:
 		return put_user(inode->i_sb->s_blocksize, p);
 	case FIONREAD:
@@ -87,6 +89,57 @@ static int file_ioctl(struct file *filp, unsigned int cmd,
 	return vfs_ioctl(filp, cmd, arg);
 }
 
+static int ioctl_fionbio(struct file *filp, int __user *argp)
+{
+	unsigned int flag;
+	int on, error;
+
+	error = get_user(on, argp);
+	if (error)
+		return error;
+	flag = O_NONBLOCK;
+#ifdef __sparc__
+	/* SunOS compatibility item. */
+	if (O_NONBLOCK != O_NDELAY)
+		flag |= O_NDELAY;
+#endif
+	if (on)
+		filp->f_flags |= flag;
+	else
+		filp->f_flags &= ~flag;
+	return error;
+}
+
+static int ioctl_fioasync(unsigned int fd, struct file *filp,
+			  int __user *argp)
+{
+	unsigned int flag;
+	int on, error;
+
+	error = get_user(on, argp);
+	if (error)
+		return error;
+	flag = on ? FASYNC : 0;
+
+	/* Did FASYNC state change ? */
+	if ((flag ^ filp->f_flags) & FASYNC) {
+		if (filp->f_op && filp->f_op->fasync) {
+			lock_kernel();
+			error = filp->f_op->fasync(fd, filp, on);
+			unlock_kernel();
+		} else
+			error = -ENOTTY;
+	}
+	if (error)
+		return error;
+
+	if (on)
+		filp->f_flags |= FASYNC;
+	else
+		filp->f_flags &= ~FASYNC;
+	return error;
+}
+
 /*
  * When you add any new common ioctls to the switches above and below
  * please update compat_sys_ioctl() too.
@@ -97,8 +150,8 @@ static int file_ioctl(struct file *filp, unsigned int cmd,
 int do_vfs_ioctl(struct file *filp, unsigned int fd, unsigned int cmd,
 	     unsigned long arg)
 {
-	unsigned int flag;
-	int on, error = 0;
+	int error = 0;
+	int __user *argp = (int __user *)arg;
 
 	switch (cmd) {
 	case FIOCLEX:
@@ -110,43 +163,11 @@ int do_vfs_ioctl(struct file *filp, unsigned int fd, unsigned int cmd,
 		break;
 
 	case FIONBIO:
-		error = get_user(on, (int __user *)arg);
-		if (error)
-			break;
-		flag = O_NONBLOCK;
-#ifdef __sparc__
-		/* SunOS compatibility item. */
-		if (O_NONBLOCK != O_NDELAY)
-			flag |= O_NDELAY;
-#endif
-		if (on)
-			filp->f_flags |= flag;
-		else
-			filp->f_flags &= ~flag;
+		error = ioctl_fionbio(filp, argp);
 		break;
 
 	case FIOASYNC:
-		error = get_user(on, (int __user *)arg);
-		if (error)
-			break;
-		flag = on ? FASYNC : 0;
-
-		/* Did FASYNC state change ? */
-		if ((flag ^ filp->f_flags) & FASYNC) {
-			if (filp->f_op && filp->f_op->fasync) {
-				lock_kernel();
-				error = filp->f_op->fasync(fd, filp, on);
-				unlock_kernel();
-			} else
-				error = -ENOTTY;
-		}
-		if (error != 0)
-			break;
-
-		if (on)
-			filp->f_flags |= FASYNC;
-		else
-			filp->f_flags &= ~FASYNC;
+		error = ioctl_fioasync(fd, filp, argp);
 		break;
 
 	case FIOQSIZE:

commit deb21db7788b97a2bccdefe605433ef97f482689
Author: Erez Zadok <ezk@cs.sunysb.edu>
Date:   Thu Feb 7 00:13:25 2008 -0800

    VFS: swap do_ioctl and vfs_ioctl names
    
    Rename old vfs_ioctl to do_ioctl, because the comment above it clearly
    indicates that it is an internal function not to be exported to modules;
    therefore it should have a more traditional do_XXX name.  The new do_ioctl
    is exported in fs.h but not to modules.
    
    Rename the old do_ioctl to vfs_ioctl because the names vfs_XXX should
    preferably be reserved to callable VFS functions which modules may call, as
    many other vfs_XXX functions already do.  Export the new vfs_ioctl to GPL
    modules so others can use it (including Unionfs and eCryptfs).  Add DocBook
    for new vfs_ioctl.
    
    [akpm@linux-foundation.org: fix build]
    Signed-off-by: Erez Zadok <ezk@cs.sunysb.edu>
    Cc: Christoph Hellwig <hch@lst.de>
    Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
    Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c
index ffdc022cae64..614bd75b5a4a 100644
--- a/fs/compat_ioctl.c
+++ b/fs/compat_ioctl.c
@@ -2986,7 +2986,7 @@ asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd,
 	}
 
  do_ioctl:
-	error = vfs_ioctl(filp, fd, cmd, arg);
+	error = do_vfs_ioctl(filp, fd, cmd, arg);
  out_fput:
 	fput_light(filp, fput_needed);
  out:
diff --git a/fs/ioctl.c b/fs/ioctl.c
index 652cacf433ff..e6500cd12258 100644
--- a/fs/ioctl.c
+++ b/fs/ioctl.c
@@ -16,8 +16,20 @@
 
 #include <asm/ioctls.h>
 
-static long do_ioctl(struct file *filp, unsigned int cmd,
-		unsigned long arg)
+/**
+ * vfs_ioctl - call filesystem specific ioctl methods
+ * @filp: [in]     open file to invoke ioctl method on
+ * @cmd:  [in]     ioctl command to execute
+ * @arg:  [in/out] command-specific argument for ioctl
+ *
+ * Invokes filesystem specific ->unlocked_ioctl, if one exists; otherwise
+ * invokes * filesystem specific ->ioctl method.  If neither method exists,
+ * returns -ENOTTY.
+ *
+ * Returns 0 on success, -errno on error.
+ */
+long vfs_ioctl(struct file *filp, unsigned int cmd,
+	       unsigned long arg)
 {
 	int error = -ENOTTY;
 
@@ -72,18 +84,18 @@ static int file_ioctl(struct file *filp, unsigned int cmd,
 		return put_user(i_size_read(inode) - filp->f_pos, p);
 	}
 
-	return do_ioctl(filp, cmd, arg);
+	return vfs_ioctl(filp, cmd, arg);
 }
 
 /*
  * When you add any new common ioctls to the switches above and below
  * please update compat_sys_ioctl() too.
  *
- * vfs_ioctl() is not for drivers and not intended to be EXPORT_SYMBOL()'d.
+ * do_vfs_ioctl() is not for drivers and not intended to be EXPORT_SYMBOL()'d.
  * It's just a simple helper for sys_ioctl and compat_sys_ioctl.
  */
-int vfs_ioctl(struct file *filp, unsigned int fd, unsigned int cmd,
-	      unsigned long arg)
+int do_vfs_ioctl(struct file *filp, unsigned int fd, unsigned int cmd,
+	     unsigned long arg)
 {
 	unsigned int flag;
 	int on, error = 0;
@@ -152,7 +164,7 @@ int vfs_ioctl(struct file *filp, unsigned int fd, unsigned int cmd,
 		if (S_ISREG(filp->f_path.dentry->d_inode->i_mode))
 			error = file_ioctl(filp, cmd, arg);
 		else
-			error = do_ioctl(filp, cmd, arg);
+			error = vfs_ioctl(filp, cmd, arg);
 		break;
 	}
 	return error;
@@ -172,7 +184,7 @@ asmlinkage long sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
 	if (error)
 		goto out_fput;
 
-	error = vfs_ioctl(filp, fd, cmd, arg);
+	error = do_vfs_ioctl(filp, fd, cmd, arg);
  out_fput:
 	fput_light(filp, fput_needed);
  out:
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 109734bf6377..2925f7011ece 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1941,7 +1941,9 @@ extern int vfs_stat_fd(int dfd, char __user *, struct kstat *);
 extern int vfs_lstat_fd(int dfd, char __user *, struct kstat *);
 extern int vfs_fstat(unsigned int, struct kstat *);
 
-extern int vfs_ioctl(struct file *, unsigned int, unsigned int, unsigned long);
+extern long vfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
+extern int do_vfs_ioctl(struct file *filp, unsigned int fd, unsigned int cmd,
+		    unsigned long arg);
 
 extern void get_filesystem(struct file_system_type *fs);
 extern void put_filesystem(struct file_system_type *fs);

commit c9845ff1df5ba007b576c26c4f1e7ca43b7c7e87
Author: Erez Zadok <ezk@cs.sunysb.edu>
Date:   Thu Feb 7 00:13:23 2008 -0800

    VFS: apply coding standards to fs/ioctl.c
    
    Signed-off-by: Erez Zadok <ezk@cs.sunysb.edu>
    Cc: Christoph Hellwig <hch@lst.de>
    Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
    Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

diff --git a/fs/ioctl.c b/fs/ioctl.c
index c2a773e8620b..652cacf433ff 100644
--- a/fs/ioctl.c
+++ b/fs/ioctl.c
@@ -12,8 +12,8 @@
 #include <linux/fs.h>
 #include <linux/security.h>
 #include <linux/module.h>
+#include <linux/uaccess.h>
 
-#include <asm/uaccess.h>
 #include <asm/ioctls.h>
 
 static long do_ioctl(struct file *filp, unsigned int cmd,
@@ -45,31 +45,31 @@ static int file_ioctl(struct file *filp, unsigned int cmd,
 {
 	int error;
 	int block;
-	struct inode * inode = filp->f_path.dentry->d_inode;
+	struct inode *inode = filp->f_path.dentry->d_inode;
 	int __user *p = (int __user *)arg;
 
 	switch (cmd) {
-		case FIBMAP:
-		{
-			struct address_space *mapping = filp->f_mapping;
-			int res;
-			/* do we support this mess? */
-			if (!mapping->a_ops->bmap)
-				return -EINVAL;
-			if (!capable(CAP_SYS_RAWIO))
-				return -EPERM;
-			if ((error = get_user(block, p)) != 0)
-				return error;
-
-			lock_kernel();
-			res = mapping->a_ops->bmap(mapping, block);
-			unlock_kernel();
-			return put_user(res, p);
-		}
-		case FIGETBSZ:
-			return put_user(inode->i_sb->s_blocksize, p);
-		case FIONREAD:
-			return put_user(i_size_read(inode) - filp->f_pos, p);
+	case FIBMAP:
+	{
+		struct address_space *mapping = filp->f_mapping;
+		int res;
+		/* do we support this mess? */
+		if (!mapping->a_ops->bmap)
+			return -EINVAL;
+		if (!capable(CAP_SYS_RAWIO))
+			return -EPERM;
+		error = get_user(block, p);
+		if (error)
+			return error;
+		lock_kernel();
+		res = mapping->a_ops->bmap(mapping, block);
+		unlock_kernel();
+		return put_user(res, p);
+	}
+	case FIGETBSZ:
+		return put_user(inode->i_sb->s_blocksize, p);
+	case FIONREAD:
+		return put_user(i_size_read(inode) - filp->f_pos, p);
 	}
 
 	return do_ioctl(filp, cmd, arg);
@@ -82,81 +82,85 @@ static int file_ioctl(struct file *filp, unsigned int cmd,
  * vfs_ioctl() is not for drivers and not intended to be EXPORT_SYMBOL()'d.
  * It's just a simple helper for sys_ioctl and compat_sys_ioctl.
  */
-int vfs_ioctl(struct file *filp, unsigned int fd, unsigned int cmd, unsigned long arg)
+int vfs_ioctl(struct file *filp, unsigned int fd, unsigned int cmd,
+	      unsigned long arg)
 {
 	unsigned int flag;
 	int on, error = 0;
 
 	switch (cmd) {
-		case FIOCLEX:
-			set_close_on_exec(fd, 1);
-			break;
+	case FIOCLEX:
+		set_close_on_exec(fd, 1);
+		break;
 
-		case FIONCLEX:
-			set_close_on_exec(fd, 0);
-			break;
+	case FIONCLEX:
+		set_close_on_exec(fd, 0);
+		break;
 
-		case FIONBIO:
-			if ((error = get_user(on, (int __user *)arg)) != 0)
-				break;
-			flag = O_NONBLOCK;
+	case FIONBIO:
+		error = get_user(on, (int __user *)arg);
+		if (error)
+			break;
+		flag = O_NONBLOCK;
 #ifdef __sparc__
-			/* SunOS compatibility item. */
-			if(O_NONBLOCK != O_NDELAY)
-				flag |= O_NDELAY;
+		/* SunOS compatibility item. */
+		if (O_NONBLOCK != O_NDELAY)
+			flag |= O_NDELAY;
 #endif
-			if (on)
-				filp->f_flags |= flag;
-			else
-				filp->f_flags &= ~flag;
+		if (on)
+			filp->f_flags |= flag;
+		else
+			filp->f_flags &= ~flag;
+		break;
+
+	case FIOASYNC:
+		error = get_user(on, (int __user *)arg);
+		if (error)
 			break;
-
-		case FIOASYNC:
-			if ((error = get_user(on, (int __user *)arg)) != 0)
-				break;
-			flag = on ? FASYNC : 0;
-
-			/* Did FASYNC state change ? */
-			if ((flag ^ filp->f_flags) & FASYNC) {
-				if (filp->f_op && filp->f_op->fasync) {
-					lock_kernel();
-					error = filp->f_op->fasync(fd, filp, on);
-					unlock_kernel();
-				}
-				else error = -ENOTTY;
-			}
-			if (error != 0)
-				break;
-
-			if (on)
-				filp->f_flags |= FASYNC;
-			else
-				filp->f_flags &= ~FASYNC;
-			break;
-
-		case FIOQSIZE:
-			if (S_ISDIR(filp->f_path.dentry->d_inode->i_mode) ||
-			    S_ISREG(filp->f_path.dentry->d_inode->i_mode) ||
-			    S_ISLNK(filp->f_path.dentry->d_inode->i_mode)) {
-				loff_t res = inode_get_bytes(filp->f_path.dentry->d_inode);
-				error = copy_to_user((loff_t __user *)arg, &res, sizeof(res)) ? -EFAULT : 0;
-			}
-			else
+		flag = on ? FASYNC : 0;
+
+		/* Did FASYNC state change ? */
+		if ((flag ^ filp->f_flags) & FASYNC) {
+			if (filp->f_op && filp->f_op->fasync) {
+				lock_kernel();
+				error = filp->f_op->fasync(fd, filp, on);
+				unlock_kernel();
+			} else
 				error = -ENOTTY;
+		}
+		if (error != 0)
 			break;
-		default:
-			if (S_ISREG(filp->f_path.dentry->d_inode->i_mode))
-				error = file_ioctl(filp, cmd, arg);
-			else
-				error = do_ioctl(filp, cmd, arg);
-			break;
+
+		if (on)
+			filp->f_flags |= FASYNC;
+		else
+			filp->f_flags &= ~FASYNC;
+		break;
+
+	case FIOQSIZE:
+		if (S_ISDIR(filp->f_path.dentry->d_inode->i_mode) ||
+		    S_ISREG(filp->f_path.dentry->d_inode->i_mode) ||
+		    S_ISLNK(filp->f_path.dentry->d_inode->i_mode)) {
+			loff_t res =
+				inode_get_bytes(filp->f_path.dentry->d_inode);
+			error = copy_to_user((loff_t __user *)arg, &res,
+					     sizeof(res)) ? -EFAULT : 0;
+		} else
+			error = -ENOTTY;
+		break;
+	default:
+		if (S_ISREG(filp->f_path.dentry->d_inode->i_mode))
+			error = file_ioctl(filp, cmd, arg);
+		else
+			error = do_ioctl(filp, cmd, arg);
+		break;
 	}
 	return error;
 }
 
 asmlinkage long sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
 {
-	struct file * filp;
+	struct file *filp;
 	int error = -EBADF;
 	int fput_needed;
 

commit f79c20f52532d38fd0aee7ef64e138cc1613c484
Author: Josef 'Jeff' Sipek <jsipek@cs.sunysb.edu>
Date:   Thu Jul 19 01:48:22 2007 -0700

    fs: remove path_walk export
    
    Signed-off-by: Josef 'Jeff' Sipek <jsipek@cs.sunysb.edu>
    Cc: Al Viro <viro@zeniv.linux.org.uk>
    Acked-by: Christoph Hellwig <hch@lst.de>
    Cc: Trond Myklebust <trond.myklebust@fys.uio.no>
    Cc: Neil Brown <neilb@suse.de>
    Cc: Michael Halcrow <mhalcrow@us.ibm.com>
    Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
    Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

diff --git a/fs/namei.c b/fs/namei.c
index b9fdda8c0930..a83160acd748 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1024,7 +1024,7 @@ static int fastcall link_path_walk(const char *name, struct nameidata *nd)
 	return result;
 }
 
-int fastcall path_walk(const char * name, struct nameidata *nd)
+static int fastcall path_walk(const char * name, struct nameidata *nd)
 {
 	current->total_link_count = 0;
 	return link_path_walk(name, nd);
@@ -2809,7 +2809,6 @@ EXPORT_SYMBOL(page_symlink_inode_operations);
 EXPORT_SYMBOL(path_lookup);
 EXPORT_SYMBOL(vfs_path_lookup);
 EXPORT_SYMBOL(path_release);
-EXPORT_SYMBOL(path_walk);
 EXPORT_SYMBOL(permission);
 EXPORT_SYMBOL(vfs_permission);
 EXPORT_SYMBOL(file_permission);
diff --git a/include/linux/namei.h b/include/linux/namei.h
index 18ea81265068..6c38efbd810f 100644
--- a/include/linux/namei.h
+++ b/include/linux/namei.h
@@ -71,7 +71,6 @@ extern int FASTCALL(__user_walk_fd(int dfd, const char __user *, unsigned, struc
 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 int FASTCALL(path_walk(const char *, struct nameidata *));
 extern void path_release(struct nameidata *);
 extern void path_release_on_umount(struct nameidata *);
 

commit c4a7808fc3d7a346d5d12e0d69d76d66d821488b
Author: Josef 'Jeff' Sipek <jsipek@cs.sunysb.edu>
Date:   Thu Jul 19 01:48:22 2007 -0700

    fs: mark link_path_walk static
    
    Signed-off-by: Josef 'Jeff' Sipek <jsipek@cs.sunysb.edu>
    Cc: Al Viro <viro@zeniv.linux.org.uk>
    Acked-by: Christoph Hellwig <hch@lst.de>
    Cc: Trond Myklebust <trond.myklebust@fys.uio.no>
    Cc: Neil Brown <neilb@suse.de>
    Cc: Michael Halcrow <mhalcrow@us.ibm.com>
    Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
    Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

diff --git a/fs/namei.c b/fs/namei.c
index 3bdb29615a9d..b9fdda8c0930 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -107,6 +107,8 @@
  * any extra contention...
  */
 
+static int fastcall link_path_walk(const char *name, struct nameidata *nd);
+
 /* In order to reduce some races, while at the same time doing additional
  * checking and hopefully speeding things up, we copy filenames to the
  * kernel data space before using them..
@@ -998,7 +1000,7 @@ static fastcall int __link_path_walk(const char * name, struct nameidata *nd)
  * Retry the whole path once, forcing real lookup requests
  * instead of relying on the dcache.
  */
-int fastcall link_path_walk(const char *name, struct nameidata *nd)
+static int fastcall link_path_walk(const char *name, struct nameidata *nd)
 {
 	struct nameidata save = *nd;
 	int result;
diff --git a/include/linux/namei.h b/include/linux/namei.h
index 2e21af0989d9..18ea81265068 100644
--- a/include/linux/namei.h
+++ b/include/linux/namei.h
@@ -72,7 +72,6 @@ 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 int FASTCALL(path_walk(const char *, struct nameidata *));
-extern int FASTCALL(link_path_walk(const char *, struct nameidata *));
 extern void path_release(struct nameidata *);
 extern void path_release_on_umount(struct nameidata *);
 

commit 16b6287a5286e872abece4f42a6eb5899157a836
Author: Josef 'Jeff' Sipek <jsipek@cs.sunysb.edu>
Date:   Thu Jul 19 01:48:21 2007 -0700

    nfsctl: use vfs_path_lookup
    
    use vfs_path_lookup instead of open-coding the necessary functionality.
    
    Signed-off-by: Josef 'Jeff' Sipek <jsipek@cs.sunysb.edu>
    Acked-by: NeilBrown <neilb@suse.de>
    Cc: Al Viro <viro@zeniv.linux.org.uk>
    Acked-by: Christoph Hellwig <hch@lst.de>
    Cc: Trond Myklebust <trond.myklebust@fys.uio.no>
    Cc: Michael Halcrow <mhalcrow@us.ibm.com>
    Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
    Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

diff --git a/fs/nfsctl.c b/fs/nfsctl.c
index c043136a82ca..51f1b31acbf6 100644
--- a/fs/nfsctl.c
+++ b/fs/nfsctl.c
@@ -23,19 +23,15 @@
 static struct file *do_open(char *name, int flags)
 {
 	struct nameidata nd;
+	struct vfsmount *mnt;
 	int error;
 
-	nd.mnt = do_kern_mount("nfsd", 0, "nfsd", NULL);
+	mnt = do_kern_mount("nfsd", 0, "nfsd", NULL);
+	if (IS_ERR(mnt))
+		return (struct file *)mnt;
 
-	if (IS_ERR(nd.mnt))
-		return (struct file *)nd.mnt;
-
-	nd.dentry = dget(nd.mnt->mnt_root);
-	nd.last_type = LAST_ROOT;
-	nd.flags = 0;
-	nd.depth = 0;
-
-	error = path_walk(name, &nd);
+	error = vfs_path_lookup(mnt->mnt_root, mnt, name, 0, &nd);
+	mntput(mnt);	/* drop do_kern_mount reference */
 	if (error)
 		return ERR_PTR(error);
 

commit 4ac4efc1f5575a268417f80ef4059aee383f8331
Author: Josef 'Jeff' Sipek <jsipek@cs.sunysb.edu>
Date:   Thu Jul 19 01:48:20 2007 -0700

    sunrpc: use vfs_path_lookup
    
    use vfs_path_lookup instead of open-coding the necessary functionality.
    
    Signed-off-by: Josef 'Jeff' Sipek <jsipek@cs.sunysb.edu>
    Acked-by: Trond Myklebust <Trond.Myklebust@netapp.com>
    Cc: Al Viro <viro@zeniv.linux.org.uk>
    Acked-by: Christoph Hellwig <hch@lst.de>
    Cc: Neil Brown <neilb@suse.de>
    Cc: Michael Halcrow <mhalcrow@us.ibm.com>
    Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
    Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
index e787b6a43eee..5b2b6fb244f2 100644
--- a/net/sunrpc/rpc_pipe.c
+++ b/net/sunrpc/rpc_pipe.c
@@ -460,21 +460,19 @@ static struct dentry_operations rpc_dentry_operations = {
 static int
 rpc_lookup_parent(char *path, struct nameidata *nd)
 {
+	struct vfsmount *mnt;
+
 	if (path[0] == '\0')
 		return -ENOENT;
-	nd->mnt = rpc_get_mount();
-	if (IS_ERR(nd->mnt)) {
+
+	mnt = rpc_get_mount();
+	if (IS_ERR(mnt)) {
 		printk(KERN_WARNING "%s: %s failed to mount "
 			       "pseudofilesystem \n", __FILE__, __FUNCTION__);
-		return PTR_ERR(nd->mnt);
+		return PTR_ERR(mnt);
 	}
-	mntget(nd->mnt);
-	nd->dentry = dget(rpc_mount->mnt_root);
-	nd->last_type = LAST_ROOT;
-	nd->flags = LOOKUP_PARENT;
-	nd->depth = 0;
 
-	if (path_walk(path, nd)) {
+	if (vfs_path_lookup(mnt->mnt_root, mnt, path, LOOKUP_PARENT, nd)) {
 		printk(KERN_WARNING "%s: %s failed to find path %s\n",
 				__FILE__, __FUNCTION__, path);
 		rpc_put_mount();

commit 16f1820028d660d9da9c03b2ae7e98253c11795b
Author: Josef 'Jeff' Sipek <jsipek@cs.sunysb.edu>
Date:   Thu Jul 19 01:48:18 2007 -0700

    fs: introduce vfs_path_lookup
    
    Stackable file systems, among others, frequently need to lookup paths or
    path components starting from an arbitrary point in the namespace
    (identified by a dentry and a vfsmount).  Currently, such file systems use
    lookup_one_len, which is frowned upon [1] as it does not pass the lookup
    intent along; not passing a lookup intent, for example, can trigger BUG_ON's
    when stacking on top of NFSv4.
    
    The first patch introduces a new lookup function to allow lookup starting
    from an arbitrary point in the namespace.  This approach has been suggested
    by Christoph Hellwig [2].
    
    The second patch changes sunrpc to use vfs_path_lookup.
    
    The third patch changes nfsctl.c to use vfs_path_lookup.
    
    The fourth patch marks link_path_walk static.
    
    The fifth, and last patch, unexports path_walk because it is no longer
    unnecessary to call it directly, and using the new vfs_path_lookup is
    cleaner.
    
    For example, the following snippet of code, looks up "some/path/component"
    in a directory pointed to by parent_{dentry,vfsmnt}:
    
    err = vfs_path_lookup(parent_dentry, parent_vfsmnt,
                          "some/path/component", 0, &nd);
    if (!err) {
            /* exits */
    
            ...
    
            /* once done, release the references */
            path_release(&nd);
    } else if (err == -ENOENT) {
            /* doesn't exist */
    } else {
            /* other error */
    }
    
    VFS functions such as lookup_create can be used on the nameidata structure
    to pass the create intent to the file system.
    
    Signed-off-by: Josef 'Jeff' Sipek <jsipek@cs.sunysb.edu>
    Cc: Al Viro <viro@zeniv.linux.org.uk>
    Acked-by: Christoph Hellwig <hch@lst.de>
    Cc: Trond Myklebust <trond.myklebust@fys.uio.no>
    Cc: Neil Brown <neilb@suse.de>
    Cc: Michael Halcrow <mhalcrow@us.ibm.com>
    Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
    Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

diff --git a/fs/namei.c b/fs/namei.c
index defaa47c11d4..3bdb29615a9d 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1172,6 +1172,37 @@ int fastcall path_lookup(const char *name, unsigned int flags,
 	return do_path_lookup(AT_FDCWD, name, flags, nd);
 }
 
+/**
+ * vfs_path_lookup - lookup a file path relative to a dentry-vfsmount pair
+ * @dentry:  pointer to dentry of the base directory
+ * @mnt: pointer to vfs mount of the base directory
+ * @name: pointer to file name
+ * @flags: lookup flags
+ * @nd: pointer to nameidata
+ */
+int vfs_path_lookup(struct dentry *dentry, struct vfsmount *mnt,
+		    const char *name, unsigned int flags,
+		    struct nameidata *nd)
+{
+	int retval;
+
+	/* same as do_path_lookup */
+	nd->last_type = LAST_ROOT;
+	nd->flags = flags;
+	nd->depth = 0;
+
+	nd->mnt = mntget(mnt);
+	nd->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);
+
+	return retval;
+
+}
+
 static int __path_lookup_intent_open(int dfd, const char *name,
 		unsigned int lookup_flags, struct nameidata *nd,
 		int open_flags, int create_mode)
@@ -2774,6 +2805,7 @@ EXPORT_SYMBOL(__page_symlink);
 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(path_walk);
 EXPORT_SYMBOL(permission);
diff --git a/include/linux/namei.h b/include/linux/namei.h
index b7dd24917f0d..2e21af0989d9 100644
--- a/include/linux/namei.h
+++ b/include/linux/namei.h
@@ -69,6 +69,8 @@ extern int FASTCALL(__user_walk_fd(int dfd, const char __user *, unsigned, struc
 #define user_path_walk_link(name,nd) \
 	__user_walk_fd(AT_FDCWD, name, 0, nd)
 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 int FASTCALL(path_walk(const char *, struct nameidata *));
 extern int FASTCALL(link_path_walk(const char *, struct nameidata *));
 extern void path_release(struct nameidata *);

commit 5d91192e667ae34733b9daf6dd5f1d4496d2f441
Author: Josef 'Jeff' Sipek <jsipek@cs.sunysb.edu>
Date:   Tue Jul 17 04:04:54 2007 -0700

    eCryptfs: Move ecryptfs docs into Documentation/filesystems/
    
    Signed-off-by: Josef 'Jeff' Sipek <jsipek@cs.sunysb.edu>
    Acked-by: Michael Halcrow <mhalcrow@us.ibm.com>
    Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
    Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

diff --git a/Documentation/ecryptfs.txt b/Documentation/filesystems/ecryptfs.txt
similarity index 100%
rename from Documentation/ecryptfs.txt
rename to Documentation/filesystems/ecryptfs.txt