|
@@ -86,6 +86,7 @@ struct outqueue_entry {
|
|
|
static void tipc_recv_work(struct work_struct *work);
|
|
|
static void tipc_send_work(struct work_struct *work);
|
|
|
static void tipc_clean_outqueues(struct tipc_conn *con);
|
|
|
+static void tipc_sock_release(struct tipc_conn *con);
|
|
|
|
|
|
static void tipc_conn_kref_release(struct kref *kref)
|
|
|
{
|
|
@@ -102,6 +103,7 @@ static void tipc_conn_kref_release(struct kref *kref)
|
|
|
}
|
|
|
saddr->scope = -TIPC_NODE_SCOPE;
|
|
|
kernel_bind(sock, (struct sockaddr *)saddr, sizeof(*saddr));
|
|
|
+ tipc_sock_release(con);
|
|
|
sock_release(sock);
|
|
|
con->sock = NULL;
|
|
|
}
|
|
@@ -184,26 +186,31 @@ static void tipc_unregister_callbacks(struct tipc_conn *con)
|
|
|
write_unlock_bh(&sk->sk_callback_lock);
|
|
|
}
|
|
|
|
|
|
+static void tipc_sock_release(struct tipc_conn *con)
|
|
|
+{
|
|
|
+ struct tipc_server *s = con->server;
|
|
|
+
|
|
|
+ if (con->conid)
|
|
|
+ s->tipc_conn_release(con->conid, con->usr_data);
|
|
|
+
|
|
|
+ tipc_unregister_callbacks(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)) {
|
|
|
- if (con->conid)
|
|
|
- s->tipc_conn_shutdown(con->conid, con->usr_data);
|
|
|
|
|
|
spin_lock_bh(&s->idr_lock);
|
|
|
idr_remove(&s->conn_idr, con->conid);
|
|
|
s->idr_in_use--;
|
|
|
spin_unlock_bh(&s->idr_lock);
|
|
|
|
|
|
- tipc_unregister_callbacks(con);
|
|
|
-
|
|
|
/* 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
|
|
|
- * connection from server connection list and set
|
|
|
- * sk->sk_user_data to 0 before releasing connection object.
|
|
|
+ * connection from server connection list.
|
|
|
*/
|
|
|
kernel_sock_shutdown(con->sock, SHUT_RDWR);
|
|
|
|