summaryrefslogtreecommitdiffstats
path: root/net/sunrpc/svcsock.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1999-01-04 16:03:48 +0000
committerRalf Baechle <ralf@linux-mips.org>1999-01-04 16:03:48 +0000
commit78c388aed2b7184182c08428db1de6c872d815f5 (patch)
tree4b2003b1b4ceb241a17faa995da8dd1004bb8e45 /net/sunrpc/svcsock.c
parenteb7a5bf93aaa4be1d7c6181100ab7639e74d67f7 (diff)
Merge with Linux 2.1.131 and more MIPS goodies.
(Did I mention that CVS is buggy ...)
Diffstat (limited to 'net/sunrpc/svcsock.c')
-rw-r--r--net/sunrpc/svcsock.c78
1 files changed, 50 insertions, 28 deletions
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index e97d339b3..4e0acee23 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -76,43 +76,52 @@ svc_serv_dequeue(struct svc_serv *serv, struct svc_rqst *rqstp)
static inline void
svc_release_skb(struct svc_rqst *rqstp)
{
- if (!rqstp->rq_skbuff)
- return;
+ struct sk_buff *skb = rqstp->rq_skbuff;
- dprintk("svc: releasing skb %p\n", rqstp->rq_skbuff);
- skb_free_datagram(rqstp->rq_sock->sk_sk, rqstp->rq_skbuff);
+ if (!skb)
+ return;
rqstp->rq_skbuff = NULL;
+
+ dprintk("svc: service %p, releasing skb %p\n", rqstp, skb);
+ skb_free_datagram(rqstp->rq_sock->sk_sk, skb);
}
/*
* Queue up a socket with data pending. If there are idle nfsd
- * processes, wake'em up.
+ * processes, wake 'em up.
* When calling this function, you should make sure it can't be interrupted
* by the network bottom half.
*/
-static inline void
+static void
svc_sock_enqueue(struct svc_sock *svsk)
{
+ struct svc_serv *serv = svsk->sk_server;
struct svc_rqst *rqstp;
- struct svc_serv *serv;
+
+ if (serv->sv_threads && serv->sv_sockets)
+ printk(KERN_ERR
+ "svc_sock_enqueue: threads and sockets both waiting??\n");
if (svsk->sk_busy) {
/* Don't enqueue socket while daemon is receiving */
- dprintk("svc: socket %p not enqueued: busy\n", svsk->sk_sk);
+ dprintk("svc: socket %p busy, not enqueued\n", svsk->sk_sk);
return;
}
/* Mark socket as busy. It will remain in this state until the
* server has processed all pending data and put the socket back
- * on the idle list
+ * on the idle list.
*/
svsk->sk_busy = 1;
- serv = svsk->sk_server;
if ((rqstp = serv->sv_threads) != NULL) {
dprintk("svc: socket %p served by daemon %p\n",
- svsk->sk_sk, rqstp);
+ svsk->sk_sk, rqstp);
svc_serv_dequeue(serv, rqstp);
+ if (rqstp->rq_sock)
+ printk(KERN_ERR
+ "svc_sock_enqueue: server %p, rq_sock=%p!\n",
+ rqstp, rqstp->rq_sock);
rqstp->rq_sock = svsk;
svsk->sk_inuse++;
wake_up(&rqstp->rq_wait);
@@ -137,7 +146,8 @@ svc_sock_dequeue(struct svc_serv *serv)
end_bh_atomic();
if (svsk) {
- dprintk("svc: socket %p dequeued\n", svsk->sk_sk);
+ dprintk("svc: socket %p dequeued, inuse=%d\n",
+ svsk->sk_sk, svsk->sk_inuse);
svsk->sk_qued = 0;
}
@@ -325,13 +335,12 @@ svc_recvfrom(struct svc_rqst *rqstp, struct iovec *iov, int nr, int buflen)
static void
svc_udp_data_ready(struct sock *sk, int count)
{
- struct svc_sock *svsk;
+ struct svc_sock *svsk = (struct svc_sock *)(sk->user_data);
- dprintk("svc: socket %p data ready (inet %p)\n", sk->user_data, sk);
-
- svsk = (struct svc_sock *)(sk->user_data);
if (!svsk)
return;
+ dprintk("svc: socket %p(inet %p), count=%d, busy=%d\n",
+ svsk, sk, count, svsk->sk_busy);
svsk->sk_data = 1;
svc_sock_enqueue(svsk);
}
@@ -677,7 +686,7 @@ error:
/*
* Send out data on TCP socket.
* FIXME: Make the sendto call non-blocking in order not to hang
- * a daemon on a a dead client. Requires write queue maintenance.
+ * a daemon on a dead client. Requires write queue maintenance.
*/
static int
svc_tcp_sendto(struct svc_rqst *rqstp)
@@ -722,14 +731,23 @@ svc_tcp_init(struct svc_sock *svsk)
* Receive the next request on any socket.
*/
int
-svc_recv(struct svc_serv *serv, struct svc_rqst *rqstp)
+svc_recv(struct svc_serv *serv, struct svc_rqst *rqstp, long timeout)
{
- struct wait_queue wait = { current, NULL };
struct svc_sock *svsk;
int len;
+ struct wait_queue wait = { current, NULL };
dprintk("svc: server %p waiting for data (to = %ld)\n",
- rqstp, current->timeout);
+ rqstp, timeout);
+
+ if (rqstp->rq_sock)
+ printk(KERN_ERR
+ "svc_recv: service %p, socket not NULL!\n",
+ rqstp);
+ if (waitqueue_active(&rqstp->rq_wait))
+ printk(KERN_ERR
+ "svc_recv: service %p, wait queue active!\n",
+ rqstp);
again:
/* Initialize the buffers */
@@ -741,13 +759,10 @@ again:
start_bh_atomic();
if ((svsk = svc_sock_dequeue(serv)) != NULL) {
- end_bh_atomic();
rqstp->rq_sock = svsk;
- svsk->sk_inuse++; /* N.B. where is this decremented? */
+ svsk->sk_inuse++;
} else {
/* No data pending. Go to sleep */
- rqstp->rq_sock = NULL;
- rqstp->rq_wait = NULL;
svc_serv_enqueue(serv, rqstp);
/*
@@ -757,17 +772,24 @@ again:
current->state = TASK_INTERRUPTIBLE;
add_wait_queue(&rqstp->rq_wait, &wait);
end_bh_atomic();
- schedule();
+ schedule_timeout(timeout);
+ remove_wait_queue(&rqstp->rq_wait, &wait);
+
+ start_bh_atomic();
if (!(svsk = rqstp->rq_sock)) {
svc_serv_dequeue(serv, rqstp);
- if (!(svsk = rqstp->rq_sock))
- return signalled()? -EINTR : -EAGAIN;
+ end_bh_atomic();
+ dprintk("svc: server %p, no data yet\n", rqstp);
+ return signalled()? -EINTR : -EAGAIN;
}
}
+ end_bh_atomic();
- dprintk("svc: server %p servicing socket %p\n", rqstp, svsk);
+ dprintk("svc: server %p, socket %p, inuse=%d\n",
+ rqstp, svsk, svsk->sk_inuse);
len = svsk->sk_recvfrom(rqstp);
+ dprintk("svc: got len=%d\n", len);
/* No data, incomplete (TCP) read, or accept() */
if (len == 0 || len == -EAGAIN) {