diff -u --recursive --new-file linux-2.4.17-svc_tcp/include/linux/nfsd/const.h linux-2.4.17-rpc_tweak/include/linux/nfsd/const.h
--- linux-2.4.17-svc_tcp/include/linux/nfsd/const.h	Sat Apr  1 18:04:27 2000
+++ linux-2.4.17-rpc_tweak/include/linux/nfsd/const.h	Wed Jan  2 17:17:37 2002
@@ -21,7 +21,7 @@
 /*
  * Maximum blocksize supported by daemon currently at 8K
  */
-#define NFSSVC_MAXBLKSIZE	8192
+#define NFSSVC_MAXBLKSIZE	(32*1024)
 
 #ifdef __KERNEL__
 
diff -u --recursive --new-file linux-2.4.17-svc_tcp/net/sunrpc/clnt.c linux-2.4.17-rpc_tweak/net/sunrpc/clnt.c
--- linux-2.4.17-svc_tcp/net/sunrpc/clnt.c	Sat Dec 22 18:57:48 2001
+++ linux-2.4.17-rpc_tweak/net/sunrpc/clnt.c	Thu Jan  3 02:39:22 2002
@@ -375,7 +375,6 @@
 	task->tk_status  = 0;
 	task->tk_action  = call_reserveresult;
 	task->tk_timeout = clnt->cl_timeout.to_resrvval;
-	clnt->cl_stats->rpccnt++;
 	xprt_reserve(task);
 }
 
@@ -399,6 +398,7 @@
 		 task->tk_status, task->tk_rqstp);
 
 	if (task->tk_status >= 0) {
+		task->tk_client->cl_stats->rpccnt++;
 		task->tk_action = call_allocate;
 		return;
 	}
@@ -448,8 +448,7 @@
 	printk(KERN_INFO "RPC: buffer allocation failed for task %p\n", task); 
 
 	if (RPC_IS_ASYNC(task) || !(task->tk_client->cl_intr && signalled())) {
-		xprt_release(task);
-		task->tk_action = call_reserve;
+		task->tk_action = call_allocate;
 		rpc_delay(task, HZ>>4);
 		return;
 	}
diff -u --recursive --new-file linux-2.4.17-svc_tcp/net/sunrpc/svcsock.c linux-2.4.17-rpc_tweak/net/sunrpc/svcsock.c
--- linux-2.4.17-svc_tcp/net/sunrpc/svcsock.c	Wed Jan  2 17:42:56 2002
+++ linux-2.4.17-rpc_tweak/net/sunrpc/svcsock.c	Wed Jan  2 17:42:32 2002
@@ -426,7 +426,7 @@
 	struct svc_serv	*serv = svsk->sk_server;
 	struct sk_buff	*skb;
 	u32		*data;
-	int		err, len;
+	int		err, len = 0;
 
 	svsk->sk_data = 0;
 	while ((skb = skb_recv_datagram(svsk->sk_sk, 0, 1, &err)) == NULL) {
@@ -439,28 +439,25 @@
 
 	/* Sorry. */
 	if (skb_is_nonlinear(skb)) {
-		if (skb_linearize(skb, GFP_KERNEL) != 0) {
-			kfree_skb(skb);
-			svc_sock_received(svsk, 0);
-			return 0;
-		}
+		if (skb_linearize(skb, GFP_KERNEL) != 0)
+			goto out;
 	}
 
 	if (skb->ip_summed != CHECKSUM_UNNECESSARY) {
-		if ((unsigned short)csum_fold(skb_checksum(skb, 0, skb->len, skb->csum))) {
-			skb_free_datagram(svsk->sk_sk, skb);
-			svc_sock_received(svsk, 0);
-			return 0;
-		}
+		if ((unsigned short)csum_fold(skb_checksum(skb, 0, skb->len, skb->csum)))
+			goto out;
 	}
 
+	dst_confirm(skb->dst);
+
+	if (!(rqstp->rq_skbuff = skb_clone(skb, GFP_KERNEL)))
+		goto out;
 	/* There may be more data */
 	svsk->sk_data = 1;
 
 	len  = skb->len - sizeof(struct udphdr);
 	data = (u32 *) (skb->data + sizeof(struct udphdr));
 
-	rqstp->rq_skbuff      = skb;
 	rqstp->rq_argbuf.base = data;
 	rqstp->rq_argbuf.buf  = data;
 	rqstp->rq_argbuf.len  = (len >> 2);
@@ -480,6 +477,8 @@
 
 	/* One down, maybe more to go... */
 	svsk->sk_sk->stamp = skb->stamp;
+out:
+	skb_free_datagram(svsk->sk_sk, skb);
 	svc_sock_received(svsk, 0);
 
 	return len;
diff -u --recursive --new-file linux-2.4.17-svc_tcp/net/sunrpc/xprt.c linux-2.4.17-rpc_tweak/net/sunrpc/xprt.c
--- linux-2.4.17-svc_tcp/net/sunrpc/xprt.c	Sat Dec 22 18:57:48 2001
+++ linux-2.4.17-rpc_tweak/net/sunrpc/xprt.c	Thu Jan  3 13:14:23 2002
@@ -68,6 +68,8 @@
 
 /* Following value should be > 32k + RPC overhead */
 #define XPRT_MIN_WRITE_SPACE (35000 + SOCK_MIN_WRITE_SPACE)
+#define XPRT_TCP_DEFAULT_SOCKSIZE (64*1024)
+#define XPRT_UDP_DEFAULT_SOCKSIZE (128*1024)
 
 extern spinlock_t rpc_queue_lock;
 
@@ -1587,6 +1589,20 @@
 }
 
 /*
+ *  * Set socket buffer length
+ *   */
+static inline void
+svc_sock_setbufsize(struct socket *sock, unsigned int size)
+{
+	mm_segment_t	oldfs;
+
+	oldfs = get_fs(); set_fs(KERNEL_DS);
+	sock_setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (char *)&size, sizeof(size));
+	sock_setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char *)&size, sizeof(size));
+	set_fs(oldfs);
+}
+
+/*
  * Create a client socket given the protocol and peer address.
  */
 static struct socket *
@@ -1609,6 +1625,11 @@
 	if (capable(CAP_NET_BIND_SERVICE) && xprt_bindresvport(sock) < 0)
 		goto failed;
 
+	if (proto == IPPROTO_UDP)
+		svc_sock_setbufsize(sock, XPRT_UDP_DEFAULT_SOCKSIZE);
+	else
+		svc_sock_setbufsize(sock, XPRT_TCP_DEFAULT_SOCKSIZE);
+
 	return sock;
 
 failed: