From 4ef6c39a72b06fdab35286e7960d7f0b31d23161 Mon Sep 17 00:00:00 2001 From: Zach Brown Date: Fri, 23 Jul 2010 10:32:31 -0700 Subject: [PATCH] --- yaml --- r: 214467 b: refs/heads/master c: 5adb5bc65f93e52341c3fc9d03d4030dd375e256 h: refs/heads/master i: 214465: f6c1f8219c9e59b4a0f0f8b77b6f9eba4e9e9719 214463: fc850d6e81fe0390a68295b989e1d8dc020bcd42 v: v3 --- [refs] | 2 +- trunk/net/rds/af_rds.c | 2 ++ trunk/net/rds/connection.c | 5 ++++- trunk/net/rds/rds.h | 1 + trunk/net/rds/transport.c | 19 ++++++++++++++----- 5 files changed, 22 insertions(+), 7 deletions(-) diff --git a/[refs] b/[refs] index 7fdf73d3156f..84e08c5d55c0 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 77510481c0c3980c8979ed236d63e59221fb8ce5 +refs/heads/master: 5adb5bc65f93e52341c3fc9d03d4030dd375e256 diff --git a/trunk/net/rds/af_rds.c b/trunk/net/rds/af_rds.c index 57ef0ec4f03d..8e3886d353b5 100644 --- a/trunk/net/rds/af_rds.c +++ b/trunk/net/rds/af_rds.c @@ -90,6 +90,8 @@ static int rds_release(struct socket *sock) rds_sock_count--; spin_unlock_irqrestore(&rds_sock_lock, flags); + rds_trans_put(rs->rs_transport); + sock->sk = NULL; sock_put(sk); out: diff --git a/trunk/net/rds/connection.c b/trunk/net/rds/connection.c index 75a1a37d64d3..968b7a798398 100644 --- a/trunk/net/rds/connection.c +++ b/trunk/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 diff --git a/trunk/net/rds/rds.h b/trunk/net/rds/rds.h index 2ff7fc9f0539..aab5e949fa93 100644 --- a/trunk/net/rds/rds.h +++ b/trunk/net/rds/rds.h @@ -798,6 +798,7 @@ void rds_connect_complete(struct rds_connection *conn); int rds_trans_register(struct rds_transport *trans); void rds_trans_unregister(struct rds_transport *trans); struct rds_transport *rds_trans_get_preferred(__be32 addr); +void rds_trans_put(struct rds_transport *trans); unsigned int rds_trans_stats_info_copy(struct rds_info_iterator *iter, unsigned int avail); int rds_trans_init(void); diff --git a/trunk/net/rds/transport.c b/trunk/net/rds/transport.c index 7e1067901353..7f2ac4fec367 100644 --- a/trunk/net/rds/transport.c +++ b/trunk/net/rds/transport.c @@ -71,19 +71,28 @@ void rds_trans_unregister(struct rds_transport *trans) } EXPORT_SYMBOL_GPL(rds_trans_unregister); +void rds_trans_put(struct rds_transport *trans) +{ + if (trans && trans->t_owner) + module_put(trans->t_owner); +} + struct rds_transport *rds_trans_get_preferred(__be32 addr) { struct rds_transport *ret = NULL; - int i; + struct rds_transport *trans; + unsigned int i; if (IN_LOOPBACK(ntohl(addr))) return &rds_loop_transport; down_read(&rds_trans_sem); - for (i = 0; i < RDS_TRANS_COUNT; i++) - { - if (transports[i] && (transports[i]->laddr_check(addr) == 0)) { - ret = transports[i]; + for (i = 0; i < RDS_TRANS_COUNT; i++) { + trans = transports[i]; + + if (trans && (trans->laddr_check(addr) == 0) && + (!trans->t_owner || try_module_get(trans->t_owner))) { + ret = trans; break; } }