提交 14bbd6a5 编写于 作者: P Pravin B Shelar 提交者: David S. Miller

net: Add skb_unclone() helper function.

This function will be used in next GRE_GSO patch. This patch does
not change any functionality.
Signed-off-by: NPravin B Shelar <pshelar@nicira.com>
Acked-by: NEric Dumazet <edumazet@google.com>
上级 d887199d
...@@ -1805,8 +1805,7 @@ ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_buff *skb) ...@@ -1805,8 +1805,7 @@ ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_buff *skb)
/* the filter instructions are constructed assuming /* the filter instructions are constructed assuming
a four-byte PPP header on each packet */ a four-byte PPP header on each packet */
if (ppp->pass_filter || ppp->active_filter) { if (ppp->pass_filter || ppp->active_filter) {
if (skb_cloned(skb) && if (skb_unclone(skb, GFP_ATOMIC))
pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
goto err; goto err;
*skb_push(skb, 2) = 0; *skb_push(skb, 2) = 0;
......
...@@ -804,6 +804,16 @@ static inline int skb_cloned(const struct sk_buff *skb) ...@@ -804,6 +804,16 @@ static inline int skb_cloned(const struct sk_buff *skb)
(atomic_read(&skb_shinfo(skb)->dataref) & SKB_DATAREF_MASK) != 1; (atomic_read(&skb_shinfo(skb)->dataref) & SKB_DATAREF_MASK) != 1;
} }
static inline int skb_unclone(struct sk_buff *skb, gfp_t pri)
{
might_sleep_if(pri & __GFP_WAIT);
if (skb_cloned(skb))
return pskb_expand_head(skb, 0, 0, pri);
return 0;
}
/** /**
* skb_header_cloned - is the header a clone * skb_header_cloned - is the header a clone
* @skb: buffer to check * @skb: buffer to check
......
...@@ -321,8 +321,7 @@ static int ah_input(struct xfrm_state *x, struct sk_buff *skb) ...@@ -321,8 +321,7 @@ static int ah_input(struct xfrm_state *x, struct sk_buff *skb)
/* We are going to _remove_ AH header to keep sockets happy, /* We are going to _remove_ AH header to keep sockets happy,
* so... Later this can change. */ * so... Later this can change. */
if (skb_cloned(skb) && if (skb_unclone(skb, GFP_ATOMIC))
pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
goto out; goto out;
skb->ip_summed = CHECKSUM_NONE; skb->ip_summed = CHECKSUM_NONE;
......
...@@ -590,7 +590,7 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev, ...@@ -590,7 +590,7 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev,
goto out_oversize; goto out_oversize;
/* Head of list must not be cloned. */ /* Head of list must not be cloned. */
if (skb_cloned(head) && pskb_expand_head(head, 0, 0, GFP_ATOMIC)) if (skb_unclone(head, GFP_ATOMIC))
goto out_nomem; goto out_nomem;
/* If the first fragment is fragmented itself, we split /* If the first fragment is fragmented itself, we split
......
...@@ -1331,7 +1331,7 @@ static void __pskb_trim_head(struct sk_buff *skb, int len) ...@@ -1331,7 +1331,7 @@ static void __pskb_trim_head(struct sk_buff *skb, int len)
/* Remove acked data from a packet in the transmit queue. */ /* Remove acked data from a packet in the transmit queue. */
int tcp_trim_head(struct sock *sk, struct sk_buff *skb, u32 len) int tcp_trim_head(struct sock *sk, struct sk_buff *skb, u32 len)
{ {
if (skb_cloned(skb) && pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) if (skb_unclone(skb, GFP_ATOMIC))
return -ENOMEM; return -ENOMEM;
__pskb_trim_head(skb, len); __pskb_trim_head(skb, len);
......
...@@ -132,7 +132,7 @@ int xfrm4_udp_encap_rcv(struct sock *sk, struct sk_buff *skb) ...@@ -132,7 +132,7 @@ int xfrm4_udp_encap_rcv(struct sock *sk, struct sk_buff *skb)
* header and optional ESP marker bytes) and then modify the * header and optional ESP marker bytes) and then modify the
* protocol to ESP, and then call into the transform receiver. * protocol to ESP, and then call into the transform receiver.
*/ */
if (skb_cloned(skb) && pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) if (skb_unclone(skb, GFP_ATOMIC))
goto drop; goto drop;
/* Now we can update and verify the packet length... */ /* Now we can update and verify the packet length... */
......
...@@ -142,8 +142,7 @@ static int xfrm4_mode_tunnel_input(struct xfrm_state *x, struct sk_buff *skb) ...@@ -142,8 +142,7 @@ static int xfrm4_mode_tunnel_input(struct xfrm_state *x, struct sk_buff *skb)
for_each_input_rcu(rcv_notify_handlers, handler) for_each_input_rcu(rcv_notify_handlers, handler)
handler->handler(skb); handler->handler(skb);
if (skb_cloned(skb) && if (err = skb_unclone(skb, GFP_ATOMIC))
(err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC)))
goto out; goto out;
if (x->props.flags & XFRM_STATE_DECAP_DSCP) if (x->props.flags & XFRM_STATE_DECAP_DSCP)
......
...@@ -521,8 +521,7 @@ static int ah6_input(struct xfrm_state *x, struct sk_buff *skb) ...@@ -521,8 +521,7 @@ static int ah6_input(struct xfrm_state *x, struct sk_buff *skb)
/* We are going to _remove_ AH header to keep sockets happy, /* We are going to _remove_ AH header to keep sockets happy,
* so... Later this can change. */ * so... Later this can change. */
if (skb_cloned(skb) && if (skb_unclone(skb, GFP_ATOMIC))
pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
goto out; goto out;
skb->ip_summed = CHECKSUM_NONE; skb->ip_summed = CHECKSUM_NONE;
......
...@@ -368,7 +368,7 @@ nf_ct_frag6_reasm(struct frag_queue *fq, struct net_device *dev) ...@@ -368,7 +368,7 @@ nf_ct_frag6_reasm(struct frag_queue *fq, struct net_device *dev)
} }
/* Head of list must not be cloned. */ /* Head of list must not be cloned. */
if (skb_cloned(head) && pskb_expand_head(head, 0, 0, GFP_ATOMIC)) { if (skb_unclone(head, GFP_ATOMIC)) {
pr_debug("skb is cloned but can't expand head"); pr_debug("skb is cloned but can't expand head");
goto out_oom; goto out_oom;
} }
......
...@@ -404,7 +404,7 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev, ...@@ -404,7 +404,7 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev,
goto out_oversize; goto out_oversize;
/* Head of list must not be cloned. */ /* Head of list must not be cloned. */
if (skb_cloned(head) && pskb_expand_head(head, 0, 0, GFP_ATOMIC)) if (skb_unclone(head, GFP_ATOMIC))
goto out_oom; goto out_oom;
/* If the first fragment is fragmented itself, we split /* If the first fragment is fragmented itself, we split
......
...@@ -69,8 +69,7 @@ static int xfrm6_mode_tunnel_input(struct xfrm_state *x, struct sk_buff *skb) ...@@ -69,8 +69,7 @@ static int xfrm6_mode_tunnel_input(struct xfrm_state *x, struct sk_buff *skb)
if (!pskb_may_pull(skb, sizeof(struct ipv6hdr))) if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
goto out; goto out;
if (skb_cloned(skb) && if (err = skb_unclone(skb, GFP_ATOMIC))
(err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC)))
goto out; goto out;
if (x->props.flags & XFRM_STATE_DECAP_DSCP) if (x->props.flags & XFRM_STATE_DECAP_DSCP)
......
...@@ -207,10 +207,8 @@ static int tcf_ipt(struct sk_buff *skb, const struct tc_action *a, ...@@ -207,10 +207,8 @@ static int tcf_ipt(struct sk_buff *skb, const struct tc_action *a,
struct tcf_ipt *ipt = a->priv; struct tcf_ipt *ipt = a->priv;
struct xt_action_param par; struct xt_action_param par;
if (skb_cloned(skb)) { if (skb_unclone(skb, GFP_ATOMIC))
if (pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) return TC_ACT_UNSPEC;
return TC_ACT_UNSPEC;
}
spin_lock(&ipt->tcf_lock); spin_lock(&ipt->tcf_lock);
......
...@@ -131,8 +131,7 @@ static int tcf_pedit(struct sk_buff *skb, const struct tc_action *a, ...@@ -131,8 +131,7 @@ static int tcf_pedit(struct sk_buff *skb, const struct tc_action *a,
int i, munged = 0; int i, munged = 0;
unsigned int off; unsigned int off;
if (skb_cloned(skb) && if (skb_unclone(skb, GFP_ATOMIC))
pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
return p->tcf_action; return p->tcf_action;
off = skb_network_offset(skb); off = skb_network_offset(skb);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册