summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/smc/af_smc.c73
1 files changed, 32 insertions, 41 deletions
diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c
index 0c874e996f85..828e319fdc0a 100644
--- a/net/smc/af_smc.c
+++ b/net/smc/af_smc.c
@@ -123,30 +123,11 @@ struct proto smc_proto6 = {
123}; 123};
124EXPORT_SYMBOL_GPL(smc_proto6); 124EXPORT_SYMBOL_GPL(smc_proto6);
125 125
126static int smc_release(struct socket *sock) 126static int __smc_release(struct smc_sock *smc)
127{ 127{
128 struct sock *sk = sock->sk; 128 struct sock *sk = &smc->sk;
129 struct smc_sock *smc;
130 int rc = 0; 129 int rc = 0;
131 130
132 if (!sk)
133 goto out;
134
135 smc = smc_sk(sk);
136
137 /* cleanup for a dangling non-blocking connect */
138 if (smc->connect_nonblock && sk->sk_state == SMC_INIT)
139 tcp_abort(smc->clcsock->sk, ECONNABORTED);
140 flush_work(&smc->connect_work);
141
142 if (sk->sk_state == SMC_LISTEN)
143 /* smc_close_non_accepted() is called and acquires
144 * sock lock for child sockets again
145 */
146 lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
147 else
148 lock_sock(sk);
149
150 if (!smc->use_fallback) { 131 if (!smc->use_fallback) {
151 rc = smc_close_active(smc); 132 rc = smc_close_active(smc);
152 sock_set_flag(sk, SOCK_DEAD); 133 sock_set_flag(sk, SOCK_DEAD);
@@ -174,6 +155,35 @@ static int smc_release(struct socket *sock)
174 smc_conn_free(&smc->conn); 155 smc_conn_free(&smc->conn);
175 } 156 }
176 157
158 return rc;
159}
160
161static int smc_release(struct socket *sock)
162{
163 struct sock *sk = sock->sk;
164 struct smc_sock *smc;
165 int rc = 0;
166
167 if (!sk)
168 goto out;
169
170 smc = smc_sk(sk);
171
172 /* cleanup for a dangling non-blocking connect */
173 if (smc->connect_nonblock && sk->sk_state == SMC_INIT)
174 tcp_abort(smc->clcsock->sk, ECONNABORTED);
175 flush_work(&smc->connect_work);
176
177 if (sk->sk_state == SMC_LISTEN)
178 /* smc_close_non_accepted() is called and acquires
179 * sock lock for child sockets again
180 */
181 lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
182 else
183 lock_sock(sk);
184
185 rc = __smc_release(smc);
186
177 /* detach socket */ 187 /* detach socket */
178 sock_orphan(sk); 188 sock_orphan(sk);
179 sock->sk = NULL; 189 sock->sk = NULL;
@@ -964,26 +974,7 @@ void smc_close_non_accepted(struct sock *sk)
964 if (!sk->sk_lingertime) 974 if (!sk->sk_lingertime)
965 /* wait for peer closing */ 975 /* wait for peer closing */
966 sk->sk_lingertime = SMC_MAX_STREAM_WAIT_TIMEOUT; 976 sk->sk_lingertime = SMC_MAX_STREAM_WAIT_TIMEOUT;
967 if (!smc->use_fallback) { 977 __smc_release(smc);
968 smc_close_active(smc);
969 sock_set_flag(sk, SOCK_DEAD);
970 sk->sk_shutdown |= SHUTDOWN_MASK;
971 }
972 sk->sk_prot->unhash(sk);
973 if (smc->clcsock) {
974 struct socket *tcp;
975
976 tcp = smc->clcsock;
977 smc->clcsock = NULL;
978 sock_release(tcp);
979 }
980 if (smc->use_fallback) {
981 sock_put(sk); /* passive closing */
982 sk->sk_state = SMC_CLOSED;
983 } else {
984 if (sk->sk_state == SMC_CLOSED)
985 smc_conn_free(&smc->conn);
986 }
987 release_sock(sk); 978 release_sock(sk);
988 sock_put(sk); /* final sock_put */ 979 sock_put(sk); /* final sock_put */
989} 980}