summaryrefslogtreecommitdiffstats
path: root/net/rds
diff options
context:
space:
mode:
authorKa-Cheong Poon <ka-cheong.poon@oracle.com>2018-04-11 03:57:25 -0400
committerDavid S. Miller <davem@davemloft.net>2018-04-11 10:24:01 -0400
commita43cced9a348901f9015f4730b70b69e7c41a9c9 (patch)
treeec0daa4fc626f408f90f69d17705e24abb39c016 /net/rds
parent1cc5954f44150bb70cac07c3cc5df7cf0dfb61ec (diff)
rds: MP-RDS may use an invalid c_path
rds_sendmsg() calls rds_send_mprds_hash() to find a c_path to use to send a message. Suppose the RDS connection is not yet up. In rds_send_mprds_hash(), it does if (conn->c_npaths == 0) wait_event_interruptible(conn->c_hs_waitq, (conn->c_npaths != 0)); If it is interrupted before the connection is set up, rds_send_mprds_hash() will return a non-zero hash value. Hence rds_sendmsg() will use a non-zero c_path to send the message. But if the RDS connection ends up to be non-MP capable, the message will be lost as only the zero c_path can be used. Signed-off-by: Ka-Cheong Poon <ka-cheong.poon@oracle.com> Acked-by: Santosh Shilimkar <santosh.shilimkar@oracle.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/rds')
-rw-r--r--net/rds/send.c15
1 files changed, 10 insertions, 5 deletions
diff --git a/net/rds/send.c b/net/rds/send.c
index acad04243b41..94c7f74909be 100644
--- a/net/rds/send.c
+++ b/net/rds/send.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2006 Oracle. All rights reserved. 2 * Copyright (c) 2006, 2018 Oracle and/or its affiliates. All rights reserved.
3 * 3 *
4 * This software is available to you under a choice of one of two 4 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU 5 * licenses. You may choose to be licensed under the terms of the GNU
@@ -1017,10 +1017,15 @@ static int rds_send_mprds_hash(struct rds_sock *rs, struct rds_connection *conn)
1017 if (conn->c_npaths == 0 && hash != 0) { 1017 if (conn->c_npaths == 0 && hash != 0) {
1018 rds_send_ping(conn, 0); 1018 rds_send_ping(conn, 0);
1019 1019
1020 if (conn->c_npaths == 0) { 1020 /* The underlying connection is not up yet. Need to wait
1021 wait_event_interruptible(conn->c_hs_waitq, 1021 * until it is up to be sure that the non-zero c_path can be
1022 (conn->c_npaths != 0)); 1022 * used. But if we are interrupted, we have to use the zero
1023 } 1023 * c_path in case the connection ends up being non-MP capable.
1024 */
1025 if (conn->c_npaths == 0)
1026 if (wait_event_interruptible(conn->c_hs_waitq,
1027 conn->c_npaths != 0))
1028 hash = 0;
1024 if (conn->c_npaths == 1) 1029 if (conn->c_npaths == 1)
1025 hash = 0; 1030 hash = 0;
1026 } 1031 }