summaryrefslogtreecommitdiffstats
path: root/net/sunrpc
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1999-06-17 13:25:08 +0000
committerRalf Baechle <ralf@linux-mips.org>1999-06-17 13:25:08 +0000
commit59223edaa18759982db0a8aced0e77457d10c68e (patch)
tree89354903b01fa0a447bffeefe00df3044495db2e /net/sunrpc
parentdb7d4daea91e105e3859cf461d7e53b9b77454b2 (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.c3
-rw-r--r--net/sunrpc/auth_unix.c3
-rw-r--r--net/sunrpc/clnt.c2
-rw-r--r--net/sunrpc/sched.c11
-rw-r--r--net/sunrpc/svc.c2
-rw-r--r--net/sunrpc/svcsock.c2
-rw-r--r--net/sunrpc/xprt.c77
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;