net: skbuff: add skb_append_pagefrags and use it
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>
This commit is contained in:
parent
d98c3edcbb
commit
be12a1fe29
3 changed files with 25 additions and 11 deletions
|
@ -861,6 +861,9 @@ int skb_append_datato_frags(struct sock *sk, struct sk_buff *skb,
|
||||||
int len, int odd, struct sk_buff *skb),
|
int len, int odd, struct sk_buff *skb),
|
||||||
void *from, int length);
|
void *from, int length);
|
||||||
|
|
||||||
|
int skb_append_pagefrags(struct sk_buff *skb, struct page *page,
|
||||||
|
int offset, size_t size);
|
||||||
|
|
||||||
struct skb_seq_state {
|
struct skb_seq_state {
|
||||||
__u32 lower_offset;
|
__u32 lower_offset;
|
||||||
__u32 upper_offset;
|
__u32 upper_offset;
|
||||||
|
|
|
@ -2915,6 +2915,24 @@ int skb_append_datato_frags(struct sock *sk, struct sk_buff *skb,
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(skb_append_datato_frags);
|
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_pull_rcsum - pull skb and update receive checksum
|
||||||
* @skb: buffer to update
|
* @skb: buffer to update
|
||||||
|
|
|
@ -1233,11 +1233,9 @@ ssize_t ip_append_page(struct sock *sk, struct flowi4 *fl4, struct page *page,
|
||||||
}
|
}
|
||||||
|
|
||||||
while (size > 0) {
|
while (size > 0) {
|
||||||
int i;
|
if (skb_is_gso(skb)) {
|
||||||
|
|
||||||
if (skb_is_gso(skb))
|
|
||||||
len = size;
|
len = size;
|
||||||
else {
|
} else {
|
||||||
|
|
||||||
/* Check if the remaining data fits into current packet. */
|
/* Check if the remaining data fits into current packet. */
|
||||||
len = mtu - skb->len;
|
len = mtu - skb->len;
|
||||||
|
@ -1289,15 +1287,10 @@ ssize_t ip_append_page(struct sock *sk, struct flowi4 *fl4, struct page *page,
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
i = skb_shinfo(skb)->nr_frags;
|
|
||||||
if (len > size)
|
if (len > size)
|
||||||
len = size;
|
len = size;
|
||||||
if (skb_can_coalesce(skb, i, page, offset)) {
|
|
||||||
skb_frag_size_add(&skb_shinfo(skb)->frags[i-1], len);
|
if (skb_append_pagefrags(skb, page, offset, len)) {
|
||||||
} else if (i < MAX_SKB_FRAGS) {
|
|
||||||
get_page(page);
|
|
||||||
skb_fill_page_desc(skb, i, page, offset, len);
|
|
||||||
} else {
|
|
||||||
err = -EMSGSIZE;
|
err = -EMSGSIZE;
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue