patch-2.4.0-test3 linux/net/sunrpc/svcsock.c

Next file: linux/net/sunrpc/xprt.c
Previous file: linux/net/sunrpc/sched.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.0-test2/linux/net/sunrpc/svcsock.c linux/net/sunrpc/svcsock.c
@@ -32,6 +32,7 @@
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <net/sock.h>
+#include <net/checksum.h>
 #include <net/ip.h>
 #include <asm/uaccess.h>
 
@@ -249,7 +250,8 @@
 svc_sendto(struct svc_rqst *rqstp, struct iovec *iov, int nr)
 {
 	mm_segment_t	oldfs;
-	struct socket	*sock = rqstp->rq_sock->sk_sock;
+	struct svc_sock	*svsk = rqstp->rq_sock;
+	struct socket	*sock = svsk->sk_sock;
 	struct msghdr	msg;
 	int		i, buflen, len;
 
@@ -341,13 +343,16 @@
 	struct svc_sock	*svsk = (struct svc_sock *)(sk->user_data);
 
 	if (!svsk)
-		return;
+		goto out;
 	dprintk("svc: socket %p(inet %p), count=%d, busy=%d\n",
 		svsk, sk, count, svsk->sk_busy);
 	spin_lock_bh(&svsk->sk_lock);
 	svsk->sk_data = 1;
 	svc_sock_enqueue(svsk);
 	spin_unlock_bh(&svsk->sk_lock);
+ out:
+	if (sk->sleep && waitqueue_active(sk->sleep))
+		wake_up_interruptible(sk->sleep);
 }
 
 /*
@@ -371,6 +376,16 @@
 		dprintk("svc: recvfrom returned error %d\n", -err);
 	}
 
+	if (skb->ip_summed != CHECKSUM_UNNECESSARY) {
+		unsigned int csum = skb->csum;
+		csum = csum_partial(skb->h.raw, skb->len, csum);
+		if ((unsigned short)csum_fold(csum)) {
+			skb_free_datagram(svsk->sk_sk, skb);
+			svc_sock_received(svsk, 0);
+			return 0;
+		}
+	}
+
 	/* There may be more data */
 	svsk->sk_data = 1;
 
@@ -448,16 +463,19 @@
 
 	if  (sk->state != TCP_ESTABLISHED) {
 		/* Aborted connection, SYN_RECV or whatever... */
-		return;
+		goto out;
 	}
 	if (!(svsk = (struct svc_sock *) sk->user_data)) {
 		printk("svc: socket %p: no user data\n", sk);
-		return;
+		goto out;
 	}
 	spin_lock_bh(&svsk->sk_lock);
 	svsk->sk_conn++;
 	svc_sock_enqueue(svsk);
 	spin_unlock_bh(&svsk->sk_lock);
+ out:
+	if (sk->sleep && waitqueue_active(sk->sleep))
+		wake_up_interruptible_all(sk->sleep);
 }
 
 /*
@@ -473,12 +491,15 @@
 
 	if (!(svsk = (struct svc_sock *) sk->user_data)) {
 		printk("svc: socket %p: no user data\n", sk);
-		return;
+		goto out;
 	}
 	spin_lock_bh(&svsk->sk_lock);
 	svsk->sk_close = 1;
 	svc_sock_enqueue(svsk);
 	spin_unlock_bh(&svsk->sk_lock);
+ out:
+	if (sk->sleep && waitqueue_active(sk->sleep))
+		wake_up_interruptible_all(sk->sleep);
 }
 
 static void
@@ -486,20 +507,17 @@
 {
 	struct svc_sock *	svsk;
 
-	/* Disconnect signalled through data_ready?!? */
-	if (sk->state != TCP_ESTABLISHED) {
-		svc_tcp_state_change2(sk);
-		return;
-	}
-
 	dprintk("svc: socket %p TCP data ready (svsk %p)\n",
 			sk, sk->user_data);
 	if (!(svsk = (struct svc_sock *)(sk->user_data)))
-		return;
+		goto out;
 	spin_lock_bh(&svsk->sk_lock);
 	svsk->sk_data++;
 	svc_sock_enqueue(svsk);
 	spin_unlock_bh(&svsk->sk_lock);
+ out:
+	if (sk->sleep && waitqueue_active(sk->sleep))
+		wake_up_interruptible(sk->sleep);
 }
 
 /*

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)