diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2017-03-01 14:35:08 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2017-03-02 16:19:33 -0500 |
commit | 94352d45092c23874532221b4d1e4721df9d63df (patch) | |
tree | 4962d392f77f9afe5fad1f5dc5eca4bd99ff651d /net | |
parent | d5afb6f9b6bb2c57bd0c05e76e12489dc0d037d9 (diff) |
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.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/core/sock.c | 16 | ||||
-rw-r--r-- | net/dccp/minisocks.c | 6 |
2 files changed, 12 insertions, 10 deletions
diff --git a/net/core/sock.c b/net/core/sock.c index e7d74940e863..f6fd79f33097 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
@@ -1539,11 +1539,7 @@ struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority) | |||
1539 | is_charged = sk_filter_charge(newsk, filter); | 1539 | is_charged = sk_filter_charge(newsk, filter); |
1540 | 1540 | ||
1541 | if (unlikely(!is_charged || xfrm_sk_clone_policy(newsk, sk))) { | 1541 | if (unlikely(!is_charged || xfrm_sk_clone_policy(newsk, sk))) { |
1542 | /* It is still raw copy of parent, so invalidate | 1542 | sk_free_unlock_clone(newsk); |
1543 | * destructor and make plain sk_free() */ | ||
1544 | newsk->sk_destruct = NULL; | ||
1545 | bh_unlock_sock(newsk); | ||
1546 | sk_free(newsk); | ||
1547 | newsk = NULL; | 1543 | newsk = NULL; |
1548 | goto out; | 1544 | goto out; |
1549 | } | 1545 | } |
@@ -1592,6 +1588,16 @@ out: | |||
1592 | } | 1588 | } |
1593 | EXPORT_SYMBOL_GPL(sk_clone_lock); | 1589 | EXPORT_SYMBOL_GPL(sk_clone_lock); |
1594 | 1590 | ||
1591 | void sk_free_unlock_clone(struct sock *sk) | ||
1592 | { | ||
1593 | /* It is still raw copy of parent, so invalidate | ||
1594 | * destructor and make plain sk_free() */ | ||
1595 | sk->sk_destruct = NULL; | ||
1596 | bh_unlock_sock(sk); | ||
1597 | sk_free(sk); | ||
1598 | } | ||
1599 | EXPORT_SYMBOL_GPL(sk_free_unlock_clone); | ||
1600 | |||
1595 | void sk_setup_caps(struct sock *sk, struct dst_entry *dst) | 1601 | void sk_setup_caps(struct sock *sk, struct dst_entry *dst) |
1596 | { | 1602 | { |
1597 | u32 max_segs = 1; | 1603 | u32 max_segs = 1; |
diff --git a/net/dccp/minisocks.c b/net/dccp/minisocks.c index d20d948a98ed..e267e6f4c9a5 100644 --- a/net/dccp/minisocks.c +++ b/net/dccp/minisocks.c | |||
@@ -119,11 +119,7 @@ struct sock *dccp_create_openreq_child(const struct sock *sk, | |||
119 | * Activate features: initialise CCIDs, sequence windows etc. | 119 | * Activate features: initialise CCIDs, sequence windows etc. |
120 | */ | 120 | */ |
121 | if (dccp_feat_activate_values(newsk, &dreq->dreq_featneg)) { | 121 | if (dccp_feat_activate_values(newsk, &dreq->dreq_featneg)) { |
122 | /* It is still raw copy of parent, so invalidate | 122 | sk_free_unlock_clone(newsk); |
123 | * destructor and make plain sk_free() */ | ||
124 | newsk->sk_destruct = NULL; | ||
125 | bh_unlock_sock(newsk); | ||
126 | sk_free(newsk); | ||
127 | return NULL; | 123 | return NULL; |
128 | } | 124 | } |
129 | dccp_init_xmit_timers(newsk); | 125 | dccp_init_xmit_timers(newsk); |