summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--net/rds/connection.c1
-rw-r--r--net/rds/rds.h3
-rw-r--r--net/rds/tcp.h1
-rw-r--r--net/rds/tcp_connect.c2
-rw-r--r--net/rds/tcp_listen.c2
5 files changed, 7 insertions, 2 deletions
diff --git a/net/rds/connection.c b/net/rds/connection.c
index 382443b060cb..50a3789ac23e 100644
--- a/net/rds/connection.c
+++ b/net/rds/connection.c
@@ -412,6 +412,7 @@ void rds_conn_destroy(struct rds_connection *conn)
"%pI4\n", conn, &conn->c_laddr,
&conn->c_faddr);
+ conn->c_destroy_in_prog = 1;
/* Ensure conn will not be scheduled for reconnect */
spin_lock_irq(&rds_conn_lock);
hlist_del_init_rcu(&conn->c_hash_node);
diff --git a/net/rds/rds.h b/net/rds/rds.h
index aa696b361e20..4a25db7075b1 100644
--- a/net/rds/rds.h
+++ b/net/rds/rds.h
@@ -137,7 +137,8 @@ struct rds_connection {
__be32 c_faddr;
unsigned int c_loopback:1,
c_ping_triggered:1,
- c_pad_to_32:30;
+ c_destroy_in_prog:1,
+ c_pad_to_32:29;
int c_npaths;
struct rds_connection *c_passive;
struct rds_transport *c_trans;
diff --git a/net/rds/tcp.h b/net/rds/tcp.h
index 56ea6620fcf9..f8800b7ce79c 100644
--- a/net/rds/tcp.h
+++ b/net/rds/tcp.h
@@ -71,6 +71,7 @@ void rds_tcp_listen_data_ready(struct sock *sk);
int rds_tcp_accept_one(struct socket *sock);
int rds_tcp_keepalive(struct socket *sock);
void *rds_tcp_listen_sock_def_readable(struct net *net);
+void rds_tcp_set_linger(struct socket *sock);
/* tcp_recv.c */
int rds_tcp_recv_init(void);
diff --git a/net/rds/tcp_connect.c b/net/rds/tcp_connect.c
index 5a62a083bb5a..cbe08a1fa4c7 100644
--- a/net/rds/tcp_connect.c
+++ b/net/rds/tcp_connect.c
@@ -170,6 +170,8 @@ void rds_tcp_conn_path_shutdown(struct rds_conn_path *cp)
cp->cp_conn, tc, sock);
if (sock) {
+ if (cp->cp_conn->c_destroy_in_prog)
+ rds_tcp_set_linger(sock);
sock->ops->shutdown(sock, RCV_SHUTDOWN | SEND_SHUTDOWN);
lock_sock(sock->sk);
rds_tcp_restore_callbacks(sock, tc); /* tc->tc_sock = NULL */
diff --git a/net/rds/tcp_listen.c b/net/rds/tcp_listen.c
index 6089e9a8e00a..c6dc8caaf5ca 100644
--- a/net/rds/tcp_listen.c
+++ b/net/rds/tcp_listen.c
@@ -112,7 +112,7 @@ struct rds_tcp_connection *rds_tcp_accept_one_path(struct rds_connection *conn)
return NULL;
}
-static void rds_tcp_set_linger(struct socket *sock)
+void rds_tcp_set_linger(struct socket *sock)
{
struct linger no_linger = {
.l_onoff = 1,