Commit 94352d45 authored by Arnaldo Carvalho de Melo's avatar Arnaldo Carvalho de Melo Committed by David S. Miller

net: Introduce sk_clone_lock() error path routine

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.orgSigned-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent d5afb6f9
...@@ -1526,6 +1526,7 @@ struct sock *sk_alloc(struct net *net, int family, gfp_t priority, ...@@ -1526,6 +1526,7 @@ struct sock *sk_alloc(struct net *net, int family, gfp_t priority,
void sk_free(struct sock *sk); void sk_free(struct sock *sk);
void sk_destruct(struct sock *sk); void sk_destruct(struct sock *sk);
struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority); 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, struct sk_buff *sock_wmalloc(struct sock *sk, unsigned long size, int force,
gfp_t priority); gfp_t priority);
......
...@@ -1539,11 +1539,7 @@ struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority) ...@@ -1539,11 +1539,7 @@ struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority)
is_charged = sk_filter_charge(newsk, filter); is_charged = sk_filter_charge(newsk, filter);
if (unlikely(!is_charged || xfrm_sk_clone_policy(newsk, sk))) { if (unlikely(!is_charged || xfrm_sk_clone_policy(newsk, sk))) {
/* It is still raw copy of parent, so invalidate sk_free_unlock_clone(newsk);
* destructor and make plain sk_free() */
newsk->sk_destruct = NULL;
bh_unlock_sock(newsk);
sk_free(newsk);
newsk = NULL; newsk = NULL;
goto out; goto out;
} }
...@@ -1592,6 +1588,16 @@ struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority) ...@@ -1592,6 +1588,16 @@ struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority)
} }
EXPORT_SYMBOL_GPL(sk_clone_lock); 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) void sk_setup_caps(struct sock *sk, struct dst_entry *dst)
{ {
u32 max_segs = 1; u32 max_segs = 1;
......
...@@ -119,11 +119,7 @@ struct sock *dccp_create_openreq_child(const struct sock *sk, ...@@ -119,11 +119,7 @@ struct sock *dccp_create_openreq_child(const struct sock *sk,
* Activate features: initialise CCIDs, sequence windows etc. * Activate features: initialise CCIDs, sequence windows etc.
*/ */
if (dccp_feat_activate_values(newsk, &dreq->dreq_featneg)) { if (dccp_feat_activate_values(newsk, &dreq->dreq_featneg)) {
/* It is still raw copy of parent, so invalidate sk_free_unlock_clone(newsk);
* destructor and make plain sk_free() */
newsk->sk_destruct = NULL;
bh_unlock_sock(newsk);
sk_free(newsk);
return NULL; return NULL;
} }
dccp_init_xmit_timers(newsk); dccp_init_xmit_timers(newsk);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment