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,