net: skbuff: add skb_append_pagefrags and use it
authorHannes Frederic Sowa <hannes@stressinduktion.org>
Thu, 21 May 2015 14:59:58 +0000 (16:59 +0200)
committerDavid S. Miller <davem@davemloft.net>
Mon, 25 May 2015 04:06:58 +0000 (00:06 -0400)
Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
Acked-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/linux/skbuff.h
net/core/skbuff.c
net/ipv4/ip_output.c

index b617095adb88b8d85f569d940261cd4d22c6c3c5..f708936cdd23c415fab8cc577a4b0226194e84ae 100644 (file)
@@ -861,6 +861,9 @@ int skb_append_datato_frags(struct sock *sk, struct sk_buff *skb,
                                        int len, int odd, struct sk_buff *skb),
                            void *from, int length);
 
+int skb_append_pagefrags(struct sk_buff *skb, struct page *page,
+                        int offset, size_t size);
+
 struct skb_seq_state {
        __u32           lower_offset;
        __u32           upper_offset;
index f3fe9bd9e67240e064b62fd0b0575c9453db9745..4f2babeaf18d425f16ebc5d647f941a7e048182c 100644 (file)
@@ -2915,6 +2915,24 @@ int skb_append_datato_frags(struct sock *sk, struct sk_buff *skb,
 }
 EXPORT_SYMBOL(skb_append_datato_frags);
 
+int skb_append_pagefrags(struct sk_buff *skb, struct page *page,
+                        int offset, size_t size)
+{
+       int i = skb_shinfo(skb)->nr_frags;
+
+       if (skb_can_coalesce(skb, i, page, offset)) {
+               skb_frag_size_add(&skb_shinfo(skb)->frags[i - 1], size);
+       } else if (i < MAX_SKB_FRAGS) {
+               get_page(page);
+               skb_fill_page_desc(skb, i, page, offset, size);
+       } else {
+               return -EMSGSIZE;
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(skb_append_pagefrags);
+
 /**
  *     skb_pull_rcsum - pull skb and update receive checksum
  *     @skb: buffer to update
index 8d91b922fcfe74ea6c46d251928f02c350feedf2..451b009dae7524c3a6e5afa4258c015263380014 100644 (file)
@@ -1233,11 +1233,9 @@ ssize_t  ip_append_page(struct sock *sk, struct flowi4 *fl4, struct page *page,
        }
 
        while (size > 0) {
-               int i;
-
-               if (skb_is_gso(skb))
+               if (skb_is_gso(skb)) {
                        len = size;
-               else {
+               else {
 
                        /* Check if the remaining data fits into current packet. */
                        len = mtu - skb->len;
@@ -1289,15 +1287,10 @@ ssize_t ip_append_page(struct sock *sk, struct flowi4 *fl4, struct page *page,
                        continue;
                }
 
-               i = skb_shinfo(skb)->nr_frags;
                if (len > size)
                        len = size;
-               if (skb_can_coalesce(skb, i, page, offset)) {
-                       skb_frag_size_add(&skb_shinfo(skb)->frags[i-1], len);
-               } else if (i < MAX_SKB_FRAGS) {
-                       get_page(page);
-                       skb_fill_page_desc(skb, i, page, offset, len);
-               } else {
+
+               if (skb_append_pagefrags(skb, page, offset, len)) {
                        err = -EMSGSIZE;
                        goto error;
                }