Merge branch 'linux-2.6'
[powerpc.git] / fs / dlm / lowcomms.c
index dd36273..7c1e5e5 100644 (file)
@@ -313,6 +313,7 @@ static void make_sockaddr(struct sockaddr_storage *saddr, uint16_t port,
                in6_addr->sin6_port = cpu_to_be16(port);
                *addr_len = sizeof(struct sockaddr_in6);
        }
+       memset((char *)saddr + *addr_len, 0, sizeof(struct sockaddr_storage) - *addr_len);
 }
 
 /* Close a remote connection and tidy up */
@@ -332,6 +333,7 @@ static void close_connection(struct connection *con, bool and_other)
                __free_page(con->rx_page);
                con->rx_page = NULL;
        }
+
        con->retries = 0;
        mutex_unlock(&con->sock_mutex);
 }
@@ -631,7 +633,7 @@ out_resched:
 
 out_close:
        mutex_unlock(&con->sock_mutex);
-       if (ret != -EAGAIN && !test_bit(CF_IS_OTHERCON, &con->flags)) {
+       if (ret != -EAGAIN) {
                close_connection(con, false);
                /* Reconnect when there is something to send */
        }
@@ -719,6 +721,8 @@ static int tcp_accept_from_sock(struct connection *con)
                        INIT_WORK(&othercon->swork, process_send_sockets);
                        INIT_WORK(&othercon->rwork, process_recv_sockets);
                        set_bit(CF_IS_OTHERCON, &othercon->flags);
+               }
+               if (!othercon->sock) {
                        newcon->othercon = othercon;
                        othercon->sock = newsock;
                        newsock->sk->sk_user_data = othercon;
@@ -860,7 +864,7 @@ static void sctp_init_assoc(struct connection *con)
 static void tcp_connect_to_sock(struct connection *con)
 {
        int result = -EHOSTUNREACH;
-       struct sockaddr_storage saddr;
+       struct sockaddr_storage saddr, src_addr;
        int addr_len;
        struct socket *sock;
 
@@ -894,6 +898,17 @@ static void tcp_connect_to_sock(struct connection *con)
        con->connect_action = tcp_connect_to_sock;
        add_sock(sock, con);
 
+       /* Bind to our cluster-known address connecting to avoid
+          routing problems */
+       memcpy(&src_addr, dlm_local_addr[0], sizeof(src_addr));
+       make_sockaddr(&src_addr, 0, &addr_len);
+       result = sock->ops->bind(sock, (struct sockaddr *) &src_addr,
+                                addr_len);
+       if (result < 0) {
+               log_print("could not bind for connect: %d", result);
+               /* This *may* not indicate a critical error */
+       }
+
        make_sockaddr(&saddr, dlm_config.ci_tcp_port, &addr_len);
 
        log_print("connecting to %d", con->nodeid);
@@ -1058,7 +1073,7 @@ static int sctp_listen_for_all(void)
        subscribe.sctp_shutdown_event = 1;
        subscribe.sctp_partial_delivery_event = 1;
 
-       result = kernel_setsockopt(sock, SOL_SOCKET, SO_RCVBUF,
+       result = kernel_setsockopt(sock, SOL_SOCKET, SO_RCVBUFFORCE,
                                 (char *)&bufsize, sizeof(bufsize));
        if (result)
                log_print("Error increasing buffer space on socket %d", result);
@@ -1122,8 +1137,6 @@ static int tcp_listen_for_all(void)
 
        log_print("Using TCP for communications");
 
-       set_bit(CF_IS_OTHERCON, &con->flags);
-
        sock = tcp_create_listen_sock(con, dlm_local_addr[0]);
        if (sock) {
                add_sock(sock, con);
@@ -1262,14 +1275,15 @@ static void send_to_sock(struct connection *con)
                if (len) {
                        ret = sendpage(con->sock, e->page, offset, len,
                                       msg_flags);
-                       if (ret == -EAGAIN || ret == 0)
+                       if (ret == -EAGAIN || ret == 0) {
+                               cond_resched();
                                goto out;
+                       }
                        if (ret <= 0)
                                goto send_error;
-               } else {
+               }
                        /* Don't starve people filling buffers */
                        cond_resched();
-               }
 
                spin_lock(&con->writequeue_lock);
                e->offset += ret;
@@ -1407,7 +1421,7 @@ void dlm_lowcomms_stop(void)
        for (i = 0; i <= max_nodeid; i++) {
                con = __nodeid2con(i, 0);
                if (con) {
-                       con->flags |= 0xFF;
+                       con->flags |= 0x0F;
                        if (con->sock)
                                con->sock->sk->sk_user_data = NULL;
                }
@@ -1453,10 +1467,6 @@ int dlm_lowcomms_start(void)
        if (!con_cache)
                goto out;
 
-       /* Set some sysctl minima */
-       if (sysctl_rmem_max < NEEDED_RMEM)
-               sysctl_rmem_max = NEEDED_RMEM;
-
        /* Start listening */
        if (dlm_config.ci_protocol == 0)
                error = tcp_listen_for_all();