aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc
diff options
context:
space:
mode:
Diffstat (limited to 'net/tipc')
-rw-r--r--net/tipc/server.c19
1 files changed, 10 insertions, 9 deletions
diff --git a/net/tipc/server.c b/net/tipc/server.c
index 215849ce453d..2e803601aa99 100644
--- a/net/tipc/server.c
+++ b/net/tipc/server.c
@@ -91,7 +91,8 @@ static void tipc_sock_release(struct tipc_conn *con);
91static void tipc_conn_kref_release(struct kref *kref) 91static void tipc_conn_kref_release(struct kref *kref)
92{ 92{
93 struct tipc_conn *con = container_of(kref, struct tipc_conn, kref); 93 struct tipc_conn *con = container_of(kref, struct tipc_conn, kref);
94 struct sockaddr_tipc *saddr = con->server->saddr; 94 struct tipc_server *s = con->server;
95 struct sockaddr_tipc *saddr = s->saddr;
95 struct socket *sock = con->sock; 96 struct socket *sock = con->sock;
96 struct sock *sk; 97 struct sock *sk;
97 98
@@ -106,6 +107,11 @@ static void tipc_conn_kref_release(struct kref *kref)
106 tipc_sock_release(con); 107 tipc_sock_release(con);
107 sock_release(sock); 108 sock_release(sock);
108 con->sock = NULL; 109 con->sock = NULL;
110
111 spin_lock_bh(&s->idr_lock);
112 idr_remove(&s->conn_idr, con->conid);
113 s->idr_in_use--;
114 spin_unlock_bh(&s->idr_lock);
109 } 115 }
110 116
111 tipc_clean_outqueues(con); 117 tipc_clean_outqueues(con);
@@ -128,8 +134,10 @@ static struct tipc_conn *tipc_conn_lookup(struct tipc_server *s, int conid)
128 134
129 spin_lock_bh(&s->idr_lock); 135 spin_lock_bh(&s->idr_lock);
130 con = idr_find(&s->conn_idr, conid); 136 con = idr_find(&s->conn_idr, conid);
131 if (con) 137 if (con && test_bit(CF_CONNECTED, &con->flags))
132 conn_get(con); 138 conn_get(con);
139 else
140 con = NULL;
133 spin_unlock_bh(&s->idr_lock); 141 spin_unlock_bh(&s->idr_lock);
134 return con; 142 return con;
135} 143}
@@ -198,15 +206,8 @@ static void tipc_sock_release(struct tipc_conn *con)
198 206
199static void tipc_close_conn(struct tipc_conn *con) 207static void tipc_close_conn(struct tipc_conn *con)
200{ 208{
201 struct tipc_server *s = con->server;
202
203 if (test_and_clear_bit(CF_CONNECTED, &con->flags)) { 209 if (test_and_clear_bit(CF_CONNECTED, &con->flags)) {
204 210
205 spin_lock_bh(&s->idr_lock);
206 idr_remove(&s->conn_idr, con->conid);
207 s->idr_in_use--;
208 spin_unlock_bh(&s->idr_lock);
209
210 /* We shouldn't flush pending works as we may be in the 211 /* We shouldn't flush pending works as we may be in the
211 * thread. In fact the races with pending rx/tx work structs 212 * thread. In fact the races with pending rx/tx work structs
212 * are harmless for us here as we have already deleted this 213 * are harmless for us here as we have already deleted this