patch-2.4.17 linux/net/core/sock.c

Next file: linux/net/decnet/README
Previous file: linux/net/core/skbuff.c
Back to the patch index
Back to the overall index

diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.16/net/core/sock.c linux/net/core/sock.c
@@ -7,7 +7,7 @@
  *		handler for protocols to use and generic option handler.
  *
  *
- * Version:	$Id: sock.c,v 1.112 2001/07/27 09:54:48 davem Exp $
+ * Version:	$Id: sock.c,v 1.116 2001/11/08 04:20:06 davem Exp $
  *
  * Authors:	Ross Biro, <bir7@leland.Stanford.Edu>
  *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -113,24 +113,20 @@
 #include <asm/uaccess.h>
 #include <asm/system.h>
 
-#include <linux/inet.h>
 #include <linux/netdevice.h>
-#include <net/ip.h>
 #include <net/protocol.h>
-#include <net/arp.h>
-#include <net/route.h>
-#include <net/tcp.h>
-#include <net/udp.h>
 #include <linux/skbuff.h>
 #include <net/sock.h>
-#include <net/raw.h>
-#include <net/icmp.h>
 #include <linux/ipsec.h>
 
 #ifdef CONFIG_FILTER
 #include <linux/filter.h>
 #endif
 
+#ifdef CONFIG_INET
+#include <net/tcp.h>
+#endif
+
 /* Run time adjustable parameters. */
 __u32 sysctl_wmem_max = SK_WMEM_MAX;
 __u32 sysctl_rmem_max = SK_RMEM_MAX;
@@ -759,48 +755,62 @@
  *	Generic send/receive buffer handlers
  */
 
-struct sk_buff *sock_alloc_send_skb(struct sock *sk, unsigned long size, 
-			int noblock, int *errcode)
+struct sk_buff *sock_alloc_send_pskb(struct sock *sk, unsigned long header_len,
+				     unsigned long data_len, int noblock, int *errcode)
 {
-	int err;
 	struct sk_buff *skb;
 	long timeo;
+	int err;
 
 	timeo = sock_sndtimeo(sk, noblock);
-
 	while (1) {
-		unsigned long try_size = size;
-
 		err = sock_error(sk);
 		if (err != 0)
 			goto failure;
 
-		/*
-		 *	We should send SIGPIPE in these cases according to
-		 *	1003.1g draft 6.4. If we (the user) did a shutdown()
-		 *	call however we should not. 
-		 *
-		 *	Note: This routine isnt just used for datagrams and
-		 *	anyway some datagram protocols have a notion of
-		 *	close down.
-		 */
-
 		err = -EPIPE;
-		if (sk->shutdown&SEND_SHUTDOWN)
+		if (sk->shutdown & SEND_SHUTDOWN)
 			goto failure;
 
 		if (atomic_read(&sk->wmem_alloc) < sk->sndbuf) {
-			skb = alloc_skb(try_size, sk->allocation);
-			if (skb)
+			skb = alloc_skb(header_len, sk->allocation);
+			if (skb) {
+				int npages;
+				int i;
+
+				/* No pages, we're done... */
+				if (!data_len)
+					break;
+
+				npages = (data_len + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
+				skb->truesize += data_len;
+				skb_shinfo(skb)->nr_frags = npages;
+				for (i = 0; i < npages; i++) {
+					struct page *page;
+					skb_frag_t *frag;
+
+					page = alloc_pages(sk->allocation, 0);
+					if (!page) {
+						err = -ENOBUFS;
+						kfree_skb(skb);
+						goto failure;
+					}
+
+					frag = &skb_shinfo(skb)->frags[i];
+					frag->page = page;
+					frag->page_offset = 0;
+					frag->size = (data_len >= PAGE_SIZE ?
+						      PAGE_SIZE :
+						      data_len);
+					data_len -= PAGE_SIZE;
+				}
+
+				/* Full success... */
 				break;
+			}
 			err = -ENOBUFS;
 			goto failure;
 		}
-
-		/*
-		 *	This means we have too many buffers for this socket already.
-		 */
-
 		set_bit(SOCK_ASYNC_NOSPACE, &sk->socket->flags);
 		set_bit(SOCK_NOSPACE, &sk->socket->flags);
 		err = -EAGAIN;
@@ -819,6 +829,12 @@
 failure:
 	*errcode = err;
 	return NULL;
+}
+
+struct sk_buff *sock_alloc_send_skb(struct sock *sk, unsigned long size, 
+				    int noblock, int *errcode)
+{
+	return sock_alloc_send_pskb(sk, size, 0, noblock, errcode);
 }
 
 void __lock_sock(struct sock *sk)

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