net: Add skb_unclone() helper function.
authorPravin B Shelar <pshelar@nicira.com>
Thu, 14 Feb 2013 09:44:49 +0000 (09:44 +0000)
committerDavid S. Miller <davem@davemloft.net>
Fri, 15 Feb 2013 20:10:37 +0000 (15:10 -0500)
This function will be used in next GRE_GSO patch. This patch does
not change any functionality.

Signed-off-by: Pravin B Shelar <pshelar@nicira.com>
Acked-by: Eric Dumazet <edumazet@google.com>
13 files changed:
drivers/net/ppp/ppp_generic.c
include/linux/skbuff.h
net/ipv4/ah4.c
net/ipv4/ip_fragment.c
net/ipv4/tcp_output.c
net/ipv4/xfrm4_input.c
net/ipv4/xfrm4_mode_tunnel.c
net/ipv6/ah6.c
net/ipv6/netfilter/nf_conntrack_reasm.c
net/ipv6/reassembly.c
net/ipv6/xfrm6_mode_tunnel.c
net/sched/act_ipt.c
net/sched/act_pedit.c

index 0b2706abe3e3b06dbd158eff440d8c2ccc4fb50b..4fd754e74eb2b113fc2eae0bb7c6792ae8eb7d73 100644 (file)
@@ -1805,8 +1805,7 @@ ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_buff *skb)
                /* the filter instructions are constructed assuming
                   a four-byte PPP header on each packet */
                if (ppp->pass_filter || ppp->active_filter) {
-                       if (skb_cloned(skb) &&
-                           pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
+                       if (skb_unclone(skb, GFP_ATOMIC))
                                goto err;
 
                        *skb_push(skb, 2) = 0;
index 9da99520ccd5f609039dfdc4f3cca31adbe06e17..ca6ee7d93edb4b325bf6a4a85545b93c497597ee 100644 (file)
@@ -804,6 +804,16 @@ static inline int skb_cloned(const struct sk_buff *skb)
               (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: buffer to check
index a69b4e4a02b5099043d98e5278355274e18ea72b..2e7f1948216fe8ade7d57aa3baa652d14d6b9b7b 100644 (file)
@@ -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,
         * so... Later this can change. */
-       if (skb_cloned(skb) &&
-           pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
+       if (skb_unclone(skb, GFP_ATOMIC))
                goto out;
 
        skb->ip_summed = CHECKSUM_NONE;
index 1211613c6c3401f520e8eb2209435e4b71360684..b6d30acb600c5e306ba825ed394c252e4fe27a8b 100644 (file)
@@ -590,7 +590,7 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev,
                goto out_oversize;
 
        /* 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;
 
        /* If the first fragment is fragmented itself, we split
index 6182d90e97b0fde55b533e3d53f78aa9136b6731..fd0cea114b5d0d08e785bb65a67e5f904bd95df3 100644 (file)
@@ -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. */
 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;
 
        __pskb_trim_head(skb, len);
index 06814b6216dc1bc71fedc9924b23d74b817a38d8..1f12c8b4586497931831515e06a8005140863ff5 100644 (file)
@@ -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
         * 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;
 
        /* Now we can update and verify the packet length... */
index ddee0a099a2c8caea19ccabbd957032f59896fdd..1162ace308380dfb53092eee7bf7d25eedc0b97d 100644 (file)
@@ -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)
                handler->handler(skb);
 
-       if (skb_cloned(skb) &&
-           (err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC)))
+       if (err = skb_unclone(skb, GFP_ATOMIC))
                goto out;
 
        if (x->props.flags & XFRM_STATE_DECAP_DSCP)
index 384233188ac1e38468b5edf71c105c21e6bf38bc..bb02e176cb70537ac7cdc01a03c0c641ab672741 100644 (file)
@@ -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,
         * so... Later this can change. */
-       if (skb_cloned(skb) &&
-           pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
+       if (skb_unclone(skb, GFP_ATOMIC))
                goto out;
 
        skb->ip_summed = CHECKSUM_NONE;
index c674f158efa8bedfcda37e4e66c5f8e7deb79202..b89a8c3186cd893c641b7813832e22ecafdf45b4 100644 (file)
@@ -368,7 +368,7 @@ nf_ct_frag6_reasm(struct frag_queue *fq, struct net_device *dev)
        }
 
        /* 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");
                goto out_oom;
        }
index bab2c270f29207c37ed7b107b6d25c6e12a6053d..e354743ed4267563c6959700c3ea99f70172b06d 100644 (file)
@@ -404,7 +404,7 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev,
                goto out_oversize;
 
        /* 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;
 
        /* If the first fragment is fragmented itself, we split
index 9f2095b19ad09bb4acfed82fd2d1c59652245373..93c41a81c4c32632338a87c43e0adf368ca2c7da 100644 (file)
@@ -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)))
                goto out;
 
-       if (skb_cloned(skb) &&
-           (err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC)))
+       if (err = skb_unclone(skb, GFP_ATOMIC))
                goto out;
 
        if (x->props.flags & XFRM_STATE_DECAP_DSCP)
index 0fb9e3f567e62340ee5b3d707d34591e54e7c7f2..e0f6de64afeca84c5400603672b4b84a11cf643d 100644 (file)
@@ -207,10 +207,8 @@ static int tcf_ipt(struct sk_buff *skb, const struct tc_action *a,
        struct tcf_ipt *ipt = a->priv;
        struct xt_action_param par;
 
-       if (skb_cloned(skb)) {
-               if (pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
-                       return TC_ACT_UNSPEC;
-       }
+       if (skb_unclone(skb, GFP_ATOMIC))
+               return TC_ACT_UNSPEC;
 
        spin_lock(&ipt->tcf_lock);
 
index 0c3faddf3f2c75f1505f5c7c1862f24a4c769dfa..7ed78c9e505cf7e18bc5a0b066837d19d33d4b10 100644 (file)
@@ -131,8 +131,7 @@ static int tcf_pedit(struct sk_buff *skb, const struct tc_action *a,
        int i, munged = 0;
        unsigned int off;
 
-       if (skb_cloned(skb) &&
-           pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
+       if (skb_unclone(skb, GFP_ATOMIC))
                return p->tcf_action;
 
        off = skb_network_offset(skb);