|
|
@@ -145,8 +145,14 @@ static int smc_release(struct socket *sock)
|
|
|
sk->sk_shutdown |= SHUTDOWN_MASK;
|
|
|
}
|
|
|
if (smc->clcsock) {
|
|
|
+ if (smc->use_fallback && sk->sk_state == SMC_LISTEN) {
|
|
|
+ /* wake up clcsock accept */
|
|
|
+ rc = kernel_sock_shutdown(smc->clcsock, SHUT_RDWR);
|
|
|
+ }
|
|
|
+ mutex_lock(&smc->clcsock_release_lock);
|
|
|
sock_release(smc->clcsock);
|
|
|
smc->clcsock = NULL;
|
|
|
+ mutex_unlock(&smc->clcsock_release_lock);
|
|
|
}
|
|
|
if (smc->use_fallback) {
|
|
|
if (sk->sk_state != SMC_LISTEN && sk->sk_state != SMC_INIT)
|
|
|
@@ -203,6 +209,7 @@ static struct sock *smc_sock_alloc(struct net *net, struct socket *sock,
|
|
|
spin_lock_init(&smc->conn.send_lock);
|
|
|
sk->sk_prot->hash(sk);
|
|
|
sk_refcnt_debug_inc(sk);
|
|
|
+ mutex_init(&smc->clcsock_release_lock);
|
|
|
|
|
|
return sk;
|
|
|
}
|
|
|
@@ -818,7 +825,7 @@ static int smc_clcsock_accept(struct smc_sock *lsmc, struct smc_sock **new_smc)
|
|
|
struct socket *new_clcsock = NULL;
|
|
|
struct sock *lsk = &lsmc->sk;
|
|
|
struct sock *new_sk;
|
|
|
- int rc;
|
|
|
+ int rc = -EINVAL;
|
|
|
|
|
|
release_sock(lsk);
|
|
|
new_sk = smc_sock_alloc(sock_net(lsk), NULL, lsk->sk_protocol);
|
|
|
@@ -831,7 +838,10 @@ static int smc_clcsock_accept(struct smc_sock *lsmc, struct smc_sock **new_smc)
|
|
|
}
|
|
|
*new_smc = smc_sk(new_sk);
|
|
|
|
|
|
- rc = kernel_accept(lsmc->clcsock, &new_clcsock, 0);
|
|
|
+ mutex_lock(&lsmc->clcsock_release_lock);
|
|
|
+ if (lsmc->clcsock)
|
|
|
+ rc = kernel_accept(lsmc->clcsock, &new_clcsock, 0);
|
|
|
+ mutex_unlock(&lsmc->clcsock_release_lock);
|
|
|
lock_sock(lsk);
|
|
|
if (rc < 0)
|
|
|
lsk->sk_err = -rc;
|