Hey Vlad,

I have resolved the last outstanding issue on the RHEL 5.2 and 2.6.22
backport.  With this patch, all of the connectathon tests pass on RHEL
5.2 and 2.6.22.

I am still working on the updated nfs-utils rpm, and should have that
out in the near future.

I have split up the patch into separate patches for RHEL 5.2 and 2.6.22.
If you would prefer me to combine them or resend the entire NFS-RDMA
backport patch, please let me know.

Thanks,
Jon
diff --git a/kernel_addons/backport/2.6.18-EL5.2/include/linux/pipe_fs_i.h b/kernel_addons/backport/2.6.18-EL5.2/include/linux/pipe_fs_i.h
index bb23ebb..4e91a24 100644
--- a/kernel_addons/backport/2.6.18-EL5.2/include/linux/pipe_fs_i.h
+++ b/kernel_addons/backport/2.6.18-EL5.2/include/linux/pipe_fs_i.h
@@ -3,111 +3,6 @@
 
 #include_next <linux/pipe_fs_i.h>
 
-static inline void backport_pipe_wait(struct pipe_inode_info *pipe)
-{
-        DEFINE_WAIT(wait);
-
-        /*
-         * Pipes are system-local resources, so sleeping on them
-         * is considered a noninteractive wait:
-         */
-        prepare_to_wait(&pipe->wait, &wait, TASK_INTERRUPTIBLE);
-        if (pipe->inode)
-                mutex_unlock(&pipe->inode->i_mutex);
-        schedule();
-        finish_wait(&pipe->wait, &wait);
-        if (pipe->inode)
-                mutex_lock(&pipe->inode->i_mutex);
-}
-
-
-static inline ssize_t __splice_from_pipe(struct pipe_inode_info *pipe, struct splice_desc *sd,
-			   splice_actor *actor)
-{
-	int ret, do_wakeup, err;
-
-	ret = 0;
-	do_wakeup = 0;
-
-	for (;;) {
-		if (pipe->nrbufs) {
-			struct pipe_buffer *buf = pipe->bufs + pipe->curbuf;
-			const struct pipe_buf_operations *ops = buf->ops;
-
-			sd->len = buf->len;
-			if (sd->len > sd->total_len)
-				sd->len = sd->total_len;
-
-			err = actor(pipe, buf, sd);
-			if (err <= 0) {
-				if (!ret && err != -ENODATA)
-					ret = err;
-
-				break;
-			}
-
-			ret += err;
-			buf->offset += err;
-			buf->len -= err;
-
-			sd->len -= err;
-			sd->pos += err;
-			sd->total_len -= err;
-			if (sd->len)
-				continue;
-
-			if (!buf->len) {
-				buf->ops = NULL;
-				ops->release(pipe, buf);
-				pipe->curbuf = (pipe->curbuf + 1) & (PIPE_BUFFERS - 1);
-				pipe->nrbufs--;
-				if (pipe->inode)
-					do_wakeup = 1;
-			}
-
-			if (!sd->total_len)
-				break;
-		}
-
-		if (pipe->nrbufs)
-			continue;
-		if (!pipe->writers)
-			break;
-		if (!pipe->waiting_writers) {
-			if (ret)
-				break;
-		}
-
-		if (sd->flags & SPLICE_F_NONBLOCK) {
-			if (!ret)
-				ret = -EAGAIN;
-			break;
-		}
-
-		if (signal_pending(current)) {
-			if (!ret)
-				ret = -ERESTARTSYS;
-			break;
-		}
-
-		if (do_wakeup) {
-			smp_mb();
-			if (waitqueue_active(&pipe->wait))
-				wake_up_interruptible_sync(&pipe->wait);
-			kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT);
-			do_wakeup = 0;
-		}
-
-		backport_pipe_wait(pipe);
-	}
-
-	if (do_wakeup) {
-		smp_mb();
-		if (waitqueue_active(&pipe->wait))
-			wake_up_interruptible(&pipe->wait);
-		kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT);
-	}
-
-	return ret;
-}
+extern ssize_t __splice_from_pipe(struct pipe_inode_info *pipe, struct splice_desc *sd,
+			   splice_actor *actor);
 #endif
diff --git a/kernel_addons/backport/2.6.18-EL5.2/include/linux/writeback.h b/kernel_addons/backport/2.6.18-EL5.2/include/linux/writeback.h
index d370a6f..0ecfd2f 100644
--- a/kernel_addons/backport/2.6.18-EL5.2/include/linux/writeback.h
+++ b/kernel_addons/backport/2.6.18-EL5.2/include/linux/writeback.h
@@ -7,103 +7,7 @@
 typedef int (*backport_writepage_t)(struct page *page, struct writeback_control *wbc,
                                 void *data);
 
-static inline int write_cache_pages(struct address_space *mapping,
+extern int write_cache_pages(struct address_space *mapping,
                       struct writeback_control *wbc, backport_writepage_t writepage,
-                      void *data)
-{
-        struct backing_dev_info *bdi = mapping->backing_dev_info;
-        int ret = 0;
-        int done = 0;
-        struct pagevec pvec;
-        int nr_pages;
-        pgoff_t index;
-        pgoff_t end;            /* Inclusive */
-        int scanned = 0;
-        int range_whole = 0;
-        long nr_to_write = wbc->nr_to_write;
-
-        if (wbc->nonblocking && bdi_write_congested(bdi)) {
-                wbc->encountered_congestion = 1;
-                return 0;
-        }
-
-        pagevec_init(&pvec, 0);
-        if (wbc->range_cyclic) {
-                index = mapping->writeback_index; /* Start from prev offset */
-                end = -1;
-        } else {
-                index = wbc->range_start >> PAGE_CACHE_SHIFT;
-                end = wbc->range_end >> PAGE_CACHE_SHIFT;
-                if (wbc->range_start == 0 && wbc->range_end == LLONG_MAX)
-                        range_whole = 1;
-                scanned = 1;
-        }
-retry:
-        while (!done && (index <= end) &&
-               (nr_pages = pagevec_lookup_tag(&pvec, mapping, &index,
-                                              PAGECACHE_TAG_DIRTY,
-                                              min(end - index, (pgoff_t)PAGEVEC_SIZE-1) + 1))) {
-                unsigned i;
-
-                scanned = 1;
-                for (i = 0; i < nr_pages; i++) {
-                        struct page *page = pvec.pages[i];
-
-                        /*
-                         * At this point we hold neither mapping->tree_lock nor
-                         * lock on the page itself: the page may be truncated or
-                         * invalidated (changing page->mapping to NULL), or even
-                         * swizzled back from swapper_space to tmpfs file
-                         * mapping
-                         */
-                        lock_page(page);
-
-                        if (unlikely(page->mapping != mapping)) {
-                                unlock_page(page);
-                                continue;
-                        }
-
-                        if (!wbc->range_cyclic && page->index > end) {
-                                done = 1;
-                                unlock_page(page);
-                                continue;
-                        }
-
-                        if (wbc->sync_mode != WB_SYNC_NONE)
-                                wait_on_page_writeback(page);
-
-                        if (PageWriteback(page) ||
-                            !clear_page_dirty_for_io(page)) {
-                                unlock_page(page);
-                                continue;
-                        }
-
-                        ret = (*writepage)(page, wbc, data);
-
-                        if (unlikely(ret == AOP_WRITEPAGE_ACTIVATE)) {
-                                unlock_page(page);
-                                ret = 0;
-                        }
-                        if (ret || (--nr_to_write <= 0))
-                                done = 1;
-                        if (wbc->nonblocking && bdi_write_congested(bdi)) {
-                                wbc->encountered_congestion = 1;
-                                done = 1;
-                        }
-                }
-                pagevec_release(&pvec);
-                cond_resched();
-        }
-        if (!scanned && !done) {
-                /*
-                 * We hit the last page and there is more work to be done: wrap
-                 * back to the start of the file
-                 */
-                scanned = 1;
-                index = 0;
-                goto retry;
-        }
-        return ret;
-}
-
+                      void *data);
 #endif
diff --git a/kernel_addons/backport/2.6.18-EL5.2/include/net/udp.h b/kernel_addons/backport/2.6.18-EL5.2/include/net/udp.h
index 3f1cf68..04c4883 100644
--- a/kernel_addons/backport/2.6.18-EL5.2/include/net/udp.h
+++ b/kernel_addons/backport/2.6.18-EL5.2/include/net/udp.h
@@ -2,36 +2,8 @@
 #define BACKPORT_NET_UDP_H
 
 #include_next <net/udp.h>
-#include <net/snmp.h>
-
-#if 0
-DECLARE_SNMP_STAT(struct udp_mib, udplite_statistics);
-DECLARE_SNMP_STAT(struct udp_mib, udp_statistics);
-DECLARE_SNMP_STAT(struct udp_mib, udplite_stats_in6);
-DECLARE_SNMP_STAT(struct udp_mib, udp_stats_in6);
-
-#define UDP6_INC_STATS_BH(field, is_udplite)	   do { \
-	if (is_udplite) SNMP_INC_STATS_BH(udplite_stats_in6, field);\
-	else	    SNMP_INC_STATS_BH(udp_stats_in6, field);  \
-} while(0)
-
-
-#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-#define UDPX_INC_STATS_BH(sk, field) \
-	do { \
-		if ((sk)->sk_family == AF_INET) \
-			UDP_INC_STATS_BH(field, 0); \
-		else \
-			UDP6_INC_STATS_BH(field, 0); \
-	} while (0);
-#else
-#define UDPX_INC_STATS_BH(sk, field) UDP_INC_STATS_BH(field, 0)
-#endif
-
-#else
 
 static inline void UDPX_INC_STATS_BH(struct sock *sk, int field)
 { }
 
 #endif
-#endif
diff --git a/kernel_addons/backport/2.6.18-EL5.2/include/src/splice.c b/kernel_addons/backport/2.6.18-EL5.2/include/src/splice.c
new file mode 100644
index 0000000..543d5f8
--- /dev/null
+++ b/kernel_addons/backport/2.6.18-EL5.2/include/src/splice.c
@@ -0,0 +1,111 @@
+#include <linux/pagemap.h>
+#include <linux/pipe_fs_i.h>
+#include <linux/module.h>
+
+static void backport_pipe_wait(struct pipe_inode_info *pipe)
+{
+	DEFINE_WAIT(wait);
+
+	/*
+	 * Pipes are system-local resources, so sleeping on them
+	 * is considered a noninteractive wait:
+	 */
+	prepare_to_wait(&pipe->wait, &wait, TASK_INTERRUPTIBLE);
+	if (pipe->inode)
+		mutex_unlock(&pipe->inode->i_mutex);
+	schedule();
+	finish_wait(&pipe->wait, &wait);
+	if (pipe->inode)
+		mutex_lock(&pipe->inode->i_mutex);
+}
+
+ssize_t __splice_from_pipe(struct pipe_inode_info *pipe, struct splice_desc *sd,
+			   splice_actor *actor)
+{
+	int ret, do_wakeup, err;
+
+	ret = 0;
+	do_wakeup = 0;
+
+	for (;;) {
+		if (pipe->nrbufs) {
+			struct pipe_buffer *buf = pipe->bufs + pipe->curbuf;
+			const struct pipe_buf_operations *ops = buf->ops;
+
+			sd->len = buf->len;
+			if (sd->len > sd->total_len)
+				sd->len = sd->total_len;
+
+			err = actor(pipe, buf, sd);
+			if (err <= 0) {
+				if (!ret && err != -ENODATA)
+					ret = err;
+
+				break;
+			}
+
+			ret += err;
+			buf->offset += err;
+			buf->len -= err;
+
+			sd->len -= err;
+			sd->pos += err;
+			sd->total_len -= err;
+			if (sd->len)
+				continue;
+
+			if (!buf->len) {
+				buf->ops = NULL;
+				ops->release(pipe, buf);
+				pipe->curbuf = (pipe->curbuf + 1) & (PIPE_BUFFERS - 1);
+				pipe->nrbufs--;
+				if (pipe->inode)
+					do_wakeup = 1;
+			}
+
+			if (!sd->total_len)
+				break;
+		}
+
+		if (pipe->nrbufs)
+			continue;
+		if (!pipe->writers)
+			break;
+		if (!pipe->waiting_writers) {
+			if (ret)
+				break;
+		}
+
+		if (sd->flags & SPLICE_F_NONBLOCK) {
+			if (!ret)
+				ret = -EAGAIN;
+			break;
+		}
+
+		if (signal_pending(current)) {
+			if (!ret)
+				ret = -ERESTARTSYS;
+			break;
+		}
+
+		if (do_wakeup) {
+			smp_mb();
+			if (waitqueue_active(&pipe->wait))
+				wake_up_interruptible_sync(&pipe->wait);
+			kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT);
+			do_wakeup = 0;
+		}
+
+		backport_pipe_wait(pipe);
+	}
+
+	if (do_wakeup) {
+		smp_mb();
+		if (waitqueue_active(&pipe->wait))
+			wake_up_interruptible(&pipe->wait);
+		kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT);
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL(__splice_from_pipe);
diff --git a/kernel_addons/backport/2.6.18-EL5.2/include/src/writeback.c b/kernel_addons/backport/2.6.18-EL5.2/include/src/writeback.c
new file mode 100644
index 0000000..e8bf5ac
--- /dev/null
+++ b/kernel_addons/backport/2.6.18-EL5.2/include/src/writeback.c
@@ -0,0 +1,105 @@
+#include <linux/fs.h>
+#include <linux/pagemap.h>
+#include <linux/pagevec.h>
+#include <linux/writeback.h>
+#include <linux/module.h>
+
+int write_cache_pages(struct address_space *mapping,
+                      struct writeback_control *wbc, backport_writepage_t writepage,
+                      void *data)
+{
+        struct backing_dev_info *bdi = mapping->backing_dev_info;
+        int ret = 0;
+        int done = 0;
+        struct pagevec pvec;
+        int nr_pages;
+        pgoff_t index;
+        pgoff_t end;            /* Inclusive */
+        int scanned = 0;
+        int range_whole = 0;
+        long nr_to_write = wbc->nr_to_write;
+
+        if (wbc->nonblocking && bdi_write_congested(bdi)) {
+                wbc->encountered_congestion = 1;
+                return 0;
+        }
+
+        pagevec_init(&pvec, 0);
+        if (wbc->range_cyclic) {
+                index = mapping->writeback_index; /* Start from prev offset */
+                end = -1;
+        } else {
+                index = wbc->range_start >> PAGE_CACHE_SHIFT;
+                end = wbc->range_end >> PAGE_CACHE_SHIFT;
+                if (wbc->range_start == 0 && wbc->range_end == LLONG_MAX)
+                        range_whole = 1;
+                scanned = 1;
+        }
+retry:
+        while (!done && (index <= end) &&
+               (nr_pages = pagevec_lookup_tag(&pvec, mapping, &index,
+                                              PAGECACHE_TAG_DIRTY,
+                                              min(end - index, (pgoff_t)PAGEVEC_SIZE-1) + 1))) {
+                unsigned i;
+
+                scanned = 1;
+                for (i = 0; i < nr_pages; i++) {
+                        struct page *page = pvec.pages[i];
+
+                        /*
+                         * At this point we hold neither mapping->tree_lock nor
+                         * lock on the page itself: the page may be truncated or
+                         * invalidated (changing page->mapping to NULL), or even
+                         * swizzled back from swapper_space to tmpfs file
+                         * mapping
+                         */
+                        lock_page(page);
+
+                        if (unlikely(page->mapping != mapping)) {
+                                unlock_page(page);
+                                continue;
+                        }
+
+                        if (!wbc->range_cyclic && page->index > end) {
+                                done = 1;
+                                unlock_page(page);
+                                continue;
+                        }
+
+                        if (wbc->sync_mode != WB_SYNC_NONE)
+                                wait_on_page_writeback(page);
+
+                        if (PageWriteback(page) ||
+                            !clear_page_dirty_for_io(page)) {
+                                unlock_page(page);
+                                continue;
+                        }
+
+                        ret = (*writepage)(page, wbc, data);
+
+                        if (unlikely(ret == AOP_WRITEPAGE_ACTIVATE)) {
+                                unlock_page(page);
+                                ret = 0;
+                        }
+                        if (ret || (--nr_to_write <= 0))
+                                done = 1;
+                        if (wbc->nonblocking && bdi_write_congested(bdi)) {
+                                wbc->encountered_congestion = 1;
+                                done = 1;
+                        }
+                }
+                pagevec_release(&pvec);
+                cond_resched();
+        }
+        if (!scanned && !done) {
+                /*
+                 * We hit the last page and there is more work to be done: wrap
+                 * back to the start of the file
+                 */
+                scanned = 1;
+                index = 0;
+                goto retry;
+        }
+        return ret;
+}
+EXPORT_SYMBOL(write_cache_pages);
diff --git a/kernel_patches/backport/2.6.18-EL5.2/rnfs_fs.patch b/kernel_patches/backport/2.6.18-EL5.2/rnfs_fs.patch
index 2184f48..e66184d 100644
--- a/kernel_patches/backport/2.6.18-EL5.2/rnfs_fs.patch
+++ b/kernel_patches/backport/2.6.18-EL5.2/rnfs_fs.patch
@@ -1,5 +1,5 @@
 diff --git a/drivers/infiniband/core/Makefile b/drivers/infiniband/core/Makefile
-index 03acfd6..a9fc20d 100644
+index 03acfd6..fcbe857 100644
 --- a/drivers/infiniband/core/Makefile
 +++ b/drivers/infiniband/core/Makefile
 @@ -31,4 +31,4 @@ ib_ucm-y :=			ucm.o
@@ -7,7 +7,7 @@ index 03acfd6..a9fc20d 100644
  ib_uverbs-y :=			uverbs_main.o uverbs_cmd.o uverbs_marshall.o
  
 -ib_core-y +=			genalloc.o
-+ib_core-y +=			genalloc.o namespace.o
++ib_core-y +=			genalloc.o namespace.o splice.o writeback.o
 diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c
 index 7edc1b5..4e222ed 100644
 --- a/drivers/infiniband/core/device.c
@@ -30,6 +30,20 @@ index 0000000..de57f8b
 +++ b/drivers/infiniband/core/namespace.c
 @@ -0,0 +1 @@
 +#include "src/namespace.c"
+diff --git a/drivers/infiniband/core/splice.c b/drivers/infiniband/core/splice.c
+new file mode 100644
+index 0000000..d070211
+--- /dev/null
++++ b/drivers/infiniband/core/splice.c
+@@ -0,0 +1 @@
++#include "src/splice.c"
+diff --git a/drivers/infiniband/core/writeback.c b/drivers/infiniband/core/writeback.c
+new file mode 100644
+index 0000000..b838ead
+--- /dev/null
++++ b/drivers/infiniband/core/writeback.c
+@@ -0,0 +1 @@
++#include "src/writeback.c"
 diff --git a/fs/exportfs/expfs.c b/fs/exportfs/expfs.c
 index cc91227..262397b 100644
 --- a/fs/exportfs/expfs.c
@@ -1571,10 +1585,18 @@ index 80292ff..47eb160 100644
 +
 +MODULE_LICENSE("Dual BSD/GPL");
 diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
-index 18060be..4cc085b 100644
+index 18060be..be88d9d 100644
 --- a/fs/nfsd/vfs.c
 +++ b/fs/nfsd/vfs.c
-@@ -97,7 +97,7 @@ static struct raparm_hbucket	raparm_hash[RAPARM_HASH_SIZE];
+@@ -23,7 +23,6 @@
+ #include <linux/file.h>
+ #include <linux/mount.h>
+ #include <linux/major.h>
+-#include <linux/splice.h>
+ #include <linux/proc_fs.h>
+ #include <linux/stat.h>
+ #include <linux/fcntl.h>
+@@ -97,7 +96,7 @@ static struct raparm_hbucket	raparm_hash[RAPARM_HASH_SIZE];
   */
  int
  nfsd_cross_mnt(struct svc_rqst *rqstp, struct dentry **dpp, 
@@ -1583,7 +1605,7 @@ index 18060be..4cc085b 100644
  {
  	struct svc_export *exp = *expp, *exp2 = NULL;
  	struct dentry *dentry = *dpp;
-@@ -765,11 +765,11 @@ static inline int nfsd_dosync(struct file *filp, struct dentry *dp,
+@@ -765,11 +764,11 @@ static inline int nfsd_dosync(struct file *filp, struct dentry *dp,
  static int
  nfsd_sync(struct file *filp)
  {
@@ -1599,23 +1621,74 @@ index 18060be..4cc085b 100644
  	mutex_unlock(&inode->i_mutex);
  
  	return err;
-@@ -837,13 +837,13 @@ static int
- nfsd_splice_actor(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
- 		  struct splice_desc *sd)
+@@ -828,53 +827,33 @@ found:
+ 	return ra;
+ }
+ 
+-/*
+- * Grab and keep cached pages associated with a file in the svc_rqst
+- * so that they can be passed to the network sendmsg/sendpage routines
+- * 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 svc_rqst *rqstp = (struct svc_rqst *)sd->file;
- 	struct page **pp = rqstp->rq_respages + rqstp->rq_resused;
- 	struct page *page = buf->page;
- 	size_t size;
- 	int ret;
- 
+-	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);
-+	ret = buf->ops->pin(pipe, buf);
- 	if (unlikely(ret))
- 		return ret;
+-	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
++	} else {
+ 		rqstp->rq_res.page_len += size;
++	}
+ 
++	desc->count = count - size;
++	desc->written += size;
+ 	return size;
+ }
  
-@@ -886,7 +886,7 @@ static inline int svc_msnfs(struct svc_fh *ffhp)
+-static int nfsd_direct_splice_actor(struct pipe_inode_info *pipe,
+-				    struct splice_desc *sd)
+-{
+-	return __splice_from_pipe(pipe, sd, nfsd_splice_actor);
+-}
+-
+ static inline int svc_msnfs(struct svc_fh *ffhp)
+ {
+ #ifdef MSNFS
+@@ -886,7 +865,7 @@ static inline int svc_msnfs(struct svc_fh *ffhp)
  
  static __be32
  nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
@@ -1624,7 +1697,7 @@ index 18060be..4cc085b 100644
  {
  	struct inode *inode;
  	struct raparms	*ra;
-@@ -895,7 +895,7 @@ nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
+@@ -895,7 +874,7 @@ nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
  	int		host_err;
  
  	err = nfserr_perm;
@@ -1633,16 +1706,26 @@ index 18060be..4cc085b 100644
  
  	if (svc_msnfs(fhp) && !lock_may_read(inode, offset, *count))
  		goto out;
-@@ -911,7 +911,7 @@ nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
- 			.len		= 0,
- 			.total_len	= *count,
- 			.pos		= offset,
+@@ -906,16 +885,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,
-+			.file		= (struct file *)rqstp,
- 		};
- 
+-		};
+-
++	if (file->f_op->sendfile && rqstp->rq_sendfile_ok) {
  		rqstp->rq_resused = 1;
-@@ -937,7 +937,7 @@ nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
+-		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);
+@@ -937,7 +909,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;
@@ -1651,7 +1734,7 @@ index 18060be..4cc085b 100644
  	} else 
  		err = nfserrno(host_err);
  out:
-@@ -971,11 +971,11 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
+@@ -971,11 +943,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) &&
@@ -1665,7 +1748,7 @@ index 18060be..4cc085b 100644
  	inode = dentry->d_inode;
  	exp   = fhp->fh_export;
  
-@@ -1004,7 +1004,7 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
+@@ -1004,7 +976,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 += cnt;
@@ -1674,7 +1757,7 @@ index 18060be..4cc085b 100644
  	}
  
  	/* clear setuid/setgid flag after write */
-@@ -1129,7 +1129,7 @@ out:
+@@ -1129,7 +1101,7 @@ out:
   */
  __be32
  nfsd_commit(struct svc_rqst *rqstp, struct svc_fh *fhp,
@@ -1683,7 +1766,7 @@ index 18060be..4cc085b 100644
  {
  	struct file	*file;
  	__be32		err;
-@@ -1316,7 +1316,7 @@ __be32
+@@ -1316,7 +1288,7 @@ __be32
  nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp,
  		char *fname, int flen, struct iattr *iap,
  		struct svc_fh *resfhp, int createmode, u32 *verifier,
@@ -2136,6 +2219,19 @@ index 10709cb..9bbadbd 100644
  };
  
  #endif /* _LINUX_SUNRPC_DEBUG_H_ */
+diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h
+index dc69068..3a0f48f 100644
+--- a/include/linux/sunrpc/svc.h
++++ b/include/linux/sunrpc/svc.h
+@@ -255,7 +255,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/net/sunrpc/auth.c b/net/sunrpc/auth.c
 index 6bfea9e..f0a110d 100644
 --- a/net/sunrpc/auth.c
@@ -2188,6 +2284,19 @@ index ef45eba..423251a 100644
  	*res = crypto_alloc_blkcipher(alg_name, 0, CRYPTO_ALG_ASYNC);
  	if (IS_ERR(*res)) {
  		printk("gss_kerberos_mech: unable to initialize crypto algorithm %s\n", alg_name);
+diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c
+index 81ae3d6..acfb1d1 100644
+--- a/net/sunrpc/auth_gss/svcauth_gss.c
++++ b/net/sunrpc/auth_gss/svcauth_gss.c
+@@ -859,7 +859,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 c996671..58e606e 100644
 --- a/net/sunrpc/cache.c
@@ -2431,7 +2540,7 @@ index 50b049c..5053a5f 100644
  }
  
 diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
-index 5a32cb7..e30e8f5 100644
+index 5a32cb7..e0e87c6 100644
 --- a/net/sunrpc/svc.c
 +++ b/net/sunrpc/svc.c
 @@ -174,7 +174,7 @@ fail:
@@ -2468,6 +2577,15 @@ index 5a32cb7..e30e8f5 100644
  		break;
  	}
  	}
+@@ -831,7 +830,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;
+ 
+ 	/* Setup reply header */
+ 	rqstp->rq_xprt->xpt_ops->xpo_prep_reply_hdr(rqstp);
 diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c
 index f24800f..b30d725 100644
 --- a/net/sunrpc/svcauth_unix.c
diff --git a/kernel_addons/backport/2.6.22/include/linux/pipe_fs_i.h b/kernel_addons/backport/2.6.22/include/linux/pipe_fs_i.h
index be965ab..e1ac0a3 100644
--- a/kernel_addons/backport/2.6.22/include/linux/pipe_fs_i.h
+++ b/kernel_addons/backport/2.6.22/include/linux/pipe_fs_i.h
@@ -6,7 +6,7 @@
 static inline ssize_t backport_splice_from_pipe(struct pipe_inode_info *pipe,
 					 struct splice_desc *sd, splice_actor *splice_actor)
 {
-	return __splice_from_pipe(pipe, sd->u.file, &sd->pos, sd->total_len, sd->flags, splice_actor);
+	return __splice_from_pipe(pipe, sd->file, &sd->pos, sd->total_len, sd->flags, splice_actor);
 }
 
 #define __splice_from_pipe backport_splice_from_pipe
diff --git a/kernel_addons/backport/2.6.22/include/linux/radix-tree.h b/kernel_addons/backport/2.6.22/include/linux/radix-tree.h
index 087a63f..735561e 100644
--- a/kernel_addons/backport/2.6.22/include/linux/radix-tree.h
+++ b/kernel_addons/backport/2.6.22/include/linux/radix-tree.h
@@ -2,15 +2,18 @@
 #define BACKPORT_LINUX_RADIX_TREE_H
 
 #include_next <linux/radix-tree.h>
-#if 0
-static inline int radix_tree_preload(gfp_t gfp_mask)
+
+static inline int backport_radix_tree_preload(gfp_t gfp_mask)
 {
 	return 0;
 }
 
-static inline void radix_tree_preload_end(void)
+#define radix_tree_preload backport_radix_tree_preload
+
+static inline void backport_radix_tree_preload_end(void)
 {
 }
 
-#endif
+#define radix_tree_preload_end backport_radix_tree_preload_end
+
 #endif
diff --git a/kernel_addons/backport/2.6.22/include/linux/string.h b/kernel_addons/backport/2.6.22/include/linux/string.h
index 265e6d0..ad7ac5b 100644
--- a/kernel_addons/backport/2.6.22/include/linux/string.h
+++ b/kernel_addons/backport/2.6.22/include/linux/string.h
@@ -4,7 +4,6 @@
 #include_next <linux/string.h>
 
 extern void *__kmalloc(size_t, gfp_t);
-//extern void *kmalloc_track_caller(size_t, gfp_t);
 
 static inline char *kstrndup(const char *s, size_t max, gfp_t gfp)
 {
diff --git a/kernel_addons/backport/2.6.22/include/net/udp.h b/kernel_addons/backport/2.6.22/include/net/udp.h
index 3f1cf68..04c4883 100644
--- a/kernel_addons/backport/2.6.22/include/net/udp.h
+++ b/kernel_addons/backport/2.6.22/include/net/udp.h
@@ -2,36 +2,8 @@
 #define BACKPORT_NET_UDP_H
 
 #include_next <net/udp.h>
-#include <net/snmp.h>
-
-#if 0
-DECLARE_SNMP_STAT(struct udp_mib, udplite_statistics);
-DECLARE_SNMP_STAT(struct udp_mib, udp_statistics);
-DECLARE_SNMP_STAT(struct udp_mib, udplite_stats_in6);
-DECLARE_SNMP_STAT(struct udp_mib, udp_stats_in6);
-
-#define UDP6_INC_STATS_BH(field, is_udplite)	   do { \
-	if (is_udplite) SNMP_INC_STATS_BH(udplite_stats_in6, field);\
-	else	    SNMP_INC_STATS_BH(udp_stats_in6, field);  \
-} while(0)
-
-
-#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-#define UDPX_INC_STATS_BH(sk, field) \
-	do { \
-		if ((sk)->sk_family == AF_INET) \
-			UDP_INC_STATS_BH(field, 0); \
-		else \
-			UDP6_INC_STATS_BH(field, 0); \
-	} while (0);
-#else
-#define UDPX_INC_STATS_BH(sk, field) UDP_INC_STATS_BH(field, 0)
-#endif
-
-#else
 
 static inline void UDPX_INC_STATS_BH(struct sock *sk, int field)
 { }
 
 #endif
-#endif
diff --git a/kernel_patches/backport/2.6.22/rnfs_fs.patch b/kernel_patches/backport/2.6.22/rnfs_fs.patch
index eb565a2..6b86cae 100644
--- a/kernel_patches/backport/2.6.22/rnfs_fs.patch
+++ b/kernel_patches/backport/2.6.22/rnfs_fs.patch
@@ -876,18 +876,103 @@ index c53e65f..fc2871b 100644
  }
  
 diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
-index 18060be..4ab0f1e 100644
+index 18060be..36c4d71 100644
 --- a/fs/nfsd/vfs.c
 +++ b/fs/nfsd/vfs.c
-@@ -843,7 +843,7 @@ nfsd_splice_actor(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
- 	size_t size;
- 	int ret;
+@@ -23,7 +23,6 @@
+ #include <linux/file.h>
+ #include <linux/mount.h>
+ #include <linux/major.h>
+-#include <linux/splice.h>
+ #include <linux/proc_fs.h>
+ #include <linux/stat.h>
+ #include <linux/fcntl.h>
+@@ -828,53 +827,33 @@ found:
+ 	return ra;
+ }
+ 
+-/*
+- * Grab and keep cached pages associated with a file in the svc_rqst
+- * so that they can be passed to the network sendmsg/sendpage routines
+- * 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;
++	unsigned long count = desc->count;
++	struct svc_rqst *rqstp = desc->arg.data;
  
 -	ret = buf->ops->confirm(pipe, buf);
-+	ret = buf->ops->pin(pipe, buf);
- 	if (unlikely(ret))
- 		return ret;
+-	if (unlikely(ret))
+-		return ret;
+-
+-	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
++	} else {
+ 		rqstp->rq_res.page_len += size;
++	}
+ 
++	desc->count = count - size;
++	desc->written += size;
+ 	return 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);
+-}
+-
+ static inline int svc_msnfs(struct svc_fh *ffhp)
+ {
+ #ifdef MSNFS
+@@ -906,16 +885,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);
 diff --git a/include/linux/exportfs.h b/include/linux/exportfs.h
 index 27e772c..d932fb1 100644
 --- a/include/linux/exportfs.h
@@ -992,13 +1077,22 @@ index 78a5922..3370498 100644
  extern int nfs_release(struct inode *, struct file *);
  extern int nfs_attribute_timeout(struct inode *inode);
 diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h
-index 8e41202..cdc1498 100644
+deleted file mode 100644
+index 8e41202..0000000
 --- a/include/linux/pipe_fs_i.h
-+++ b/include/linux/pipe_fs_i.h
-@@ -9,39 +9,13 @@
- #define PIPE_BUF_FLAG_ATOMIC	0x02	/* was atomically mapped */
- #define PIPE_BUF_FLAG_GIFT	0x04	/* page is a gift */
- 
++++ /dev/null
+@@ -1,151 +0,0 @@
+-#ifndef _LINUX_PIPE_FS_I_H
+-#define _LINUX_PIPE_FS_I_H
+-
+-#define PIPEFS_MAGIC 0x50495045
+-
+-#define PIPE_BUFFERS (16)
+-
+-#define PIPE_BUF_FLAG_LRU	0x01	/* page is on the LRU */
+-#define PIPE_BUF_FLAG_ATOMIC	0x02	/* was atomically mapped */
+-#define PIPE_BUF_FLAG_GIFT	0x04	/* page is a gift */
+-
 -/**
 - *	struct pipe_buffer - a linux kernel pipe buffer
 - *	@page: the page containing the data for the pipe buffer
@@ -1008,14 +1102,14 @@ index 8e41202..cdc1498 100644
 - *	@flags: pipe buffer flags. See above.
 - *	@private: private data owned by the ops.
 - **/
- struct pipe_buffer {
- 	struct page *page;
- 	unsigned int offset, len;
- 	const struct pipe_buf_operations *ops;
- 	unsigned int flags;
+-struct pipe_buffer {
+-	struct page *page;
+-	unsigned int offset, len;
+-	const struct pipe_buf_operations *ops;
+-	unsigned int flags;
 -	unsigned long private;
- };
- 
+-};
+-
 -/**
 - *	struct pipe_inode_info - a linux kernel pipe
 - *	@wait: reader/writer wait point in case of empty/full pipe
@@ -1032,34 +1126,43 @@ index 8e41202..cdc1498 100644
 - *	@inode: inode this pipe is attached to
 - *	@bufs: the circular array of pipe buffers
 - **/
- struct pipe_inode_info {
- 	wait_queue_head_t wait;
- 	unsigned int nrbufs, curbuf;
-@@ -60,73 +34,22 @@ struct pipe_inode_info {
- /*
-  * Note on the nesting of these functions:
-  *
+-struct pipe_inode_info {
+-	wait_queue_head_t wait;
+-	unsigned int nrbufs, curbuf;
+-	struct page *tmp_page;
+-	unsigned int readers;
+-	unsigned int writers;
+-	unsigned int waiting_writers;
+-	unsigned int r_counter;
+-	unsigned int w_counter;
+-	struct fasync_struct *fasync_readers;
+-	struct fasync_struct *fasync_writers;
+-	struct inode *inode;
+-	struct pipe_buffer bufs[PIPE_BUFFERS];
+-};
+-
+-/*
+- * Note on the nesting of these functions:
+- *
 - * ->confirm()
-+ * ->pin()
-  *	->steal()
-  *	...
-  *	->map()
-  *	...
-  *	->unmap()
-  *
+- *	->steal()
+- *	...
+- *	->map()
+- *	...
+- *	->unmap()
+- *
 - * That is, ->map() must be called on a confirmed buffer,
 - * same goes for ->steal(). See below for the meaning of each
 - * operation. Also see kerneldoc in fs/pipe.c for the pipe
 - * and generic variants of these hooks.
-+ * That is, ->map() must be called on a pinned buffer, same goes for ->steal().
-  */
- struct pipe_buf_operations {
+- */
+-struct pipe_buf_operations {
 -	/*
 -	 * This is set to 1, if the generic pipe read/write may coalesce
 -	 * data into an existing buffer. If this is set to 0, a new pipe
 -	 * page segment is always used for new data.
 -	 */
- 	int can_merge;
+-	int can_merge;
 -
 -	/*
 -	 * ->map() returns a virtual address mapping of the pipe buffer.
@@ -1073,12 +1176,12 @@ index 8e41202..cdc1498 100644
 -	 * or destination for a copy (IOW, it has to use something else
 -	 * than KM_USER0).
 -	 */
- 	void * (*map)(struct pipe_inode_info *, struct pipe_buffer *, int);
+-	void * (*map)(struct pipe_inode_info *, struct pipe_buffer *, int);
 -
 -	/*
 -	 * Undoes ->map(), finishes the virtual mapping of the pipe buffer.
 -	 */
- 	void (*unmap)(struct pipe_inode_info *, struct pipe_buffer *, void *);
+-	void (*unmap)(struct pipe_inode_info *, struct pipe_buffer *, void *);
 -
 -	/*
 -	 * ->confirm() verifies that the data in the pipe buffer is there
@@ -1093,8 +1196,7 @@ index 8e41202..cdc1498 100644
 -	 * When the contents of this pipe buffer has been completely
 -	 * consumed by a reader, ->release() is called.
 -	 */
-+	int (*pin)(struct pipe_inode_info *, struct pipe_buffer *);
- 	void (*release)(struct pipe_inode_info *, struct pipe_buffer *);
+-	void (*release)(struct pipe_inode_info *, struct pipe_buffer *);
 -
 -	/*
 -	 * Attempt to take ownership of the pipe buffer and its contents.
@@ -1104,60 +1206,126 @@ index 8e41202..cdc1498 100644
 -	 * mapping, the most often used case is insertion into different
 -	 * file address space cache.
 -	 */
- 	int (*steal)(struct pipe_inode_info *, struct pipe_buffer *);
+-	int (*steal)(struct pipe_inode_info *, struct pipe_buffer *);
 -
 -	/*
 -	 * Get a reference to the pipe buffer.
 -	 */
- 	void (*get)(struct pipe_inode_info *, struct pipe_buffer *);
- };
- 
-@@ -145,7 +68,44 @@ void __free_pipe_info(struct pipe_inode_info *);
- void *generic_pipe_buf_map(struct pipe_inode_info *, struct pipe_buffer *, int);
- void generic_pipe_buf_unmap(struct pipe_inode_info *, struct pipe_buffer *, void *);
- void generic_pipe_buf_get(struct pipe_inode_info *, struct pipe_buffer *);
+-	void (*get)(struct pipe_inode_info *, struct pipe_buffer *);
+-};
+-
+-/* Differs from PIPE_BUF in that PIPE_SIZE is the length of the actual
+-   memory allocation, whereas PIPE_BUF makes atomicity guarantees.  */
+-#define PIPE_SIZE		PAGE_SIZE
+-
+-/* Drop the inode semaphore and wait for a pipe event, atomically */
+-void pipe_wait(struct pipe_inode_info *pipe);
+-
+-struct pipe_inode_info * alloc_pipe_info(struct inode * inode);
+-void free_pipe_info(struct inode * inode);
+-void __free_pipe_info(struct pipe_inode_info *);
+-
+-/* Generic pipe buffer ops functions */
+-void *generic_pipe_buf_map(struct pipe_inode_info *, struct pipe_buffer *, int);
+-void generic_pipe_buf_unmap(struct pipe_inode_info *, struct pipe_buffer *, void *);
+-void generic_pipe_buf_get(struct pipe_inode_info *, struct pipe_buffer *);
 -int generic_pipe_buf_confirm(struct pipe_inode_info *, struct pipe_buffer *);
-+int generic_pipe_buf_pin(struct pipe_inode_info *, struct pipe_buffer *);
- int generic_pipe_buf_steal(struct pipe_inode_info *, struct pipe_buffer *);
- 
-+/*
-+ * splice is tied to pipes as a transport (at least for now), so we'll just
-+ * add the splice flags here.
-+ */
-+#define SPLICE_F_MOVE	(0x01)	/* move pages instead of copying */
-+#define SPLICE_F_NONBLOCK (0x02) /* don't block on the pipe splicing (but */
-+				 /* we may still block on the fd we splice */
-+				 /* from/to, of course */
-+#define SPLICE_F_MORE	(0x04)	/* expect more data */
-+#define SPLICE_F_GIFT	(0x08)	/* pages passed in are a gift */
-+
-+/*
-+ * Passed to the actors
-+ */
-+struct splice_desc {
-+	unsigned int len, total_len;	/* current and remaining length */
-+	unsigned int flags;		/* splice flags */
-+	/*
-+	 * actor() private data
-+	 */
-+	union {
-+		void __user *userptr;	/* memory to write to */
-+		struct file *file;	/* file to read/write */
-+		void *data;		/* cookie */
-+	} u;
-+	loff_t pos;			/* file position */
-+};
-+typedef int (splice_actor)(struct pipe_inode_info *, struct pipe_buffer *,
-+			   struct splice_desc *);
-+
-+extern ssize_t splice_from_pipe(struct pipe_inode_info *, struct file *,
-+				loff_t *, size_t, unsigned int,
-+				splice_actor *);
-+
-+extern ssize_t __splice_from_pipe(struct pipe_inode_info *, struct file *,
-+				  loff_t *, size_t, unsigned int,
-+				  splice_actor *);
- #endif
+-int generic_pipe_buf_steal(struct pipe_inode_info *, struct pipe_buffer *);
+-
+-#endif
+diff --git a/include/linux/splice.h b/include/linux/splice.h
+deleted file mode 100644
+index 528dcb9..0000000
+--- a/include/linux/splice.h
++++ /dev/null
+@@ -1,74 +0,0 @@
+-/*
+- * Function declerations and data structures related to the splice
+- * implementation.
+- *
+- * Copyright (C) 2007 Jens Axboe <[email protected]>
+- *
+- */
+-#ifndef SPLICE_H
+-#define SPLICE_H
+-
+-#include <linux/pipe_fs_i.h>
+-
+-/*
+- * splice is tied to pipes as a transport (at least for now), so we'll just
+- * add the splice flags here.
+- */
+-#define SPLICE_F_MOVE	(0x01)	/* move pages instead of copying */
+-#define SPLICE_F_NONBLOCK (0x02) /* don't block on the pipe splicing (but */
+-				 /* we may still block on the fd we splice */
+-				 /* from/to, of course */
+-#define SPLICE_F_MORE	(0x04)	/* expect more data */
+-#define SPLICE_F_GIFT	(0x08)	/* pages passed in are a gift */
+-
+-/*
+- * Passed to the actors
+- */
+-struct splice_desc {
+-	unsigned int len, total_len;	/* current and remaining length */
+-	unsigned int flags;		/* splice flags */
+-	/*
+-	 * actor() private data
+-	 */
+-	union {
+-		void __user *userptr;	/* memory to write to */
+-		struct file *file;	/* file to read/write */
+-		void *data;		/* cookie */
+-	} u;
+-	loff_t pos;			/* file position */
+-};
+-
+-struct partial_page {
+-	unsigned int offset;
+-	unsigned int len;
+-	unsigned long private;
+-};
+-
+-/*
+- * Passed to splice_to_pipe
+- */
+-struct splice_pipe_desc {
+-	struct page **pages;		/* page map */
+-	struct partial_page *partial;	/* pages[] may not be contig */
+-	int nr_pages;			/* number of pages in map */
+-	unsigned int flags;		/* splice flags */
+-	const struct pipe_buf_operations *ops;/* ops associated with output pipe */
+-	void (*spd_release)(struct splice_pipe_desc *, unsigned int);
+-};
+-
+-typedef int (splice_actor)(struct pipe_inode_info *, struct pipe_buffer *,
+-			   struct splice_desc *);
+-typedef int (splice_direct_actor)(struct pipe_inode_info *,
+-				  struct splice_desc *);
+-
+-extern ssize_t splice_from_pipe(struct pipe_inode_info *, struct file *,
+-				loff_t *, size_t, unsigned int,
+-				splice_actor *);
+-extern ssize_t __splice_from_pipe(struct pipe_inode_info *,
+-				  struct splice_desc *, splice_actor *);
+-extern ssize_t splice_to_pipe(struct pipe_inode_info *,
+-			      struct splice_pipe_desc *);
+-extern ssize_t splice_direct_to_actor(struct file *, struct splice_desc *,
+-				      splice_direct_actor *);
+-
+-#endif
+diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h
+index dc69068..3a0f48f 100644
+--- a/include/linux/sunrpc/svc.h
++++ b/include/linux/sunrpc/svc.h
+@@ -255,7 +255,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/net/sunrpc/auth.c b/net/sunrpc/auth.c
 index 6bfea9e..f0a110d 100644
 --- a/net/sunrpc/auth.c
@@ -1185,6 +1353,19 @@ index 6bfea9e..f0a110d 100644
 -	unregister_shrinker(&rpc_cred_shrinker);
 +	remove_shrinker(rpc_cred_shrinker);
  }
+diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c
+index 81ae3d6..acfb1d1 100644
+--- a/net/sunrpc/auth_gss/svcauth_gss.c
++++ b/net/sunrpc/auth_gss/svcauth_gss.c
+@@ -859,7 +859,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/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
 index 23a2b8f..cc07d23 100644
 --- a/net/sunrpc/rpc_pipe.c
@@ -1248,7 +1429,7 @@ index 50b049c..5053a5f 100644
  }
  
 diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
-index 5a32cb7..3fba57a 100644
+index 5a32cb7..61a5616 100644
 --- a/net/sunrpc/svc.c
 +++ b/net/sunrpc/svc.c
 @@ -310,13 +310,12 @@ svc_pool_map_set_cpumask(struct task_struct *task, unsigned int pidx)
@@ -1267,3 +1448,12 @@ index 5a32cb7..3fba57a 100644
  		break;
  	}
  	}
+@@ -831,7 +830,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;
+ 
+ 	/* Setup reply header */
+ 	rqstp->rq_xprt->xpt_ops->xpo_prep_reply_hdr(rqstp);
_______________________________________________
ewg mailing list
[email protected]
http://lists.openfabrics.org/cgi-bin/mailman/listinfo/ewg

Reply via email to