|
@@ -91,7 +91,8 @@ static void tipc_sock_release(struct tipc_conn *con);
|
|
|
static void tipc_conn_kref_release(struct kref *kref)
|
|
|
{
|
|
|
struct tipc_conn *con = container_of(kref, struct tipc_conn, kref);
|
|
|
- struct sockaddr_tipc *saddr = con->server->saddr;
|
|
|
+ struct tipc_server *s = con->server;
|
|
|
+ struct sockaddr_tipc *saddr = s->saddr;
|
|
|
struct socket *sock = con->sock;
|
|
|
struct sock *sk;
|
|
|
|
|
@@ -106,6 +107,11 @@ static void tipc_conn_kref_release(struct kref *kref)
|
|
|
tipc_sock_release(con);
|
|
|
sock_release(sock);
|
|
|
con->sock = NULL;
|
|
|
+
|
|
|
+ spin_lock_bh(&s->idr_lock);
|
|
|
+ idr_remove(&s->conn_idr, con->conid);
|
|
|
+ s->idr_in_use--;
|
|
|
+ spin_unlock_bh(&s->idr_lock);
|
|
|
}
|
|
|
|
|
|
tipc_clean_outqueues(con);
|
|
@@ -128,8 +134,10 @@ static struct tipc_conn *tipc_conn_lookup(struct tipc_server *s, int conid)
|
|
|
|
|
|
spin_lock_bh(&s->idr_lock);
|
|
|
con = idr_find(&s->conn_idr, conid);
|
|
|
- if (con)
|
|
|
+ if (con && test_bit(CF_CONNECTED, &con->flags))
|
|
|
conn_get(con);
|
|
|
+ else
|
|
|
+ con = NULL;
|
|
|
spin_unlock_bh(&s->idr_lock);
|
|
|
return con;
|
|
|
}
|
|
@@ -198,15 +206,8 @@ static void tipc_sock_release(struct tipc_conn *con)
|
|
|
|
|
|
static void tipc_close_conn(struct tipc_conn *con)
|
|
|
{
|
|
|
- struct tipc_server *s = con->server;
|
|
|
-
|
|
|
if (test_and_clear_bit(CF_CONNECTED, &con->flags)) {
|
|
|
|
|
|
- spin_lock_bh(&s->idr_lock);
|
|
|
- idr_remove(&s->conn_idr, con->conid);
|
|
|
- s->idr_in_use--;
|
|
|
- spin_unlock_bh(&s->idr_lock);
|
|
|
-
|
|
|
/* We shouldn't flush pending works as we may be in the
|
|
|
* thread. In fact the races with pending rx/tx work structs
|
|
|
* are harmless for us here as we have already deleted this
|