|
@@ -1699,17 +1699,18 @@ static bool __skb_splice_bits(struct sk_buff *skb, struct pipe_inode_info *pipe,
|
|
|
struct splice_pipe_desc *spd, struct sock *sk)
|
|
|
{
|
|
|
int seg;
|
|
|
- bool head_is_linear = !skb->head_frag;
|
|
|
+ bool head_is_locked = !skb->head_frag || skb_cloned(skb);
|
|
|
|
|
|
/* map the linear part :
|
|
|
- * If skb->head_frag is set, this 'linear' part is backed
|
|
|
- * by a fragment, and we can avoid a copy.
|
|
|
+ * If skb->head_frag is set, this 'linear' part is backed by a
|
|
|
+ * fragment, and if the head is not shared with any clones then
|
|
|
+ * we can avoid a copy since we own the head portion of this page.
|
|
|
*/
|
|
|
if (__splice_segment(virt_to_page(skb->data),
|
|
|
(unsigned long) skb->data & (PAGE_SIZE - 1),
|
|
|
skb_headlen(skb),
|
|
|
offset, len, skb, spd,
|
|
|
- head_is_linear,
|
|
|
+ head_is_locked,
|
|
|
sk, pipe))
|
|
|
return true;
|
|
|
|