]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
net: Introduce sk_clone_lock() error path routine
authorArnaldo Carvalho de Melo <acme@redhat.com>
Wed, 1 Mar 2017 19:35:08 +0000 (16:35 -0300)
committerDavid S. Miller <davem@davemloft.net>
Thu, 2 Mar 2017 21:19:33 +0000 (13:19 -0800)
When handling problems in cloning a socket with the sk_clone_locked()
function we need to perform several steps that were open coded in it and
its callers, so introduce a routine to avoid this duplication:
sk_free_unlock_clone().

Cc: Cong Wang <xiyou.wangcong@gmail.com>
Cc: Dmitry Vyukov <dvyukov@google.com>
Cc: Eric Dumazet <edumazet@google.com>
Cc: Gerrit Renker <gerrit@erg.abdn.ac.uk>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/n/net-ui6laqkotycunhtmqryl9bfx@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/net/sock.h
net/core/sock.c
net/dccp/minisocks.c

index 9ccefa5c5487863e69831c3bf45e4f0edf78eb65..5e5997654db6454f82179cc35c4bc22e89d0c06f 100644 (file)
@@ -1526,6 +1526,7 @@ struct sock *sk_alloc(struct net *net, int family, gfp_t priority,
 void sk_free(struct sock *sk);
 void sk_destruct(struct sock *sk);
 struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority);
+void sk_free_unlock_clone(struct sock *sk);
 
 struct sk_buff *sock_wmalloc(struct sock *sk, unsigned long size, int force,
                             gfp_t priority);
index e7d74940e8637dfe0a5b6629f1d1bff827a62073..f6fd79f33097f3fa279fcb0b610286259af9b111 100644 (file)
@@ -1539,11 +1539,7 @@ struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority)
                        is_charged = sk_filter_charge(newsk, filter);
 
                if (unlikely(!is_charged || xfrm_sk_clone_policy(newsk, sk))) {
-                       /* It is still raw copy of parent, so invalidate
-                        * destructor and make plain sk_free() */
-                       newsk->sk_destruct = NULL;
-                       bh_unlock_sock(newsk);
-                       sk_free(newsk);
+                       sk_free_unlock_clone(newsk);
                        newsk = NULL;
                        goto out;
                }
@@ -1592,6 +1588,16 @@ out:
 }
 EXPORT_SYMBOL_GPL(sk_clone_lock);
 
+void sk_free_unlock_clone(struct sock *sk)
+{
+       /* It is still raw copy of parent, so invalidate
+        * destructor and make plain sk_free() */
+       sk->sk_destruct = NULL;
+       bh_unlock_sock(sk);
+       sk_free(sk);
+}
+EXPORT_SYMBOL_GPL(sk_free_unlock_clone);
+
 void sk_setup_caps(struct sock *sk, struct dst_entry *dst)
 {
        u32 max_segs = 1;
index d20d948a98ed3c32f61e7b265fe21a459cbd016e..e267e6f4c9a5566b369a03a600a408e5bd41cbad 100644 (file)
@@ -119,11 +119,7 @@ struct sock *dccp_create_openreq_child(const struct sock *sk,
                 * Activate features: initialise CCIDs, sequence windows etc.
                 */
                if (dccp_feat_activate_values(newsk, &dreq->dreq_featneg)) {
-                       /* It is still raw copy of parent, so invalidate
-                        * destructor and make plain sk_free() */
-                       newsk->sk_destruct = NULL;
-                       bh_unlock_sock(newsk);
-                       sk_free(newsk);
+                       sk_free_unlock_clone(newsk);
                        return NULL;
                }
                dccp_init_xmit_timers(newsk);