Bluetooth: Fix IPSP connection callback event issue.
[platform/kernel/linux-starfive.git] / net / tipc / topsrv.c
index d92ec92..69c88cc 100644 (file)
@@ -176,7 +176,7 @@ static void tipc_conn_close(struct tipc_conn *con)
        conn_put(con);
 }
 
-static struct tipc_conn *tipc_conn_alloc(struct tipc_topsrv *s)
+static struct tipc_conn *tipc_conn_alloc(struct tipc_topsrv *s, struct socket *sock)
 {
        struct tipc_conn *con;
        int ret;
@@ -202,10 +202,12 @@ static struct tipc_conn *tipc_conn_alloc(struct tipc_topsrv *s)
        }
        con->conid = ret;
        s->idr_in_use++;
-       spin_unlock_bh(&s->idr_lock);
 
        set_bit(CF_CONNECTED, &con->flags);
        con->server = s;
+       con->sock = sock;
+       conn_get(con);
+       spin_unlock_bh(&s->idr_lock);
 
        return con;
 }
@@ -394,7 +396,7 @@ static int tipc_conn_rcv_from_sock(struct tipc_conn *con)
        iov.iov_base = &s;
        iov.iov_len = sizeof(s);
        msg.msg_name = NULL;
-       iov_iter_kvec(&msg.msg_iter, READ, &iov, 1, iov.iov_len);
+       iov_iter_kvec(&msg.msg_iter, ITER_DEST, &iov, 1, iov.iov_len);
        ret = sock_recvmsg(con->sock, &msg, MSG_DONTWAIT);
        if (ret == -EWOULDBLOCK)
                return -EWOULDBLOCK;
@@ -467,7 +469,7 @@ static void tipc_topsrv_accept(struct work_struct *work)
                ret = kernel_accept(lsock, &newsock, O_NONBLOCK);
                if (ret < 0)
                        return;
-               con = tipc_conn_alloc(srv);
+               con = tipc_conn_alloc(srv, newsock);
                if (IS_ERR(con)) {
                        ret = PTR_ERR(con);
                        sock_release(newsock);
@@ -479,11 +481,11 @@ static void tipc_topsrv_accept(struct work_struct *work)
                newsk->sk_data_ready = tipc_conn_data_ready;
                newsk->sk_write_space = tipc_conn_write_space;
                newsk->sk_user_data = con;
-               con->sock = newsock;
                write_unlock_bh(&newsk->sk_callback_lock);
 
                /* Wake up receive process in case of 'SYN+' message */
                newsk->sk_data_ready(newsk);
+               conn_put(con);
        }
 }
 
@@ -577,17 +579,17 @@ bool tipc_topsrv_kern_subscr(struct net *net, u32 port, u32 type, u32 lower,
        sub.filter = filter;
        *(u64 *)&sub.usr_handle = (u64)port;
 
-       con = tipc_conn_alloc(tipc_topsrv(net));
+       con = tipc_conn_alloc(tipc_topsrv(net), NULL);
        if (IS_ERR(con))
                return false;
 
        *conid = con->conid;
-       con->sock = NULL;
        rc = tipc_conn_rcv_sub(tipc_topsrv(net), con, &sub);
-       if (rc >= 0)
-               return true;
+       if (rc)
+               conn_put(con);
+
        conn_put(con);
-       return false;
+       return !rc;
 }
 
 void tipc_topsrv_kern_unsubscr(struct net *net, int conid)