diff options
author | Ka-Cheong Poon <ka-cheong.poon@oracle.com> | 2018-04-11 03:57:25 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-04-11 10:24:01 -0400 |
commit | a43cced9a348901f9015f4730b70b69e7c41a9c9 (patch) | |
tree | ec0daa4fc626f408f90f69d17705e24abb39c016 /net/rds | |
parent | 1cc5954f44150bb70cac07c3cc5df7cf0dfb61ec (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.c | 15 |
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 | } |