diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1999-06-17 13:25:08 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1999-06-17 13:25:08 +0000 |
commit | 59223edaa18759982db0a8aced0e77457d10c68e (patch) | |
tree | 89354903b01fa0a447bffeefe00df3044495db2e /net/sunrpc | |
parent | db7d4daea91e105e3859cf461d7e53b9b77454b2 (diff) |
Merge with Linux 2.3.6. Sorry, this isn't tested on silicon, I don't
have a MIPS box at hand.
Diffstat (limited to 'net/sunrpc')
-rw-r--r-- | net/sunrpc/auth.c | 3 | ||||
-rw-r--r-- | net/sunrpc/auth_unix.c | 3 | ||||
-rw-r--r-- | net/sunrpc/clnt.c | 2 | ||||
-rw-r--r-- | net/sunrpc/sched.c | 11 | ||||
-rw-r--r-- | net/sunrpc/svc.c | 2 | ||||
-rw-r--r-- | net/sunrpc/svcsock.c | 2 | ||||
-rw-r--r-- | net/sunrpc/xprt.c | 77 |
7 files changed, 80 insertions, 20 deletions
diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c index 2b8db00cc..7c966779b 100644 --- a/net/sunrpc/auth.c +++ b/net/sunrpc/auth.c @@ -4,9 +4,12 @@ * Generic RPC authentication API. * * Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de> + * + * Modified May 1999, Horst von Brand <vonbrand@sleipnir.valparaiso.cl> */ #include <linux/types.h> +#include <linux/string.h> #include <linux/sched.h> #include <linux/malloc.h> #include <linux/errno.h> diff --git a/net/sunrpc/auth_unix.c b/net/sunrpc/auth_unix.c index 6912c229d..6596085b3 100644 --- a/net/sunrpc/auth_unix.c +++ b/net/sunrpc/auth_unix.c @@ -4,9 +4,12 @@ * UNIX-style authentication; no AUTH_SHORT support * * Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de> + * + * Modified May 1999 Horst von Brand <vonbrand@sleipnir.valparaiso.cl> */ #include <linux/types.h> +#include <linux/string.h> #include <linux/malloc.h> #include <linux/socket.h> #include <linux/in.h> diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index dc06be6b0..6ffcc187b 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c @@ -39,7 +39,7 @@ # define RPCDBG_FACILITY RPCDBG_CALL #endif -static struct wait_queue * destroy_wait = NULL; +static DECLARE_WAIT_QUEUE_HEAD(destroy_wait); static void call_bind(struct rpc_task *task); diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c index 222a3f9ec..b4e0b4b76 100644 --- a/net/sunrpc/sched.c +++ b/net/sunrpc/sched.c @@ -60,9 +60,9 @@ static struct rpc_task * all_tasks = NULL; /* * rpciod-related stuff */ -static struct wait_queue * rpciod_idle = NULL; -static struct wait_queue * rpciod_killer = NULL; -static struct semaphore rpciod_sema = MUTEX; +static DECLARE_WAIT_QUEUE_HEAD(rpciod_idle); +static DECLARE_WAIT_QUEUE_HEAD(rpciod_killer); +static DECLARE_MUTEX(rpciod_sema); static unsigned int rpciod_users = 0; static pid_t rpciod_pid = 0; static int rpc_inhibit = 0; @@ -616,6 +616,7 @@ rpc_init_task(struct rpc_task *task, struct rpc_clnt *clnt, task->tk_client = clnt; task->tk_flags = RPC_TASK_RUNNING | flags; task->tk_exit = callback; + init_waitqueue_head(&task->tk_wait); if (current->uid != current->fsuid || current->gid != current->fsgid) task->tk_flags |= RPC_TASK_SETUID; @@ -800,7 +801,7 @@ rpc_killall_tasks(struct rpc_clnt *clnt) rpc_inhibit--; } -static struct semaphore rpciod_running = MUTEX_LOCKED; +static DECLARE_MUTEX_LOCKED(rpciod_running); /* * This is the rpciod kernel thread @@ -808,7 +809,7 @@ static struct semaphore rpciod_running = MUTEX_LOCKED; static int rpciod(void *ptr) { - struct wait_queue **assassin = (struct wait_queue **) ptr; + wait_queue_head_t *assassin = (wait_queue_head_t*) ptr; unsigned long oldflags; int rounds = 0; diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c index 2353c2e27..d98adb31c 100644 --- a/net/sunrpc/svc.c +++ b/net/sunrpc/svc.c @@ -123,6 +123,8 @@ svc_create_thread(svc_thread_fn func, struct svc_serv *serv) goto out; memset(rqstp, 0, sizeof(*rqstp)); + init_waitqueue_head(&rqstp->rq_wait); + if (!(rqstp->rq_argp = (u32 *) kmalloc(serv->sv_xdrsize, GFP_KERNEL)) || !(rqstp->rq_resp = (u32 *) kmalloc(serv->sv_xdrsize, GFP_KERNEL)) || !svc_init_buffer(&rqstp->rq_defbuf, serv->sv_bufsz)) diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index d2248ad74..0fb992f47 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c @@ -738,7 +738,7 @@ svc_recv(struct svc_serv *serv, struct svc_rqst *rqstp, long timeout) { struct svc_sock *svsk; int len; - struct wait_queue wait = { current, NULL }; + DECLARE_WAITQUEUE(wait, current); dprintk("svc: server %p waiting for data (to = %ld)\n", rqstp, timeout); diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index 1e5ad01c3..aa1bfa8f5 100644 --- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c @@ -42,6 +42,7 @@ #define __KERNEL_SYSCALLS__ #include <linux/version.h> +#include <linux/config.h> #include <linux/types.h> #include <linux/malloc.h> #include <linux/sched.h> @@ -56,6 +57,8 @@ #include <linux/file.h> #include <net/sock.h> +#include <net/checksum.h> +#include <net/udp.h> #include <asm/uaccess.h> @@ -356,6 +359,7 @@ xprt_close(struct rpc_xprt *xprt) sk->user_data = NULL; #endif sk->data_ready = xprt->old_data_ready; + sk->no_check = 0; sk->state_change = xprt->old_state_change; sk->write_space = xprt->old_write_space; @@ -563,18 +567,61 @@ xprt_complete_rqst(struct rpc_xprt *xprt, struct rpc_rqst *req, int copied) return; } -/* - * Input handler for RPC replies. Called from a bottom half and hence +/* We have set things up such that we perform the checksum of the UDP + * packet in parallel with the copies into the RPC client iovec. -DaveM + */ +static int csum_partial_copy_to_page_cache(struct iovec *iov, + struct sk_buff *skb, + int copied) +{ + __u8 *pkt_data = skb->data + sizeof(struct udphdr); + __u8 *cur_ptr = iov->iov_base; + __kernel_size_t cur_len = iov->iov_len; + unsigned int csum = skb->csum; + int need_csum = (skb->ip_summed != CHECKSUM_UNNECESSARY); + int slack = skb->len - copied - sizeof(struct udphdr); + + if (need_csum) + csum = csum_partial(skb->h.raw, sizeof(struct udphdr), csum); + while (copied > 0) { + if (cur_len) { + int to_move = cur_len; + if (to_move > copied) + to_move = copied; + if (need_csum) + csum = csum_partial_copy_nocheck(pkt_data, cur_ptr, + to_move, csum); + else + memcpy(cur_ptr, pkt_data, to_move); + pkt_data += to_move; + copied -= to_move; + cur_ptr += to_move; + cur_len -= to_move; + } + if (cur_len <= 0) { + iov++; + cur_len = iov->iov_len; + cur_ptr = iov->iov_base; + } + } + if (need_csum) { + if (slack > 0) + csum = csum_partial(pkt_data, slack, csum); + if ((unsigned short)csum_fold(csum)) + return -1; + } + return 0; +} + +/* Input handler for RPC replies. Called from a bottom half and hence * atomic. */ static inline void udp_data_ready(struct sock *sk, int len) { - struct rpc_task *task; struct rpc_xprt *xprt; struct rpc_rqst *rovr; struct sk_buff *skb; - struct iovec iov[MAX_IOVEC]; int err, repsize, copied; dprintk("RPC: udp_data_ready...\n"); @@ -584,28 +631,31 @@ udp_data_ready(struct sock *sk, int len) if ((skb = skb_recv_datagram(sk, 0, 1, &err)) == NULL) return; - repsize = skb->len - 8; /* don't account for UDP header */ + repsize = skb->len - sizeof(struct udphdr); if (repsize < 4) { printk("RPC: impossible RPC reply size %d!\n", repsize); goto dropit; } /* Look up the request corresponding to the given XID */ - if (!(rovr = xprt_lookup_rqst(xprt, *(u32 *) (skb->h.raw + 8)))) + if (!(rovr = xprt_lookup_rqst(xprt, + *(u32 *) (skb->h.raw + sizeof(struct udphdr))))) goto dropit; - task = rovr->rq_task; - dprintk("RPC: %4d received reply\n", task->tk_pid); - xprt_pktdump("packet data:", (u32 *) (skb->h.raw+8), repsize); + dprintk("RPC: %4d received reply\n", rovr->rq_task->tk_pid); + xprt_pktdump("packet data:", + (u32 *) (skb->h.raw + sizeof(struct udphdr)), repsize); if ((copied = rovr->rq_rlen) > repsize) copied = repsize; - /* Okay, we have it. Copy datagram... */ - memcpy(iov, rovr->rq_rvec, rovr->rq_rnr * sizeof(iov[0])); - /* This needs to stay tied with the usermode skb_copy_dagram... */ - memcpy_tokerneliovec(iov, skb->data+8, copied); + /* Suck it into the iovec, verify checksum if not done by hw. */ + if (csum_partial_copy_to_page_cache(rovr->rq_rvec, skb, copied)) + goto dropit; + + /* Something worked... */ + dst_confirm(skb->dst); xprt_complete_rqst(xprt, rovr, copied); @@ -1341,6 +1391,7 @@ xprt_setup(struct socket *sock, int proto, xprt->old_write_space = inet->write_space; if (proto == IPPROTO_UDP) { inet->data_ready = udp_data_ready; + inet->no_check = UDP_CSUM_NORCV; } else { inet->data_ready = tcp_data_ready; inet->state_change = tcp_state_change; |