aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/inet_connection_sock.h6
-rw-r--r--include/net/sock.h4
-rw-r--r--net/core/sock.c11
-rw-r--r--net/dccp/minisocks.c2
-rw-r--r--net/ipv4/inet_connection_sock.c17
-rw-r--r--net/ipv4/tcp_minisocks.c2
6 files changed, 29 insertions, 13 deletions
diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h
index e6db62e756dc..dbf9aab34c82 100644
--- a/include/net/inet_connection_sock.h
+++ b/include/net/inet_connection_sock.h
@@ -143,9 +143,9 @@ static inline void *inet_csk_ca(const struct sock *sk)
143 return (void *)inet_csk(sk)->icsk_ca_priv; 143 return (void *)inet_csk(sk)->icsk_ca_priv;
144} 144}
145 145
146extern struct sock *inet_csk_clone(struct sock *sk, 146extern struct sock *inet_csk_clone_lock(const struct sock *sk,
147 const struct request_sock *req, 147 const struct request_sock *req,
148 const gfp_t priority); 148 const gfp_t priority);
149 149
150enum inet_csk_ack_state_t { 150enum inet_csk_ack_state_t {
151 ICSK_ACK_SCHED = 1, 151 ICSK_ACK_SCHED = 1,
diff --git a/include/net/sock.h b/include/net/sock.h
index abb6e0f0c3c3..67cd4581b6da 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -1089,8 +1089,8 @@ extern struct sock *sk_alloc(struct net *net, int family,
1089 struct proto *prot); 1089 struct proto *prot);
1090extern void sk_free(struct sock *sk); 1090extern void sk_free(struct sock *sk);
1091extern void sk_release_kernel(struct sock *sk); 1091extern void sk_release_kernel(struct sock *sk);
1092extern struct sock *sk_clone(const struct sock *sk, 1092extern struct sock *sk_clone_lock(const struct sock *sk,
1093 const gfp_t priority); 1093 const gfp_t priority);
1094 1094
1095extern struct sk_buff *sock_wmalloc(struct sock *sk, 1095extern struct sk_buff *sock_wmalloc(struct sock *sk,
1096 unsigned long size, int force, 1096 unsigned long size, int force,
diff --git a/net/core/sock.c b/net/core/sock.c
index 4ed7b1d12f5e..2de9dc295956 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -1204,7 +1204,14 @@ void sk_release_kernel(struct sock *sk)
1204} 1204}
1205EXPORT_SYMBOL(sk_release_kernel); 1205EXPORT_SYMBOL(sk_release_kernel);
1206 1206
1207struct sock *sk_clone(const struct sock *sk, const gfp_t priority) 1207/**
1208 * sk_clone_lock - clone a socket, and lock its clone
1209 * @sk: the socket to clone
1210 * @priority: for allocation (%GFP_KERNEL, %GFP_ATOMIC, etc)
1211 *
1212 * Caller must unlock socket even in error path (bh_unlock_sock(newsk))
1213 */
1214struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority)
1208{ 1215{
1209 struct sock *newsk; 1216 struct sock *newsk;
1210 1217
@@ -1297,7 +1304,7 @@ struct sock *sk_clone(const struct sock *sk, const gfp_t priority)
1297out: 1304out:
1298 return newsk; 1305 return newsk;
1299} 1306}
1300EXPORT_SYMBOL_GPL(sk_clone); 1307EXPORT_SYMBOL_GPL(sk_clone_lock);
1301 1308
1302void sk_setup_caps(struct sock *sk, struct dst_entry *dst) 1309void sk_setup_caps(struct sock *sk, struct dst_entry *dst)
1303{ 1310{
diff --git a/net/dccp/minisocks.c b/net/dccp/minisocks.c
index d7041a0963af..563b7c74e49d 100644
--- a/net/dccp/minisocks.c
+++ b/net/dccp/minisocks.c
@@ -100,7 +100,7 @@ struct sock *dccp_create_openreq_child(struct sock *sk,
100 * (* Generate a new socket and switch to that socket *) 100 * (* Generate a new socket and switch to that socket *)
101 * Set S := new socket for this port pair 101 * Set S := new socket for this port pair
102 */ 102 */
103 struct sock *newsk = inet_csk_clone(sk, req, GFP_ATOMIC); 103 struct sock *newsk = inet_csk_clone_lock(sk, req, GFP_ATOMIC);
104 104
105 if (newsk != NULL) { 105 if (newsk != NULL) {
106 struct dccp_request_sock *dreq = dccp_rsk(req); 106 struct dccp_request_sock *dreq = dccp_rsk(req);
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
index c14d88ad348d..a598768c616c 100644
--- a/net/ipv4/inet_connection_sock.c
+++ b/net/ipv4/inet_connection_sock.c
@@ -588,10 +588,19 @@ void inet_csk_reqsk_queue_prune(struct sock *parent,
588} 588}
589EXPORT_SYMBOL_GPL(inet_csk_reqsk_queue_prune); 589EXPORT_SYMBOL_GPL(inet_csk_reqsk_queue_prune);
590 590
591struct sock *inet_csk_clone(struct sock *sk, const struct request_sock *req, 591/**
592 const gfp_t priority) 592 * inet_csk_clone_lock - clone an inet socket, and lock its clone
593 * @sk: the socket to clone
594 * @req: request_sock
595 * @priority: for allocation (%GFP_KERNEL, %GFP_ATOMIC, etc)
596 *
597 * Caller must unlock socket even in error path (bh_unlock_sock(newsk))
598 */
599struct sock *inet_csk_clone_lock(const struct sock *sk,
600 const struct request_sock *req,
601 const gfp_t priority)
593{ 602{
594 struct sock *newsk = sk_clone(sk, priority); 603 struct sock *newsk = sk_clone_lock(sk, priority);
595 604
596 if (newsk != NULL) { 605 if (newsk != NULL) {
597 struct inet_connection_sock *newicsk = inet_csk(newsk); 606 struct inet_connection_sock *newicsk = inet_csk(newsk);
@@ -615,7 +624,7 @@ struct sock *inet_csk_clone(struct sock *sk, const struct request_sock *req,
615 } 624 }
616 return newsk; 625 return newsk;
617} 626}
618EXPORT_SYMBOL_GPL(inet_csk_clone); 627EXPORT_SYMBOL_GPL(inet_csk_clone_lock);
619 628
620/* 629/*
621 * At this point, there should be no process reference to this 630 * At this point, there should be no process reference to this
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c
index 66363b689ad6..0a7e3398c461 100644
--- a/net/ipv4/tcp_minisocks.c
+++ b/net/ipv4/tcp_minisocks.c
@@ -425,7 +425,7 @@ static inline void TCP_ECN_openreq_child(struct tcp_sock *tp,
425 */ 425 */
426struct sock *tcp_create_openreq_child(struct sock *sk, struct request_sock *req, struct sk_buff *skb) 426struct sock *tcp_create_openreq_child(struct sock *sk, struct request_sock *req, struct sk_buff *skb)
427{ 427{
428 struct sock *newsk = inet_csk_clone(sk, req, GFP_ATOMIC); 428 struct sock *newsk = inet_csk_clone_lock(sk, req, GFP_ATOMIC);
429 429
430 if (newsk != NULL) { 430 if (newsk != NULL) {
431 const struct inet_request_sock *ireq = inet_rsk(req); 431 const struct inet_request_sock *ireq = inet_rsk(req);