aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
authorAlexander Duyck <alexander.h.duyck@intel.com>2012-05-02 14:18:42 -0400
committerDavid S. Miller <davem@davemloft.net>2012-05-03 01:34:37 -0400
commit2996d31f9f292cce67cd9105dc0a4a5ee43d2f14 (patch)
tree4368e35e13d083a40530c88de554de8d88c0aa41 /net/ipv4
parentb081f85c2977b1cbb6e635d53d9512f1ef985972 (diff)
net: Stop decapitating clones that have a head_frag
This change is meant ot prevent stealing the skb->head to use as a page in the event that the skb->head was cloned. This allows the other clones to track each other via shinfo->dataref. Without this we break down to two methods for tracking the reference count, one being dataref, the other being the page count. As a result it becomes difficult to track how many references there are to skb->head. Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com> Cc: Eric Dumazet <edumazet@google.com> Cc: Jeff Kirsher <jeffrey.t.kirsher@intel.com> Acked-by: Eric Dumazet <edumazet@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/tcp_input.c9
1 files changed, 2 insertions, 7 deletions
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 2f696ef13dcd..c6f78e2b590f 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -4589,7 +4589,7 @@ copyfrags:
4589 to->data_len += len; 4589 to->data_len += len;
4590 goto merge; 4590 goto merge;
4591 } 4591 }
4592 if (from->head_frag) { 4592 if (from->head_frag && !skb_cloned(from)) {
4593 struct page *page; 4593 struct page *page;
4594 unsigned int offset; 4594 unsigned int offset;
4595 4595
@@ -4599,12 +4599,7 @@ copyfrags:
4599 offset = from->data - (unsigned char *)page_address(page); 4599 offset = from->data - (unsigned char *)page_address(page);
4600 skb_fill_page_desc(to, skb_shinfo(to)->nr_frags, 4600 skb_fill_page_desc(to, skb_shinfo(to)->nr_frags,
4601 page, offset, skb_headlen(from)); 4601 page, offset, skb_headlen(from));
4602 4602 *fragstolen = true;
4603 if (skb_cloned(from))
4604 get_page(page);
4605 else
4606 *fragstolen = true;
4607
4608 delta = len; /* we dont know real truesize... */ 4603 delta = len; /* we dont know real truesize... */
4609 goto copyfrags; 4604 goto copyfrags;
4610 } 4605 }