Commit a43cced9 authored by Ka-Cheong Poon's avatar Ka-Cheong Poon Committed by David S. Miller

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: default avatarKa-Cheong Poon <ka-cheong.poon@oracle.com>
Acked-by: default avatarSantosh Shilimkar <santosh.shilimkar@oracle.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 1cc5954f
/* /*
* Copyright (c) 2006 Oracle. All rights reserved. * Copyright (c) 2006, 2018 Oracle and/or its affiliates. All rights reserved.
* *
* This software is available to you under a choice of one of two * This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU * 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,10 +1017,15 @@ static int rds_send_mprds_hash(struct rds_sock *rs, struct rds_connection *conn)
if (conn->c_npaths == 0 && hash != 0) { if (conn->c_npaths == 0 && hash != 0) {
rds_send_ping(conn, 0); rds_send_ping(conn, 0);
if (conn->c_npaths == 0) { /* The underlying connection is not up yet. Need to wait
wait_event_interruptible(conn->c_hs_waitq, * until it is up to be sure that the non-zero c_path can be
(conn->c_npaths != 0)); * used. But if we are interrupted, we have to use the zero
} * c_path in case the connection ends up being non-MP capable.
*/
if (conn->c_npaths == 0)
if (wait_event_interruptible(conn->c_hs_waitq,
conn->c_npaths != 0))
hash = 0;
if (conn->c_npaths == 1) if (conn->c_npaths == 1)
hash = 0; hash = 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment