diff options
Diffstat (limited to 'net/sunrpc/xprtsock.c')
-rw-r--r-- | net/sunrpc/xprtsock.c | 226 |
1 files changed, 146 insertions, 80 deletions
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 6fa52f44de0f..30e7ac243a90 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c | |||
@@ -280,7 +280,9 @@ static inline struct sockaddr_in6 *xs_addr_in6(struct rpc_xprt *xprt) | |||
280 | return (struct sockaddr_in6 *) &xprt->addr; | 280 | return (struct sockaddr_in6 *) &xprt->addr; |
281 | } | 281 | } |
282 | 282 | ||
283 | static void xs_format_ipv4_peer_addresses(struct rpc_xprt *xprt) | 283 | static void xs_format_ipv4_peer_addresses(struct rpc_xprt *xprt, |
284 | const char *protocol, | ||
285 | const char *netid) | ||
284 | { | 286 | { |
285 | struct sockaddr_in *addr = xs_addr_in(xprt); | 287 | struct sockaddr_in *addr = xs_addr_in(xprt); |
286 | char *buf; | 288 | char *buf; |
@@ -299,21 +301,14 @@ static void xs_format_ipv4_peer_addresses(struct rpc_xprt *xprt) | |||
299 | } | 301 | } |
300 | xprt->address_strings[RPC_DISPLAY_PORT] = buf; | 302 | xprt->address_strings[RPC_DISPLAY_PORT] = buf; |
301 | 303 | ||
302 | buf = kzalloc(8, GFP_KERNEL); | 304 | xprt->address_strings[RPC_DISPLAY_PROTO] = protocol; |
303 | if (buf) { | ||
304 | if (xprt->prot == IPPROTO_UDP) | ||
305 | snprintf(buf, 8, "udp"); | ||
306 | else | ||
307 | snprintf(buf, 8, "tcp"); | ||
308 | } | ||
309 | xprt->address_strings[RPC_DISPLAY_PROTO] = buf; | ||
310 | 305 | ||
311 | buf = kzalloc(48, GFP_KERNEL); | 306 | buf = kzalloc(48, GFP_KERNEL); |
312 | if (buf) { | 307 | if (buf) { |
313 | snprintf(buf, 48, "addr="NIPQUAD_FMT" port=%u proto=%s", | 308 | snprintf(buf, 48, "addr="NIPQUAD_FMT" port=%u proto=%s", |
314 | NIPQUAD(addr->sin_addr.s_addr), | 309 | NIPQUAD(addr->sin_addr.s_addr), |
315 | ntohs(addr->sin_port), | 310 | ntohs(addr->sin_port), |
316 | xprt->prot == IPPROTO_UDP ? "udp" : "tcp"); | 311 | protocol); |
317 | } | 312 | } |
318 | xprt->address_strings[RPC_DISPLAY_ALL] = buf; | 313 | xprt->address_strings[RPC_DISPLAY_ALL] = buf; |
319 | 314 | ||
@@ -340,12 +335,12 @@ static void xs_format_ipv4_peer_addresses(struct rpc_xprt *xprt) | |||
340 | } | 335 | } |
341 | xprt->address_strings[RPC_DISPLAY_UNIVERSAL_ADDR] = buf; | 336 | xprt->address_strings[RPC_DISPLAY_UNIVERSAL_ADDR] = buf; |
342 | 337 | ||
343 | xprt->address_strings[RPC_DISPLAY_NETID] = | 338 | xprt->address_strings[RPC_DISPLAY_NETID] = netid; |
344 | kstrdup(xprt->prot == IPPROTO_UDP ? | ||
345 | RPCBIND_NETID_UDP : RPCBIND_NETID_TCP, GFP_KERNEL); | ||
346 | } | 339 | } |
347 | 340 | ||
348 | static void xs_format_ipv6_peer_addresses(struct rpc_xprt *xprt) | 341 | static void xs_format_ipv6_peer_addresses(struct rpc_xprt *xprt, |
342 | const char *protocol, | ||
343 | const char *netid) | ||
349 | { | 344 | { |
350 | struct sockaddr_in6 *addr = xs_addr_in6(xprt); | 345 | struct sockaddr_in6 *addr = xs_addr_in6(xprt); |
351 | char *buf; | 346 | char *buf; |
@@ -364,21 +359,14 @@ static void xs_format_ipv6_peer_addresses(struct rpc_xprt *xprt) | |||
364 | } | 359 | } |
365 | xprt->address_strings[RPC_DISPLAY_PORT] = buf; | 360 | xprt->address_strings[RPC_DISPLAY_PORT] = buf; |
366 | 361 | ||
367 | buf = kzalloc(8, GFP_KERNEL); | 362 | xprt->address_strings[RPC_DISPLAY_PROTO] = protocol; |
368 | if (buf) { | ||
369 | if (xprt->prot == IPPROTO_UDP) | ||
370 | snprintf(buf, 8, "udp"); | ||
371 | else | ||
372 | snprintf(buf, 8, "tcp"); | ||
373 | } | ||
374 | xprt->address_strings[RPC_DISPLAY_PROTO] = buf; | ||
375 | 363 | ||
376 | buf = kzalloc(64, GFP_KERNEL); | 364 | buf = kzalloc(64, GFP_KERNEL); |
377 | if (buf) { | 365 | if (buf) { |
378 | snprintf(buf, 64, "addr="NIP6_FMT" port=%u proto=%s", | 366 | snprintf(buf, 64, "addr="NIP6_FMT" port=%u proto=%s", |
379 | NIP6(addr->sin6_addr), | 367 | NIP6(addr->sin6_addr), |
380 | ntohs(addr->sin6_port), | 368 | ntohs(addr->sin6_port), |
381 | xprt->prot == IPPROTO_UDP ? "udp" : "tcp"); | 369 | protocol); |
382 | } | 370 | } |
383 | xprt->address_strings[RPC_DISPLAY_ALL] = buf; | 371 | xprt->address_strings[RPC_DISPLAY_ALL] = buf; |
384 | 372 | ||
@@ -405,17 +393,21 @@ static void xs_format_ipv6_peer_addresses(struct rpc_xprt *xprt) | |||
405 | } | 393 | } |
406 | xprt->address_strings[RPC_DISPLAY_UNIVERSAL_ADDR] = buf; | 394 | xprt->address_strings[RPC_DISPLAY_UNIVERSAL_ADDR] = buf; |
407 | 395 | ||
408 | xprt->address_strings[RPC_DISPLAY_NETID] = | 396 | xprt->address_strings[RPC_DISPLAY_NETID] = netid; |
409 | kstrdup(xprt->prot == IPPROTO_UDP ? | ||
410 | RPCBIND_NETID_UDP6 : RPCBIND_NETID_TCP6, GFP_KERNEL); | ||
411 | } | 397 | } |
412 | 398 | ||
413 | static void xs_free_peer_addresses(struct rpc_xprt *xprt) | 399 | static void xs_free_peer_addresses(struct rpc_xprt *xprt) |
414 | { | 400 | { |
415 | int i; | 401 | unsigned int i; |
416 | 402 | ||
417 | for (i = 0; i < RPC_DISPLAY_MAX; i++) | 403 | for (i = 0; i < RPC_DISPLAY_MAX; i++) |
418 | kfree(xprt->address_strings[i]); | 404 | switch (i) { |
405 | case RPC_DISPLAY_PROTO: | ||
406 | case RPC_DISPLAY_NETID: | ||
407 | continue; | ||
408 | default: | ||
409 | kfree(xprt->address_strings[i]); | ||
410 | } | ||
419 | } | 411 | } |
420 | 412 | ||
421 | #define XS_SENDMSG_FLAGS (MSG_DONTWAIT | MSG_NOSIGNAL) | 413 | #define XS_SENDMSG_FLAGS (MSG_DONTWAIT | MSG_NOSIGNAL) |
@@ -614,6 +606,22 @@ static int xs_udp_send_request(struct rpc_task *task) | |||
614 | return status; | 606 | return status; |
615 | } | 607 | } |
616 | 608 | ||
609 | /** | ||
610 | * xs_tcp_shutdown - gracefully shut down a TCP socket | ||
611 | * @xprt: transport | ||
612 | * | ||
613 | * Initiates a graceful shutdown of the TCP socket by calling the | ||
614 | * equivalent of shutdown(SHUT_WR); | ||
615 | */ | ||
616 | static void xs_tcp_shutdown(struct rpc_xprt *xprt) | ||
617 | { | ||
618 | struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt); | ||
619 | struct socket *sock = transport->sock; | ||
620 | |||
621 | if (sock != NULL) | ||
622 | kernel_sock_shutdown(sock, SHUT_WR); | ||
623 | } | ||
624 | |||
617 | static inline void xs_encode_tcp_record_marker(struct xdr_buf *buf) | 625 | static inline void xs_encode_tcp_record_marker(struct xdr_buf *buf) |
618 | { | 626 | { |
619 | u32 reclen = buf->len - sizeof(rpc_fraghdr); | 627 | u32 reclen = buf->len - sizeof(rpc_fraghdr); |
@@ -691,7 +699,7 @@ static int xs_tcp_send_request(struct rpc_task *task) | |||
691 | default: | 699 | default: |
692 | dprintk("RPC: sendmsg returned unrecognized error %d\n", | 700 | dprintk("RPC: sendmsg returned unrecognized error %d\n", |
693 | -status); | 701 | -status); |
694 | xprt_disconnect(xprt); | 702 | xs_tcp_shutdown(xprt); |
695 | break; | 703 | break; |
696 | } | 704 | } |
697 | 705 | ||
@@ -759,7 +767,9 @@ static void xs_close(struct rpc_xprt *xprt) | |||
759 | clear_close_wait: | 767 | clear_close_wait: |
760 | smp_mb__before_clear_bit(); | 768 | smp_mb__before_clear_bit(); |
761 | clear_bit(XPRT_CLOSE_WAIT, &xprt->state); | 769 | clear_bit(XPRT_CLOSE_WAIT, &xprt->state); |
770 | clear_bit(XPRT_CLOSING, &xprt->state); | ||
762 | smp_mb__after_clear_bit(); | 771 | smp_mb__after_clear_bit(); |
772 | xprt_disconnect_done(xprt); | ||
763 | } | 773 | } |
764 | 774 | ||
765 | /** | 775 | /** |
@@ -775,7 +785,6 @@ static void xs_destroy(struct rpc_xprt *xprt) | |||
775 | 785 | ||
776 | cancel_rearming_delayed_work(&transport->connect_worker); | 786 | cancel_rearming_delayed_work(&transport->connect_worker); |
777 | 787 | ||
778 | xprt_disconnect(xprt); | ||
779 | xs_close(xprt); | 788 | xs_close(xprt); |
780 | xs_free_peer_addresses(xprt); | 789 | xs_free_peer_addresses(xprt); |
781 | kfree(xprt->slot); | 790 | kfree(xprt->slot); |
@@ -886,7 +895,7 @@ static inline void xs_tcp_read_fraghdr(struct rpc_xprt *xprt, struct xdr_skb_rea | |||
886 | /* Sanity check of the record length */ | 895 | /* Sanity check of the record length */ |
887 | if (unlikely(transport->tcp_reclen < 4)) { | 896 | if (unlikely(transport->tcp_reclen < 4)) { |
888 | dprintk("RPC: invalid TCP record fragment length\n"); | 897 | dprintk("RPC: invalid TCP record fragment length\n"); |
889 | xprt_disconnect(xprt); | 898 | xprt_force_disconnect(xprt); |
890 | return; | 899 | return; |
891 | } | 900 | } |
892 | dprintk("RPC: reading TCP record fragment of length %d\n", | 901 | dprintk("RPC: reading TCP record fragment of length %d\n", |
@@ -1113,21 +1122,44 @@ static void xs_tcp_state_change(struct sock *sk) | |||
1113 | transport->tcp_flags = | 1122 | transport->tcp_flags = |
1114 | TCP_RCV_COPY_FRAGHDR | TCP_RCV_COPY_XID; | 1123 | TCP_RCV_COPY_FRAGHDR | TCP_RCV_COPY_XID; |
1115 | 1124 | ||
1116 | xprt->reestablish_timeout = XS_TCP_INIT_REEST_TO; | ||
1117 | xprt_wake_pending_tasks(xprt, 0); | 1125 | xprt_wake_pending_tasks(xprt, 0); |
1118 | } | 1126 | } |
1119 | spin_unlock_bh(&xprt->transport_lock); | 1127 | spin_unlock_bh(&xprt->transport_lock); |
1120 | break; | 1128 | break; |
1121 | case TCP_SYN_SENT: | 1129 | case TCP_FIN_WAIT1: |
1122 | case TCP_SYN_RECV: | 1130 | /* The client initiated a shutdown of the socket */ |
1131 | xprt->reestablish_timeout = 0; | ||
1132 | set_bit(XPRT_CLOSING, &xprt->state); | ||
1133 | smp_mb__before_clear_bit(); | ||
1134 | clear_bit(XPRT_CONNECTED, &xprt->state); | ||
1135 | clear_bit(XPRT_CLOSE_WAIT, &xprt->state); | ||
1136 | smp_mb__after_clear_bit(); | ||
1123 | break; | 1137 | break; |
1124 | case TCP_CLOSE_WAIT: | 1138 | case TCP_CLOSE_WAIT: |
1125 | /* Try to schedule an autoclose RPC calls */ | 1139 | /* The server initiated a shutdown of the socket */ |
1126 | set_bit(XPRT_CLOSE_WAIT, &xprt->state); | 1140 | set_bit(XPRT_CLOSING, &xprt->state); |
1127 | if (test_and_set_bit(XPRT_LOCKED, &xprt->state) == 0) | 1141 | xprt_force_disconnect(xprt); |
1128 | queue_work(rpciod_workqueue, &xprt->task_cleanup); | 1142 | case TCP_SYN_SENT: |
1129 | default: | 1143 | case TCP_CLOSING: |
1130 | xprt_disconnect(xprt); | 1144 | /* |
1145 | * If the server closed down the connection, make sure that | ||
1146 | * we back off before reconnecting | ||
1147 | */ | ||
1148 | if (xprt->reestablish_timeout < XS_TCP_INIT_REEST_TO) | ||
1149 | xprt->reestablish_timeout = XS_TCP_INIT_REEST_TO; | ||
1150 | break; | ||
1151 | case TCP_LAST_ACK: | ||
1152 | smp_mb__before_clear_bit(); | ||
1153 | clear_bit(XPRT_CONNECTED, &xprt->state); | ||
1154 | smp_mb__after_clear_bit(); | ||
1155 | break; | ||
1156 | case TCP_CLOSE: | ||
1157 | smp_mb__before_clear_bit(); | ||
1158 | clear_bit(XPRT_CLOSE_WAIT, &xprt->state); | ||
1159 | clear_bit(XPRT_CLOSING, &xprt->state); | ||
1160 | smp_mb__after_clear_bit(); | ||
1161 | /* Mark transport as closed and wake up all pending tasks */ | ||
1162 | xprt_disconnect_done(xprt); | ||
1131 | } | 1163 | } |
1132 | out: | 1164 | out: |
1133 | read_unlock(&sk->sk_callback_lock); | 1165 | read_unlock(&sk->sk_callback_lock); |
@@ -1279,34 +1311,53 @@ static void xs_set_port(struct rpc_xprt *xprt, unsigned short port) | |||
1279 | } | 1311 | } |
1280 | } | 1312 | } |
1281 | 1313 | ||
1314 | static unsigned short xs_get_srcport(struct sock_xprt *transport, struct socket *sock) | ||
1315 | { | ||
1316 | unsigned short port = transport->port; | ||
1317 | |||
1318 | if (port == 0 && transport->xprt.resvport) | ||
1319 | port = xs_get_random_port(); | ||
1320 | return port; | ||
1321 | } | ||
1322 | |||
1323 | static unsigned short xs_next_srcport(struct sock_xprt *transport, struct socket *sock, unsigned short port) | ||
1324 | { | ||
1325 | if (transport->port != 0) | ||
1326 | transport->port = 0; | ||
1327 | if (!transport->xprt.resvport) | ||
1328 | return 0; | ||
1329 | if (port <= xprt_min_resvport || port > xprt_max_resvport) | ||
1330 | return xprt_max_resvport; | ||
1331 | return --port; | ||
1332 | } | ||
1333 | |||
1282 | static int xs_bind4(struct sock_xprt *transport, struct socket *sock) | 1334 | static int xs_bind4(struct sock_xprt *transport, struct socket *sock) |
1283 | { | 1335 | { |
1284 | struct sockaddr_in myaddr = { | 1336 | struct sockaddr_in myaddr = { |
1285 | .sin_family = AF_INET, | 1337 | .sin_family = AF_INET, |
1286 | }; | 1338 | }; |
1287 | struct sockaddr_in *sa; | 1339 | struct sockaddr_in *sa; |
1288 | int err; | 1340 | int err, nloop = 0; |
1289 | unsigned short port = transport->port; | 1341 | unsigned short port = xs_get_srcport(transport, sock); |
1342 | unsigned short last; | ||
1290 | 1343 | ||
1291 | if (!transport->xprt.resvport) | ||
1292 | port = 0; | ||
1293 | sa = (struct sockaddr_in *)&transport->addr; | 1344 | sa = (struct sockaddr_in *)&transport->addr; |
1294 | myaddr.sin_addr = sa->sin_addr; | 1345 | myaddr.sin_addr = sa->sin_addr; |
1295 | do { | 1346 | do { |
1296 | myaddr.sin_port = htons(port); | 1347 | myaddr.sin_port = htons(port); |
1297 | err = kernel_bind(sock, (struct sockaddr *) &myaddr, | 1348 | err = kernel_bind(sock, (struct sockaddr *) &myaddr, |
1298 | sizeof(myaddr)); | 1349 | sizeof(myaddr)); |
1299 | if (!transport->xprt.resvport) | 1350 | if (port == 0) |
1300 | break; | 1351 | break; |
1301 | if (err == 0) { | 1352 | if (err == 0) { |
1302 | transport->port = port; | 1353 | transport->port = port; |
1303 | break; | 1354 | break; |
1304 | } | 1355 | } |
1305 | if (port <= xprt_min_resvport) | 1356 | last = port; |
1306 | port = xprt_max_resvport; | 1357 | port = xs_next_srcport(transport, sock, port); |
1307 | else | 1358 | if (port > last) |
1308 | port--; | 1359 | nloop++; |
1309 | } while (err == -EADDRINUSE && port != transport->port); | 1360 | } while (err == -EADDRINUSE && nloop != 2); |
1310 | dprintk("RPC: %s "NIPQUAD_FMT":%u: %s (%d)\n", | 1361 | dprintk("RPC: %s "NIPQUAD_FMT":%u: %s (%d)\n", |
1311 | __FUNCTION__, NIPQUAD(myaddr.sin_addr), | 1362 | __FUNCTION__, NIPQUAD(myaddr.sin_addr), |
1312 | port, err ? "failed" : "ok", err); | 1363 | port, err ? "failed" : "ok", err); |
@@ -1319,28 +1370,27 @@ static int xs_bind6(struct sock_xprt *transport, struct socket *sock) | |||
1319 | .sin6_family = AF_INET6, | 1370 | .sin6_family = AF_INET6, |
1320 | }; | 1371 | }; |
1321 | struct sockaddr_in6 *sa; | 1372 | struct sockaddr_in6 *sa; |
1322 | int err; | 1373 | int err, nloop = 0; |
1323 | unsigned short port = transport->port; | 1374 | unsigned short port = xs_get_srcport(transport, sock); |
1375 | unsigned short last; | ||
1324 | 1376 | ||
1325 | if (!transport->xprt.resvport) | ||
1326 | port = 0; | ||
1327 | sa = (struct sockaddr_in6 *)&transport->addr; | 1377 | sa = (struct sockaddr_in6 *)&transport->addr; |
1328 | myaddr.sin6_addr = sa->sin6_addr; | 1378 | myaddr.sin6_addr = sa->sin6_addr; |
1329 | do { | 1379 | do { |
1330 | myaddr.sin6_port = htons(port); | 1380 | myaddr.sin6_port = htons(port); |
1331 | err = kernel_bind(sock, (struct sockaddr *) &myaddr, | 1381 | err = kernel_bind(sock, (struct sockaddr *) &myaddr, |
1332 | sizeof(myaddr)); | 1382 | sizeof(myaddr)); |
1333 | if (!transport->xprt.resvport) | 1383 | if (port == 0) |
1334 | break; | 1384 | break; |
1335 | if (err == 0) { | 1385 | if (err == 0) { |
1336 | transport->port = port; | 1386 | transport->port = port; |
1337 | break; | 1387 | break; |
1338 | } | 1388 | } |
1339 | if (port <= xprt_min_resvport) | 1389 | last = port; |
1340 | port = xprt_max_resvport; | 1390 | port = xs_next_srcport(transport, sock, port); |
1341 | else | 1391 | if (port > last) |
1342 | port--; | 1392 | nloop++; |
1343 | } while (err == -EADDRINUSE && port != transport->port); | 1393 | } while (err == -EADDRINUSE && nloop != 2); |
1344 | dprintk("RPC: xs_bind6 "NIP6_FMT":%u: %s (%d)\n", | 1394 | dprintk("RPC: xs_bind6 "NIP6_FMT":%u: %s (%d)\n", |
1345 | NIP6(myaddr.sin6_addr), port, err ? "failed" : "ok", err); | 1395 | NIP6(myaddr.sin6_addr), port, err ? "failed" : "ok", err); |
1346 | return err; | 1396 | return err; |
@@ -1602,8 +1652,7 @@ static void xs_tcp_connect_worker4(struct work_struct *work) | |||
1602 | break; | 1652 | break; |
1603 | default: | 1653 | default: |
1604 | /* get rid of existing socket, and retry */ | 1654 | /* get rid of existing socket, and retry */ |
1605 | xs_close(xprt); | 1655 | xs_tcp_shutdown(xprt); |
1606 | break; | ||
1607 | } | 1656 | } |
1608 | } | 1657 | } |
1609 | out: | 1658 | out: |
@@ -1662,8 +1711,7 @@ static void xs_tcp_connect_worker6(struct work_struct *work) | |||
1662 | break; | 1711 | break; |
1663 | default: | 1712 | default: |
1664 | /* get rid of existing socket, and retry */ | 1713 | /* get rid of existing socket, and retry */ |
1665 | xs_close(xprt); | 1714 | xs_tcp_shutdown(xprt); |
1666 | break; | ||
1667 | } | 1715 | } |
1668 | } | 1716 | } |
1669 | out: | 1717 | out: |
@@ -1710,6 +1758,19 @@ static void xs_connect(struct rpc_task *task) | |||
1710 | } | 1758 | } |
1711 | } | 1759 | } |
1712 | 1760 | ||
1761 | static void xs_tcp_connect(struct rpc_task *task) | ||
1762 | { | ||
1763 | struct rpc_xprt *xprt = task->tk_xprt; | ||
1764 | |||
1765 | /* Initiate graceful shutdown of the socket if not already done */ | ||
1766 | if (test_bit(XPRT_CONNECTED, &xprt->state)) | ||
1767 | xs_tcp_shutdown(xprt); | ||
1768 | /* Exit if we need to wait for socket shutdown to complete */ | ||
1769 | if (test_bit(XPRT_CLOSING, &xprt->state)) | ||
1770 | return; | ||
1771 | xs_connect(task); | ||
1772 | } | ||
1773 | |||
1713 | /** | 1774 | /** |
1714 | * xs_udp_print_stats - display UDP socket-specifc stats | 1775 | * xs_udp_print_stats - display UDP socket-specifc stats |
1715 | * @xprt: rpc_xprt struct containing statistics | 1776 | * @xprt: rpc_xprt struct containing statistics |
@@ -1780,12 +1841,12 @@ static struct rpc_xprt_ops xs_tcp_ops = { | |||
1780 | .release_xprt = xs_tcp_release_xprt, | 1841 | .release_xprt = xs_tcp_release_xprt, |
1781 | .rpcbind = rpcb_getport_async, | 1842 | .rpcbind = rpcb_getport_async, |
1782 | .set_port = xs_set_port, | 1843 | .set_port = xs_set_port, |
1783 | .connect = xs_connect, | 1844 | .connect = xs_tcp_connect, |
1784 | .buf_alloc = rpc_malloc, | 1845 | .buf_alloc = rpc_malloc, |
1785 | .buf_free = rpc_free, | 1846 | .buf_free = rpc_free, |
1786 | .send_request = xs_tcp_send_request, | 1847 | .send_request = xs_tcp_send_request, |
1787 | .set_retrans_timeout = xprt_set_retrans_timeout_def, | 1848 | .set_retrans_timeout = xprt_set_retrans_timeout_def, |
1788 | .close = xs_close, | 1849 | .close = xs_tcp_shutdown, |
1789 | .destroy = xs_destroy, | 1850 | .destroy = xs_destroy, |
1790 | .print_stats = xs_tcp_print_stats, | 1851 | .print_stats = xs_tcp_print_stats, |
1791 | }; | 1852 | }; |
@@ -1822,11 +1883,17 @@ static struct rpc_xprt *xs_setup_xprt(struct xprt_create *args, | |||
1822 | xprt->addrlen = args->addrlen; | 1883 | xprt->addrlen = args->addrlen; |
1823 | if (args->srcaddr) | 1884 | if (args->srcaddr) |
1824 | memcpy(&new->addr, args->srcaddr, args->addrlen); | 1885 | memcpy(&new->addr, args->srcaddr, args->addrlen); |
1825 | new->port = xs_get_random_port(); | ||
1826 | 1886 | ||
1827 | return xprt; | 1887 | return xprt; |
1828 | } | 1888 | } |
1829 | 1889 | ||
1890 | static const struct rpc_timeout xs_udp_default_timeout = { | ||
1891 | .to_initval = 5 * HZ, | ||
1892 | .to_maxval = 30 * HZ, | ||
1893 | .to_increment = 5 * HZ, | ||
1894 | .to_retries = 5, | ||
1895 | }; | ||
1896 | |||
1830 | /** | 1897 | /** |
1831 | * xs_setup_udp - Set up transport to use a UDP socket | 1898 | * xs_setup_udp - Set up transport to use a UDP socket |
1832 | * @args: rpc transport creation arguments | 1899 | * @args: rpc transport creation arguments |
@@ -1855,10 +1922,7 @@ static struct rpc_xprt *xs_setup_udp(struct xprt_create *args) | |||
1855 | 1922 | ||
1856 | xprt->ops = &xs_udp_ops; | 1923 | xprt->ops = &xs_udp_ops; |
1857 | 1924 | ||
1858 | if (args->timeout) | 1925 | xprt->timeout = &xs_udp_default_timeout; |
1859 | xprt->timeout = *args->timeout; | ||
1860 | else | ||
1861 | xprt_set_timeout(&xprt->timeout, 5, 5 * HZ); | ||
1862 | 1926 | ||
1863 | switch (addr->sa_family) { | 1927 | switch (addr->sa_family) { |
1864 | case AF_INET: | 1928 | case AF_INET: |
@@ -1867,7 +1931,7 @@ static struct rpc_xprt *xs_setup_udp(struct xprt_create *args) | |||
1867 | 1931 | ||
1868 | INIT_DELAYED_WORK(&transport->connect_worker, | 1932 | INIT_DELAYED_WORK(&transport->connect_worker, |
1869 | xs_udp_connect_worker4); | 1933 | xs_udp_connect_worker4); |
1870 | xs_format_ipv4_peer_addresses(xprt); | 1934 | xs_format_ipv4_peer_addresses(xprt, "udp", RPCBIND_NETID_UDP); |
1871 | break; | 1935 | break; |
1872 | case AF_INET6: | 1936 | case AF_INET6: |
1873 | if (((struct sockaddr_in6 *)addr)->sin6_port != htons(0)) | 1937 | if (((struct sockaddr_in6 *)addr)->sin6_port != htons(0)) |
@@ -1875,7 +1939,7 @@ static struct rpc_xprt *xs_setup_udp(struct xprt_create *args) | |||
1875 | 1939 | ||
1876 | INIT_DELAYED_WORK(&transport->connect_worker, | 1940 | INIT_DELAYED_WORK(&transport->connect_worker, |
1877 | xs_udp_connect_worker6); | 1941 | xs_udp_connect_worker6); |
1878 | xs_format_ipv6_peer_addresses(xprt); | 1942 | xs_format_ipv6_peer_addresses(xprt, "udp", RPCBIND_NETID_UDP6); |
1879 | break; | 1943 | break; |
1880 | default: | 1944 | default: |
1881 | kfree(xprt); | 1945 | kfree(xprt); |
@@ -1893,6 +1957,12 @@ static struct rpc_xprt *xs_setup_udp(struct xprt_create *args) | |||
1893 | return ERR_PTR(-EINVAL); | 1957 | return ERR_PTR(-EINVAL); |
1894 | } | 1958 | } |
1895 | 1959 | ||
1960 | static const struct rpc_timeout xs_tcp_default_timeout = { | ||
1961 | .to_initval = 60 * HZ, | ||
1962 | .to_maxval = 60 * HZ, | ||
1963 | .to_retries = 2, | ||
1964 | }; | ||
1965 | |||
1896 | /** | 1966 | /** |
1897 | * xs_setup_tcp - Set up transport to use a TCP socket | 1967 | * xs_setup_tcp - Set up transport to use a TCP socket |
1898 | * @args: rpc transport creation arguments | 1968 | * @args: rpc transport creation arguments |
@@ -1919,11 +1989,7 @@ static struct rpc_xprt *xs_setup_tcp(struct xprt_create *args) | |||
1919 | xprt->idle_timeout = XS_IDLE_DISC_TO; | 1989 | xprt->idle_timeout = XS_IDLE_DISC_TO; |
1920 | 1990 | ||
1921 | xprt->ops = &xs_tcp_ops; | 1991 | xprt->ops = &xs_tcp_ops; |
1922 | 1992 | xprt->timeout = &xs_tcp_default_timeout; | |
1923 | if (args->timeout) | ||
1924 | xprt->timeout = *args->timeout; | ||
1925 | else | ||
1926 | xprt_set_timeout(&xprt->timeout, 2, 60 * HZ); | ||
1927 | 1993 | ||
1928 | switch (addr->sa_family) { | 1994 | switch (addr->sa_family) { |
1929 | case AF_INET: | 1995 | case AF_INET: |
@@ -1931,14 +1997,14 @@ static struct rpc_xprt *xs_setup_tcp(struct xprt_create *args) | |||
1931 | xprt_set_bound(xprt); | 1997 | xprt_set_bound(xprt); |
1932 | 1998 | ||
1933 | INIT_DELAYED_WORK(&transport->connect_worker, xs_tcp_connect_worker4); | 1999 | INIT_DELAYED_WORK(&transport->connect_worker, xs_tcp_connect_worker4); |
1934 | xs_format_ipv4_peer_addresses(xprt); | 2000 | xs_format_ipv4_peer_addresses(xprt, "tcp", RPCBIND_NETID_TCP); |
1935 | break; | 2001 | break; |
1936 | case AF_INET6: | 2002 | case AF_INET6: |
1937 | if (((struct sockaddr_in6 *)addr)->sin6_port != htons(0)) | 2003 | if (((struct sockaddr_in6 *)addr)->sin6_port != htons(0)) |
1938 | xprt_set_bound(xprt); | 2004 | xprt_set_bound(xprt); |
1939 | 2005 | ||
1940 | INIT_DELAYED_WORK(&transport->connect_worker, xs_tcp_connect_worker6); | 2006 | INIT_DELAYED_WORK(&transport->connect_worker, xs_tcp_connect_worker6); |
1941 | xs_format_ipv6_peer_addresses(xprt); | 2007 | xs_format_ipv6_peer_addresses(xprt, "tcp", RPCBIND_NETID_TCP6); |
1942 | break; | 2008 | break; |
1943 | default: | 2009 | default: |
1944 | kfree(xprt); | 2010 | kfree(xprt); |