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
- Lines: 138
- Date:
Fri Dec 21 16:40:33 2001
- Orig file:
linux-2.4.16/net/core/sock.c
- Orig date:
Sat Jul 28 19:12:38 2001
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)