forked from luck/tmp_suning_uos_patched
[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>
This commit is contained in:
parent
dcb7cd97f1
commit
e9fa4f7bd2
|
@ -1039,6 +1039,21 @@ static inline int pskb_trim(struct sk_buff *skb, unsigned int len)
|
|||
return (len < skb->len) ? __pskb_trim(skb, len) : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* pskb_trim_unique - remove end from a paged unique (not cloned) buffer
|
||||
* @skb: buffer to alter
|
||||
* @len: new length
|
||||
*
|
||||
* This is identical to pskb_trim except that the caller knows that
|
||||
* the skb is not cloned so we should never get an error due to out-
|
||||
* of-memory.
|
||||
*/
|
||||
static inline void pskb_trim_unique(struct sk_buff *skb, unsigned int len)
|
||||
{
|
||||
int err = pskb_trim(skb, len);
|
||||
BUG_ON(err);
|
||||
}
|
||||
|
||||
/**
|
||||
* skb_orphan - orphan a buffer
|
||||
* @skb: buffer to orphan
|
||||
|
|
|
@ -947,7 +947,7 @@ int ip_append_data(struct sock *sk,
|
|||
skb_prev->csum = csum_sub(skb_prev->csum,
|
||||
skb->csum);
|
||||
data += fraggap;
|
||||
skb_trim(skb_prev, maxfraglen);
|
||||
pskb_trim_unique(skb_prev, maxfraglen);
|
||||
}
|
||||
|
||||
copy = datalen - transhdrlen - fraggap;
|
||||
|
@ -1142,7 +1142,7 @@ ssize_t ip_append_page(struct sock *sk, struct page *page,
|
|||
data, fraggap, 0);
|
||||
skb_prev->csum = csum_sub(skb_prev->csum,
|
||||
skb->csum);
|
||||
skb_trim(skb_prev, maxfraglen);
|
||||
pskb_trim_unique(skb_prev, maxfraglen);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -1095,7 +1095,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
|
|||
skb_prev->csum = csum_sub(skb_prev->csum,
|
||||
skb->csum);
|
||||
data += fraggap;
|
||||
skb_trim(skb_prev, maxfraglen);
|
||||
pskb_trim_unique(skb_prev, maxfraglen);
|
||||
}
|
||||
copy = datalen - transhdrlen - fraggap;
|
||||
if (copy < 0) {
|
||||
|
|
Loading…
Reference in New Issue
Block a user