diff options
Diffstat (limited to 'net/rds/af_rds.c')
| -rw-r--r-- | net/rds/af_rds.c | 26 | 
1 files changed, 22 insertions, 4 deletions
diff --git a/net/rds/af_rds.c b/net/rds/af_rds.c index aebfecbdb84..bb6ad81b671 100644 --- a/net/rds/af_rds.c +++ b/net/rds/af_rds.c @@ -39,7 +39,15 @@  #include <net/sock.h>  #include "rds.h" -#include "rdma.h" + +char *rds_str_array(char **array, size_t elements, size_t index) +{ +	if ((index < elements) && array[index]) +		return array[index]; +	else +		return "unknown"; +} +EXPORT_SYMBOL(rds_str_array);  /* this is just used for stats gathering :/ */  static DEFINE_SPINLOCK(rds_sock_lock); @@ -62,7 +70,7 @@ static int rds_release(struct socket *sock)  	struct rds_sock *rs;  	unsigned long flags; -	if (sk == NULL) +	if (!sk)  		goto out;  	rs = rds_sk_to_rs(sk); @@ -73,7 +81,15 @@ static int rds_release(struct socket *sock)  	 * with the socket. */  	rds_clear_recv_queue(rs);  	rds_cong_remove_socket(rs); + +	/* +	 * the binding lookup hash uses rcu, we need to +	 * make sure we sychronize_rcu before we free our +	 * entry +	 */  	rds_remove_bound(rs); +	synchronize_rcu(); +  	rds_send_drop_to(rs, NULL);  	rds_rdma_drop_keys(rs);  	rds_notify_queue_get(rs, NULL); @@ -83,6 +99,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: @@ -514,7 +532,7 @@ out:  	spin_unlock_irqrestore(&rds_sock_lock, flags);  } -static void __exit rds_exit(void) +static void rds_exit(void)  {  	sock_unregister(rds_family_ops.family);  	proto_unregister(&rds_proto); @@ -529,7 +547,7 @@ static void __exit rds_exit(void)  }  module_exit(rds_exit); -static int __init rds_init(void) +static int rds_init(void)  {  	int ret;  |