aboutsummaryrefslogtreecommitdiffstats
path: root/net/rds/bind.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/rds/bind.c')
-rw-r--r--net/rds/bind.c40
1 files changed, 18 insertions, 22 deletions
diff --git a/net/rds/bind.c b/net/rds/bind.c
index 6dbb763bc1fd..20c156a73e73 100644
--- a/net/rds/bind.c
+++ b/net/rds/bind.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2006, 2018 Oracle and/or its affiliates. All rights reserved. 2 * Copyright (c) 2006, 2019 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
@@ -239,34 +239,30 @@ int rds_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
239 goto out; 239 goto out;
240 } 240 }
241 241
242 sock_set_flag(sk, SOCK_RCU_FREE); 242 /* The transport can be set using SO_RDS_TRANSPORT option before the
243 ret = rds_add_bound(rs, binding_addr, &port, scope_id); 243 * socket is bound.
244 if (ret) 244 */
245 goto out; 245 if (rs->rs_transport) {
246
247 if (rs->rs_transport) { /* previously bound */
248 trans = rs->rs_transport; 246 trans = rs->rs_transport;
249 if (trans->laddr_check(sock_net(sock->sk), 247 if (trans->laddr_check(sock_net(sock->sk),
250 binding_addr, scope_id) != 0) { 248 binding_addr, scope_id) != 0) {
251 ret = -ENOPROTOOPT; 249 ret = -ENOPROTOOPT;
252 rds_remove_bound(rs); 250 goto out;
253 } else {
254 ret = 0;
255 } 251 }
256 goto out; 252 } else {
257 } 253 trans = rds_trans_get_preferred(sock_net(sock->sk),
258 trans = rds_trans_get_preferred(sock_net(sock->sk), binding_addr, 254 binding_addr, scope_id);
259 scope_id); 255 if (!trans) {
260 if (!trans) { 256 ret = -EADDRNOTAVAIL;
261 ret = -EADDRNOTAVAIL; 257 pr_info_ratelimited("RDS: %s could not find a transport for %pI6c, load rds_tcp or rds_rdma?\n",
262 rds_remove_bound(rs); 258 __func__, binding_addr);
263 pr_info_ratelimited("RDS: %s could not find a transport for %pI6c, load rds_tcp or rds_rdma?\n", 259 goto out;
264 __func__, binding_addr); 260 }
265 goto out; 261 rs->rs_transport = trans;
266 } 262 }
267 263
268 rs->rs_transport = trans; 264 sock_set_flag(sk, SOCK_RCU_FREE);
269 ret = 0; 265 ret = rds_add_bound(rs, binding_addr, &port, scope_id);
270 266
271out: 267out:
272 release_sock(sk); 268 release_sock(sk);