aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2006-08-13 23:12:58 -0400
committerDavid S. Miller <davem@davemloft.net>2006-08-13 23:12:58 -0400
commite9fa4f7bd291c29a785666e2fa5a9cf3241ee6c3 (patch)
tree7313e7994ed8dbeb47ca454ee7c53d45e040738d
parentdcb7cd97f133f7cfbd181149a1e60215a869f895 (diff)
[INET]: Use pskb_trim_unique when trimming paged unique skbs
The IPv4/IPv6 datagram output path was using skb_trim to trim paged packets because they know that the packet has not been cloned yet (since the packet hasn't been given to anything else in the system). This broke because skb_trim no longer allows paged packets to be trimmed. Paged packets must be given to one of the pskb_trim functions instead. This patch adds a new pskb_trim_unique function to cover the IPv4/IPv6 datagram output path scenario and replaces the corresponding skb_trim calls with it. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/linux/skbuff.h15
-rw-r--r--net/ipv4/ip_output.c4
-rw-r--r--net/ipv6/ip6_output.c2
3 files changed, 18 insertions, 3 deletions
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 3573ba9a2555..755e9cddac47 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -1040,6 +1040,21 @@ static inline int pskb_trim(struct sk_buff *skb, unsigned int len)
1040} 1040}
1041 1041
1042/** 1042/**
1043 * pskb_trim_unique - remove end from a paged unique (not cloned) buffer
1044 * @skb: buffer to alter
1045 * @len: new length
1046 *
1047 * This is identical to pskb_trim except that the caller knows that
1048 * the skb is not cloned so we should never get an error due to out-
1049 * of-memory.
1050 */
1051static inline void pskb_trim_unique(struct sk_buff *skb, unsigned int len)
1052{
1053 int err = pskb_trim(skb, len);
1054 BUG_ON(err);
1055}
1056
1057/**
1043 * skb_orphan - orphan a buffer 1058 * skb_orphan - orphan a buffer
1044 * @skb: buffer to orphan 1059 * @skb: buffer to orphan
1045 * 1060 *
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 9bf307a29783..4c20f5546893 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -947,7 +947,7 @@ alloc_new_skb:
947 skb_prev->csum = csum_sub(skb_prev->csum, 947 skb_prev->csum = csum_sub(skb_prev->csum,
948 skb->csum); 948 skb->csum);
949 data += fraggap; 949 data += fraggap;
950 skb_trim(skb_prev, maxfraglen); 950 pskb_trim_unique(skb_prev, maxfraglen);
951 } 951 }
952 952
953 copy = datalen - transhdrlen - fraggap; 953 copy = datalen - transhdrlen - fraggap;
@@ -1142,7 +1142,7 @@ ssize_t ip_append_page(struct sock *sk, struct page *page,
1142 data, fraggap, 0); 1142 data, fraggap, 0);
1143 skb_prev->csum = csum_sub(skb_prev->csum, 1143 skb_prev->csum = csum_sub(skb_prev->csum,
1144 skb->csum); 1144 skb->csum);
1145 skb_trim(skb_prev, maxfraglen); 1145 pskb_trim_unique(skb_prev, maxfraglen);
1146 } 1146 }
1147 1147
1148 /* 1148 /*
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 69451af6abe7..4fb47a252913 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -1095,7 +1095,7 @@ alloc_new_skb:
1095 skb_prev->csum = csum_sub(skb_prev->csum, 1095 skb_prev->csum = csum_sub(skb_prev->csum,
1096 skb->csum); 1096 skb->csum);
1097 data += fraggap; 1097 data += fraggap;
1098 skb_trim(skb_prev, maxfraglen); 1098 pskb_trim_unique(skb_prev, maxfraglen);
1099 } 1099 }
1100 copy = datalen - transhdrlen - fraggap; 1100 copy = datalen - transhdrlen - fraggap;
1101 if (copy < 0) { 1101 if (copy < 0) {