aboutsummaryrefslogtreecommitdiffstats
path: root/net/rds
diff options
context:
space:
mode:
Diffstat (limited to 'net/rds')
-rw-r--r--net/rds/send.c11
-rw-r--r--net/rds/tcp_connect.c5
-rw-r--r--net/rds/threads.c3
3 files changed, 12 insertions, 7 deletions
diff --git a/net/rds/send.c b/net/rds/send.c
index 23718160d71e..0a64541020b0 100644
--- a/net/rds/send.c
+++ b/net/rds/send.c
@@ -593,8 +593,11 @@ static void rds_send_remove_from_sock(struct list_head *messages, int status)
593 sock_put(rds_rs_to_sk(rs)); 593 sock_put(rds_rs_to_sk(rs));
594 } 594 }
595 rs = rm->m_rs; 595 rs = rm->m_rs;
596 sock_hold(rds_rs_to_sk(rs)); 596 if (rs)
597 sock_hold(rds_rs_to_sk(rs));
597 } 598 }
599 if (!rs)
600 goto unlock_and_drop;
598 spin_lock(&rs->rs_lock); 601 spin_lock(&rs->rs_lock);
599 602
600 if (test_and_clear_bit(RDS_MSG_ON_SOCK, &rm->m_flags)) { 603 if (test_and_clear_bit(RDS_MSG_ON_SOCK, &rm->m_flags)) {
@@ -638,9 +641,6 @@ unlock_and_drop:
638 * queue. This means that in the TCP case, the message may not have been 641 * queue. This means that in the TCP case, the message may not have been
639 * assigned the m_ack_seq yet - but that's fine as long as tcp_is_acked 642 * assigned the m_ack_seq yet - but that's fine as long as tcp_is_acked
640 * checks the RDS_MSG_HAS_ACK_SEQ bit. 643 * checks the RDS_MSG_HAS_ACK_SEQ bit.
641 *
642 * XXX It's not clear to me how this is safely serialized with socket
643 * destruction. Maybe it should bail if it sees SOCK_DEAD.
644 */ 644 */
645void rds_send_drop_acked(struct rds_connection *conn, u64 ack, 645void rds_send_drop_acked(struct rds_connection *conn, u64 ack,
646 is_acked_func is_acked) 646 is_acked_func is_acked)
@@ -711,6 +711,9 @@ void rds_send_drop_to(struct rds_sock *rs, struct sockaddr_in *dest)
711 */ 711 */
712 if (!test_and_clear_bit(RDS_MSG_ON_CONN, &rm->m_flags)) { 712 if (!test_and_clear_bit(RDS_MSG_ON_CONN, &rm->m_flags)) {
713 spin_unlock_irqrestore(&conn->c_lock, flags); 713 spin_unlock_irqrestore(&conn->c_lock, flags);
714 spin_lock_irqsave(&rm->m_rs_lock, flags);
715 rm->m_rs = NULL;
716 spin_unlock_irqrestore(&rm->m_rs_lock, flags);
714 continue; 717 continue;
715 } 718 }
716 list_del_init(&rm->m_conn_item); 719 list_del_init(&rm->m_conn_item);
diff --git a/net/rds/tcp_connect.c b/net/rds/tcp_connect.c
index a65ee78db0c5..f9f564a6c960 100644
--- a/net/rds/tcp_connect.c
+++ b/net/rds/tcp_connect.c
@@ -106,11 +106,14 @@ int rds_tcp_conn_connect(struct rds_connection *conn)
106 rds_tcp_set_callbacks(sock, conn); 106 rds_tcp_set_callbacks(sock, conn);
107 ret = sock->ops->connect(sock, (struct sockaddr *)&dest, sizeof(dest), 107 ret = sock->ops->connect(sock, (struct sockaddr *)&dest, sizeof(dest),
108 O_NONBLOCK); 108 O_NONBLOCK);
109 sock = NULL;
110 109
111 rdsdebug("connect to address %pI4 returned %d\n", &conn->c_faddr, ret); 110 rdsdebug("connect to address %pI4 returned %d\n", &conn->c_faddr, ret);
112 if (ret == -EINPROGRESS) 111 if (ret == -EINPROGRESS)
113 ret = 0; 112 ret = 0;
113 if (ret == 0)
114 sock = NULL;
115 else
116 rds_tcp_restore_callbacks(sock, conn->c_transport_data);
114 117
115out: 118out:
116 if (sock) 119 if (sock)
diff --git a/net/rds/threads.c b/net/rds/threads.c
index 65eaefcab241..dc2402e871fd 100644
--- a/net/rds/threads.c
+++ b/net/rds/threads.c
@@ -78,8 +78,7 @@ void rds_connect_complete(struct rds_connection *conn)
78 "current state is %d\n", 78 "current state is %d\n",
79 __func__, 79 __func__,
80 atomic_read(&conn->c_state)); 80 atomic_read(&conn->c_state));
81 atomic_set(&conn->c_state, RDS_CONN_ERROR); 81 rds_conn_drop(conn);
82 queue_work(rds_wq, &conn->c_down_w);
83 return; 82 return;
84 } 83 }
85 84