[ewg] [PATCH OFED-1.5] NFSRDMA: NFS backport for RHEL5.3

Jon Mason jon at opengridcomputing.com
Mon Jun 8 14:23:50 PDT 2009


This patch provides the NFS backport for RHEL5.3.

It passes Connectathon as a client and server over TCP and RDMA.

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

diff --git a/kernel_addons/backport/2.6.18-EL5.3/include/asm/bitops.h b/kernel_addons/backport/2.6.18-EL5.3/include/asm/bitops.h
new file mode 100644
index 0000000..50d5e8b
--- /dev/null
+++ b/kernel_addons/backport/2.6.18-EL5.3/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.18-EL5.3/include/linux/cpumask.h b/kernel_addons/backport/2.6.18-EL5.3/include/linux/cpumask.h
new file mode 100644
index 0000000..13100f7
--- /dev/null
+++ b/kernel_addons/backport/2.6.18-EL5.3/include/linux/cpumask.h
@@ -0,0 +1,15 @@
+#ifndef BACKPORT_LINUX_CPUMASK_H
+#define BACKPORT_LINUX_CPUMASK_H
+
+#include_next <linux/cpumask.h>
+
+#define cpumask_of(cpu)			(cpumask_of_cpu(cpu))
+#define cpumask_of_node(node)		(node_to_cpumask(node))
+#define nr_node_ids			(highest_possible_processor_id() + 1)
+#define nr_cpu_ids			(highest_possible_processor_id() + 1)
+
+//#define set_cpus_allowed_ptr(a, b)	(set_cpus_allowed(a, b))
+extern int set_cpus_allowed(struct task_struct *p, cpumask_t new_mask);
+
+
+#endif /* BACKPORT_LINUX_CPUMASK_H */
diff --git a/kernel_addons/backport/2.6.18-EL5.3/include/linux/cred.h b/kernel_addons/backport/2.6.18-EL5.3/include/linux/cred.h
new file mode 100644
index 0000000..4b8b680
--- /dev/null
+++ b/kernel_addons/backport/2.6.18-EL5.3/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.18-EL5.3/include/linux/dcache.h b/kernel_addons/backport/2.6.18-EL5.3/include/linux/dcache.h
new file mode 100644
index 0000000..4a571af
--- /dev/null
+++ b/kernel_addons/backport/2.6.18-EL5.3/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.18-EL5.3/include/linux/fs.h b/kernel_addons/backport/2.6.18-EL5.3/include/linux/fs.h
index e94b212..b306bec 100644
--- a/kernel_addons/backport/2.6.18-EL5.3/include/linux/fs.h
+++ b/kernel_addons/backport/2.6.18-EL5.3/include/linux/fs.h
@@ -2,39 +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
@@ -47,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)
@@ -59,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.18-EL5.3/include/linux/fscache.h b/kernel_addons/backport/2.6.18-EL5.3/include/linux/fscache.h
new file mode 100644
index 0000000..2bf84b6
--- /dev/null
+++ b/kernel_addons/backport/2.6.18-EL5.3/include/linux/fscache.h
@@ -0,0 +1,50 @@
+#ifndef BACKPORT_LINUX_FSCACHE_H
+#define BACKPORT_LINUX_FSCACHE_H
+
+#include_next <linux/fscache.h>
+#include <linux/page-flags.h>
+
+#define NFS_PAGE_WRITING	0
+#define NFS_PAGE_CACHED		1
+
+#define PageNfsBit(bit, page)		test_bit(bit, &(page)->private)
+
+#define SetPageNfsBit(bit, page)		\
+do {						\
+	SetPagePrivate((page));			\
+	set_bit(bit, &(page)->private);		\
+} while(0)
+
+#define ClearPageNfsBit(bit, page)		\
+do {						\
+	clear_bit(bit, &(page)->private);	\
+} while(0)
+
+#define PageNfsWriting(page)		PageNfsBit(NFS_PAGE_WRITING, (page))
+#define SetPageNfsWriting(page)		SetPageNfsBit(NFS_PAGE_WRITING, (page))
+#define ClearPageNfsWriting(page)	ClearPageNfsBit(NFS_PAGE_WRITING, (page))
+
+#define PageNfsCached(page)		PageNfsBit(NFS_PAGE_CACHED, (page))
+#define SetPageNfsCached(page)		SetPageNfsBit(NFS_PAGE_CACHED, (page))
+#define ClearPageNfsCached(page)	ClearPageNfsBit(NFS_PAGE_CACHED, (page))
+
+
+#define PageFsCache(page)		PageNfsCached(page)
+#define ClearPageFsCache(page)		ClearPageNfsCached(page)
+#define fscache_check_page_write(cookie, page)	PageNfsWriting(page)
+
+static inline void
+fscache_wait_on_page_write(struct fscache_cookie *cookie, struct page *page)
+{
+	wait_queue_head_t *wq = bit_waitqueue(&(page)->private, 0);
+	wait_event(*wq, !PageNfsWriting(page));
+}
+
+static inline int
+backport_fscache_write_page(struct fscache_cookie *cookie, struct page *page, gfp_t gfp)
+{
+	return fscache_write_page(cookie, page, NULL, NULL, gfp);
+}
+#define fscache_write_page backport_fscache_write_page
+
+#endif
diff --git a/kernel_addons/backport/2.6.18-EL5.3/include/linux/jiffies.h b/kernel_addons/backport/2.6.18-EL5.3/include/linux/jiffies.h
index ccfd69f..3c48bb6 100644
--- a/kernel_addons/backport/2.6.18-EL5.3/include/linux/jiffies.h
+++ b/kernel_addons/backport/2.6.18-EL5.3/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.18-EL5.3/include/linux/magic.h b/kernel_addons/backport/2.6.18-EL5.3/include/linux/magic.h
index 5470e48..2793ee8 100644
--- a/kernel_addons/backport/2.6.18-EL5.3/include/linux/magic.h
+++ b/kernel_addons/backport/2.6.18-EL5.3/include/linux/magic.h
@@ -2,5 +2,6 @@
 #define BACKPORT_LINUX_MAGIC_H
 
 #define NFS_SUPER_MAGIC		0x6969
+#define MSDOS_SUPER_MAGIC	0x4d44
 
 #endif
diff --git a/kernel_addons/backport/2.6.18-EL5.3/include/linux/mm.h b/kernel_addons/backport/2.6.18-EL5.3/include/linux/mm.h
index 18fe1e2..54b1891 100644
--- a/kernel_addons/backport/2.6.18-EL5.3/include/linux/mm.h
+++ b/kernel_addons/backport/2.6.18-EL5.3/include/linux/mm.h
@@ -8,6 +8,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.18-EL5.3/include/linux/mnt_namespace.h b/kernel_addons/backport/2.6.18-EL5.3/include/linux/mnt_namespace.h
new file mode 100644
index 0000000..59c8502
--- /dev/null
+++ b/kernel_addons/backport/2.6.18-EL5.3/include/linux/mnt_namespace.h
@@ -0,0 +1,4 @@
+#ifndef BACKPORT_LINUX_MNT_NAMESPACE_H
+#define BACKPORT_LINUX_MNT_NAMESPACE_H
+
+#endif
diff --git a/kernel_addons/backport/2.6.18-EL5.3/include/linux/mutex.h b/kernel_addons/backport/2.6.18-EL5.3/include/linux/mutex.h
new file mode 100644
index 0000000..553d487
--- /dev/null
+++ b/kernel_addons/backport/2.6.18-EL5.3/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.18-EL5.3/include/linux/namei.h b/kernel_addons/backport/2.6.18-EL5.3/include/linux/namei.h
index 347948c..77de824 100644
--- a/kernel_addons/backport/2.6.18-EL5.3/include/linux/namei.h
+++ b/kernel_addons/backport/2.6.18-EL5.3/include/linux/namei.h
@@ -2,7 +2,26 @@
 #define BACKPORT_LINUX_NAMEI_H
 
 #include_next <linux/namei.h>
-#include <linux/mount.h>
+
+#define LOOKUP_EXCL 0x0400
+
+struct path {
+	struct vfsmount *mnt;
+	struct dentry *dentry;
+};
+
+#include <linux/path.h>
+
+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,
@@ -24,4 +43,5 @@ static inline int vfs_path_lookup(struct dentry *dentry, struct vfsmount *mnt,
 
 	return retval;
 }
+
 #endif /* BACKPORT_LINUX_NAMEI_H */
diff --git a/kernel_addons/backport/2.6.18-EL5.3/include/linux/pagevec.h b/kernel_addons/backport/2.6.18-EL5.3/include/linux/pagevec.h
new file mode 100644
index 0000000..1fb684d
--- /dev/null
+++ b/kernel_addons/backport/2.6.18-EL5.3/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.18-EL5.3/include/linux/path.h b/kernel_addons/backport/2.6.18-EL5.3/include/linux/path.h
index d13c8c8..a261eb0 100644
--- a/kernel_addons/backport/2.6.18-EL5.3/include/linux/path.h
+++ b/kernel_addons/backport/2.6.18-EL5.3/include/linux/path.h
@@ -4,11 +4,6 @@
 #include <linux/mount.h>
 #include <linux/namei.h>
 
-struct path {
-	struct vfsmount *mnt;
-	struct dentry *dentry;
-};
-
 static inline void path_put(struct path *path)
 {
 	dput(path->dentry);
diff --git a/kernel_addons/backport/2.6.18-EL5.3/include/linux/quotaops.h b/kernel_addons/backport/2.6.18-EL5.3/include/linux/quotaops.h
new file mode 100644
index 0000000..0a87ccd
--- /dev/null
+++ b/kernel_addons/backport/2.6.18-EL5.3/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.18-EL5.3/include/linux/radix-tree.h b/kernel_addons/backport/2.6.18-EL5.3/include/linux/radix-tree.h
new file mode 100644
index 0000000..735561e
--- /dev/null
+++ b/kernel_addons/backport/2.6.18-EL5.3/include/linux/radix-tree.h
@@ -0,0 +1,19 @@
+#ifndef BACKPORT_LINUX_RADIX_TREE_H
+#define BACKPORT_LINUX_RADIX_TREE_H
+
+#include_next <linux/radix-tree.h>
+
+static inline int backport_radix_tree_preload(gfp_t gfp_mask)
+{
+	return 0;
+}
+
+#define radix_tree_preload backport_radix_tree_preload
+
+static inline void backport_radix_tree_preload_end(void)
+{
+}
+
+#define radix_tree_preload_end backport_radix_tree_preload_end
+
+#endif
diff --git a/kernel_addons/backport/2.6.18-EL5.3/include/linux/sched.h b/kernel_addons/backport/2.6.18-EL5.3/include/linux/sched.h
index 926e520..b87dc73 100644
--- a/kernel_addons/backport/2.6.18-EL5.3/include/linux/sched.h
+++ b/kernel_addons/backport/2.6.18-EL5.3/include/linux/sched.h
@@ -23,4 +23,12 @@ static inline pid_t task_pid_nr(struct task_struct *tsk)
 {
 	return tsk->pid;
 }
+
+static inline int
+backport_set_cpus_allowed_ptr(struct task_struct *p, const cpumask_t new_mask)
+{
+	return set_cpus_allowed(p, new_mask);
+}
+#define set_cpus_allowed_ptr backport_set_cpus_allowed_ptr
+
 #endif
diff --git a/kernel_addons/backport/2.6.18-EL5.3/include/linux/splice.h b/kernel_addons/backport/2.6.18-EL5.3/include/linux/splice.h
new file mode 100644
index 0000000..7c133b5
--- /dev/null
+++ b/kernel_addons/backport/2.6.18-EL5.3/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.18-EL5.3/include/linux/types.h b/kernel_addons/backport/2.6.18-EL5.3/include/linux/types.h
index 855a346..fe4babb 100644
--- a/kernel_addons/backport/2.6.18-EL5.3/include/linux/types.h
+++ b/kernel_addons/backport/2.6.18-EL5.3/include/linux/types.h
@@ -1,9 +1,10 @@
-#ifndef BACKPORT_LINUX_TYPES_TO_2_6_19
-#define BACKPORT_LINUX_TYPES_TO_2_6_19
+#ifndef BACKPORT_LINUX_TYPES_H
+#define BACKPORT_LINUX_TYPES_H
 
 #include_next <linux/types.h>
-
-typedef __u16	__sum16;
-typedef __u32	__wsum;
+  
+typedef __u16   __sum16;
+typedef __u32   __wsum;
+typedef unsigned __bitwise__ fmode_t;
 
 #endif
diff --git a/kernel_addons/backport/2.6.18-EL5.3/include/src/writeback.c b/kernel_addons/backport/2.6.18-EL5.3/include/src/writeback.c
index 7f8ebbe..0e34f32 100644
--- a/kernel_addons/backport/2.6.18-EL5.3/include/src/writeback.c
+++ b/kernel_addons/backport/2.6.18-EL5.3/include/src/writeback.c
@@ -5,7 +5,7 @@
 #include <linux/mpage.h>
 #include <linux/module.h>
 
-int backport_write_cache_pages(struct address_space *mapping,
+int write_cache_pages(struct address_space *mapping,
                       struct writeback_control *wbc, backport_writepage_t writepage,
                       void *data)
 {
@@ -103,4 +103,4 @@ retry:
         }
         return ret;
 }
-EXPORT_SYMBOL(backport_write_cache_pages);
+EXPORT_SYMBOL(write_cache_pages);
diff --git a/kernel_patches/backport/2.6.18-EL5.3/rnfs_fs.patch b/kernel_patches/backport/2.6.18-EL5.3/rnfs_fs.patch
new file mode 100644
index 0000000..cf34a68
--- /dev/null
+++ b/kernel_patches/backport/2.6.18-EL5.3/rnfs_fs.patch
@@ -0,0 +1,2799 @@
+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/clntlock.c b/fs/lockd/clntlock.c
+index 1f3b0fc..6c55555 100644
+--- a/fs/lockd/clntlock.c
++++ b/fs/lockd/clntlock.c
+@@ -168,7 +168,7 @@ __be32 nlmclnt_grant(const struct sockaddr *addr, const struct nlm_lock *lock)
+ 			continue;
+ 		if (!nlm_cmp_addr(nlm_addr(block->b_host), addr))
+ 			continue;
+-		if (nfs_compare_fh(NFS_FH(fl_blocked->fl_file->f_path.dentry->d_inode) ,fh) != 0)
++		if (nfs_compare_fh(NFS_FH(fl_blocked->fl_file->f_dentry->d_inode), fh) != 0)
+ 			continue;
+ 		/* Alright, we found a lock. Set the return status
+ 		 * and wake up the caller
+diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c
+index dd79570..6e2063a 100644
+--- a/fs/lockd/clntproc.c
++++ b/fs/lockd/clntproc.c
+@@ -127,12 +127,12 @@ static void nlmclnt_setlockargs(struct nlm_rqst *req, struct file_lock *fl)
+ 
+ 	nlmclnt_next_cookie(&argp->cookie);
+ 	argp->state   = nsm_local_state;
+-	memcpy(&lock->fh, NFS_FH(fl->fl_file->f_path.dentry->d_inode), sizeof(struct nfs_fh));
+-	lock->caller  = utsname()->nodename;
++	memcpy(&lock->fh, NFS_FH(fl->fl_file->f_dentry->d_inode), sizeof(struct nfs_fh));
++	lock->caller  = system_utsname.nodename;
+ 	lock->oh.data = req->a_owner;
+ 	lock->oh.len  = snprintf(req->a_owner, sizeof(req->a_owner), "%u@%s",
+ 				(unsigned int)fl->fl_u.nfs_fl.owner->pid,
+-				utsname()->nodename);
++				system_utsname.nodename);
+ 	lock->svid = fl->fl_u.nfs_fl.owner->pid;
+ 	lock->fl.fl_start = fl->fl_start;
+ 	lock->fl.fl_end = fl->fl_end;
+diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c
+index 6d5d4a4..1831d8e 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,
+@@ -465,7 +464,7 @@ static int encode_my_id(struct xdr_stream *xdr, const struct nsm_args *argp)
+ 	int status;
+ 	__be32 *p;
+ 
+-	status = encode_nsm_string(xdr, utsname()->nodename);
++	status = encode_nsm_string(xdr, system_utsname.nodename);
+ 	if (unlikely(status != 0))
+ 		return status;
+ 	p = xdr_reserve_space(xdr, 3 * sizeof(u32));
+diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c
+index 83ee342..517d1a9 100644
+--- a/fs/lockd/svclock.c
++++ b/fs/lockd/svclock.c
+@@ -304,7 +304,7 @@ static int nlmsvc_setgrantargs(struct nlm_rqst *call, struct nlm_lock *lock)
+ {
+ 	locks_copy_lock(&call->a_args.lock.fl, &lock->fl);
+ 	memcpy(&call->a_args.lock.fh, &lock->fh, sizeof(call->a_args.lock.fh));
+-	call->a_args.lock.caller = utsname()->nodename;
++	call->a_args.lock.caller = system_utsname.nodename;
+ 	call->a_args.lock.oh.len = lock->oh.len;
+ 
+ 	/* set default data area */
+@@ -367,8 +367,8 @@ nlmsvc_lock(struct svc_rqst *rqstp, struct nlm_file *file,
+ 	__be32			ret;
+ 
+ 	dprintk("lockd: nlmsvc_lock(%s/%ld, ty=%d, pi=%d, %Ld-%Ld, bl=%d)\n",
+-				file->f_file->f_path.dentry->d_inode->i_sb->s_id,
+-				file->f_file->f_path.dentry->d_inode->i_ino,
++				file->f_file->f_dentry->d_inode->i_sb->s_id,
++				file->f_file->f_dentry->d_inode->i_ino,
+ 				lock->fl.fl_type, lock->fl.fl_pid,
+ 				(long long)lock->fl.fl_start,
+ 				(long long)lock->fl.fl_end,
+@@ -474,8 +474,8 @@ nlmsvc_testlock(struct svc_rqst *rqstp, struct nlm_file *file,
+ 	__be32			ret;
+ 
+ 	dprintk("lockd: nlmsvc_testlock(%s/%ld, ty=%d, %Ld-%Ld)\n",
+-				file->f_file->f_path.dentry->d_inode->i_sb->s_id,
+-				file->f_file->f_path.dentry->d_inode->i_ino,
++				file->f_file->f_dentry->d_inode->i_sb->s_id,
++				file->f_file->f_dentry->d_inode->i_ino,
+ 				lock->fl.fl_type,
+ 				(long long)lock->fl.fl_start,
+ 				(long long)lock->fl.fl_end);
+@@ -567,8 +567,8 @@ nlmsvc_unlock(struct nlm_file *file, struct nlm_lock *lock)
+ 	int	error;
+ 
+ 	dprintk("lockd: nlmsvc_unlock(%s/%ld, pi=%d, %Ld-%Ld)\n",
+-				file->f_file->f_path.dentry->d_inode->i_sb->s_id,
+-				file->f_file->f_path.dentry->d_inode->i_ino,
++				file->f_file->f_dentry->d_inode->i_sb->s_id,
++				file->f_file->f_dentry->d_inode->i_ino,
+ 				lock->fl.fl_pid,
+ 				(long long)lock->fl.fl_start,
+ 				(long long)lock->fl.fl_end);
+@@ -596,8 +596,8 @@ nlmsvc_cancel_blocked(struct nlm_file *file, struct nlm_lock *lock)
+ 	int status = 0;
+ 
+ 	dprintk("lockd: nlmsvc_cancel(%s/%ld, pi=%d, %Ld-%Ld)\n",
+-				file->f_file->f_path.dentry->d_inode->i_sb->s_id,
+-				file->f_file->f_path.dentry->d_inode->i_ino,
++				file->f_file->f_dentry->d_inode->i_sb->s_id,
++				file->f_file->f_dentry->d_inode->i_ino,
+ 				lock->fl.fl_pid,
+ 				(long long)lock->fl.fl_start,
+ 				(long long)lock->fl.fl_end);
+diff --git a/fs/lockd/svcsubs.c b/fs/lockd/svcsubs.c
+index 9e4d6aa..40884ca 100644
+--- a/fs/lockd/svcsubs.c
++++ b/fs/lockd/svcsubs.c
+@@ -44,7 +44,7 @@ static inline void nlm_debug_print_fh(char *msg, struct nfs_fh *f)
+ 
+ static inline void nlm_debug_print_file(char *msg, struct nlm_file *file)
+ {
+-	struct inode *inode = file->f_file->f_path.dentry->d_inode;
++	struct inode *inode = file->f_file->f_dentry->d_inode;
+ 
+ 	dprintk("lockd: %s %s/%ld\n",
+ 		msg, inode->i_sb->s_id, inode->i_ino);
+@@ -395,7 +395,7 @@ nlmsvc_match_sb(void *datap, struct nlm_file *file)
+ {
+ 	struct super_block *sb = datap;
+ 
+-	return sb == file->f_file->f_path.mnt->mnt_sb;
++	return sb == file->f_file->f_vfsmnt->mnt_sb;
+ }
+ 
+ /**
+diff --git a/fs/nfs/Makefile b/fs/nfs/Makefile
+index 8451598..fdde308 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 writeback.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..56585c3 100644
+--- a/fs/nfs/dir.c
++++ b/fs/nfs/dir.c
+@@ -66,7 +66,7 @@ const struct file_operations nfs_dir_operations = {
+ 	.fsync		= nfs_fsync_dir,
+ };
+ 
+-const struct inode_operations nfs_dir_inode_operations = {
++struct inode_operations nfs_dir_inode_operations = {
+ 	.create		= nfs_create,
+ 	.lookup		= nfs_lookup,
+ 	.link		= nfs_link,
+@@ -82,7 +82,7 @@ const struct inode_operations nfs_dir_inode_operations = {
+ };
+ 
+ #ifdef CONFIG_NFS_V3
+-const struct inode_operations nfs3_dir_inode_operations = {
++struct inode_operations nfs3_dir_inode_operations = {
+ 	.create		= nfs_create,
+ 	.lookup		= nfs_lookup,
+ 	.link		= nfs_link,
+@@ -105,7 +105,7 @@ const struct inode_operations nfs3_dir_inode_operations = {
+ #ifdef CONFIG_NFS_V4
+ 
+ static struct dentry *nfs_atomic_lookup(struct inode *, struct dentry *, struct nameidata *);
+-const struct inode_operations nfs4_dir_inode_operations = {
++struct inode_operations nfs4_dir_inode_operations = {
+ 	.create		= nfs_create,
+ 	.lookup		= nfs_atomic_lookup,
+ 	.link		= nfs_link,
+@@ -134,8 +134,8 @@ nfs_opendir(struct inode *inode, struct file *filp)
+ 	int res;
+ 
+ 	dfprintk(FILE, "NFS: open dir(%s/%s)\n",
+-			filp->f_path.dentry->d_parent->d_name.name,
+-			filp->f_path.dentry->d_name.name);
++			filp->f_dentry->d_parent->d_name.name,
++			filp->f_dentry->d_name.name);
+ 
+ 	nfs_inc_stats(inode, NFSIOS_VFSOPEN);
+ 
+@@ -176,7 +176,7 @@ static
+ int nfs_readdir_filler(nfs_readdir_descriptor_t *desc, struct page *page)
+ {
+ 	struct file	*file = desc->file;
+-	struct inode	*inode = file->f_path.dentry->d_inode;
++	struct inode	*inode = file->f_dentry->d_inode;
+ 	struct rpc_cred	*cred = nfs_file_cred(file);
+ 	unsigned long	timestamp, gencount;
+ 	int		error;
+@@ -188,7 +188,7 @@ int nfs_readdir_filler(nfs_readdir_descriptor_t *desc, struct page *page)
+  again:
+ 	timestamp = jiffies;
+ 	gencount = nfs_inc_attr_generation_counter();
+-	error = NFS_PROTO(inode)->readdir(file->f_path.dentry, cred, desc->entry->cookie, page,
++	error = NFS_PROTO(inode)->readdir(file->f_dentry, cred, desc->entry->cookie, page,
+ 					  NFS_SERVER(inode)->dtsize, desc->plus);
+ 	if (error < 0) {
+ 		/* We requested READDIRPLUS, but the server doesn't grok it */
+@@ -315,7 +315,7 @@ int find_dirent_index(nfs_readdir_descriptor_t *desc)
+ static inline
+ int find_dirent_page(nfs_readdir_descriptor_t *desc)
+ {
+-	struct inode	*inode = desc->file->f_path.dentry->d_inode;
++	struct inode	*inode = desc->file->f_dentry->d_inode;
+ 	struct page	*page;
+ 	int		status;
+ 
+@@ -471,7 +471,7 @@ int uncached_readdir(nfs_readdir_descriptor_t *desc, void *dirent,
+ 		     filldir_t filldir)
+ {
+ 	struct file	*file = desc->file;
+-	struct inode	*inode = file->f_path.dentry->d_inode;
++	struct inode	*inode = file->f_dentry->d_inode;
+ 	struct rpc_cred	*cred = nfs_file_cred(file);
+ 	struct page	*page = NULL;
+ 	int		status;
+@@ -487,7 +487,7 @@ int uncached_readdir(nfs_readdir_descriptor_t *desc, void *dirent,
+ 	}
+ 	timestamp = jiffies;
+ 	gencount = nfs_inc_attr_generation_counter();
+-	status = NFS_PROTO(inode)->readdir(file->f_path.dentry, cred,
++	status = NFS_PROTO(inode)->readdir(file->f_dentry, cred,
+ 						*desc->dir_cookie, page,
+ 						NFS_SERVER(inode)->dtsize,
+ 						desc->plus);
+@@ -526,7 +526,7 @@ int uncached_readdir(nfs_readdir_descriptor_t *desc, void *dirent,
+  */
+ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
+ {
+-	struct dentry	*dentry = filp->f_path.dentry;
++	struct dentry	*dentry = filp->f_dentry;
+ 	struct inode	*inode = dentry->d_inode;
+ 	nfs_readdir_descriptor_t my_desc,
+ 			*desc = &my_desc;
+@@ -607,7 +607,7 @@ out:
+ 
+ static loff_t nfs_llseek_dir(struct file *filp, loff_t offset, int origin)
+ {
+-	struct dentry *dentry = filp->f_path.dentry;
++	struct dentry *dentry = filp->f_dentry;
+ 	struct inode *inode = dentry->d_inode;
+ 
+ 	dfprintk(FILE, "NFS: llseek dir(%s/%s, %lld, %d)\n",
+@@ -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;
+@@ -1094,7 +1094,7 @@ no_open:
+ 
+ static struct dentry *nfs_readdir_lookup(nfs_readdir_descriptor_t *desc)
+ {
+-	struct dentry *parent = desc->file->f_path.dentry;
++	struct dentry *parent = desc->file->f_dentry;
+ 	struct inode *dir = parent->d_inode;
+ 	struct nfs_entry *entry = desc->entry;
+ 	struct dentry *dentry, *alias;
+@@ -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/direct.c b/fs/nfs/direct.c
+index 08f6b04..91f5069 100644
+--- a/fs/nfs/direct.c
++++ b/fs/nfs/direct.c
+@@ -116,7 +116,7 @@ static inline int put_dreq(struct nfs_direct_req *dreq)
+ ssize_t nfs_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, loff_t pos, unsigned long nr_segs)
+ {
+ 	dprintk("NFS: nfs_direct_IO (%s) off/no(%Ld/%lu) EINVAL\n",
+-			iocb->ki_filp->f_path.dentry->d_name.name,
++			iocb->ki_filp->f_dentry->d_name.name,
+ 			(long long) pos, nr_segs);
+ 
+ 	return -EINVAL;
+@@ -891,8 +891,8 @@ ssize_t nfs_file_direct_read(struct kiocb *iocb, const struct iovec *iov,
+ 	nfs_add_stats(mapping->host, NFSIOS_DIRECTREADBYTES, count);
+ 
+ 	dfprintk(FILE, "NFS: direct read(%s/%s, %zd@%Ld)\n",
+-		file->f_path.dentry->d_parent->d_name.name,
+-		file->f_path.dentry->d_name.name,
++		file->f_dentry->d_parent->d_name.name,
++		file->f_dentry->d_name.name,
+ 		count, (long long) pos);
+ 
+ 	retval = 0;
+@@ -948,8 +948,8 @@ ssize_t nfs_file_direct_write(struct kiocb *iocb, const struct iovec *iov,
+ 	nfs_add_stats(mapping->host, NFSIOS_DIRECTWRITTENBYTES, count);
+ 
+ 	dfprintk(FILE, "NFS: direct write(%s/%s, %zd@%Ld)\n",
+-		file->f_path.dentry->d_parent->d_name.name,
+-		file->f_path.dentry->d_name.name,
++		file->f_dentry->d_parent->d_name.name,
++		file->f_dentry->d_name.name,
+ 		count, (long long) pos);
+ 
+ 	retval = generic_write_checks(file, &pos, &count, 0);
+diff --git a/fs/nfs/file.c b/fs/nfs/file.c
+index ec7e27d..9795f7c 100644
+--- a/fs/nfs/file.c
++++ b/fs/nfs/file.c
+@@ -46,16 +46,13 @@ static int  nfs_file_mmap(struct file *, struct vm_area_struct *);
+ static ssize_t nfs_file_splice_read(struct file *filp, loff_t *ppos,
+ 					struct pipe_inode_info *pipe,
+ 					size_t count, unsigned int flags);
+-static ssize_t nfs_file_read(struct kiocb *, const struct iovec *iov,
+-				unsigned long nr_segs, loff_t pos);
+-static ssize_t nfs_file_write(struct kiocb *, const struct iovec *iov,
+-				unsigned long nr_segs, loff_t pos);
++static ssize_t nfs_file_read(struct kiocb *iocb, char __user * buf, size_t count, loff_t pos);
++static ssize_t nfs_file_write(struct kiocb *iocb, const char __user *buf, size_t count, loff_t pos);
+ static int  nfs_file_flush(struct file *, fl_owner_t id);
+ 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,17 +71,16 @@ 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 = {
++struct inode_operations nfs_file_inode_operations = {
+ 	.permission	= nfs_permission,
+ 	.getattr	= nfs_getattr,
+ 	.setattr	= nfs_setattr,
+ };
+ 
+ #ifdef CONFIG_NFS_V3
+-const struct inode_operations nfs3_file_inode_operations = {
++struct inode_operations nfs3_file_inode_operations = {
+ 	.permission	= nfs_permission,
+ 	.getattr	= nfs_getattr,
+ 	.setattr	= nfs_setattr,
+@@ -117,8 +113,8 @@ nfs_file_open(struct inode *inode, struct file *filp)
+ 	int res;
+ 
+ 	dprintk("NFS: open file(%s/%s)\n",
+-			filp->f_path.dentry->d_parent->d_name.name,
+-			filp->f_path.dentry->d_name.name);
++			filp->f_dentry->d_parent->d_name.name,
++			filp->f_dentry->d_name.name);
+ 
+ 	res = nfs_check_flags(filp->f_flags);
+ 	if (res)
+@@ -132,7 +128,7 @@ nfs_file_open(struct inode *inode, struct file *filp)
+ static int
+ nfs_file_release(struct inode *inode, struct file *filp)
+ {
+-	struct dentry *dentry = filp->f_path.dentry;
++	struct dentry *dentry = filp->f_dentry;
+ 
+ 	dprintk("NFS: release(%s/%s)\n",
+ 			dentry->d_parent->d_name.name,
+@@ -175,8 +171,8 @@ static loff_t nfs_file_llseek(struct file *filp, loff_t offset, int origin)
+ 	loff_t loff;
+ 
+ 	dprintk("NFS: llseek file(%s/%s, %lld, %d)\n",
+-			filp->f_path.dentry->d_parent->d_name.name,
+-			filp->f_path.dentry->d_name.name,
++			filp->f_dentry->d_parent->d_name.name,
++			filp->f_dentry->d_name.name,
+ 			offset, origin);
+ 
+ 	/* origin == SEEK_END => we must revalidate the cached file length */
+@@ -186,12 +182,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;
+ }
+ 
+@@ -227,7 +219,7 @@ static int
+ nfs_file_flush(struct file *file, fl_owner_t id)
+ {
+ 	struct nfs_open_context *ctx = nfs_file_open_context(file);
+-	struct dentry	*dentry = file->f_path.dentry;
++	struct dentry	*dentry = file->f_dentry;
+ 	struct inode	*inode = dentry->d_inode;
+ 
+ 	dprintk("NFS: flush(%s/%s)\n",
+@@ -243,16 +235,15 @@ nfs_file_flush(struct file *file, fl_owner_t id)
+ }
+ 
+ static ssize_t
+-nfs_file_read(struct kiocb *iocb, const struct iovec *iov,
+-		unsigned long nr_segs, loff_t pos)
++nfs_file_read(struct kiocb *iocb, char __user * buf, size_t count, loff_t pos)
+ {
+-	struct dentry * dentry = iocb->ki_filp->f_path.dentry;
++	struct dentry * dentry = iocb->ki_filp->f_dentry;
+ 	struct inode * inode = dentry->d_inode;
+ 	ssize_t result;
+-	size_t count = iov_length(iov, nr_segs);
++	struct iovec local_iov = { .iov_base = buf, .iov_len = count };
+ 
+ 	if (iocb->ki_filp->f_flags & O_DIRECT)
+-		return nfs_file_direct_read(iocb, iov, nr_segs, pos);
++		return nfs_file_direct_read(iocb, &local_iov, 1, pos);
+ 
+ 	dprintk("NFS: read(%s/%s, %lu@%lu)\n",
+ 		dentry->d_parent->d_name.name, dentry->d_name.name,
+@@ -261,7 +252,7 @@ nfs_file_read(struct kiocb *iocb, const struct iovec *iov,
+ 	result = nfs_revalidate_mapping(inode, iocb->ki_filp->f_mapping);
+ 	nfs_add_stats(inode, NFSIOS_NORMALREADBYTES, count);
+ 	if (!result)
+-		result = generic_file_aio_read(iocb, iov, nr_segs, pos);
++		result = generic_file_aio_read(iocb, buf, count, pos);
+ 	return result;
+ }
+ 
+@@ -270,7 +261,7 @@ nfs_file_splice_read(struct file *filp, loff_t *ppos,
+ 		     struct pipe_inode_info *pipe, size_t count,
+ 		     unsigned int flags)
+ {
+-	struct dentry *dentry = filp->f_path.dentry;
++	struct dentry *dentry = filp->f_dentry;
+ 	struct inode *inode = dentry->d_inode;
+ 	ssize_t res;
+ 
+@@ -287,7 +278,7 @@ nfs_file_splice_read(struct file *filp, loff_t *ppos,
+ static int
+ nfs_file_mmap(struct file * file, struct vm_area_struct * vma)
+ {
+-	struct dentry *dentry = file->f_path.dentry;
++	struct dentry *dentry = file->f_dentry;
+ 	struct inode *inode = dentry->d_inode;
+ 	int	status;
+ 
+@@ -332,82 +323,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;
+ }
+ 
+ /*
+@@ -445,38 +390,17 @@ static int nfs_release_page(struct page *page, gfp_t gfp)
+ 	return nfs_fscache_release_page(page, gfp);
+ }
+ 
+-/*
+- * Attempt to clear the private state associated with a page when an error
+- * occurs that requires the cached contents of an inode to be written back or
+- * destroyed
+- * - Called if either PG_private or fscache is set on the page
+- * - Caller holds page lock
+- * - Return 0 if successful, -error otherwise
+- */
+-static int nfs_launder_page(struct page *page)
+-{
+-	struct inode *inode = page->mapping->host;
+-	struct nfs_inode *nfsi = NFS_I(inode);
+-
+-	dfprintk(PAGECACHE, "NFS: launder_page(%ld, %llu)\n",
+-		inode->i_ino, (long long)page_offset(page));
+-
+-	nfs_fscache_wait_on_page_write(nfsi, page);
+-	return nfs_wb_page(inode, page);
+-}
+-
+ const struct address_space_operations nfs_file_aops = {
+ 	.readpage = nfs_readpage,
+ 	.readpages = nfs_readpages,
+ 	.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,
+-	.launder_page = nfs_launder_page,
+ };
+ 
+ /*
+@@ -484,11 +408,10 @@ 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;
++	struct dentry *dentry = filp->f_dentry;
+ 	unsigned pagelen;
+ 	int ret = -EINVAL;
+ 	struct address_space *mapping;
+@@ -517,14 +440,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,
+ };
+ 
+@@ -540,16 +464,16 @@ static int nfs_need_sync_write(struct file *filp, struct inode *inode)
+ 	return 0;
+ }
+ 
+-static ssize_t nfs_file_write(struct kiocb *iocb, const struct iovec *iov,
+-				unsigned long nr_segs, loff_t pos)
++static ssize_t
++nfs_file_write(struct kiocb *iocb, const char __user *buf, size_t count, loff_t pos)
+ {
+-	struct dentry * dentry = iocb->ki_filp->f_path.dentry;
++	struct dentry * dentry = iocb->ki_filp->f_dentry;
+ 	struct inode * inode = dentry->d_inode;
+ 	ssize_t result;
+-	size_t count = iov_length(iov, nr_segs);
++	struct iovec local_iov = { .iov_base = (void __user *)buf, .iov_len = count };
+ 
+ 	if (iocb->ki_filp->f_flags & O_DIRECT)
+-		return nfs_file_direct_write(iocb, iov, nr_segs, pos);
++		return nfs_file_direct_write(iocb, &local_iov, 1, pos);
+ 
+ 	dprintk("NFS: write(%s/%s, %lu@%Ld)\n",
+ 		dentry->d_parent->d_name.name, dentry->d_name.name,
+@@ -572,7 +496,7 @@ static ssize_t nfs_file_write(struct kiocb *iocb, const struct iovec *iov,
+ 		goto out;
+ 
+ 	nfs_add_stats(inode, NFSIOS_NORMALWRITTENBYTES, count);
+-	result = generic_file_aio_write(iocb, iov, nr_segs, pos);
++	result = generic_file_aio_write(iocb, buf, count, pos);
+ 	/* Return error values for O_SYNC and IS_SYNC() */
+ 	if (result >= 0 && nfs_need_sync_write(iocb->ki_filp, inode)) {
+ 		int err = nfs_do_fsync(nfs_file_open_context(iocb->ki_filp), inode);
+@@ -589,14 +513,20 @@ out_swapfile:
+ 
+ static int do_getlk(struct file *filp, int cmd, struct file_lock *fl)
+ {
++	struct file_lock cfl;
+ 	struct inode *inode = filp->f_mapping->host;
+ 	int status = 0;
+ 
+ 	lock_kernel();
+ 	/* Try local locking first */
+-	posix_test_lock(filp, fl);
++	posix_test_lock(filp, fl, &cfl);
+ 	if (fl->fl_type != F_UNLCK) {
+ 		/* found a conflict */
++		fl->fl_start = cfl.fl_start;
++		fl->fl_end = cfl.fl_end;
++		fl->fl_type = cfl.fl_type;
++		fl->fl_pid = cfl.fl_pid;
++
+ 		goto out;
+ 	}
+ 
+@@ -702,8 +632,8 @@ static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl)
+ 	int ret = -ENOLCK;
+ 
+ 	dprintk("NFS: lock(%s/%s, t=%x, fl=%x, r=%lld:%lld)\n",
+-			filp->f_path.dentry->d_parent->d_name.name,
+-			filp->f_path.dentry->d_name.name,
++			filp->f_dentry->d_parent->d_name.name,
++			filp->f_dentry->d_name.name,
+ 			fl->fl_type, fl->fl_flags,
+ 			(long long)fl->fl_start, (long long)fl->fl_end);
+ 
+@@ -735,8 +665,8 @@ out_err:
+ static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl)
+ {
+ 	dprintk("NFS: flock(%s/%s, t=%x, fl=%x)\n",
+-			filp->f_path.dentry->d_parent->d_name.name,
+-			filp->f_path.dentry->d_name.name,
++			filp->f_dentry->d_parent->d_name.name,
++			filp->f_dentry->d_name.name,
+ 			fl->fl_type, fl->fl_flags);
+ 
+ 	if (!(fl->fl_flags & FL_FLOCK))
+@@ -751,16 +681,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/fscache-index.c b/fs/nfs/fscache-index.c
+index 5b10064..8970249 100644
+--- a/fs/nfs/fscache-index.c
++++ b/fs/nfs/fscache-index.c
+@@ -107,7 +107,7 @@ static uint16_t nfs_server_get_key(const void *cookie_netfs_data,
+  * object to fscache_acquire_cookie().  It is keyed by the NFS protocol and
+  * server address parameters.
+  */
+-const struct fscache_cookie_def nfs_fscache_server_index_def = {
++struct fscache_cookie_def nfs_fscache_server_index_def = {
+ 	.name		= "NFS.server",
+ 	.type 		= FSCACHE_COOKIE_TYPE_INDEX,
+ 	.get_key	= nfs_server_get_key,
+@@ -141,7 +141,7 @@ static uint16_t nfs_super_get_key(const void *cookie_netfs_data,
+  * superblock object to fscache_acquire_cookie().  It is keyed by all the NFS
+  * parameters that might cause a separate superblock.
+  */
+-const struct fscache_cookie_def nfs_fscache_super_index_def = {
++struct fscache_cookie_def nfs_fscache_super_index_def = {
+ 	.name		= "NFS.super",
+ 	.type 		= FSCACHE_COOKIE_TYPE_INDEX,
+ 	.get_key	= nfs_super_get_key,
+@@ -228,7 +228,7 @@ static uint16_t nfs_fscache_inode_get_aux(const void *cookie_netfs_data,
+  *   presented, as is the auxiliary data
+  */
+ static
+-enum fscache_checkaux nfs_fscache_inode_check_aux(void *cookie_netfs_data,
++fscache_checkaux_t nfs_fscache_inode_check_aux(void *cookie_netfs_data,
+ 						  const void *data,
+ 						  uint16_t datalen)
+ {
+@@ -324,7 +324,7 @@ static void nfs_fh_put_context(void *cookie_netfs_data, void *context)
+  * held in the cache auxiliary data for the data storage object with those in
+  * the inode struct in memory.
+  */
+-const struct fscache_cookie_def nfs_fscache_inode_object_def = {
++struct fscache_cookie_def nfs_fscache_inode_object_def = {
+ 	.name		= "NFS.fh",
+ 	.type		= FSCACHE_COOKIE_TYPE_DATAFILE,
+ 	.get_key	= nfs_fscache_inode_get_key,
+diff --git a/fs/nfs/fscache.h b/fs/nfs/fscache.h
+index 6e809bb..aed2aad 100644
+--- a/fs/nfs/fscache.h
++++ b/fs/nfs/fscache.h
+@@ -60,9 +60,9 @@ struct nfs_fscache_key {
+  * fscache-index.c
+  */
+ extern struct fscache_netfs nfs_fscache_netfs;
+-extern const struct fscache_cookie_def nfs_fscache_server_index_def;
+-extern const struct fscache_cookie_def nfs_fscache_super_index_def;
+-extern const struct fscache_cookie_def nfs_fscache_inode_object_def;
++extern struct fscache_cookie_def nfs_fscache_server_index_def;
++extern struct fscache_cookie_def nfs_fscache_super_index_def;
++extern struct fscache_cookie_def nfs_fscache_inode_object_def;
+ 
+ extern int nfs_fscache_register(void);
+ extern void nfs_fscache_unregister(void);
+diff --git a/fs/nfs/idmap.c b/fs/nfs/idmap.c
+index 86147b0..148aebe 100644
+--- a/fs/nfs/idmap.c
++++ b/fs/nfs/idmap.c
+@@ -376,7 +376,7 @@ idmap_pipe_upcall(struct file *filp, struct rpc_pipe_msg *msg,
+ static ssize_t
+ idmap_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
+ {
+-	struct rpc_inode *rpci = RPC_I(filp->f_path.dentry->d_inode);
++	struct rpc_inode *rpci = RPC_I(filp->f_dentry->d_inode);
+ 	struct idmap *idmap = (struct idmap *)rpci->private;
+ 	struct idmap_msg im_in, *im = &idmap->idmap_im;
+ 	struct idmap_hashtable *h;
+diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
+index 64f8719..2c50380 100644
+--- a/fs/nfs/inode.c
++++ b/fs/nfs/inode.c
+@@ -628,7 +628,7 @@ static void put_nfs_open_context_sync(struct nfs_open_context *ctx)
+  */
+ static void nfs_file_set_open_context(struct file *filp, struct nfs_open_context *ctx)
+ {
+-	struct inode *inode = filp->f_path.dentry->d_inode;
++	struct inode *inode = filp->f_dentry->d_inode;
+ 	struct nfs_inode *nfsi = NFS_I(inode);
+ 
+ 	filp->private_data = get_nfs_open_context(ctx);
+@@ -660,7 +660,7 @@ struct nfs_open_context *nfs_find_open_context(struct inode *inode, struct rpc_c
+ 
+ static void nfs_file_clear_open_context(struct file *filp)
+ {
+-	struct inode *inode = filp->f_path.dentry->d_inode;
++	struct inode *inode = filp->f_dentry->d_inode;
+ 	struct nfs_open_context *ctx = nfs_file_open_context(filp);
+ 
+ 	if (ctx) {
+@@ -683,7 +683,7 @@ int nfs_open(struct inode *inode, struct file *filp)
+ 	cred = rpc_lookup_cred();
+ 	if (IS_ERR(cred))
+ 		return PTR_ERR(cred);
+-	ctx = alloc_nfs_open_context(filp->f_path.mnt, filp->f_path.dentry, cred);
++	ctx = alloc_nfs_open_context(filp->f_vfsmnt, filp->f_dentry, cred);
+ 	put_rpccred(cred);
+ 	if (ctx == NULL)
+ 		return -ENOMEM;
+@@ -948,14 +948,14 @@ static int nfs_check_inode_attributes(struct inode *inode, struct nfs_fattr *fat
+ 	return 0;
+ }
+ 
+-static int nfs_ctime_need_update(const struct inode *inode, const struct nfs_fattr *fattr)
++static int nfs_ctime_need_update(struct inode *inode, struct nfs_fattr *fattr)
+ {
+ 	if (!(fattr->valid & NFS_ATTR_FATTR_CTIME))
+ 		return 0;
+ 	return timespec_compare(&fattr->ctime, &inode->i_ctime) > 0;
+ }
+ 
+-static int nfs_size_need_update(const struct inode *inode, const struct nfs_fattr *fattr)
++static int nfs_size_need_update(struct inode *inode, struct nfs_fattr *fattr)
+ {
+ 	if (!(fattr->valid & NFS_ATTR_FATTR_SIZE))
+ 		return 0;
+@@ -1000,7 +1000,7 @@ void nfs_fattr_init(struct nfs_fattr *fattr)
+  * more recent than the ones cached in the inode.
+  *
+  */
+-static int nfs_inode_attrs_need_update(const struct inode *inode, const struct nfs_fattr *fattr)
++static int nfs_inode_attrs_need_update(struct inode *inode, struct nfs_fattr *fattr)
+ {
+ 	const struct nfs_inode *nfsi = NFS_I(inode);
+ 
+@@ -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..0ba15d4 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,22 +150,22 @@ 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;
+ }
+ 
+-const struct inode_operations nfs_mountpoint_inode_operations = {
++struct inode_operations nfs_mountpoint_inode_operations = {
+ 	.follow_link	= nfs_follow_mountpoint,
+ 	.getattr	= nfs_getattr,
+ };
+ 
+-const struct inode_operations nfs_referral_inode_operations = {
++struct inode_operations nfs_referral_inode_operations = {
+ 	.follow_link	= nfs_follow_mountpoint,
+ };
+ 
+diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c
+index d0cc5ce..d112912 100644
+--- a/fs/nfs/nfs3proc.c
++++ b/fs/nfs/nfs3proc.c
+@@ -795,7 +795,7 @@ static void nfs3_proc_commit_setup(struct nfs_write_data *data, struct rpc_messa
+ static int
+ nfs3_proc_lock(struct file *filp, int cmd, struct file_lock *fl)
+ {
+-	struct inode *inode = filp->f_path.dentry->d_inode;
++	struct inode *inode = filp->f_dentry->d_inode;
+ 
+ 	return nlmclnt_proc(NFS_SERVER(inode)->nlm_host, cmd, fl);
+ }
+diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
+index 84345de..a98b322 100644
+--- a/fs/nfs/nfs4_fs.h
++++ b/fs/nfs/nfs4_fs.h
+@@ -179,8 +179,8 @@ struct nfs4_state_recovery_ops {
+ 	int (*recover_lock)(struct nfs4_state *, struct file_lock *);
+ };
+ 
+-extern const struct dentry_operations nfs4_dentry_operations;
+-extern const struct inode_operations nfs4_dir_inode_operations;
++extern struct dentry_operations nfs4_dentry_operations;
++extern struct inode_operations nfs4_dir_inode_operations;
+ 
+ /* inode.c */
+ extern ssize_t nfs4_getxattr(struct dentry *, const char *, void *, size_t);
+diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
+index a4d2426..84285cd 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;
+@@ -3740,7 +3740,7 @@ struct nfs4_state_recovery_ops nfs4_nograce_recovery_ops = {
+ 	.recover_lock	= nfs4_lock_expired,
+ };
+ 
+-static const struct inode_operations nfs4_file_inode_operations = {
++static struct inode_operations nfs4_file_inode_operations = {
+ 	.permission	= nfs_permission,
+ 	.getattr	= nfs_getattr,
+ 	.setattr	= nfs_setattr,
+diff --git a/fs/nfs/nfsroot.c b/fs/nfs/nfsroot.c
+index d9ef602..b51f6cb 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;
+ }
+ 
+@@ -425,8 +425,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/proc.c b/fs/nfs/proc.c
+index 7be72d9..d1fcb5d 100644
+--- a/fs/nfs/proc.c
++++ b/fs/nfs/proc.c
+@@ -601,7 +601,7 @@ nfs_proc_commit_setup(struct nfs_write_data *data, struct rpc_message *msg)
+ static int
+ nfs_proc_lock(struct file *filp, int cmd, struct file_lock *fl)
+ {
+-	struct inode *inode = filp->f_path.dentry->d_inode;
++	struct inode *inode = filp->f_dentry->d_inode;
+ 
+ 	return nlmclnt_proc(NFS_SERVER(inode)->nlm_host, cmd, fl);
+ }
+diff --git a/fs/nfs/super.c b/fs/nfs/super.c
+index 6717200..3b5967b 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 *);
+@@ -255,7 +255,7 @@ struct file_system_type nfs_xdev_fs_type = {
+ 	.fs_flags	= FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
+ };
+ 
+-static const struct super_operations nfs_sops = {
++static struct super_operations nfs_sops = {
+ 	.alloc_inode	= nfs_alloc_inode,
+ 	.destroy_inode	= nfs_destroy_inode,
+ 	.write_inode	= nfs_write_inode,
+@@ -300,7 +300,7 @@ struct file_system_type nfs4_referral_fs_type = {
+ 	.fs_flags	= FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
+ };
+ 
+-static const struct super_operations nfs4_sops = {
++static struct super_operations nfs4_sops = {
+ 	.alloc_inode	= nfs_alloc_inode,
+ 	.destroy_inode	= nfs_destroy_inode,
+ 	.write_inode	= nfs_write_inode,
+@@ -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/nfs/symlink.c b/fs/nfs/symlink.c
+index 412738d..b17f14a 100644
+--- a/fs/nfs/symlink.c
++++ b/fs/nfs/symlink.c
+@@ -70,7 +70,7 @@ read_failed:
+ /*
+  * symlinks can't do much...
+  */
+-const struct inode_operations nfs_symlink_inode_operations = {
++struct inode_operations nfs_symlink_inode_operations = {
+ 	.readlink	= generic_readlink,
+ 	.follow_link	= nfs_follow_link,
+ 	.put_link	= page_put_link,
+diff --git a/fs/nfs/write.c b/fs/nfs/write.c
+index e560a78..d623b02 100644
+--- a/fs/nfs/write.c
++++ b/fs/nfs/write.c
+@@ -12,6 +12,7 @@
+ #include <linux/pagemap.h>
+ #include <linux/file.h>
+ #include <linux/writeback.h>
++#include <linux/mpage.h>
+ #include <linux/swap.h>
+ 
+ #include <linux/sunrpc/clnt.h>
+@@ -748,8 +749,8 @@ int nfs_updatepage(struct file *file, struct page *page,
+ 	nfs_inc_stats(inode, NFSIOS_VFSUPDATEPAGE);
+ 
+ 	dprintk("NFS:       nfs_updatepage(%s/%s %d@%lld)\n",
+-		file->f_path.dentry->d_parent->d_name.name,
+-		file->f_path.dentry->d_name.name, count,
++		file->f_dentry->d_parent->d_name.name,
++		file->f_dentry->d_name.name, count,
+ 		(long long)(page_offset(page) + offset));
+ 
+ 	/* If we're not using byte range locks, and we know the page
+diff --git a/fs/nfs/writeback.c b/fs/nfs/writeback.c
+new file mode 100644
+index 0000000..b838ead
+--- /dev/null
++++ b/fs/nfs/writeback.c
+@@ -0,0 +1 @@
++#include "src/writeback.c"
+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..436bc25 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;
+ 		}
+ 	}
+@@ -2376,7 +2376,7 @@ static __be32
+ nfs4_upgrade_open(struct svc_rqst *rqstp, struct svc_fh *cur_fh, struct nfs4_stateid *stp, struct nfsd4_open *open)
+ {
+ 	struct file *filp = stp->st_vfs_file;
+-	struct inode *inode = filp->f_path.dentry->d_inode;
++	struct inode *inode = filp->f_dentry->d_inode;
+ 	unsigned int share_access, new_writer;
+ 	__be32 status;
+ 
+@@ -2733,7 +2733,7 @@ search_close_lru(u32 st_id, int flags)
+ static inline int
+ nfs4_check_fh(struct svc_fh *fhp, struct nfs4_stateid *stp)
+ {
+-	return fhp->fh_dentry->d_inode != stp->st_vfs_file->f_path.dentry->d_inode;
++	return fhp->fh_dentry->d_inode != stp->st_vfs_file->f_dentry->d_inode;
+ }
+ 
+ static int
+@@ -3804,7 +3804,7 @@ static int
+ check_for_locks(struct file *filp, struct nfs4_stateowner *lowner)
+ {
+ 	struct file_lock **flpp;
+-	struct inode *inode = filp->f_path.dentry->d_inode;
++	struct inode *inode = filp->f_dentry->d_inode;
+ 	int status = 0;
+ 
+ 	lock_kernel();
+diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
+index b820c31..c8a317c 100644
+--- a/fs/nfsd/nfs4xdr.c
++++ b/fs/nfsd/nfs4xdr.c
+@@ -2956,9 +2956,9 @@ nfsd4_encode_exchange_id(struct nfsd4_compoundres *resp, int nfserr,
+ 	if (nfserr)
+ 		return nfserr;
+ 
+-	major_id = utsname()->nodename;
++	major_id = system_utsname.nodename;
+ 	major_id_sz = strlen(major_id);
+-	server_scope = utsname()->nodename;
++	server_scope = system_utsname.nodename;
+ 	server_scope_sz = strlen(server_scope);
+ 
+ 	RESERVE_SPACE(
+diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
+index af16849..b61f3b4 100644
+--- a/fs/nfsd/nfsctl.c
++++ b/fs/nfsd/nfsctl.c
+@@ -121,7 +121,7 @@ static ssize_t (*write_op[])(struct file *, char *, size_t) = {
+ 
+ static ssize_t nfsctl_transaction_write(struct file *file, const char __user *buf, size_t size, loff_t *pos)
+ {
+-	ino_t ino =  file->f_path.dentry->d_inode->i_ino;
++	ino_t ino =  file->f_dentry->d_inode->i_ino;
+ 	char *data;
+ 	ssize_t rv;
+ 
+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..3a82587 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:
+@@ -775,10 +775,10 @@ static int
+ nfsd_sync(struct file *filp)
+ {
+         int err;
+-	struct inode *inode = filp->f_path.dentry->d_inode;
+-	dprintk("nfsd: sync file %s\n", filp->f_path.dentry->d_name.name);
++	struct inode *inode = filp->f_dentry->d_inode;
++	dprintk("nfsd: sync file %s\n", filp->f_dentry->d_name.name);
+ 	mutex_lock(&inode->i_mutex);
+-	err=nfsd_dosync(filp, filp->f_path.dentry, filp->f_op);
++	err=nfsd_dosync(filp, filp->f_dentry, filp->f_op);
+ 	mutex_unlock(&inode->i_mutex);
+ 
+ 	return err;
+@@ -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)
+@@ -904,7 +889,7 @@ nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
+ 	int		host_err;
+ 
+ 	err = nfserr_perm;
+-	inode = file->f_path.dentry->d_inode;
++	inode = file->f_dentry->d_inode;
+ 
+ 	if (svc_msnfs(fhp) && !lock_may_read(inode, offset, *count))
+ 		goto out;
+@@ -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);
+@@ -946,7 +924,7 @@ nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
+ 		nfsdstats.io_read += host_err;
+ 		*count = host_err;
+ 		err = 0;
+-		fsnotify_access(file->f_path.dentry);
++		fsnotify_access(file->f_dentry);
+ 	} else 
+ 		err = nfserrno(host_err);
+ out:
+@@ -980,11 +958,11 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
+ 	err = nfserr_perm;
+ 
+ 	if ((fhp->fh_export->ex_flags & NFSEXP_MSNFS) &&
+-		(!lock_may_write(file->f_path.dentry->d_inode, offset, *cnt)))
++		(!lock_may_write(file->f_dentry->d_inode, offset, *cnt)))
+ 		goto out;
+ #endif
+ 
+-	dentry = file->f_path.dentry;
++	dentry = file->f_dentry;
+ 	inode = dentry->d_inode;
+ 	exp   = fhp->fh_export;
+ 
+@@ -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. */
+@@ -1016,7 +992,7 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
+ 	set_fs(oldfs);
+ 	if (host_err >= 0) {
+ 		nfsdstats.io_write += host_err;
+-		fsnotify_modify(file->f_path.dentry);
++		fsnotify_modify(file->f_dentry);
+ 	}
+ 
+ 	/* clear setuid/setgid flag after write */
+@@ -1906,7 +1882,7 @@ static __be32 nfsd_buffered_readdir(struct file *file, filldir_t func,
+ 	offset = *offsetp;
+ 
+ 	while (1) {
+-		struct inode *dir_inode = file->f_path.dentry->d_inode;
++		struct inode *dir_inode = file->f_dentry->d_inode;
+ 		unsigned int reclen;
+ 
+ 		cdp->err = nfserr_eof; /* will be cleared on successful read */
+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/lockd/lockd.h b/include/linux/lockd/lockd.h
+index 51855df..2142bf0 100644
+--- a/include/linux/lockd/lockd.h
++++ b/include/linux/lockd/lockd.h
+@@ -285,7 +285,7 @@ int           nlmsvc_unlock_all_by_ip(struct sockaddr *server_addr);
+ 
+ static inline struct inode *nlmsvc_file_inode(struct nlm_file *file)
+ {
+-	return file->f_file->f_path.dentry->d_inode;
++	return file->f_file->f_dentry->d_inode;
+ }
+ 
+ static inline int __nlm_privileged_request4(const struct sockaddr *sap)
+diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
+index fdffb41..a41d1a5 100644
+--- a/include/linux/nfs_fs.h
++++ b/include/linux/nfs_fs.h
+@@ -10,6 +10,7 @@
+ #define _LINUX_NFS_FS_H
+ 
+ #include <linux/magic.h>
++#include <linux/path.h>
+ 
+ /* Default timeout values */
+ #define NFS_DEF_UDP_TIMEO	(11)
+@@ -343,7 +344,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);
+@@ -366,9 +367,9 @@ extern unsigned long nfs_inc_attr_generation_counter(void);
+ /*
+  * linux/fs/nfs/file.c
+  */
+-extern const struct inode_operations nfs_file_inode_operations;
++extern struct inode_operations nfs_file_inode_operations;
+ #ifdef CONFIG_NFS_V3
+-extern const struct inode_operations nfs3_file_inode_operations;
++extern struct inode_operations nfs3_file_inode_operations;
+ #endif /* CONFIG_NFS_V3 */
+ extern const struct file_operations nfs_file_operations;
+ extern const struct address_space_operations nfs_file_aops;
+@@ -420,12 +421,12 @@ extern ssize_t nfs_file_direct_write(struct kiocb *iocb,
+ /*
+  * linux/fs/nfs/dir.c
+  */
+-extern const struct inode_operations nfs_dir_inode_operations;
++extern struct inode_operations nfs_dir_inode_operations;
+ #ifdef CONFIG_NFS_V3
+-extern const struct inode_operations nfs3_dir_inode_operations;
++extern 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);
+@@ -435,7 +436,7 @@ extern void nfs_access_zap_cache(struct inode *inode);
+ /*
+  * linux/fs/nfs/symlink.c
+  */
+-extern const struct inode_operations nfs_symlink_inode_operations;
++extern struct inode_operations nfs_symlink_inode_operations;
+ 
+ /*
+  * linux/fs/nfs/sysctl.c
+@@ -451,8 +452,8 @@ extern void nfs_unregister_sysctl(void);
+ /*
+  * linux/fs/nfs/namespace.c
+  */
+-extern const struct inode_operations nfs_mountpoint_inode_operations;
+-extern const struct inode_operations nfs_referral_inode_operations;
++extern struct inode_operations nfs_mountpoint_inode_operations;
++extern struct inode_operations nfs_referral_inode_operations;
+ extern int nfs_mountpoint_expiry_timeout;
+ extern void nfs_release_automount_timer(void);
+ 
+diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
+index b89c34e..4303536 100644
+--- a/include/linux/nfs_xdr.h
++++ b/include/linux/nfs_xdr.h
+@@ -817,9 +817,9 @@ struct nfs_access_entry;
+  */
+ struct nfs_rpc_ops {
+ 	u32	version;		/* Protocol version */
+-	const struct dentry_operations *dentry_ops;
+-	const struct inode_operations *dir_inode_ops;
+-	const struct inode_operations *file_inode_ops;
++	struct dentry_operations *dentry_ops;
++	struct inode_operations *dir_inode_ops;
++	struct inode_operations *file_inode_ops;
+ 
+ 	int	(*getroot) (struct nfs_server *, struct nfs_fh *,
+ 			    struct nfs_fsinfo *);
+diff --git a/include/linux/nfsd/export.h b/include/linux/nfsd/export.h
+index bcd0201..fc59b1d 100644
+--- a/include/linux/nfsd/export.h
++++ b/include/linux/nfsd/export.h
+@@ -11,6 +11,7 @@
+ #define NFSD_EXPORT_H
+ 
+ # include <linux/types.h>
++# include <linux/path.h>
+ #ifdef __KERNEL__
+ # include <linux/in.h>
+ #endif
+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/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
+index e630b38..d207ac1 100644
+--- a/net/sunrpc/auth_gss/auth_gss.c
++++ b/net/sunrpc/auth_gss/auth_gss.c
+@@ -602,7 +602,7 @@ gss_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
+ 	const void *p, *end;
+ 	void *buf;
+ 	struct gss_upcall_msg *gss_msg;
+-	struct inode *inode = filp->f_path.dentry->d_inode;
++	struct inode *inode = filp->f_dentry->d_inode;
+ 	struct gss_cl_ctx *ctx;
+ 	uid_t uid;
+ 	ssize_t err = -EFBIG;
+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/cache.c b/net/sunrpc/cache.c
+index 20029a7..b682372 100644
+--- a/net/sunrpc/cache.c
++++ b/net/sunrpc/cache.c
+@@ -692,7 +692,7 @@ cache_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos)
+ {
+ 	struct cache_reader *rp = filp->private_data;
+ 	struct cache_request *rq;
+-	struct cache_detail *cd = PDE(filp->f_path.dentry->d_inode)->data;
++	struct cache_detail *cd = PDE(filp->f_dentry->d_inode)->data;
+ 	int err;
+ 
+ 	if (count == 0)
+@@ -769,7 +769,7 @@ cache_write(struct file *filp, const char __user *buf, size_t count,
+ 	    loff_t *ppos)
+ {
+ 	int err;
+-	struct cache_detail *cd = PDE(filp->f_path.dentry->d_inode)->data;
++	struct cache_detail *cd = PDE(filp->f_dentry->d_inode)->data;
+ 
+ 	if (count == 0)
+ 		return 0;
+@@ -800,7 +800,7 @@ cache_poll(struct file *filp, poll_table *wait)
+ 	unsigned int mask;
+ 	struct cache_reader *rp = filp->private_data;
+ 	struct cache_queue *cq;
+-	struct cache_detail *cd = PDE(filp->f_path.dentry->d_inode)->data;
++	struct cache_detail *cd = PDE(filp->f_dentry->d_inode)->data;
+ 
+ 	poll_wait(filp, &queue_wait, wait);
+ 
+@@ -1235,7 +1235,7 @@ static int c_show(struct seq_file *m, void *p)
+ 	return cd->cache_show(m, cd, cp);
+ }
+ 
+-static const struct seq_operations cache_content_op = {
++static struct seq_operations cache_content_op = {
+ 	.start	= c_start,
+ 	.next	= c_next,
+ 	.stop	= c_stop,
+@@ -1265,7 +1265,7 @@ static const struct file_operations content_file_operations = {
+ static ssize_t read_flush(struct file *file, char __user *buf,
+ 			    size_t count, loff_t *ppos)
+ {
+-	struct cache_detail *cd = PDE(file->f_path.dentry->d_inode)->data;
++	struct cache_detail *cd = PDE(file->f_dentry->d_inode)->data;
+ 	char tbuf[20];
+ 	unsigned long p = *ppos;
+ 	size_t len;
+@@ -1286,7 +1286,7 @@ static ssize_t read_flush(struct file *file, char __user *buf,
+ static ssize_t write_flush(struct file * file, const char __user * buf,
+ 			     size_t count, loff_t *ppos)
+ {
+-	struct cache_detail *cd = PDE(file->f_path.dentry->d_inode)->data;
++	struct cache_detail *cd = PDE(file->f_dentry->d_inode)->data;
+ 	char tbuf[20];
+ 	char *ep;
+ 	long flushtime;
+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..aad5e3e 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>
+@@ -235,7 +235,7 @@ out:
+ static ssize_t
+ rpc_pipe_read(struct file *filp, char __user *buf, size_t len, loff_t *offset)
+ {
+-	struct inode *inode = filp->f_path.dentry->d_inode;
++	struct inode *inode = filp->f_dentry->d_inode;
+ 	struct rpc_inode *rpci = RPC_I(inode);
+ 	struct rpc_pipe_msg *msg;
+ 	int res = 0;
+@@ -278,7 +278,7 @@ out_unlock:
+ static ssize_t
+ rpc_pipe_write(struct file *filp, const char __user *buf, size_t len, loff_t *offset)
+ {
+-	struct inode *inode = filp->f_path.dentry->d_inode;
++	struct inode *inode = filp->f_dentry->d_inode;
+ 	struct rpc_inode *rpci = RPC_I(inode);
+ 	int res;
+ 
+@@ -296,7 +296,7 @@ rpc_pipe_poll(struct file *filp, struct poll_table_struct *wait)
+ 	struct rpc_inode *rpci;
+ 	unsigned int mask = 0;
+ 
+-	rpci = RPC_I(filp->f_path.dentry->d_inode);
++	rpci = RPC_I(filp->f_dentry->d_inode);
+ 	poll_wait(filp, &rpci->waitq, wait);
+ 
+ 	mask = POLLOUT | POLLWRNORM;
+@@ -311,7 +311,7 @@ static int
+ rpc_pipe_ioctl(struct inode *ino, struct file *filp,
+ 		unsigned int cmd, unsigned long arg)
+ {
+-	struct rpc_inode *rpci = RPC_I(filp->f_path.dentry->d_inode);
++	struct rpc_inode *rpci = RPC_I(filp->f_dentry->d_inode);
+ 	int len;
+ 
+ 	switch (cmd) {
+@@ -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/svc_xprt.c b/net/sunrpc/svc_xprt.c
+index c200d92..554296d 100644
+--- a/net/sunrpc/svc_xprt.c
++++ b/net/sunrpc/svc_xprt.c
+@@ -1202,7 +1202,7 @@ static int svc_pool_stats_show(struct seq_file *m, void *p)
+ 	return 0;
+ }
+ 
+-static const struct seq_operations svc_pool_stats_seq_ops = {
++static struct seq_operations svc_pool_stats_seq_ops = {
+ 	.start	= svc_pool_stats_start,
+ 	.next	= svc_pool_stats_next,
+ 	.stop	= svc_pool_stats_stop,
+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..3d7d7a6 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:
+@@ -467,12 +467,16 @@ static int svc_udp_recvfrom(struct svc_rqst *rqstp)
+ 	if (len < 0)
+ 		return len;
+ 	rqstp->rq_addrlen = len;
+-	if (skb->tstamp.tv64 == 0) {
+-		skb->tstamp = ktime_get_real();
++	if (skb->tstamp.off_sec == 0) {
++		struct timeval tv;
++ 
++		tv.tv_sec = xtime.tv_sec;
++		tv.tv_usec = xtime.tv_nsec / NSEC_PER_USEC;
++		skb_set_timestamp(skb, &tv);
+ 		/* Don't enable netstamp, sunrpc doesn't
+ 		   need that much accuracy */
+ 	}
+-	svsk->sk_sk->sk_stamp = skb->tstamp;
++	skb_get_timestamp(skb, &svsk->sk_sk->sk_stamp);
+ 	set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags); /* there may be more data... */
+ 
+ 	/*
+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