patch-2.3.4 linux/net/ipv4/af_inet.c

Next file: linux/net/ipv4/devinet.c
Previous file: linux/net/ethernet/eth.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.3/linux/net/ipv4/af_inet.c linux/net/ipv4/af_inet.c
@@ -5,7 +5,7 @@
  *
  *		PF_INET protocol family socket handler.
  *
- * Version:	$Id: af_inet.c,v 1.88 1999/05/12 11:24:27 davem Exp $
+ * Version:	$Id: af_inet.c,v 1.90 1999/05/29 04:30:38 davem Exp $
  *
  * Authors:	Ross Biro, <bir7@leland.Stanford.Edu>
  *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -147,22 +147,17 @@
 	struct sk_buff *skb;
 
 	/* First the read buffer. */
-	while((skb = skb_dequeue(&sk->receive_queue)) != NULL) {
-		/* This will take care of closing sockets that were
-		 * listening and didn't accept everything.
-		 */
-		if (skb->sk != NULL && skb->sk != sk)
-			skb->sk->prot->close(skb->sk, 0);
+	while((skb = skb_dequeue(&sk->receive_queue)) != NULL)
 		kfree_skb(skb);
-	}
 
 	/* Next, the error queue. */
 	while((skb = skb_dequeue(&sk->error_queue)) != NULL)
 		kfree_skb(skb);
 
-  	/* Now the backlog. */
-  	while((skb=skb_dequeue(&sk->back_log)) != NULL)
-		kfree_skb(skb);
+	/* It is _impossible_ for the backlog to contain anything
+	 * when we get here.  All user references to this socket
+	 * have gone away, only the net layer knows can touch it.
+	 */
 }
 
 static __inline__ void kill_sk_now(struct sock *sk)
@@ -195,14 +190,19 @@
 
 	sk->destroy = 1;
 	sk->ack_backlog = 0;
-	release_sock(sk);
+	bh_unlock_sock(sk);
 	net_reset_timer(sk, TIME_DESTROY, SOCK_DESTROY_TIME);
 }
 
+/* Callers must hold the BH spinlock.
+ *
+ * At this point, there should be no process reference to this
+ * socket, and thus no user references at all.  Therefore we
+ * can assume the socket waitqueue is inactive and nobody will
+ * try to jump onto it.
+ */
 void destroy_sock(struct sock *sk)
 {
-	lock_sock(sk);			/* just to be safe. */
-
   	/* Now we can no longer get new packets or once the
   	 * timers are killed, send them.
   	 */
@@ -213,12 +213,6 @@
 
 	kill_sk_queues(sk);
 
-	/* Now if it has a half accepted/ closed socket. */
-	if (sk->pair) {
-		sk->pair->prot->close(sk->pair, 0);
-		sk->pair = NULL;
-  	}
-
 	/* Now if everything is gone we can free the socket
 	 * structure, otherwise we need to keep it around until
 	 * everything is gone.
@@ -284,6 +278,14 @@
 	return 0;
 }
 
+/* Listening INET sockets never sleep to wait for memory, so
+ * it is completely silly to wake them up on queue space
+ * available events.  So we hook them up to this dummy callback.
+ */
+static void inet_listen_write_space(struct sock *sk)
+{
+}
+
 /*
  *	Move a socket into listening state.
  */
@@ -310,6 +312,7 @@
 		dst_release(xchg(&sk->dst_cache, NULL));
 		sk->prot->rehash(sk);
 		add_to_prot_sklist(sk);
+		sk->write_space = inet_listen_write_space;
 	}
 	sk->socket->flags |= SO_ACCEPTCON;
 	return(0);
@@ -684,14 +687,8 @@
 	if (sk1->prot->accept == NULL)
 		goto do_err;
 
-	/* Restore the state if we have been interrupted, and then returned. */
-	if (sk1->pair != NULL) {
-		sk2 = sk1->pair;
-		sk1->pair = NULL;
-	} else {
-		if((sk2 = sk1->prot->accept(sk1,flags)) == NULL)
-			goto do_sk1_err;
-	}
+	if((sk2 = sk1->prot->accept(sk1,flags)) == NULL)
+		goto do_sk1_err;
 
 	/*
 	 *	We've been passed an extra socket.

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