Merge branch 'misc' of git://git.kernel.org/pub/scm/linux/kernel/git/mmarek/kbuild
[linux-2.6-microblaze.git] / net / tipc / socket.c
index dbce274..9b4e483 100644 (file)
@@ -946,13 +946,6 @@ restart:
        sz = msg_data_sz(msg);
        err = msg_errcode(msg);
 
-       /* Complete connection setup for an implied connect */
-       if (unlikely(sock->state == SS_CONNECTING)) {
-               res = auto_connect(sock, msg);
-               if (res)
-                       goto exit;
-       }
-
        /* Discard an empty non-errored message & try again */
        if ((!sz) && (!err)) {
                advance_rx_queue(sk);
@@ -1516,8 +1509,13 @@ static int listen(struct socket *sock, int len)
  */
 static int accept(struct socket *sock, struct socket *new_sock, int flags)
 {
-       struct sock *sk = sock->sk;
+       struct sock *new_sk, *sk = sock->sk;
        struct sk_buff *buf;
+       struct tipc_sock *new_tsock;
+       struct tipc_port *new_tport;
+       struct tipc_msg *msg;
+       u32 new_ref;
+
        int res;
 
        lock_sock(sk);
@@ -1543,48 +1541,51 @@ static int accept(struct socket *sock, struct socket *new_sock, int flags)
        buf = skb_peek(&sk->sk_receive_queue);
 
        res = tipc_create(sock_net(sock->sk), new_sock, 0, 0);
-       if (!res) {
-               struct sock *new_sk = new_sock->sk;
-               struct tipc_sock *new_tsock = tipc_sk(new_sk);
-               struct tipc_port *new_tport = new_tsock->p;
-               u32 new_ref = new_tport->ref;
-               struct tipc_msg *msg = buf_msg(buf);
-
-               lock_sock(new_sk);
-
-               /*
-                * Reject any stray messages received by new socket
-                * before the socket lock was taken (very, very unlikely)
-                */
-               reject_rx_queue(new_sk);
-
-               /* Connect new socket to it's peer */
-               new_tsock->peer_name.ref = msg_origport(msg);
-               new_tsock->peer_name.node = msg_orignode(msg);
-               tipc_connect(new_ref, &new_tsock->peer_name);
-               new_sock->state = SS_CONNECTED;
-
-               tipc_set_portimportance(new_ref, msg_importance(msg));
-               if (msg_named(msg)) {
-                       new_tport->conn_type = msg_nametype(msg);
-                       new_tport->conn_instance = msg_nameinst(msg);
-               }
+       if (res)
+               goto exit;
 
-               /*
-                * Respond to 'SYN-' by discarding it & returning 'ACK'-.
-                * Respond to 'SYN+' by queuing it on new socket.
-                */
-               if (!msg_data_sz(msg)) {
-                       struct msghdr m = {NULL,};
+       new_sk = new_sock->sk;
+       new_tsock = tipc_sk(new_sk);
+       new_tport = new_tsock->p;
+       new_ref = new_tport->ref;
+       msg = buf_msg(buf);
 
-                       advance_rx_queue(sk);
-                       send_packet(NULL, new_sock, &m, 0);
-               } else {
-                       __skb_dequeue(&sk->sk_receive_queue);
-                       __skb_queue_head(&new_sk->sk_receive_queue, buf);
-               }
-               release_sock(new_sk);
+       /* we lock on new_sk; but lockdep sees the lock on sk */
+       lock_sock_nested(new_sk, SINGLE_DEPTH_NESTING);
+
+       /*
+        * Reject any stray messages received by new socket
+        * before the socket lock was taken (very, very unlikely)
+        */
+       reject_rx_queue(new_sk);
+
+       /* Connect new socket to it's peer */
+       new_tsock->peer_name.ref = msg_origport(msg);
+       new_tsock->peer_name.node = msg_orignode(msg);
+       tipc_connect(new_ref, &new_tsock->peer_name);
+       new_sock->state = SS_CONNECTED;
+
+       tipc_set_portimportance(new_ref, msg_importance(msg));
+       if (msg_named(msg)) {
+               new_tport->conn_type = msg_nametype(msg);
+               new_tport->conn_instance = msg_nameinst(msg);
        }
+
+       /*
+        * Respond to 'SYN-' by discarding it & returning 'ACK'-.
+        * Respond to 'SYN+' by queuing it on new socket.
+        */
+       if (!msg_data_sz(msg)) {
+               struct msghdr m = {NULL,};
+
+               advance_rx_queue(sk);
+               send_packet(NULL, new_sock, &m, 0);
+       } else {
+               __skb_dequeue(&sk->sk_receive_queue);
+               __skb_queue_head(&new_sk->sk_receive_queue, buf);
+       }
+       release_sock(new_sk);
+
 exit:
        release_sock(sk);
        return res;