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: