From 5adb5bc65f93e52341c3fc9d03d4030dd375e256 Mon Sep 17 00:00:00 2001 From: Zach Brown Date: Fri, 23 Jul 2010 10:32:31 -0700 Subject: RDS: have sockets get transport module references Right now there's nothing to stop the various paths that use rs->rs_transport from racing with rmmod and executing freed transport code. The simple fix is to have binding to a transport also hold a reference to the transport's module, removing this class of races. We already had an unused t_owner field which was set for the modular transports and which wasn't set for the built-in loop transport. Signed-off-by: Zach Brown --- net/rds/connection.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'net/rds/connection.c') diff --git a/net/rds/connection.c b/net/rds/connection.c index 75a1a37d64d..968b7a79839 100644 --- a/net/rds/connection.c +++ b/net/rds/connection.c @@ -117,6 +117,7 @@ static struct rds_connection *__rds_conn_create(__be32 laddr, __be32 faddr, { struct rds_connection *conn, *parent = NULL; struct hlist_head *head = rds_conn_bucket(laddr, faddr); + struct rds_transport *loop_trans; unsigned long flags; int ret; @@ -163,7 +164,9 @@ static struct rds_connection *__rds_conn_create(__be32 laddr, __be32 faddr, * can bind to the destination address then we'd rather the messages * flow through loopback rather than either transport. */ - if (rds_trans_get_preferred(faddr)) { + loop_trans = rds_trans_get_preferred(faddr); + if (loop_trans) { + rds_trans_put(loop_trans); conn->c_loopback = 1; if (is_outgoing && trans->t_prefer_loopback) { /* "outgoing" connection - and the transport -- cgit v1.2.3