diff options
Diffstat (limited to 'net/rds/bind.c')
-rw-r--r-- | net/rds/bind.c | 40 |
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 | ||
271 | out: | 267 | out: |
272 | release_sock(sk); | 268 | release_sock(sk); |