Merge tag 'powerpc-4.9-2' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc...
[cascardo/linux.git] / net / rds / tcp_connect.c
index f6e95d6..05f61c5 100644 (file)
 void rds_tcp_state_change(struct sock *sk)
 {
        void (*state_change)(struct sock *sk);
-       struct rds_connection *conn;
+       struct rds_conn_path *cp;
        struct rds_tcp_connection *tc;
 
        read_lock_bh(&sk->sk_callback_lock);
-       conn = sk->sk_user_data;
-       if (!conn) {
+       cp = sk->sk_user_data;
+       if (!cp) {
                state_change = sk->sk_state_change;
                goto out;
        }
-       tc = conn->c_transport_data;
+       tc = cp->cp_transport_data;
        state_change = tc->t_orig_state_change;
 
        rdsdebug("sock %p state_change to %d\n", tc->t_sock, sk->sk_state);
@@ -60,11 +60,11 @@ void rds_tcp_state_change(struct sock *sk)
        case TCP_SYN_RECV:
                break;
        case TCP_ESTABLISHED:
-               rds_connect_path_complete(conn, RDS_CONN_CONNECTING);
+               rds_connect_path_complete(cp, RDS_CONN_CONNECTING);
                break;
        case TCP_CLOSE_WAIT:
        case TCP_CLOSE:
-               rds_conn_drop(conn);
+               rds_conn_path_drop(cp);
        default:
                break;
        }
@@ -73,17 +73,24 @@ out:
        state_change(sk);
 }
 
-int rds_tcp_conn_connect(struct rds_connection *conn)
+int rds_tcp_conn_path_connect(struct rds_conn_path *cp)
 {
        struct socket *sock = NULL;
        struct sockaddr_in src, dest;
        int ret;
-       struct rds_tcp_connection *tc = conn->c_transport_data;
+       struct rds_connection *conn = cp->cp_conn;
+       struct rds_tcp_connection *tc = cp->cp_transport_data;
 
-       mutex_lock(&tc->t_conn_lock);
+       /* for multipath rds,we only trigger the connection after
+        * the handshake probe has determined the number of paths.
+        */
+       if (cp->cp_index > 0 && cp->cp_conn->c_npaths < 2)
+               return -EAGAIN;
+
+       mutex_lock(&tc->t_conn_path_lock);
 
-       if (rds_conn_up(conn)) {
-               mutex_unlock(&tc->t_conn_lock);
+       if (rds_conn_path_up(cp)) {
+               mutex_unlock(&tc->t_conn_path_lock);
                return 0;
        }
        ret = sock_create_kern(rds_conn_net(conn), PF_INET,
@@ -112,10 +119,11 @@ int rds_tcp_conn_connect(struct rds_connection *conn)
         * once we call connect() we can start getting callbacks and they
         * own the socket
         */
-       rds_tcp_set_callbacks(sock, conn);
+       rds_tcp_set_callbacks(sock, cp);
        ret = sock->ops->connect(sock, (struct sockaddr *)&dest, sizeof(dest),
                                 O_NONBLOCK);
 
+       cp->cp_outgoing = 1;
        rdsdebug("connect to address %pI4 returned %d\n", &conn->c_faddr, ret);
        if (ret == -EINPROGRESS)
                ret = 0;
@@ -123,11 +131,11 @@ int rds_tcp_conn_connect(struct rds_connection *conn)
                rds_tcp_keepalive(sock);
                sock = NULL;
        } else {
-               rds_tcp_restore_callbacks(sock, conn->c_transport_data);
+               rds_tcp_restore_callbacks(sock, cp->cp_transport_data);
        }
 
 out:
-       mutex_unlock(&tc->t_conn_lock);
+       mutex_unlock(&tc->t_conn_path_lock);
        if (sock)
                sock_release(sock);
        return ret;
@@ -142,12 +150,13 @@ out:
  * callbacks to those set by TCP.  Our callbacks won't execute again once we
  * hold the sock lock.
  */
-void rds_tcp_conn_shutdown(struct rds_connection *conn)
+void rds_tcp_conn_path_shutdown(struct rds_conn_path *cp)
 {
-       struct rds_tcp_connection *tc = conn->c_transport_data;
+       struct rds_tcp_connection *tc = cp->cp_transport_data;
        struct socket *sock = tc->t_sock;
 
-       rdsdebug("shutting down conn %p tc %p sock %p\n", conn, tc, sock);
+       rdsdebug("shutting down conn %p tc %p sock %p\n",
+                cp->cp_conn, tc, sock);
 
        if (sock) {
                sock->ops->shutdown(sock, RCV_SHUTDOWN | SEND_SHUTDOWN);