diff options
Diffstat (limited to 'net/rds')
-rw-r--r-- | net/rds/send.c | 11 | ||||
-rw-r--r-- | net/rds/tcp_connect.c | 5 | ||||
-rw-r--r-- | net/rds/threads.c | 3 |
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 | */ |
645 | void rds_send_drop_acked(struct rds_connection *conn, u64 ack, | 645 | void 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 | ||
115 | out: | 118 | out: |
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 | ||