[ewg] [PATCH OFED-1.5] NFSRDMA: NFS backport for 2.6.22

Jon Mason jon at opengridcomputing.com
Tue Jun 2 16:41:13 PDT 2009


This patch provides the NFS backport for 2.6.22.  Since the RDMA
infrastructure does not work for this kernel release, only TCP
support has been tested.  It passes Connectathon as a client and server.

Signed-Off-By: Jon Mason <jon at opengridcomputing.com>
---

diff --git a/kernel_addons/backport/2.6.22/include/asm/bitops.h b/kernel_addons/backport/2.6.22/include/asm/bitops.h
new file mode 100644
index 0000000..50d5e8b
--- /dev/null
+++ b/kernel_addons/backport/2.6.22/include/asm/bitops.h
@@ -0,0 +1,12 @@
+#ifndef BACKPORT_ASM_BITOPS_H
+#define BACKPORT_ASM_BITOPS_H
+
+#include_next <asm/bitops.h>
+
+static inline void clear_bit_unlock(unsigned long nr, volatile unsigned long *addr)
+{
+	smp_mb__before_clear_bit();
+	clear_bit(nr, addr);
+}
+
+#endif
diff --git a/kernel_addons/backport/2.6.22/include/linux/cpumask.h b/kernel_addons/backport/2.6.22/include/linux/cpumask.h
new file mode 100644
index 0000000..d6fcf4e
--- /dev/null
+++ b/kernel_addons/backport/2.6.22/include/linux/cpumask.h
@@ -0,0 +1,10 @@
+#ifndef BACKPORT_LINUX_CPUMASK_H
+#define BACKPORT_LINUX_CPUMASK_H
+
+#include_next <linux/cpumask.h>
+
+#define cpumask_of(cpu)			(cpumask_of_cpu(cpu))
+#define set_cpus_allowed_ptr(a, b)	(set_cpus_allowed(a, b))
+#define cpumask_of_node(node)		(node_to_cpumask(node))
+
+#endif /* BACKPORT_LINUX_CPUMASK_H */
diff --git a/kernel_addons/backport/2.6.22/include/linux/cred.h b/kernel_addons/backport/2.6.22/include/linux/cred.h
new file mode 100644
index 0000000..4b8b680
--- /dev/null
+++ b/kernel_addons/backport/2.6.22/include/linux/cred.h
@@ -0,0 +1,11 @@
+#ifndef BACKPORT_LINUX_CRED_H
+#define BACKPORT_LINUX_CRED_H
+
+#define current_cred_xxx(xxx)	\
+({				\
+	current->xxx;	\
+})
+
+#define current_fsuid()	(current_cred_xxx(fsuid))
+
+#endif /* BACKPORT_LINUX_CRED_H */
diff --git a/kernel_addons/backport/2.6.22/include/linux/dcache.h b/kernel_addons/backport/2.6.22/include/linux/dcache.h
new file mode 100644
index 0000000..4a571af
--- /dev/null
+++ b/kernel_addons/backport/2.6.22/include/linux/dcache.h
@@ -0,0 +1,22 @@
+#ifndef BACKPORT_LINUX_DCACHE_H
+#define BACKPORT_LINUX_DCACHE_H
+
+#include_next <linux/dcache.h>
+#include <linux/err.h>
+
+extern void iput(struct inode *);
+
+static inline struct dentry *d_obtain_alias(struct inode *inode)
+{
+	struct dentry *rc;
+
+	rc = d_alloc_anon(inode);
+	if (!rc) {
+		iput(inode);
+		return ERR_PTR(-ENOMEM);
+	}
+
+	return rc;
+}
+
+#endif
diff --git a/kernel_addons/backport/2.6.22/include/linux/fs.h b/kernel_addons/backport/2.6.22/include/linux/fs.h
index 27f2045..b306bec 100644
--- a/kernel_addons/backport/2.6.22/include/linux/fs.h
+++ b/kernel_addons/backport/2.6.22/include/linux/fs.h
@@ -2,38 +2,81 @@
 #define BACKPORT_LINUX_FS_H
 
 #include_next <linux/fs.h>
+#include <linux/sched.h>
+#include <linux/fs_struct.h>
+#include <linux/mount.h>
 
-#define FILE_LOCK_DEFERRED 1
+#define ATTR_KILL_PRIV		(1 << 14)
+#define FILE_LOCK_DEFERRED	1
 
-#define ATTR_KILL_PRIV  (1 << 14)
+#define __locks_copy_lock	locks_copy_lock
+#define mandatory_lock(_args)	(MANDATORY_LOCK(_args))
+#define vfs_setlease(a, b, c) 	(setlease(a, b, c))
 
-static inline void __locks_copy_lock(struct file_lock *new, const struct file_lock *fl)
+struct lock_manager {
+	struct list_head list;
+};
+
+void locks_start_grace(struct lock_manager *);
+void locks_end_grace(struct lock_manager *);
+int locks_in_grace(void);
+
+static inline bool execute_ok(struct inode *inode)
 {
-	new->fl_owner = fl->fl_owner;
-	new->fl_pid = fl->fl_pid;
-	new->fl_file = NULL;
-	new->fl_flags = fl->fl_flags;
-	new->fl_type = fl->fl_type;
-	new->fl_start = fl->fl_start;
-	new->fl_end = fl->fl_end;
-	new->fl_ops = NULL;
-	new->fl_lmops = NULL;
+	return (inode->i_mode & S_IXUGO) || S_ISDIR(inode->i_mode);
 }
 
-#define vfs_setlease(a, b, c) setlease(a, b, c)
+static inline int current_umask(void)
+{
+	return current->fs->umask;
+}
 
-static inline int __mandatory_lock(struct inode *ino)
+static inline void free_fs_struct(struct fs_struct *fs)
 {
-	return (ino->i_mode & (S_ISGID | S_IXGRP)) == S_ISGID;
+	struct task_struct *tsk;
+
+	tsk = kzalloc(sizeof(struct task_struct), GFP_KERNEL);
+	if (!tsk)
+		return;
+
+	spin_lock_init(&tsk->alloc_lock);
+	tsk->fs = fs;
+
+	exit_fs(tsk);
+	kfree(tsk);
+}
+
+static inline int unshare_fs_struct(void)
+{
+	struct fs_struct *fs = current->fs;
+	struct fs_struct *new_fs = copy_fs_struct(fs);
+	int kill;
+
+	if (!new_fs)
+		return -ENOMEM;
+
+	task_lock(current);
+	write_lock(&fs->lock);
+	kill = atomic_read(&fs->count) == 1;
+	current->fs = new_fs;
+	write_unlock(&fs->lock);
+	task_unlock(current);
+
+	if (kill)
+		free_fs_struct(fs);
+
+	return 0;
 }
 
-#define mandatory_lock(_args) MANDATORY_LOCK(_args)
+static inline int inode_permission(struct inode *inode, int flags)
+{
+	return permission(inode, flags, NULL);
+}
 
 static inline int backport_vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname)
 {
 	return vfs_symlink(dir, dentry, oldname, 0);
 }
-
 #define vfs_symlink(_dir, _dentry, _oldname) backport_vfs_symlink(_dir, _dentry, _oldname)
 
 #ifdef CONFIG_DEBUG_WRITECOUNT
@@ -46,11 +89,6 @@ static inline void file_take_write(struct file *f)
 static inline void file_take_write(struct file *filp) {}
 #endif
 
-static inline int inode_permission(struct inode *inode, int flags)
-{
-	return permission(inode, flags, NULL);
-}
-
 static inline int __mnt_is_readonly(struct vfsmount *mnt)
 {
 	if (mnt->mnt_sb->s_flags & MS_RDONLY)
@@ -58,4 +96,9 @@ static inline int __mnt_is_readonly(struct vfsmount *mnt)
 	return 0;
 }
 
+static inline int __mandatory_lock(struct inode *ino)
+{
+	return (ino->i_mode & (S_ISGID | S_IXGRP)) == S_ISGID;
+}
+
 #endif
diff --git a/kernel_addons/backport/2.6.22/include/linux/fscache.h b/kernel_addons/backport/2.6.22/include/linux/fscache.h
new file mode 100644
index 0000000..f758384
--- /dev/null
+++ b/kernel_addons/backport/2.6.22/include/linux/fscache.h
@@ -0,0 +1,4 @@
+#ifndef BACKPORT_LINUX_FSCACHE_H
+#define BACKPORT_LINUX_FSCACHE_H
+
+#endif
diff --git a/kernel_addons/backport/2.6.22/include/linux/jiffies.h b/kernel_addons/backport/2.6.22/include/linux/jiffies.h
index ccfd69f..3c48bb6 100644
--- a/kernel_addons/backport/2.6.22/include/linux/jiffies.h
+++ b/kernel_addons/backport/2.6.22/include/linux/jiffies.h
@@ -1,10 +1,10 @@
-#ifndef _JIFFIES_BACKPORT_H
-#define _JIFFIES_BACKPORT_H
+#ifndef BACKPORT_LINUX_JIFFIES_H
+#define BACKPORT_LINUX_JIFFIES_H
 
 #include_next <linux/jiffies.h>
 
-#define time_in_range(a,b,c) \
+#define time_in_range_open(a,b,c) \
 	(time_after_eq(a,b) && \
-	 time_before_eq(a,c))
+	 time_before(a,c))
 
-#endif /* _JIFFIES_BACKPORT_H */
+#endif /* BACKPORT_LINUX_JIFFIES_H */
diff --git a/kernel_addons/backport/2.6.22/include/linux/mm.h b/kernel_addons/backport/2.6.22/include/linux/mm.h
index 31d4849..009e984 100644
--- a/kernel_addons/backport/2.6.22/include/linux/mm.h
+++ b/kernel_addons/backport/2.6.22/include/linux/mm.h
@@ -7,6 +7,7 @@
 #include <asm/highmem.h>
 #endif
 
+#define VM_FAULT_LOCKED  0x0200		/* ->fault locked the returned page */
 #define VM_CAN_NONLINEAR 0x08000000     /* Has ->fault & does nonlinear pages */
 
 #define is_vmalloc_addr(x) ((unsigned long)(x) >= VMALLOC_START && (unsigned long)(x) < VMALLOC_END)
diff --git a/kernel_addons/backport/2.6.22/include/linux/mutex.h b/kernel_addons/backport/2.6.22/include/linux/mutex.h
new file mode 100644
index 0000000..553d487
--- /dev/null
+++ b/kernel_addons/backport/2.6.22/include/linux/mutex.h
@@ -0,0 +1,8 @@
+#ifndef LINUX_MUTEX_BACKPORT_H
+#define LINUX_MUTEX_BACKPORT_H
+
+#include_next <linux/mutex.h>
+
+#define mutex_lock_killable(lock) mutex_lock_interruptible(lock)
+
+#endif
diff --git a/kernel_addons/backport/2.6.22/include/linux/namei.h b/kernel_addons/backport/2.6.22/include/linux/namei.h
index 156afcd..9ede722 100644
--- a/kernel_addons/backport/2.6.22/include/linux/namei.h
+++ b/kernel_addons/backport/2.6.22/include/linux/namei.h
@@ -2,9 +2,21 @@
 #define BACKPORT_LINUX_NAMEI_H
 
 #include_next <linux/namei.h>
-#include <linux/audit.h>
 #include <linux/path.h>
 
+#define LOOKUP_EXCL             0x0400
+
+static inline int kern_path(const char *name, unsigned int flags, struct path *path)
+{
+	struct nameidata nd;
+	int rc = path_lookup(name, flags, &nd);
+	if (!rc) {
+		(*path).mnt = nd.mnt;
+		(*path).dentry = nd.dentry;
+	}
+	return rc;
+}
+
 static inline int vfs_path_lookup(struct dentry *dentry, struct vfsmount *mnt,
 		    const char *name, unsigned int flags,
 		    struct nameidata *nd)
@@ -21,10 +33,8 @@ static inline int vfs_path_lookup(struct dentry *dentry, struct vfsmount *mnt,
 	backport_path_get(nd);
 
 	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;
 }
+
 #endif /* BACKPORT_LINUX_NAMEI_H */
diff --git a/kernel_addons/backport/2.6.22/include/linux/pagevec.h b/kernel_addons/backport/2.6.22/include/linux/pagevec.h
new file mode 100644
index 0000000..1fb684d
--- /dev/null
+++ b/kernel_addons/backport/2.6.22/include/linux/pagevec.h
@@ -0,0 +1,17 @@
+#ifndef BACKPORT_LINUX_PAGEVEC_H
+#define BACKPORT_LINUX_PAGEVEC_H
+
+#include_next <linux/pagevec.h>
+
+static inline void __pagevec_lru_add_file(struct pagevec *pvec)
+{
+	__pagevec_lru_add(pvec);
+}
+
+static inline void pagevec_lru_add_file(struct pagevec *pvec)
+{
+	if (pagevec_count(pvec))
+		__pagevec_lru_add_file(pvec);
+}
+
+#endif
diff --git a/kernel_addons/backport/2.6.22/include/linux/quotaops.h b/kernel_addons/backport/2.6.22/include/linux/quotaops.h
new file mode 100644
index 0000000..0a87ccd
--- /dev/null
+++ b/kernel_addons/backport/2.6.22/include/linux/quotaops.h
@@ -0,0 +1,70 @@
+#ifndef BACKPORT_LINUX_QUOTAOPS_H
+#define BACKPORT_LINUX_QUOTAOPS_H
+
+#include_next <linux/quotaops.h>
+
+/* Quota state flags - they actually come in two flavors - for users and groups */
+enum {
+	_DQUOT_USAGE_ENABLED = 0,	/* Track disk usage for users */
+	_DQUOT_LIMITS_ENABLED,		/* Enforce quota limits for users */
+	_DQUOT_SUSPENDED,		/* User diskquotas are off, but
+					 * we have necessary info in
+					 * memory to turn them on */
+	_DQUOT_STATE_FLAGS
+};
+
+#define DQUOT_USAGE_ENABLED	(1 << _DQUOT_USAGE_ENABLED)
+#define DQUOT_LIMITS_ENABLED	(1 << _DQUOT_LIMITS_ENABLED)
+#define DQUOT_SUSPENDED		(1 << _DQUOT_SUSPENDED)
+
+static inline unsigned int dquot_state_flag(unsigned int flags, int type)
+{
+	if (type == USRQUOTA)
+		return flags;
+	return flags << _DQUOT_STATE_FLAGS;
+}
+
+static inline int sb_has_quota_usage_enabled(struct super_block *sb, int type)
+{
+	return sb_dqopt(sb)->flags &
+				dquot_state_flag(DQUOT_USAGE_ENABLED, type);
+}
+
+static inline int sb_has_quota_limits_enabled(struct super_block *sb, int type)
+{
+	return sb_dqopt(sb)->flags &
+				dquot_state_flag(DQUOT_LIMITS_ENABLED, type);
+}
+
+static inline int sb_has_quota_suspended(struct super_block *sb, int type)
+{
+	return sb_dqopt(sb)->flags &
+				dquot_state_flag(DQUOT_SUSPENDED, type);
+}
+
+static inline int sb_has_quota_loaded(struct super_block *sb, int type)
+{
+	/* Currently if anything is on, then quota usage is on as well */
+	return sb_has_quota_usage_enabled(sb, type);
+}
+
+static inline int sb_has_quota_active(struct super_block *sb, int type)
+{
+	return sb_has_quota_loaded(sb, type) &&
+	       !sb_has_quota_suspended(sb, type);
+}
+
+static inline int sb_any_quota_active(struct super_block *sb)
+{
+	return sb_has_quota_active(sb, USRQUOTA) ||
+	       sb_has_quota_active(sb, GRPQUOTA);
+}
+
+static inline void vfs_dq_init(struct inode *inode)
+{
+	BUG_ON(!inode->i_sb);
+	if (sb_any_quota_active(inode->i_sb) && !IS_NOQUOTA(inode))
+		inode->i_sb->dq_op->initialize(inode, -1);
+}
+
+#endif /* BACKPORT_LINUX_QUOTAOPS_H */
diff --git a/kernel_addons/backport/2.6.22/include/linux/security.h b/kernel_addons/backport/2.6.22/include/linux/security.h
index 604e600..ad853bb 100644
--- a/kernel_addons/backport/2.6.22/include/linux/security.h
+++ b/kernel_addons/backport/2.6.22/include/linux/security.h
@@ -47,7 +47,6 @@ static inline int security_sb_parse_opts_str(char *options, struct security_mnt_
 static inline int backport_security_sb_copy_data(void *orig, void *copy)
 {
 	return 0;
-	//return security_sb_copy_data(NULL, orig, copy);
 }
 
 #define security_sb_copy_data(a,b) backport_security_sb_copy_data(a,b)
diff --git a/kernel_addons/backport/2.6.22/include/linux/splice.h b/kernel_addons/backport/2.6.22/include/linux/splice.h
new file mode 100644
index 0000000..7c133b5
--- /dev/null
+++ b/kernel_addons/backport/2.6.22/include/linux/splice.h
@@ -0,0 +1,4 @@
+#ifndef BACKPORT_LINUX_SPLICE_H
+#define BACKPORT_LINUX_SPLICE_H
+
+#endif /* BACKPORT_LINUX_SPLICE_H */
diff --git a/kernel_addons/backport/2.6.22/include/linux/types.h b/kernel_addons/backport/2.6.22/include/linux/types.h
new file mode 100644
index 0000000..b1a6937
--- /dev/null
+++ b/kernel_addons/backport/2.6.22/include/linux/types.h
@@ -0,0 +1,8 @@
+#ifndef BACKPORT_LINUX_TYPES_H
+#define BACKPORT_LINUX_TYPES_H
+
+#include_next <linux/types.h>
+
+typedef unsigned __bitwise__ fmode_t;
+
+#endif
diff --git a/kernel_patches/backport/2.6.22/rnfs_fs.patch b/kernel_patches/backport/2.6.22/rnfs_fs.patch
new file mode 100644
index 0000000..8e1e0b2
--- /dev/null
+++ b/kernel_patches/backport/2.6.22/rnfs_fs.patch
@@ -0,0 +1,1744 @@
+diff --git a/fs/exportfs/expfs.c b/fs/exportfs/expfs.c
+index 197c7db..027f947 100644
+--- a/fs/exportfs/expfs.c
++++ b/fs/exportfs/expfs.c
+@@ -250,7 +250,6 @@ static int filldir_one(void * __buf, const char * name, int len,
+ static int get_name(struct vfsmount *mnt, struct dentry *dentry,
+ 		char *name, struct dentry *child)
+ {
+-	const struct cred *cred = current_cred();
+ 	struct inode *dir = dentry->d_inode;
+ 	int error;
+ 	struct file *file;
+@@ -265,7 +264,7 @@ static int get_name(struct vfsmount *mnt, struct dentry *dentry,
+ 	/*
+ 	 * Open the directory ...
+ 	 */
+-	file = dentry_open(dget(dentry), mntget(mnt), O_RDONLY, cred);
++	file = dentry_open(dget(dentry), mntget(mnt), O_RDONLY);
+ 	error = PTR_ERR(file);
+ 	if (IS_ERR(file))
+ 		goto out;
+@@ -364,11 +363,15 @@ struct dentry *exportfs_decode_fh(struct vfsmount *mnt, struct fid *fid,
+ 	struct dentry *result, *alias;
+ 	char nbuf[NAME_MAX+1];
+ 	int err;
++	__u32 objp[2];
++
++	objp[0] = fid->i32.ino;
++	objp[1] = fid->i32.gen;
+ 
+ 	/*
+ 	 * Try to get any dentry for the given file handle from the filesystem.
+ 	 */
+-	result = nop->fh_to_dentry(mnt->mnt_sb, fid, fh_len, fileid_type);
++	result = nop->get_dentry(mnt->mnt_sb, &objp);
+ 	if (!result)
+ 		result = ERR_PTR(-ESTALE);
+ 	if (IS_ERR(result))
+@@ -419,11 +422,10 @@ struct dentry *exportfs_decode_fh(struct vfsmount *mnt, struct fid *fid,
+ 		 * file handle.  If this fails we'll have to give up.
+ 		 */
+ 		err = -ESTALE;
+-		if (!nop->fh_to_parent)
++		if (!nop->get_parent)
+ 			goto err_result;
+ 
+-		target_dir = nop->fh_to_parent(mnt->mnt_sb, fid,
+-				fh_len, fileid_type);
++		target_dir = nop->get_parent(result);
+ 		if (!target_dir)
+ 			goto err_result;
+ 		err = PTR_ERR(target_dir);
+diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c
+index 6d5d4a4..80af4b4 100644
+--- a/fs/lockd/mon.c
++++ b/fs/lockd/mon.c
+@@ -65,7 +65,7 @@ static void nsm_display_ipv4_address(const struct sockaddr *sap, char *buf,
+ 				     const size_t len)
+ {
+ 	const struct sockaddr_in *sin = (struct sockaddr_in *)sap;
+-	snprintf(buf, len, "%pI4", &sin->sin_addr.s_addr);
++	snprintf(buf, len, NIPQUAD_FMT, NIPQUAD(sin->sin_addr.s_addr));
+ }
+ 
+ static void nsm_display_ipv6_address(const struct sockaddr *sap, char *buf,
+@@ -74,12 +74,11 @@ static void nsm_display_ipv6_address(const struct sockaddr *sap, char *buf,
+ 	const struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sap;
+ 
+ 	if (ipv6_addr_v4mapped(&sin6->sin6_addr))
+-		snprintf(buf, len, "%pI4", &sin6->sin6_addr.s6_addr32[3]);
++		snprintf(buf, len, NIPQUAD_FMT, NIPQUAD(sin6->sin6_addr.s6_addr32[3]));
+ 	else if (sin6->sin6_scope_id != 0)
+-		snprintf(buf, len, "%pI6%%%u", &sin6->sin6_addr,
+-				sin6->sin6_scope_id);
++		snprintf(buf, len, NIP6_FMT"%%%u", NIP6(sin6->sin6_addr), sin6->sin6_scope_id);
+ 	else
+-		snprintf(buf, len, "%pI6", &sin6->sin6_addr);
++		snprintf(buf, len, NIP6_FMT, NIP6(sin6->sin6_addr));
+ }
+ 
+ static void nsm_display_address(const struct sockaddr *sap,
+diff --git a/fs/nfs/Makefile b/fs/nfs/Makefile
+index 8451598..5637a95 100644
+--- a/fs/nfs/Makefile
++++ b/fs/nfs/Makefile
+@@ -6,7 +6,7 @@ obj-$(CONFIG_NFS_FS) += nfs.o
+ 
+ nfs-y 			:= client.o dir.o file.o getroot.o inode.o super.o nfs2xdr.o \
+ 			   direct.o pagelist.o proc.o read.o symlink.o unlink.o \
+-			   write.o namespace.o mount_clnt.o
++			   write.o namespace.o mount_clnt.o backport-namespace.o
+ nfs-$(CONFIG_ROOT_NFS)	+= nfsroot.o
+ nfs-$(CONFIG_NFS_V3)	+= nfs3proc.o nfs3xdr.o
+ nfs-$(CONFIG_NFS_V3_ACL)	+= nfs3acl.o
+diff --git a/fs/nfs/backport-namespace.c b/fs/nfs/backport-namespace.c
+new file mode 100644
+index 0000000..de57f8b
+--- /dev/null
++++ b/fs/nfs/backport-namespace.c
+@@ -0,0 +1 @@
++#include "src/namespace.c"
+diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
+index 370b190..55877c8 100644
+--- a/fs/nfs/dir.c
++++ b/fs/nfs/dir.c
+@@ -899,7 +899,7 @@ static void nfs_dentry_iput(struct dentry *dentry, struct inode *inode)
+ 	iput(inode);
+ }
+ 
+-const struct dentry_operations nfs_dentry_operations = {
++struct dentry_operations nfs_dentry_operations = {
+ 	.d_revalidate	= nfs_lookup_revalidate,
+ 	.d_delete	= nfs_dentry_delete,
+ 	.d_iput		= nfs_dentry_iput,
+@@ -967,7 +967,7 @@ out:
+ #ifdef CONFIG_NFS_V4
+ static int nfs_open_revalidate(struct dentry *, struct nameidata *);
+ 
+-const struct dentry_operations nfs4_dentry_operations = {
++struct dentry_operations nfs4_dentry_operations = {
+ 	.d_revalidate	= nfs_open_revalidate,
+ 	.d_delete	= nfs_dentry_delete,
+ 	.d_iput		= nfs_dentry_iput,
+@@ -985,7 +985,7 @@ static int is_atomic_open(struct nameidata *nd)
+ 	if (nd->flags & LOOKUP_DIRECTORY)
+ 		return 0;
+ 	/* Are we trying to write to a read only partition? */
+-	if (__mnt_is_readonly(nd->path.mnt) &&
++	if (__mnt_is_readonly(nd->mnt) &&
+ 	    (nd->intent.open.flags & (O_CREAT|O_TRUNC|FMODE_WRITE)))
+ 		return 0;
+ 	return 1;
+@@ -1924,7 +1924,7 @@ int nfs_may_open(struct inode *inode, struct rpc_cred *cred, int openflags)
+ 	return nfs_do_access(inode, cred, nfs_open_permission_mask(openflags));
+ }
+ 
+-int nfs_permission(struct inode *inode, int mask)
++int nfs_permission(struct inode *inode, int mask, struct nameidata *nd)
+ {
+ 	struct rpc_cred *cred;
+ 	int res = 0;
+@@ -1934,7 +1934,7 @@ int nfs_permission(struct inode *inode, int mask)
+ 	if ((mask & (MAY_READ | MAY_WRITE | MAY_EXEC)) == 0)
+ 		goto out;
+ 	/* Is this sys_access() ? */
+-	if (mask & MAY_ACCESS)
++	if (nd != NULL && (nd->flags & LOOKUP_ACCESS))
+ 		goto force_lookup;
+ 
+ 	switch (inode->i_mode & S_IFMT) {
+@@ -1943,7 +1943,8 @@ int nfs_permission(struct inode *inode, int mask)
+ 		case S_IFREG:
+ 			/* NFSv4 has atomic_open... */
+ 			if (nfs_server_capable(inode, NFS_CAP_ATOMIC_OPEN)
+-					&& (mask & MAY_OPEN))
++					&& nd != NULL
++					&& (nd->flags & LOOKUP_OPEN))
+ 				goto out;
+ 			break;
+ 		case S_IFDIR:
+diff --git a/fs/nfs/file.c b/fs/nfs/file.c
+index ec7e27d..dd7dafa 100644
+--- a/fs/nfs/file.c
++++ b/fs/nfs/file.c
+@@ -55,7 +55,6 @@ static int  nfs_file_fsync(struct file *, struct dentry *dentry, int datasync);
+ static int nfs_check_flags(int flags);
+ static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl);
+ static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl);
+-static int nfs_setlease(struct file *file, long arg, struct file_lock **fl);
+ 
+ static struct vm_operations_struct nfs_file_vm_ops;
+ 
+@@ -74,7 +73,6 @@ const struct file_operations nfs_file_operations = {
+ 	.flock		= nfs_flock,
+ 	.splice_read	= nfs_file_splice_read,
+ 	.check_flags	= nfs_check_flags,
+-	.setlease	= nfs_setlease,
+ };
+ 
+ const struct inode_operations nfs_file_inode_operations = {
+@@ -186,12 +184,8 @@ static loff_t nfs_file_llseek(struct file *filp, loff_t offset, int origin)
+ 		int retval = nfs_revalidate_file_size(inode, filp);
+ 		if (retval < 0)
+ 			return (loff_t)retval;
+-
+-		spin_lock(&inode->i_lock);
+-		loff = generic_file_llseek_unlocked(filp, offset, origin);
+-		spin_unlock(&inode->i_lock);
+-	} else
+-		loff = generic_file_llseek_unlocked(filp, offset, origin);
++	}
++	loff = remote_llseek(filp, offset, origin);
+ 	return loff;
+ }
+ 
+@@ -332,82 +326,36 @@ nfs_file_fsync(struct file *file, struct dentry *dentry, int datasync)
+  * If the writer ends up delaying the write, the writer needs to
+  * increment the page use counts until he is done with the page.
+  */
+-static int nfs_write_begin(struct file *file, struct address_space *mapping,
+-			loff_t pos, unsigned len, unsigned flags,
+-			struct page **pagep, void **fsdata)
++static int nfs_prepare_write(struct file *file, struct page *page, unsigned offset, unsigned to)
+ {
+-	int ret;
+-	pgoff_t index;
+-	struct page *page;
+-	index = pos >> PAGE_CACHE_SHIFT;
+-
+-	dfprintk(PAGECACHE, "NFS: write_begin(%s/%s(%ld), %u@%lld)\n",
+-		file->f_path.dentry->d_parent->d_name.name,
+-		file->f_path.dentry->d_name.name,
+-		mapping->host->i_ino, len, (long long) pos);
+-
+-	/*
+-	 * Prevent starvation issues if someone is doing a consistency
+-	 * sync-to-disk
+-	 */
+-	ret = wait_on_bit(&NFS_I(mapping->host)->flags, NFS_INO_FLUSHING,
+-			nfs_wait_bit_killable, TASK_KILLABLE);
+-	if (ret)
+-		return ret;
+-
+-	page = grab_cache_page_write_begin(mapping, index, flags);
+-	if (!page)
+-		return -ENOMEM;
+-	*pagep = page;
+-
+-	ret = nfs_flush_incompatible(file, page);
+-	if (ret) {
+-		unlock_page(page);
+-		page_cache_release(page);
+-	}
+-	return ret;
++	return nfs_flush_incompatible(file, page);
+ }
+ 
+-static int nfs_write_end(struct file *file, struct address_space *mapping,
+-			loff_t pos, unsigned len, unsigned copied,
+-			struct page *page, void *fsdata)
++static int nfs_commit_write(struct file *file, struct page *page, unsigned offset, unsigned to)
+ {
+-	unsigned offset = pos & (PAGE_CACHE_SIZE - 1);
+ 	int status;
+ 
+-	dfprintk(PAGECACHE, "NFS: write_end(%s/%s(%ld), %u@%lld)\n",
+-		file->f_path.dentry->d_parent->d_name.name,
+-		file->f_path.dentry->d_name.name,
+-		mapping->host->i_ino, len, (long long) pos);
+-
+ 	/*
+ 	 * Zero any uninitialised parts of the page, and then mark the page
+ 	 * as up to date if it turns out that we're extending the file.
+ 	 */
+ 	if (!PageUptodate(page)) {
+ 		unsigned pglen = nfs_page_length(page);
+-		unsigned end = offset + len;
+ 
+ 		if (pglen == 0) {
+ 			zero_user_segments(page, 0, offset,
+-					end, PAGE_CACHE_SIZE);
++					to, PAGE_CACHE_SIZE);
+ 			SetPageUptodate(page);
+-		} else if (end >= pglen) {
+-			zero_user_segment(page, end, PAGE_CACHE_SIZE);
++		} else if (to >= pglen) {
++			zero_user_segment(page, to, PAGE_CACHE_SIZE);
+ 			if (offset == 0)
+ 				SetPageUptodate(page);
+ 		} else
+ 			zero_user_segment(page, pglen, PAGE_CACHE_SIZE);
+ 	}
+ 
+-	status = nfs_updatepage(file, page, offset, copied);
+-
+-	unlock_page(page);
+-	page_cache_release(page);
+-
+-	if (status < 0)
+-		return status;
+-	return copied;
++	status = nfs_updatepage(file, page, offset, to-offset);
++	return status;
+ }
+ 
+ /*
+@@ -471,8 +419,8 @@ const struct address_space_operations nfs_file_aops = {
+ 	.set_page_dirty = __set_page_dirty_nobuffers,
+ 	.writepage = nfs_writepage,
+ 	.writepages = nfs_writepages,
+-	.write_begin = nfs_write_begin,
+-	.write_end = nfs_write_end,
++	.prepare_write = nfs_prepare_write,
++	.commit_write = nfs_commit_write,
+ 	.invalidatepage = nfs_invalidate_page,
+ 	.releasepage = nfs_release_page,
+ 	.direct_IO = nfs_direct_IO,
+@@ -484,9 +432,8 @@ const struct address_space_operations nfs_file_aops = {
+  * writable, implying that someone is about to modify the page through a
+  * shared-writable mapping
+  */
+-static int nfs_vm_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
++static int nfs_vm_page_mkwrite(struct vm_area_struct *vma, struct page *page)
+ {
+-	struct page *page = vmf->page;
+ 	struct file *filp = vma->vm_file;
+ 	struct dentry *dentry = filp->f_path.dentry;
+ 	unsigned pagelen;
+@@ -517,14 +464,15 @@ static int nfs_vm_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
+ 
+ 	ret = nfs_updatepage(filp, page, 0, pagelen);
+ out_unlock:
++	unlock_page(page);
+ 	if (!ret)
+ 		return VM_FAULT_LOCKED;
+-	unlock_page(page);
+ 	return VM_FAULT_SIGBUS;
+ }
+ 
+ static struct vm_operations_struct nfs_file_vm_ops = {
+-	.fault = filemap_fault,
++	.nopage         = filemap_nopage,
++	.populate       = filemap_populate,
+ 	.page_mkwrite = nfs_vm_page_mkwrite,
+ };
+ 
+@@ -751,16 +699,3 @@ static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl)
+ 		return do_unlk(filp, cmd, fl);
+ 	return do_setlk(filp, cmd, fl);
+ }
+-
+-/*
+- * There is no protocol support for leases, so we have no way to implement
+- * them correctly in the face of opens by other clients.
+- */
+-static int nfs_setlease(struct file *file, long arg, struct file_lock **fl)
+-{
+-	dprintk("NFS: setlease(%s/%s, arg=%ld)\n",
+-			file->f_path.dentry->d_parent->d_name.name,
+-			file->f_path.dentry->d_name.name, arg);
+-
+-	return -EINVAL;
+-}
+diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
+index 64f8719..a66bfaf 100644
+--- a/fs/nfs/inode.c
++++ b/fs/nfs/inode.c
+@@ -1372,7 +1372,7 @@ static inline void nfs4_init_once(struct nfs_inode *nfsi)
+ #endif
+ }
+ 
+-static void init_once(void *foo)
++static void init_once(void *foo, struct kmem_cache *cachep, unsigned long temp)
+ {
+ 	struct nfs_inode *nfsi = (struct nfs_inode *) foo;
+ 
+@@ -1443,6 +1443,10 @@ static int __init init_nfs_fs(void)
+ {
+ 	int err;
+ 
++	err = init_mnt_writers();
++	if (err)
++		goto out7;
++
+ 	err = nfs_fscache_register();
+ 	if (err < 0)
+ 		goto out7;
+diff --git a/fs/nfs/namespace.c b/fs/nfs/namespace.c
+index 64a288e..3c0cf14 100644
+--- a/fs/nfs/namespace.c
++++ b/fs/nfs/namespace.c
+@@ -110,29 +110,29 @@ static void * nfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd)
+ 		goto out_err;
+ 
+ 	dprintk("%s: enter\n", __func__);
+-	dput(nd->path.dentry);
+-	nd->path.dentry = dget(dentry);
++	dput(nd->dentry);
++	nd->dentry = dget(dentry);
+ 
+ 	/* Look it up again */
+-	parent = dget_parent(nd->path.dentry);
++	parent = dget_parent(nd->dentry);
+ 	err = server->nfs_client->rpc_ops->lookup(parent->d_inode,
+-						  &nd->path.dentry->d_name,
++						  &nd->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->path.mnt, nd->path.dentry);
++		mnt = nfs_do_refmount(nd->mnt, nd->dentry);
+ 	else
+-		mnt = nfs_do_submount(nd->path.mnt, nd->path.dentry, &fh,
++		mnt = nfs_do_submount(nd->mnt, nd->dentry, &fh,
+ 				      &fattr);
+ 	err = PTR_ERR(mnt);
+ 	if (IS_ERR(mnt))
+ 		goto out_err;
+ 
+ 	mntget(mnt);
+-	err = do_add_mount(mnt, &nd->path, nd->path.mnt->mnt_flags|MNT_SHRINKABLE,
++	err = do_add_mount(mnt, nd, nd->mnt->mnt_flags|MNT_SHRINKABLE,
+ 			   &nfs_automount_list);
+ 	if (err < 0) {
+ 		mntput(mnt);
+@@ -140,9 +140,9 @@ static void * nfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd)
+ 			goto out_follow;
+ 		goto out_err;
+ 	}
+-	path_put(&nd->path);
+-	nd->path.mnt = mnt;
+-	nd->path.dentry = dget(mnt->mnt_root);
++	backport_path_put(nd);
++	nd->mnt = mnt;
++	nd->dentry = dget(mnt->mnt_root);
+ 	schedule_delayed_work(&nfs_automount_task, nfs_mountpoint_expiry_timeout);
+ out:
+ 	dprintk("%s: done, returned %d\n", __func__, err);
+@@ -150,11 +150,11 @@ out:
+ 	dprintk("<-- nfs_follow_mountpoint() = %d\n", err);
+ 	return ERR_PTR(err);
+ out_err:
+-	path_put(&nd->path);
++	backport_path_put(nd);
+ 	goto out;
+ out_follow:
+-	while (d_mountpoint(nd->path.dentry) &&
+-	       follow_down(&nd->path.mnt, &nd->path.dentry))
++	while (d_mountpoint(nd->dentry) &&
++	       follow_down(&nd->mnt, &nd->dentry))
+ 		;
+ 	err = 0;
+ 	goto out;
+diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
+index 84345de..4e4d332 100644
+--- a/fs/nfs/nfs4_fs.h
++++ b/fs/nfs/nfs4_fs.h
+@@ -179,7 +179,7 @@ struct nfs4_state_recovery_ops {
+ 	int (*recover_lock)(struct nfs4_state *, struct file_lock *);
+ };
+ 
+-extern const struct dentry_operations nfs4_dentry_operations;
++extern struct dentry_operations nfs4_dentry_operations;
+ extern const struct inode_operations nfs4_dir_inode_operations;
+ 
+ /* inode.c */
+diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
+index a4d2426..385ce91 100644
+--- a/fs/nfs/nfs4proc.c
++++ b/fs/nfs/nfs4proc.c
+@@ -1487,7 +1487,7 @@ struct dentry *
+ nfs4_atomic_open(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
+ {
+ 	struct path path = {
+-		.mnt = nd->path.mnt,
++		.mnt = nd->mnt,
+ 		.dentry = dentry,
+ 	};
+ 	struct dentry *parent;
+@@ -1536,7 +1536,7 @@ int
+ nfs4_open_revalidate(struct inode *dir, struct dentry *dentry, int openflags, struct nameidata *nd)
+ {
+ 	struct path path = {
+-		.mnt = nd->path.mnt,
++		.mnt = nd->mnt,
+ 		.dentry = dentry,
+ 	};
+ 	struct rpc_cred *cred;
+@@ -1999,7 +1999,7 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
+                  int flags, struct nameidata *nd)
+ {
+ 	struct path path = {
+-		.mnt = nd->path.mnt,
++		.mnt = nd->mnt,
+ 		.dentry = dentry,
+ 	};
+ 	struct nfs4_state *state;
+diff --git a/fs/nfs/nfsroot.c b/fs/nfs/nfsroot.c
+index d9ef602..00e51a5 100644
+--- a/fs/nfs/nfsroot.c
++++ b/fs/nfs/nfsroot.c
+@@ -331,7 +331,7 @@ static int __init root_nfs_addr(void)
+ 	}
+ 
+ 	snprintf(nfs_data.hostname, sizeof(nfs_data.hostname),
+-		 "%pI4", &servaddr);
++		 NIPQUAD_FMT, NIPQUAD(servaddr));
+ 	return 0;
+ }
+ 
+@@ -423,8 +423,8 @@ static int __init root_nfs_getport(int program, int version, int proto)
+ {
+ 	struct sockaddr_in sin;
+ 
+-	printk(KERN_NOTICE "Looking up port of RPC %d/%d on %pI4\n",
+-		program, version, &servaddr);
++	printk(KERN_NOTICE "Looking up port of RPC %d/%d on "NIPQUAD_FMT"\n",
++		program, version, NIPQUAD(servaddr));
+ 	set_sockaddr(&sin, servaddr, 0);
+ 	return rpcb_getport_sync(&sin, program, version, proto);
+ }
+diff --git a/fs/nfs/super.c b/fs/nfs/super.c
+index 6717200..b8dd762 100644
+--- a/fs/nfs/super.c
++++ b/fs/nfs/super.c
+@@ -103,7 +103,7 @@ enum {
+ 	Opt_err
+ };
+ 
+-static const match_table_t nfs_mount_option_tokens = {
++static match_table_t nfs_mount_option_tokens = {
+ 	{ Opt_userspace, "bg" },
+ 	{ Opt_userspace, "fg" },
+ 	{ Opt_userspace, "retry=%s" },
+@@ -175,7 +175,7 @@ enum {
+ 	Opt_xprt_err
+ };
+ 
+-static const match_table_t nfs_xprt_protocol_tokens = {
++static match_table_t nfs_xprt_protocol_tokens = {
+ 	{ Opt_xprt_udp, "udp" },
+ 	{ Opt_xprt_tcp, "tcp" },
+ 	{ Opt_xprt_rdma, "rdma" },
+@@ -192,7 +192,7 @@ enum {
+ 	Opt_sec_err
+ };
+ 
+-static const match_table_t nfs_secflavor_tokens = {
++static match_table_t nfs_secflavor_tokens = {
+ 	{ Opt_sec_none, "none" },
+ 	{ Opt_sec_none, "null" },
+ 	{ Opt_sec_sys, "sys" },
+@@ -229,7 +229,7 @@ static match_table_t nfs_lookupcache_tokens = {
+ };
+ 
+ 
+-static void nfs_umount_begin(struct super_block *);
++static void nfs_umount_begin(struct vfsmount *vfsmnt, int flags);
+ static int  nfs_statfs(struct dentry *, struct kstatfs *);
+ static int  nfs_show_options(struct seq_file *, struct vfsmount *);
+ static int  nfs_show_stats(struct seq_file *, struct vfsmount *);
+@@ -313,10 +313,7 @@ static const struct super_operations nfs4_sops = {
+ };
+ #endif
+ 
+-static struct shrinker acl_shrinker = {
+-	.shrink		= nfs_access_cache_shrinker,
+-	.seeks		= DEFAULT_SEEKS,
+-};
++static struct shrinker *acl_shrinker;
+ 
+ /*
+  * Register the NFS filesystems
+@@ -337,7 +334,7 @@ int __init register_nfs_fs(void)
+ 	if (ret < 0)
+ 		goto error_2;
+ #endif
+-	register_shrinker(&acl_shrinker);
++	acl_shrinker = set_shrinker(DEFAULT_SEEKS, nfs_access_cache_shrinker);
+ 	return 0;
+ 
+ #ifdef CONFIG_NFS_V4
+@@ -355,7 +352,8 @@ error_0:
+  */
+ void __exit unregister_nfs_fs(void)
+ {
+-	unregister_shrinker(&acl_shrinker);
++	if (acl_shrinker != NULL)
++		remove_shrinker(acl_shrinker);
+ #ifdef CONFIG_NFS_V4
+ 	unregister_filesystem(&nfs4_fs_type);
+ #endif
+@@ -471,12 +469,12 @@ static void nfs_show_mountd_options(struct seq_file *m, struct nfs_server *nfss,
+ 	switch (sap->sa_family) {
+ 	case AF_INET: {
+ 		struct sockaddr_in *sin = (struct sockaddr_in *)sap;
+-		seq_printf(m, ",mountaddr=%pI4", &sin->sin_addr.s_addr);
++		seq_printf(m, ",mountaddr="NIPQUAD_FMT, NIPQUAD(sin->sin_addr.s_addr));
+ 		break;
+ 	}
+ 	case AF_INET6: {
+ 		struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sap;
+-		seq_printf(m, ",mountaddr=%pI6", &sin6->sin6_addr);
++		seq_printf(m, ",mountaddr="NIP6_FMT, NIP6(sin6->sin6_addr));
+ 		break;
+ 	}
+ 	default:
+@@ -681,11 +679,14 @@ static int nfs_show_stats(struct seq_file *m, struct vfsmount *mnt)
+  * Begin unmount by attempting to remove all automounted mountpoints we added
+  * in response to xdev traversals and referrals
+  */
+-static void nfs_umount_begin(struct super_block *sb)
++static void nfs_umount_begin(struct vfsmount *vfsmnt, int flags)
+ {
+-	struct nfs_server *server = NFS_SB(sb);
++	struct nfs_server *server = NFS_SB(vfsmnt->mnt_sb);
+ 	struct rpc_clnt *rpc;
+ 
++	if (!(flags & MNT_FORCE))
++		return;
++
+ 	/* -EIO all pending I/O */
+ 	rpc = server->client_acl;
+ 	if (!IS_ERR(rpc))
+diff --git a/fs/nfsd/auth.c b/fs/nfsd/auth.c
+index 5573508..294992e 100644
+--- a/fs/nfsd/auth.c
++++ b/fs/nfsd/auth.c
+@@ -27,73 +27,53 @@ int nfsexp_flags(struct svc_rqst *rqstp, struct svc_export *exp)
+ 
+ int nfsd_setuser(struct svc_rqst *rqstp, struct svc_export *exp)
+ {
+-	struct group_info *rqgi;
+-	struct group_info *gi;
+-	struct cred *new;
++	struct svc_cred	cred = rqstp->rq_cred;
+ 	int i;
+ 	int flags = nfsexp_flags(rqstp, exp);
+ 	int ret;
+ 
+-	/* discard any old override before preparing the new set */
+-	revert_creds(get_cred(current->real_cred));
+-	new = prepare_creds();
+-	if (!new)
+-		return -ENOMEM;
+-
+-	new->fsuid = rqstp->rq_cred.cr_uid;
+-	new->fsgid = rqstp->rq_cred.cr_gid;
+-
+-	rqgi = rqstp->rq_cred.cr_group_info;
+-
+ 	if (flags & NFSEXP_ALLSQUASH) {
+-		new->fsuid = exp->ex_anon_uid;
+-		new->fsgid = exp->ex_anon_gid;
+-		gi = groups_alloc(0);
+-		if (!gi)
+-			goto oom;
++		cred.cr_uid = exp->ex_anon_uid;
++		cred.cr_gid = exp->ex_anon_gid;
++		cred.cr_group_info = groups_alloc(0);
+ 	} else if (flags & NFSEXP_ROOTSQUASH) {
+-		if (!new->fsuid)
+-			new->fsuid = exp->ex_anon_uid;
+-		if (!new->fsgid)
+-			new->fsgid = exp->ex_anon_gid;
+-
+-		gi = groups_alloc(rqgi->ngroups);
+-		if (!gi)
+-			goto oom;
++		struct group_info *gi;
++		if (!cred.cr_uid)
++			cred.cr_uid = exp->ex_anon_uid;
++		if (!cred.cr_gid)
++			cred.cr_gid = exp->ex_anon_gid;
++		gi = groups_alloc(cred.cr_group_info->ngroups);
++		if (gi)
++			for (i = 0; i < cred.cr_group_info->ngroups; i++) {
++				if (!GROUP_AT(cred.cr_group_info, i))
++					GROUP_AT(gi, i) = exp->ex_anon_gid;
++				else
++					GROUP_AT(gi, i) = GROUP_AT(cred.cr_group_info, i);
++			}
++		cred.cr_group_info = gi;
++	} else
++		get_group_info(cred.cr_group_info);
++
++	if (cred.cr_uid != (uid_t) -1)
++		current->fsuid = cred.cr_uid;
++	else
++		current->fsuid = exp->ex_anon_uid;
++	if (cred.cr_gid != (gid_t) -1)
++		current->fsgid = cred.cr_gid;
++	else
++		current->fsgid = exp->ex_anon_gid;
+ 
+-		for (i = 0; i < rqgi->ngroups; i++) {
+-			if (!GROUP_AT(rqgi, i))
+-				GROUP_AT(gi, i) = exp->ex_anon_gid;
+-			else
+-				GROUP_AT(gi, i) = GROUP_AT(rqgi, i);
+-		}
++	if (!cred.cr_group_info)
++		return -ENOMEM;
++	ret = set_current_groups(cred.cr_group_info);
++	put_group_info(cred.cr_group_info);
++	if ((cred.cr_uid)) {
++		current->cap_effective =
++			cap_drop_nfsd_set(current->cap_effective);
+ 	} else {
+-		gi = get_group_info(rqgi);
++		current->cap_effective =
++			cap_raise_nfsd_set(current->cap_effective,
++					   current->cap_permitted);
+ 	}
+-
+-	if (new->fsuid == (uid_t) -1)
+-		new->fsuid = exp->ex_anon_uid;
+-	if (new->fsgid == (gid_t) -1)
+-		new->fsgid = exp->ex_anon_gid;
+-
+-	ret = set_groups(new, gi);
+-	put_group_info(gi);
+-	if (ret < 0)
+-		goto error;
+-
+-	if (new->fsuid)
+-		new->cap_effective = cap_drop_nfsd_set(new->cap_effective);
+-	else
+-		new->cap_effective = cap_raise_nfsd_set(new->cap_effective,
+-							new->cap_permitted);
+-	put_cred(override_creds(new));
+-	put_cred(new);
+-	return 0;
+-
+-oom:
+-	ret = -ENOMEM;
+-error:
+-	abort_creds(new);
+ 	return ret;
+ }
+-
+diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c
+index 5839b22..1850a29 100644
+--- a/fs/nfsd/export.c
++++ b/fs/nfsd/export.c
+@@ -203,7 +203,7 @@ static int expkey_show(struct seq_file *m,
+ 	if (test_bit(CACHE_VALID, &h->flags) && 
+ 	    !test_bit(CACHE_NEGATIVE, &h->flags)) {
+ 		seq_printf(m, " ");
+-		seq_path(m, &ek->ek_path, "\\ \t\n");
++		seq_path(m, ek->ek_path.mnt, ek->ek_path.dentry, "\\ \t\n");
+ 	}
+ 	seq_printf(m, "\n");
+ 	return 0;
+@@ -345,7 +345,7 @@ static void svc_export_request(struct cache_detail *cd,
+ 	char *pth;
+ 
+ 	qword_add(bpp, blen, exp->ex_client->name);
+-	pth = d_path(&exp->ex_path, *bpp, *blen);
++	pth = d_path(exp->ex_path.dentry, exp->ex_path.mnt, *bpp, *blen);
+ 	if (IS_ERR(pth)) {
+ 		/* is this correct? */
+ 		(*bpp)[0] = '\n';
+@@ -384,7 +384,7 @@ static int check_export(struct inode *inode, int flags, unsigned char *uuid)
+ 	}
+ 
+ 	if (!inode->i_sb->s_export_op ||
+-	    !inode->i_sb->s_export_op->fh_to_dentry) {
++	    !inode->i_sb->s_export_op->get_dentry) {
+ 		dprintk("exp_export: export of invalid fs type.\n");
+ 		return -EINVAL;
+ 	}
+@@ -642,7 +642,7 @@ static int svc_export_show(struct seq_file *m,
+ 		return 0;
+ 	}
+ 	exp = container_of(h, struct svc_export, h);
+-	seq_path(m, &exp->ex_path, " \t\n\\");
++	seq_path(m, exp->ex_path.mnt, exp->ex_path.dentry, " \t\n\\");
+ 	seq_putc(m, '\t');
+ 	seq_escape(m, exp->ex_client->name, " \t\n\\");
+ 	seq_putc(m, '(');
+diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
+index 5275097..fd193b6 100644
+--- a/fs/nfsd/nfs4recover.c
++++ b/fs/nfsd/nfs4recover.c
+@@ -54,26 +54,20 @@
+ static struct path rec_dir;
+ static int rec_dir_init = 0;
+ 
+-static int
+-nfs4_save_creds(const struct cred **original_creds)
++static void
++nfs4_save_user(uid_t *saveuid, gid_t *savegid)
+ {
+-	struct cred *new;
+-
+-	new = prepare_creds();
+-	if (!new)
+-		return -ENOMEM;
+-
+-	new->fsuid = 0;
+-	new->fsgid = 0;
+-	*original_creds = override_creds(new);
+-	put_cred(new);
+-	return 0;
++	*saveuid = current->fsuid;
++	*savegid = current->fsgid;
++	current->fsuid = 0;
++	current->fsgid = 0;
+ }
+ 
+ static void
+-nfs4_reset_creds(const struct cred *original)
++nfs4_reset_user(uid_t saveuid, gid_t savegid)
+ {
+-	revert_creds(original);
++	current->fsuid = saveuid;
++	current->fsgid = savegid;
+ }
+ 
+ static void
+@@ -135,7 +129,8 @@ nfsd4_sync_rec_dir(void)
+ int
+ nfsd4_create_clid_dir(struct nfs4_client *clp)
+ {
+-	const struct cred *original_cred;
++	uid_t uid;
++	gid_t gid;
+ 	char *dname = clp->cl_recdir;
+ 	struct dentry *dentry;
+ 	int status;
+@@ -145,9 +140,7 @@ nfsd4_create_clid_dir(struct nfs4_client *clp)
+ 	if (!rec_dir_init || clp->cl_firststate)
+ 		return 0;
+ 
+-	status = nfs4_save_creds(&original_cred);
+-	if (status < 0)
+-		return status;
++	nfs4_save_user(&uid, &gid);
+ 
+ 	/* lock the parent */
+ 	mutex_lock(&rec_dir.dentry->d_inode->i_mutex);
+@@ -175,7 +168,7 @@ out_unlock:
+ 		clp->cl_firststate = 1;
+ 		nfsd4_sync_rec_dir();
+ 	}
+-	nfs4_reset_creds(original_cred);
++	nfs4_reset_user(uid, gid);
+ 	dprintk("NFSD: nfsd4_create_clid_dir returns %d\n", status);
+ 	return status;
+ }
+@@ -208,7 +201,8 @@ nfsd4_build_namelist(void *arg, const char *name, int namlen,
+ static int
+ nfsd4_list_rec_dir(struct dentry *dir, recdir_func *f)
+ {
+-	const struct cred *original_cred;
++	uid_t uid;
++	gid_t gid;
+ 	struct file *filp;
+ 	LIST_HEAD(names);
+ 	struct name_list *entry;
+@@ -218,12 +212,9 @@ nfsd4_list_rec_dir(struct dentry *dir, recdir_func *f)
+ 	if (!rec_dir_init)
+ 		return 0;
+ 
+-	status = nfs4_save_creds(&original_cred);
+-	if (status < 0)
+-		return status;
++	nfs4_save_user(&uid, &gid);
+ 
+-	filp = dentry_open(dget(dir), mntget(rec_dir.mnt), O_RDONLY,
+-			   current_cred());
++	filp = dentry_open(dget(dir), mntget(rec_dir.mnt), O_RDONLY);
+ 	status = PTR_ERR(filp);
+ 	if (IS_ERR(filp))
+ 		goto out;
+@@ -252,7 +243,7 @@ out:
+ 		list_del(&entry->list);
+ 		kfree(entry);
+ 	}
+-	nfs4_reset_creds(original_cred);
++	nfs4_reset_user(uid, gid);
+ 	return status;
+ }
+ 
+@@ -284,7 +275,8 @@ out_unlock:
+ void
+ nfsd4_remove_clid_dir(struct nfs4_client *clp)
+ {
+-	const struct cred *original_cred;
++	uid_t uid;
++	gid_t gid;
+ 	int status;
+ 
+ 	if (!rec_dir_init || !clp->cl_firststate)
+@@ -295,12 +287,10 @@ nfsd4_remove_clid_dir(struct nfs4_client *clp)
+ 		goto out;
+ 	clp->cl_firststate = 0;
+ 
+-	status = nfs4_save_creds(&original_cred);
+-	if (status < 0)
+-		goto out;
++	nfs4_save_user(&uid, &gid);
+ 
+ 	status = nfsd4_unlink_clid_dir(clp->cl_recdir, HEXDIR_LEN-1);
+-	nfs4_reset_creds(original_cred);
++	nfs4_reset_user(uid, gid);
+ 	if (status == 0)
+ 		nfsd4_sync_rec_dir();
+ 	mnt_drop_write(rec_dir.mnt);
+@@ -378,7 +368,8 @@ nfsd4_recdir_load(void) {
+ void
+ nfsd4_init_recdir(char *rec_dirname)
+ {
+-	const struct cred *original_cred;
++	uid_t uid;
++	gid_t gid;
+ 	int status;
+ 
+ 	printk("NFSD: Using %s as the NFSv4 state recovery directory\n",
+@@ -386,13 +377,7 @@ nfsd4_init_recdir(char *rec_dirname)
+ 
+ 	BUG_ON(rec_dir_init);
+ 
+-	status = nfs4_save_creds(&original_cred);
+-	if (status < 0) {
+-		printk("NFSD: Unable to change credentials to find recovery"
+-		       " directory: error %d\n",
+-		       status);
+-		return;
+-	}
++	nfs4_save_user(&uid, &gid);
+ 
+ 	status = kern_path(rec_dirname, LOOKUP_FOLLOW | LOOKUP_DIRECTORY,
+ 			&rec_dir);
+@@ -402,7 +387,7 @@ nfsd4_init_recdir(char *rec_dirname)
+ 
+ 	if (!status)
+ 		rec_dir_init = 1;
+-	nfs4_reset_creds(original_cred);
++	nfs4_reset_user(uid, gid);
+ }
+ 
+ void
+diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
+index c65a27b..d84c232 100644
+--- a/fs/nfsd/nfs4state.c
++++ b/fs/nfsd/nfs4state.c
+@@ -1552,7 +1552,7 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+ 		status = nfserr_clid_inuse;
+ 		if (!same_creds(&conf->cl_cred, &rqstp->rq_cred)) {
+ 			dprintk("NFSD: setclientid: string in use by client"
+-				" at %pI4\n", &conf->cl_addr);
++				" at "NIPQUAD_FMT"\n", NIPQUAD(conf->cl_addr));
+ 			goto out;
+ 		}
+ 	}
+diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c
+index 9f1ca17..3702de6 100644
+--- a/fs/nfsd/nfsfh.c
++++ b/fs/nfsd/nfsfh.c
+@@ -186,14 +186,9 @@ static __be32 nfsd_set_fh_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp)
+ 		 * access control settings being in effect, we cannot
+ 		 * fix that case easily.
+ 		 */
+-		struct cred *new = prepare_creds();
+-		if (!new)
+-			return nfserrno(-ENOMEM);
+-		new->cap_effective =
+-			cap_raise_nfsd_set(new->cap_effective,
+-					   new->cap_permitted);
+-		put_cred(override_creds(new));
+-		put_cred(new);
++		current->cap_effective =
++			cap_raise_nfsd_set(current->cap_effective,
++					   current->cap_permitted);
+ 	} else {
+ 		error = nfsd_setuser_and_check_port(rqstp, exp);
+ 		if (error)
+diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
+index 6c68ffd..5e76f84 100644
+--- a/fs/nfsd/vfs.c
++++ b/fs/nfsd/vfs.c
+@@ -55,6 +55,7 @@
+ #include <linux/security.h>
+ #endif /* CONFIG_NFSD_V4 */
+ #include <linux/jhash.h>
++#include <linux/cred.h>
+ 
+ #include <asm/uaccess.h>
+ 
+@@ -677,7 +678,6 @@ __be32
+ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
+ 			int access, struct file **filp)
+ {
+-	const struct cred *cred = current_cred();
+ 	struct dentry	*dentry;
+ 	struct inode	*inode;
+ 	int		flags = O_RDONLY|O_LARGEFILE;
+@@ -732,7 +732,7 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
+ 		vfs_dq_init(inode);
+ 	}
+ 	*filp = dentry_open(dget(dentry), mntget(fhp->fh_export->ex_path.mnt),
+-			    flags, cred);
++			    flags);
+ 	if (IS_ERR(*filp))
+ 		host_err = PTR_ERR(*filp);
+ out_nfserr:
+@@ -843,45 +843,30 @@ found:
+  * directly. They will be released after the sending has completed.
+  */
+ static int
+-nfsd_splice_actor(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
+-		  struct splice_desc *sd)
++nfsd_read_actor(read_descriptor_t *desc, struct page *page, unsigned long offset, unsigned long size)
+ {
+-	struct svc_rqst *rqstp = sd->u.data;
+-	struct page **pp = rqstp->rq_respages + rqstp->rq_resused;
+-	struct page *page = buf->page;
+-	size_t size;
+-	int ret;
+-
+-	ret = buf->ops->confirm(pipe, buf);
+-	if (unlikely(ret))
+-		return ret;
++	unsigned long count = desc->count;
++	struct svc_rqst *rqstp = desc->arg.data;
+ 
+-	size = sd->len;
++	if (size > count)
++		size = count;
+ 
+ 	if (rqstp->rq_res.page_len == 0) {
+ 		get_page(page);
+-		put_page(*pp);
+-		*pp = page;
+-		rqstp->rq_resused++;
+-		rqstp->rq_res.page_base = buf->offset;
++		rqstp->rq_respages[rqstp->rq_resused++] = page;
++		rqstp->rq_res.page_base = offset;
+ 		rqstp->rq_res.page_len = size;
+-	} else if (page != pp[-1]) {
++	} else if (page != rqstp->rq_respages[rqstp->rq_resused-1]) { 
+ 		get_page(page);
+-		if (*pp)
+-			put_page(*pp);
+-		*pp = page;
+-		rqstp->rq_resused++;
++		rqstp->rq_respages[rqstp->rq_resused++] = page;
+ 		rqstp->rq_res.page_len += size;
+ 	} else
+ 		rqstp->rq_res.page_len += size;
+ 
+-	return size;
+-}
++	desc->count = count - size;
++	desc->written += size;
+ 
+-static int nfsd_direct_splice_actor(struct pipe_inode_info *pipe,
+-				    struct splice_desc *sd)
+-{
+-	return __splice_from_pipe(pipe, sd, nfsd_splice_actor);
++	return size;
+ }
+ 
+ static inline int svc_msnfs(struct svc_fh *ffhp)
+@@ -915,16 +900,9 @@ nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
+ 	if (ra && ra->p_set)
+ 		file->f_ra = ra->p_ra;
+ 
+-	if (file->f_op->splice_read && rqstp->rq_splice_ok) {
+-		struct splice_desc sd = {
+-			.len		= 0,
+-			.total_len	= *count,
+-			.pos		= offset,
+-			.u.data		= rqstp,
+-		};
+-
++	if (file->f_op->sendfile && rqstp->rq_sendfile_ok) {
+ 		rqstp->rq_resused = 1;
+-		host_err = splice_direct_to_actor(file, &sd, nfsd_direct_splice_actor);
++		host_err = file->f_op->sendfile(file, &offset, *count, nfsd_read_actor, rqstp);
+ 	} else {
+ 		oldfs = get_fs();
+ 		set_fs(KERNEL_DS);
+@@ -1005,9 +983,7 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
+ 	if (!EX_ISSYNC(exp))
+ 		stable = 0;
+ 	if (stable && !EX_WGATHER(exp)) {
+-		spin_lock(&file->f_lock);
+ 		file->f_flags |= O_SYNC;
+-		spin_unlock(&file->f_lock);
+ 	}
+ 
+ 	/* Write the data. */
+diff --git a/include/linux/exportfs.h b/include/linux/exportfs.h
+index 27e772c..ad9a829 100644
+--- a/include/linux/exportfs.h
++++ b/include/linux/exportfs.h
+@@ -89,85 +89,10 @@ struct fid {
+ 	};
+ };
+ 
+-/**
+- * struct export_operations - for nfsd to communicate with file systems
+- * @encode_fh:      encode a file handle fragment from a dentry
+- * @fh_to_dentry:   find the implied object and get a dentry for it
+- * @fh_to_parent:   find the implied object's parent and get a dentry for it
+- * @get_name:       find the name for a given inode in a given directory
+- * @get_parent:     find the parent of a given directory
+- *
+- * See Documentation/filesystems/Exporting for details on how to use
+- * this interface correctly.
+- *
+- * encode_fh:
+- *    @encode_fh should store in the file handle fragment @fh (using at most
+- *    @max_len bytes) information that can be used by @decode_fh to recover the
+- *    file refered to by the &struct dentry @de.  If the @connectable flag is
+- *    set, the encode_fh() should store sufficient information so that a good
+- *    attempt can be made to find not only the file but also it's place in the
+- *    filesystem.   This typically means storing a reference to de->d_parent in
+- *    the filehandle fragment.  encode_fh() should return the number of bytes
+- *    stored or a negative error code such as %-ENOSPC
+- *
+- * fh_to_dentry:
+- *    @fh_to_dentry is given a &struct super_block (@sb) and a file handle
+- *    fragment (@fh, @fh_len). It should return a &struct dentry which refers
+- *    to the same file that the file handle fragment refers to.  If it cannot,
+- *    it should return a %NULL pointer if the file was found but no acceptable
+- *    &dentries were available, or an %ERR_PTR error code indicating why it
+- *    couldn't be found (e.g. %ENOENT or %ENOMEM).  Any suitable dentry can be
+- *    returned including, if necessary, a new dentry created with d_alloc_root.
+- *    The caller can then find any other extant dentries by following the
+- *    d_alias links.
+- *
+- * fh_to_parent:
+- *    Same as @fh_to_dentry, except that it returns a pointer to the parent
+- *    dentry if it was encoded into the filehandle fragment by @encode_fh.
+- *
+- * get_name:
+- *    @get_name should find a name for the given @child in the given @parent
+- *    directory.  The name should be stored in the @name (with the
+- *    understanding that it is already pointing to a a %NAME_MAX+1 sized
+- *    buffer.   get_name() should return %0 on success, a negative error code
+- *    or error.  @get_name will be called without @parent->i_mutex held.
+- *
+- * get_parent:
+- *    @get_parent should find the parent directory for the given @child which
+- *    is also a directory.  In the event that it cannot be found, or storage
+- *    space cannot be allocated, a %ERR_PTR should be returned.
+- *
+- * Locking rules:
+- *    get_parent is called with child->d_inode->i_mutex down
+- *    get_name is not (which is possibly inconsistent)
+- */
+-
+-struct export_operations {
+-	int (*encode_fh)(struct dentry *de, __u32 *fh, int *max_len,
+-			int connectable);
+-	struct dentry * (*fh_to_dentry)(struct super_block *sb, struct fid *fid,
+-			int fh_len, int fh_type);
+-	struct dentry * (*fh_to_parent)(struct super_block *sb, struct fid *fid,
+-			int fh_len, int fh_type);
+-	int (*get_name)(struct dentry *parent, char *name,
+-			struct dentry *child);
+-	struct dentry * (*get_parent)(struct dentry *child);
+-};
+-
+ extern int exportfs_encode_fh(struct dentry *dentry, struct fid *fid,
+ 	int *max_len, int connectable);
+ extern struct dentry *exportfs_decode_fh(struct vfsmount *mnt, struct fid *fid,
+ 	int fh_len, int fileid_type, int (*acceptable)(void *, struct dentry *),
+ 	void *context);
+ 
+-/*
+- * Generic helpers for filesystems.
+- */
+-extern struct dentry *generic_fh_to_dentry(struct super_block *sb,
+-	struct fid *fid, int fh_len, int fh_type,
+-	struct inode *(*get_inode) (struct super_block *sb, u64 ino, u32 gen));
+-extern struct dentry *generic_fh_to_parent(struct super_block *sb,
+-	struct fid *fid, int fh_len, int fh_type,
+-	struct inode *(*get_inode) (struct super_block *sb, u64 ino, u32 gen));
+-
+ #endif /* LINUX_EXPORTFS_H */
+diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
+index fdffb41..4f1382b 100644
+--- a/include/linux/nfs_fs.h
++++ b/include/linux/nfs_fs.h
+@@ -343,7 +343,7 @@ 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_post_op_update_inode_force_wcc(struct inode *inode, struct nfs_fattr *fattr);
+ extern int nfs_getattr(struct vfsmount *, struct dentry *, struct kstat *);
+-extern int nfs_permission(struct inode *, int);
++extern int nfs_permission(struct inode *, int, struct nameidata *);
+ extern int nfs_open(struct inode *, struct file *);
+ extern int nfs_release(struct inode *, struct file *);
+ extern int nfs_attribute_timeout(struct inode *inode);
+@@ -425,7 +425,7 @@ extern const struct inode_operations nfs_dir_inode_operations;
+ extern const struct inode_operations nfs3_dir_inode_operations;
+ #endif /* CONFIG_NFS_V3 */
+ extern const struct file_operations nfs_dir_operations;
+-extern const struct dentry_operations nfs_dentry_operations;
++extern struct dentry_operations nfs_dentry_operations;
+ 
+ extern void nfs_force_lookup_revalidate(struct inode *dir);
+ extern int nfs_instantiate(struct dentry *dentry, struct nfs_fh *fh, struct nfs_fattr *fattr);
+diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
+index b89c34e..9708e78 100644
+--- a/include/linux/nfs_xdr.h
++++ b/include/linux/nfs_xdr.h
+@@ -817,7 +817,7 @@ struct nfs_access_entry;
+  */
+ struct nfs_rpc_ops {
+ 	u32	version;		/* Protocol version */
+-	const struct dentry_operations *dentry_ops;
++	struct dentry_operations *dentry_ops;
+ 	const struct inode_operations *dir_inode_ops;
+ 	const struct inode_operations *file_inode_ops;
+ 
+diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h
+index 2a30775..972e62c 100644
+--- a/include/linux/sunrpc/svc.h
++++ b/include/linux/sunrpc/svc.h
+@@ -272,7 +272,7 @@ struct svc_rqst {
+ 						 * determine what device number
+ 						 * to report (real or virtual)
+ 						 */
+-	int			rq_splice_ok;   /* turned off in gss privacy
++	int			rq_sendfile_ok;	/* turned off in gss privacy
+ 						 * to prevent encrypting page
+ 						 * cache pages */
+ 	wait_queue_head_t	rq_wait;	/* synchronization */
+diff --git a/include/linux/sunrpc/svc_xprt.h b/include/linux/sunrpc/svc_xprt.h
+index 0d9cb6e..66ac213 100644
+--- a/include/linux/sunrpc/svc_xprt.h
++++ b/include/linux/sunrpc/svc_xprt.h
+@@ -147,13 +147,13 @@ static inline char *__svc_print_addr(const struct sockaddr *addr,
+ 
+ 	switch (addr->sa_family) {
+ 	case AF_INET:
+-		snprintf(buf, len, "%pI4, port=%u", &sin->sin_addr,
++		snprintf(buf, len,  NIPQUAD_FMT", port=%u", NIPQUAD(sin->sin_addr),
+ 			ntohs(sin->sin_port));
+ 		break;
+ 
+ 	case AF_INET6:
+-		snprintf(buf, len, "%pI6, port=%u",
+-			 &sin6->sin6_addr,
++		snprintf(buf, len, NIP6_FMT", port=%u",
++			NIP6(sin6->sin6_addr),
+ 			ntohs(sin6->sin6_port));
+ 		break;
+ 
+diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c
+index 0c431c2..1b48190 100644
+--- a/net/sunrpc/auth.c
++++ b/net/sunrpc/auth.c
+@@ -350,18 +350,17 @@ EXPORT_SYMBOL_GPL(rpcauth_lookup_credcache);
+ struct rpc_cred *
+ rpcauth_lookupcred(struct rpc_auth *auth, int flags)
+ {
+-	struct auth_cred acred;
++	struct auth_cred acred = {
++		.uid = current->fsuid,
++		.gid = current->fsgid,
++		.group_info = current->group_info,
++	};
+ 	struct rpc_cred *ret;
+-	const struct cred *cred = current_cred();
+ 
+ 	dprintk("RPC:       looking up %s cred\n",
+ 		auth->au_ops->au_name);
+ 
+-	memset(&acred, 0, sizeof(acred));
+-	acred.uid = cred->fsuid;
+-	acred.gid = cred->fsgid;
+-	acred.group_info = get_group_info(((struct cred *)cred)->group_info);
+-
++	get_group_info(acred.group_info);
+ 	ret = auth->au_ops->lookup_cred(auth, &acred, flags);
+ 	put_group_info(acred.group_info);
+ 	return ret;
+@@ -568,19 +567,16 @@ rpcauth_uptodatecred(struct rpc_task *task)
+ 		test_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags) != 0;
+ }
+ 
+-static struct shrinker rpc_cred_shrinker = {
+-	.shrink = rpcauth_cache_shrinker,
+-	.seeks = DEFAULT_SEEKS,
+-};
++static struct shrinker *rpc_cred_shrinker;
+ 
+ void __init rpcauth_init_module(void)
+ {
+ 	rpc_init_authunix();
+ 	rpc_init_generic_auth();
+-	register_shrinker(&rpc_cred_shrinker);
++	rpc_cred_shrinker = set_shrinker(DEFAULT_SEEKS, rpcauth_cache_shrinker);
+ }
+ 
+ void __exit rpcauth_remove_module(void)
+ {
+-	unregister_shrinker(&rpc_cred_shrinker);
++	remove_shrinker(rpc_cred_shrinker);
+ }
+diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c
+index 2278a50..44b2e70 100644
+--- a/net/sunrpc/auth_gss/svcauth_gss.c
++++ b/net/sunrpc/auth_gss/svcauth_gss.c
+@@ -873,7 +873,7 @@ unwrap_priv_data(struct svc_rqst *rqstp, struct xdr_buf *buf, u32 seq, struct gs
+ 	u32 priv_len, maj_stat;
+ 	int pad, saved_len, remaining_len, offset;
+ 
+-	rqstp->rq_splice_ok = 0;
++	rqstp->rq_sendfile_ok = 0;
+ 
+ 	priv_len = svc_getnl(&buf->head[0]);
+ 	if (rqstp->rq_deferred) {
+diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
+index 5abab09..6555f87 100644
+--- a/net/sunrpc/clnt.c
++++ b/net/sunrpc/clnt.c
+@@ -279,15 +279,15 @@ struct rpc_clnt *rpc_create(struct rpc_create_args *args)
+ 		case AF_INET: {
+ 			struct sockaddr_in *sin =
+ 					(struct sockaddr_in *)args->address;
+-			snprintf(servername, sizeof(servername), "%pI4",
+-				 &sin->sin_addr.s_addr);
++			snprintf(servername, sizeof(servername),  NIPQUAD_FMT,
++				 NIPQUAD(sin->sin_addr.s_addr));
+ 			break;
+ 		}
+ 		case AF_INET6: {
+ 			struct sockaddr_in6 *sin =
+ 					(struct sockaddr_in6 *)args->address;
+-			snprintf(servername, sizeof(servername), "%pI6",
+-				 &sin->sin6_addr);
++			snprintf(servername, sizeof(servername), NIP6_FMT,
++				 NIP6(sin->sin6_addr));
+ 			break;
+ 		}
+ 		default:
+diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
+index 9ced062..849e10f 100644
+--- a/net/sunrpc/rpc_pipe.c
++++ b/net/sunrpc/rpc_pipe.c
+@@ -14,7 +14,7 @@
+ #include <linux/pagemap.h>
+ #include <linux/mount.h>
+ #include <linux/namei.h>
+-#include <linux/fsnotify.h>
++#include <linux/dnotify.h>
+ #include <linux/kernel.h>
+ 
+ #include <asm/ioctls.h>
+@@ -480,7 +480,7 @@ static int rpc_delete_dentry(struct dentry *dentry)
+ 	return 1;
+ }
+ 
+-static const struct dentry_operations rpc_dentry_operations = {
++static struct dentry_operations rpc_dentry_operations = {
+ 	.d_delete = rpc_delete_dentry,
+ };
+ 
+@@ -511,7 +511,7 @@ rpc_lookup_parent(char *path, struct nameidata *nd)
+ static void
+ rpc_release_path(struct nameidata *nd)
+ {
+-	path_put(&nd->path);
++	backport_path_put(nd);
+ 	rpc_put_mount();
+ }
+ 
+@@ -611,7 +611,6 @@ rpc_populate(struct dentry *parent,
+ 		if (S_ISDIR(mode))
+ 			inc_nlink(dir);
+ 		d_add(dentry, inode);
+-		fsnotify_create(dir, dentry);
+ 	}
+ 	mutex_unlock(&dir->i_mutex);
+ 	return 0;
+@@ -633,7 +632,7 @@ __rpc_mkdir(struct inode *dir, struct dentry *dentry)
+ 	inode->i_ino = iunique(dir->i_sb, 100);
+ 	d_instantiate(dentry, inode);
+ 	inc_nlink(dir);
+-	fsnotify_mkdir(dir, dentry);
++	inode_dir_notify(dir, DN_CREATE);
+ 	return 0;
+ out_err:
+ 	printk(KERN_WARNING "%s: %s failed to allocate inode for dentry %s\n",
+@@ -682,7 +681,7 @@ rpc_lookup_negative(char *path, struct nameidata *nd)
+ 
+ 	if ((error = rpc_lookup_parent(path, nd)) != 0)
+ 		return ERR_PTR(error);
+-	dentry = rpc_lookup_create(nd->path.dentry, nd->last.name, nd->last.len,
++	dentry = rpc_lookup_create(nd->dentry, nd->last.name, nd->last.len,
+ 				   1);
+ 	if (IS_ERR(dentry))
+ 		rpc_release_path(nd);
+@@ -710,7 +709,7 @@ rpc_mkdir(char *path, struct rpc_clnt *rpc_client)
+ 	dentry = rpc_lookup_negative(path, &nd);
+ 	if (IS_ERR(dentry))
+ 		return dentry;
+-	dir = nd.path.dentry->d_inode;
++	dir = nd.dentry->d_inode;
+ 	if ((error = __rpc_mkdir(dir, dentry)) != 0)
+ 		goto err_dput;
+ 	RPC_I(dentry->d_inode)->private = rpc_client;
+@@ -809,7 +808,7 @@ rpc_mkpipe(struct dentry *parent, const char *name, void *private, struct rpc_pi
+ 	rpci->flags = flags;
+ 	rpci->ops = ops;
+ 	rpci->nkern_readwriters = 1;
+-	fsnotify_create(dir, dentry);
++	inode_dir_notify(dir, DN_CREATE);
+ 	dget(dentry);
+ out:
+ 	mutex_unlock(&dir->i_mutex);
+@@ -911,7 +910,7 @@ static struct file_system_type rpc_pipe_fs_type = {
+ };
+ 
+ static void
+-init_once(void *foo)
++init_once(void *foo, struct kmem_cache *cachep, unsigned long temp)
+ {
+ 	struct rpc_inode *rpci = (struct rpc_inode *) foo;
+ 
+diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c
+index beee6da..f5674ff 100644
+--- a/net/sunrpc/rpcb_clnt.c
++++ b/net/sunrpc/rpcb_clnt.c
+@@ -271,8 +271,8 @@ static int rpcb_register_inet4(const struct sockaddr *sap,
+ 	char buf[32];
+ 
+ 	/* Construct AF_INET universal address */
+-	snprintf(buf, sizeof(buf), "%pI4.%u.%u",
+-		 &sin->sin_addr.s_addr, port >> 8, port & 0xff);
++	snprintf(buf, sizeof(buf), NIPQUAD_FMT".%u.%u",
++		 NIPQUAD(sin->sin_addr.s_addr), port >> 8, port & 0xff);
+ 	map->r_addr = buf;
+ 
+ 	dprintk("RPC:       %sregistering [%u, %u, %s, '%s'] with "
+@@ -303,8 +303,8 @@ static int rpcb_register_inet6(const struct sockaddr *sap,
+ 		snprintf(buf, sizeof(buf), "::.%u.%u",
+ 				port >> 8, port & 0xff);
+ 	else
+-		snprintf(buf, sizeof(buf), "%pI6.%u.%u",
+-			 &sin6->sin6_addr, port >> 8, port & 0xff);
++		snprintf(buf, sizeof(buf), NIP6_FMT".%u.%u",
++			 NIP6(sin6->sin6_addr), port >> 8, port & 0xff);
+ 	map->r_addr = buf;
+ 
+ 	dprintk("RPC:       %sregistering [%u, %u, %s, '%s'] with "
+@@ -433,8 +433,8 @@ int rpcb_getport_sync(struct sockaddr_in *sin, u32 prog, u32 vers, int prot)
+ 	struct rpc_clnt	*rpcb_clnt;
+ 	int status;
+ 
+-	dprintk("RPC:       %s(%pI4, %u, %u, %d)\n",
+-		__func__, &sin->sin_addr.s_addr, prog, vers, prot);
++	dprintk("RPC:       %s("NIPQUAD_FMT", %u, %u, %d)\n",
++		__func__, NIPQUAD(sin->sin_addr.s_addr), prog, vers, prot);
+ 
+ 	rpcb_clnt = rpcb_create(NULL, (struct sockaddr *)sin,
+ 				sizeof(*sin), prot, RPCBVERS_2);
+diff --git a/net/sunrpc/stats.c b/net/sunrpc/stats.c
+index 1ef6e46..3713319 100644
+--- a/net/sunrpc/stats.c
++++ b/net/sunrpc/stats.c
+@@ -263,7 +263,7 @@ rpc_proc_init(void)
+ {
+ 	dprintk("RPC:       registering /proc/net/rpc\n");
+ 	if (!proc_net_rpc)
+-		proc_net_rpc = proc_mkdir("rpc", init_net.proc_net);
++		proc_net_rpc = proc_mkdir("rpc", proc_net);
+ }
+ 
+ void
+@@ -272,7 +272,7 @@ rpc_proc_exit(void)
+ 	dprintk("RPC:       unregistering /proc/net/rpc\n");
+ 	if (proc_net_rpc) {
+ 		proc_net_rpc = NULL;
+-		remove_proc_entry("rpc", init_net.proc_net);
++		remove_proc_entry("rpc", proc_net);
+ 	}
+ }
+ 
+diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
+index 8847add..8bfdc87 100644
+--- a/net/sunrpc/svc.c
++++ b/net/sunrpc/svc.c
+@@ -1007,7 +1007,7 @@ svc_process(struct svc_rqst *rqstp)
+ 	rqstp->rq_res.tail[0].iov_base = NULL;
+ 	rqstp->rq_res.tail[0].iov_len = 0;
+ 	/* Will be turned off only in gss privacy case: */
+-	rqstp->rq_splice_ok = 1;
++	rqstp->rq_sendfile_ok = 1;
+ 	/* Will be turned off only when NFSv4 Sessions are used */
+ 	rqstp->rq_usedeferral = 1;
+ 
+diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c
+index 5c865e2..02c4bce 100644
+--- a/net/sunrpc/svcauth_unix.c
++++ b/net/sunrpc/svcauth_unix.c
+@@ -162,9 +162,9 @@ static void ip_map_request(struct cache_detail *cd,
+ 	struct ip_map *im = container_of(h, struct ip_map, h);
+ 
+ 	if (ipv6_addr_v4mapped(&(im->m_addr))) {
+-		snprintf(text_addr, 20, "%pI4", &im->m_addr.s6_addr32[3]);
++		snprintf(text_addr, 20, NIPQUAD_FMT, NIPQUAD(im->m_addr.s6_addr32[3]));
+ 	} else {
+-		snprintf(text_addr, 40, "%pI6", &im->m_addr);
++		snprintf(text_addr, 40, NIP6_FMT, NIP6(im->m_addr));
+ 	}
+ 	qword_add(bpp, blen, im->m_class);
+ 	qword_add(bpp, blen, text_addr);
+@@ -274,10 +274,10 @@ static int ip_map_show(struct seq_file *m,
+ 		dom = im->m_client->h.name;
+ 
+ 	if (ipv6_addr_v4mapped(&addr)) {
+-		seq_printf(m, "%s %pI4 %s\n",
+-			im->m_class, &addr.s6_addr32[3], dom);
++		seq_printf(m, "%s "NIPQUAD_FMT" %s\n",
++			im->m_class, NIPQUAD(addr.s6_addr32[3]), dom);
+ 	} else {
+-		seq_printf(m, "%s %pI6 %s\n", im->m_class, &addr, dom);
++		seq_printf(m, "%s "NIP6_FMT" %s\n", im->m_class, NIP6(addr), dom);
+ 	}
+ 	return 0;
+ }
+diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
+index af31988..21c266e 100644
+--- a/net/sunrpc/svcsock.c
++++ b/net/sunrpc/svcsock.c
+@@ -246,10 +246,10 @@ static int one_sock_name(char *buf, struct svc_sock *svsk)
+ 
+ 	switch(svsk->sk_sk->sk_family) {
+ 	case AF_INET:
+-		len = sprintf(buf, "ipv4 %s %pI4 %d\n",
++		len = sprintf(buf, "ipv4 %s "NIPQUAD_FMT" %d\n",
+ 			      svsk->sk_sk->sk_protocol == IPPROTO_UDP ?
+ 			      "udp" : "tcp",
+-			      &inet_sk(svsk->sk_sk)->rcv_saddr,
++			      NIPQUAD(inet_sk(svsk->sk_sk)->rcv_saddr),
+ 			      inet_sk(svsk->sk_sk)->num);
+ 		break;
+ 	default:
+diff --git a/net/sunrpc/xprtrdma/svc_rdma_transport.c b/net/sunrpc/xprtrdma/svc_rdma_transport.c
+index 3d810e7..41b93e9 100644
+--- a/net/sunrpc/xprtrdma/svc_rdma_transport.c
++++ b/net/sunrpc/xprtrdma/svc_rdma_transport.c
+@@ -1048,21 +1048,21 @@ static struct svc_xprt *svc_rdma_accept(struct svc_xprt *xprt)
+ 
+ 	dprintk("svcrdma: new connection %p accepted with the following "
+ 		"attributes:\n"
+-		"    local_ip        : %pI4\n"
++		"    local_ip        : "NIPQUAD_FMT"\n"
+ 		"    local_port	     : %d\n"
+-		"    remote_ip       : %pI4\n"
++		"    remote_ip       : "NIPQUAD_FMT"\n"
+ 		"    remote_port     : %d\n"
+ 		"    max_sge         : %d\n"
+ 		"    sq_depth        : %d\n"
+ 		"    max_requests    : %d\n"
+ 		"    ord             : %d\n",
+ 		newxprt,
+-		&((struct sockaddr_in *)&newxprt->sc_cm_id->
+-			 route.addr.src_addr)->sin_addr.s_addr,
++		NIPQUAD(((struct sockaddr_in *)&newxprt->sc_cm_id->
++			 route.addr.src_addr)->sin_addr.s_addr),
+ 		ntohs(((struct sockaddr_in *)&newxprt->sc_cm_id->
+ 		       route.addr.src_addr)->sin_port),
+-		&((struct sockaddr_in *)&newxprt->sc_cm_id->
+-			 route.addr.dst_addr)->sin_addr.s_addr,
++		NIPQUAD(((struct sockaddr_in *)&newxprt->sc_cm_id->
++			 route.addr.dst_addr)->sin_addr.s_addr),
+ 		ntohs(((struct sockaddr_in *)&newxprt->sc_cm_id->
+ 		       route.addr.dst_addr)->sin_port),
+ 		newxprt->sc_max_sge,
+diff --git a/net/sunrpc/xprtrdma/transport.c b/net/sunrpc/xprtrdma/transport.c
+index 1dd6123..cc21d83 100644
+--- a/net/sunrpc/xprtrdma/transport.c
++++ b/net/sunrpc/xprtrdma/transport.c
+@@ -174,7 +174,7 @@ xprt_rdma_format_addresses(struct rpc_xprt *xprt)
+ 
+ 	buf = kzalloc(20, GFP_KERNEL);
+ 	if (buf)
+-		snprintf(buf, 20, "%pI4", &addr->sin_addr.s_addr);
++		snprintf(buf, 20,  NIPQUAD_FMT, NIPQUAD(addr->sin_addr.s_addr));
+ 	xprt->address_strings[RPC_DISPLAY_ADDR] = buf;
+ 
+ 	buf = kzalloc(8, GFP_KERNEL);
+@@ -186,8 +186,8 @@ xprt_rdma_format_addresses(struct rpc_xprt *xprt)
+ 
+ 	buf = kzalloc(48, GFP_KERNEL);
+ 	if (buf)
+-		snprintf(buf, 48, "addr=%pI4 port=%u proto=%s",
+-			&addr->sin_addr.s_addr,
++		snprintf(buf, 48, "addr="NIPQUAD_FMT" port=%u proto=%s",
++			NIPQUAD(addr->sin_addr.s_addr),
+ 			ntohs(addr->sin_port), "rdma");
+ 	xprt->address_strings[RPC_DISPLAY_ALL] = buf;
+ 
+@@ -204,8 +204,8 @@ xprt_rdma_format_addresses(struct rpc_xprt *xprt)
+ 
+ 	buf = kzalloc(30, GFP_KERNEL);
+ 	if (buf)
+-		snprintf(buf, 30, "%pI4.%u.%u",
+-			&addr->sin_addr.s_addr,
++		snprintf(buf, 30, NIPQUAD_FMT".%u.%u",
++			NIPQUAD(addr->sin_addr.s_addr),
+ 			ntohs(addr->sin_port) >> 8,
+ 			ntohs(addr->sin_port) & 0xff);
+ 	xprt->address_strings[RPC_DISPLAY_UNIVERSAL_ADDR] = buf;
+@@ -369,8 +369,8 @@ xprt_setup_rdma(struct xprt_create *args)
+ 	if (ntohs(sin->sin_port) != 0)
+ 		xprt_set_bound(xprt);
+ 
+-	dprintk("RPC:       %s: %pI4:%u\n",
+-		__func__, &sin->sin_addr.s_addr, ntohs(sin->sin_port));
++	dprintk("RPC:       %s: "NIPQUAD_FMT":%u\n",
++		__func__, NIPQUAD(sin->sin_addr.s_addr), ntohs(sin->sin_port));
+ 
+ 	/* Set max requests */
+ 	cdata.max_requests = xprt->max_reqs;
+diff --git a/net/sunrpc/xprtrdma/verbs.c b/net/sunrpc/xprtrdma/verbs.c
+index 3b21e0c..5d234d6 100644
+--- a/net/sunrpc/xprtrdma/verbs.c
++++ b/net/sunrpc/xprtrdma/verbs.c
+@@ -325,11 +325,11 @@ rpcrdma_conn_upcall(struct rdma_cm_id *id, struct rdma_cm_event *event)
+ 	case RDMA_CM_EVENT_DEVICE_REMOVAL:
+ 		connstate = -ENODEV;
+ connected:
+-		dprintk("RPC:       %s: %s: %pI4:%u (ep 0x%p event 0x%x)\n",
++		dprintk("RPC:       %s: %s: "NIPQUAD_FMT":%u (ep 0x%p event 0x%x)\n",
+ 			__func__,
+ 			(event->event <= 11) ? conn[event->event] :
+ 						"unknown connection error",
+-			&addr->sin_addr.s_addr,
++			NIPQUAD(addr->sin_addr.s_addr),
+ 			ntohs(addr->sin_port),
+ 			ep, event->event);
+ 		atomic_set(&rpcx_to_rdmax(ep->rep_xprt)->rx_buf.rb_credits, 1);
+@@ -349,17 +349,17 @@ connected:
+ 	if (connstate == 1) {
+ 		int ird = attr.max_dest_rd_atomic;
+ 		int tird = ep->rep_remote_cma.responder_resources;
+-		printk(KERN_INFO "rpcrdma: connection to %pI4:%u "
++		printk(KERN_INFO "rpcrdma: connection to "NIPQUAD_FMT":%u "
+ 			"on %s, memreg %d slots %d ird %d%s\n",
+-			&addr->sin_addr.s_addr,
++			NIPQUAD(addr->sin_addr.s_addr),
+ 			ntohs(addr->sin_port),
+ 			ia->ri_id->device->name,
+ 			ia->ri_memreg_strategy,
+ 			xprt->rx_buf.rb_max_requests,
+ 			ird, ird < 4 && ird < tird / 2 ? " (low!)" : "");
+ 	} else if (connstate < 0) {
+-		printk(KERN_INFO "rpcrdma: connection to %pI4:%u closed (%d)\n",
+-			&addr->sin_addr.s_addr,
++		printk(KERN_INFO "rpcrdma: connection to "NIPQUAD_FMT":%u closed (%d)\n",
++			NIPQUAD(addr->sin_addr.s_addr),
+ 			ntohs(addr->sin_port),
+ 			connstate);
+ 	}
+diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
+index e185961..2de8b4e 100644
+--- a/net/sunrpc/xprtsock.c
++++ b/net/sunrpc/xprtsock.c
+@@ -295,7 +295,7 @@ static void xs_format_ipv4_peer_addresses(struct rpc_xprt *xprt,
+ 
+ 	buf = kzalloc(20, GFP_KERNEL);
+ 	if (buf) {
+-		snprintf(buf, 20, "%pI4", &addr->sin_addr.s_addr);
++		snprintf(buf, 20, NIPQUAD_FMT, NIPQUAD(addr->sin_addr.s_addr));
+ 	}
+ 	xprt->address_strings[RPC_DISPLAY_ADDR] = buf;
+ 
+@@ -310,8 +310,8 @@ static void xs_format_ipv4_peer_addresses(struct rpc_xprt *xprt,
+ 
+ 	buf = kzalloc(48, GFP_KERNEL);
+ 	if (buf) {
+-		snprintf(buf, 48, "addr=%pI4 port=%u proto=%s",
+-			&addr->sin_addr.s_addr,
++		snprintf(buf, 48, "addr="NIPQUAD_FMT" port=%u proto=%s",
++			NIPQUAD(addr->sin_addr.s_addr),
+ 			ntohs(addr->sin_port),
+ 			protocol);
+ 	}
+@@ -333,8 +333,8 @@ static void xs_format_ipv4_peer_addresses(struct rpc_xprt *xprt,
+ 
+ 	buf = kzalloc(30, GFP_KERNEL);
+ 	if (buf) {
+-		snprintf(buf, 30, "%pI4.%u.%u",
+-				&addr->sin_addr.s_addr,
++		snprintf(buf, 30, NIPQUAD_FMT".%u.%u",
++				NIPQUAD(addr->sin_addr.s_addr),
+ 				ntohs(addr->sin_port) >> 8,
+ 				ntohs(addr->sin_port) & 0xff);
+ 	}
+@@ -352,7 +352,7 @@ static void xs_format_ipv6_peer_addresses(struct rpc_xprt *xprt,
+ 
+ 	buf = kzalloc(40, GFP_KERNEL);
+ 	if (buf) {
+-		snprintf(buf, 40, "%pI6",&addr->sin6_addr);
++		snprintf(buf, 40, NIP6_FMT, NIP6(addr->sin6_addr));
+ 	}
+ 	xprt->address_strings[RPC_DISPLAY_ADDR] = buf;
+ 
+@@ -367,8 +367,8 @@ static void xs_format_ipv6_peer_addresses(struct rpc_xprt *xprt,
+ 
+ 	buf = kzalloc(64, GFP_KERNEL);
+ 	if (buf) {
+-		snprintf(buf, 64, "addr=%pI6 port=%u proto=%s",
+-				&addr->sin6_addr,
++		snprintf(buf, 64, "addr="NIP6_FMT" port=%u proto=%s",
++				NIP6(addr->sin6_addr),
+ 				ntohs(addr->sin6_port),
+ 				protocol);
+ 	}
+@@ -376,7 +376,7 @@ static void xs_format_ipv6_peer_addresses(struct rpc_xprt *xprt,
+ 
+ 	buf = kzalloc(36, GFP_KERNEL);
+ 	if (buf)
+-		snprintf(buf, 36, "%pi6", &addr->sin6_addr);
++		snprintf(buf, 36, NIP6_FMT, NIP6(addr->sin6_addr));
+ 
+ 	xprt->address_strings[RPC_DISPLAY_HEX_ADDR] = buf;
+ 
+@@ -389,8 +389,8 @@ static void xs_format_ipv6_peer_addresses(struct rpc_xprt *xprt,
+ 
+ 	buf = kzalloc(50, GFP_KERNEL);
+ 	if (buf) {
+-		snprintf(buf, 50, "%pI6.%u.%u",
+-			 &addr->sin6_addr,
++		snprintf(buf, 50, NIP6_FMT".%u.%u",
++			 NIP6(addr->sin6_addr),
+ 			 ntohs(addr->sin6_port) >> 8,
+ 			 ntohs(addr->sin6_port) & 0xff);
+ 	}
+@@ -1477,8 +1477,8 @@ static int xs_bind4(struct sock_xprt *transport, struct socket *sock)
+ 		if (port > last)
+ 			nloop++;
+ 	} while (err == -EADDRINUSE && nloop != 2);
+-	dprintk("RPC:       %s %pI4:%u: %s (%d)\n",
+-			__func__, &myaddr.sin_addr,
++	dprintk("RPC:       %s "NIPQUAD_FMT":%u: %s (%d)\n",
++			__func__, NIPQUAD(myaddr.sin_addr),
+ 			port, err ? "failed" : "ok", err);
+ 	return err;
+ }
+@@ -1510,8 +1510,8 @@ static int xs_bind6(struct sock_xprt *transport, struct socket *sock)
+ 		if (port > last)
+ 			nloop++;
+ 	} while (err == -EADDRINUSE && nloop != 2);
+-	dprintk("RPC:       xs_bind6 %pI6:%u: %s (%d)\n",
+-		&myaddr.sin6_addr, port, err ? "failed" : "ok", err);
++	dprintk("RPC:       xs_bind6 "NIP6_FMT":%u: %s (%d)\n",
++		NIP6(myaddr.sin6_addr), port, err ? "failed" : "ok", err);
+ 	return err;
+ }
+ 




More information about the ewg mailing list