Commit f300baba5a1536070d6d77bf0c8c4ca999bb4f0f
Committed by
J. Bruce Fields
1 parent
908329f2c0
Exists in
master
and in
39 other branches
nfsd41: sunrpc: add new xprt class for nfsv4.1 backchannel
[sunrpc: change idle timeout value for the backchannel] Signed-off-by: Alexandros Batsakis <batsakis@netapp.com> Signed-off-by: Benny Halevy <bhalevy@panasas.com> Acked-by: Trond Myklebust <Trond.Myklebust@netapp.com> Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
Showing 6 changed files with 114 additions and 18 deletions Side-by-side Diff
include/linux/sunrpc/clnt.h
include/linux/sunrpc/xprt.h
... | ... | @@ -124,6 +124,23 @@ |
124 | 124 | void (*print_stats)(struct rpc_xprt *xprt, struct seq_file *seq); |
125 | 125 | }; |
126 | 126 | |
127 | +/* | |
128 | + * RPC transport identifiers | |
129 | + * | |
130 | + * To preserve compatibility with the historical use of raw IP protocol | |
131 | + * id's for transport selection, UDP and TCP identifiers are specified | |
132 | + * with the previous values. No such restriction exists for new transports, | |
133 | + * except that they may not collide with these values (17 and 6, | |
134 | + * respectively). | |
135 | + */ | |
136 | +#define XPRT_TRANSPORT_BC (1 << 31) | |
137 | +enum xprt_transports { | |
138 | + XPRT_TRANSPORT_UDP = IPPROTO_UDP, | |
139 | + XPRT_TRANSPORT_TCP = IPPROTO_TCP, | |
140 | + XPRT_TRANSPORT_BC_TCP = IPPROTO_TCP | XPRT_TRANSPORT_BC, | |
141 | + XPRT_TRANSPORT_RDMA = 256 | |
142 | +}; | |
143 | + | |
127 | 144 | struct rpc_xprt { |
128 | 145 | struct kref kref; /* Reference count */ |
129 | 146 | struct rpc_xprt_ops * ops; /* transport methods */ |
... | ... | @@ -232,6 +249,7 @@ |
232 | 249 | struct sockaddr * srcaddr; /* optional local address */ |
233 | 250 | struct sockaddr * dstaddr; /* remote peer address */ |
234 | 251 | size_t addrlen; |
252 | + struct svc_xprt *bc_xprt; /* NFSv4.1 backchannel */ | |
235 | 253 | }; |
236 | 254 | |
237 | 255 | struct xprt_class { |
include/linux/sunrpc/xprtrdma.h
include/linux/sunrpc/xprtsock.h
... | ... | @@ -13,17 +13,6 @@ |
13 | 13 | void cleanup_socket_xprt(void); |
14 | 14 | |
15 | 15 | /* |
16 | - * RPC transport identifiers for UDP, TCP | |
17 | - * | |
18 | - * To preserve compatibility with the historical use of raw IP protocol | |
19 | - * id's for transport selection, these are specified with the previous | |
20 | - * values. No such restriction exists for new transports, except that | |
21 | - * they may not collide with these values (17 and 6, respectively). | |
22 | - */ | |
23 | -#define XPRT_TRANSPORT_UDP IPPROTO_UDP | |
24 | -#define XPRT_TRANSPORT_TCP IPPROTO_TCP | |
25 | - | |
26 | -/* | |
27 | 16 | * RPC slot table sizes for UDP, TCP transports |
28 | 17 | */ |
29 | 18 | extern unsigned int xprt_udp_slot_table_entries; |
net/sunrpc/clnt.c
net/sunrpc/xprtsock.c
... | ... | @@ -2468,11 +2468,93 @@ |
2468 | 2468 | return ERR_PTR(-EINVAL); |
2469 | 2469 | } |
2470 | 2470 | |
2471 | +/** | |
2472 | + * xs_setup_bc_tcp - Set up transport to use a TCP backchannel socket | |
2473 | + * @args: rpc transport creation arguments | |
2474 | + * | |
2475 | + */ | |
2476 | +static struct rpc_xprt *xs_setup_bc_tcp(struct xprt_create *args) | |
2477 | +{ | |
2478 | + struct sockaddr *addr = args->dstaddr; | |
2479 | + struct rpc_xprt *xprt; | |
2480 | + struct sock_xprt *transport; | |
2481 | + struct svc_sock *bc_sock; | |
2482 | + | |
2483 | + if (!args->bc_xprt) | |
2484 | + ERR_PTR(-EINVAL); | |
2485 | + | |
2486 | + xprt = xs_setup_xprt(args, xprt_tcp_slot_table_entries); | |
2487 | + if (IS_ERR(xprt)) | |
2488 | + return xprt; | |
2489 | + transport = container_of(xprt, struct sock_xprt, xprt); | |
2490 | + | |
2491 | + xprt->prot = IPPROTO_TCP; | |
2492 | + xprt->tsh_size = sizeof(rpc_fraghdr) / sizeof(u32); | |
2493 | + xprt->max_payload = RPC_MAX_FRAGMENT_SIZE; | |
2494 | + xprt->timeout = &xs_tcp_default_timeout; | |
2495 | + | |
2496 | + /* backchannel */ | |
2497 | + xprt_set_bound(xprt); | |
2498 | + xprt->bind_timeout = 0; | |
2499 | + xprt->connect_timeout = 0; | |
2500 | + xprt->reestablish_timeout = 0; | |
2501 | + xprt->idle_timeout = 0; | |
2502 | + | |
2503 | + /* | |
2504 | + * The backchannel uses the same socket connection as the | |
2505 | + * forechannel | |
2506 | + */ | |
2507 | + xprt->bc_xprt = args->bc_xprt; | |
2508 | + bc_sock = container_of(args->bc_xprt, struct svc_sock, sk_xprt); | |
2509 | + bc_sock->sk_bc_xprt = xprt; | |
2510 | + transport->sock = bc_sock->sk_sock; | |
2511 | + transport->inet = bc_sock->sk_sk; | |
2512 | + | |
2513 | + xprt->ops = &bc_tcp_ops; | |
2514 | + | |
2515 | + switch (addr->sa_family) { | |
2516 | + case AF_INET: | |
2517 | + xs_format_peer_addresses(xprt, "tcp", | |
2518 | + RPCBIND_NETID_TCP); | |
2519 | + break; | |
2520 | + case AF_INET6: | |
2521 | + xs_format_peer_addresses(xprt, "tcp", | |
2522 | + RPCBIND_NETID_TCP6); | |
2523 | + break; | |
2524 | + default: | |
2525 | + kfree(xprt); | |
2526 | + return ERR_PTR(-EAFNOSUPPORT); | |
2527 | + } | |
2528 | + | |
2529 | + if (xprt_bound(xprt)) | |
2530 | + dprintk("RPC: set up xprt to %s (port %s) via %s\n", | |
2531 | + xprt->address_strings[RPC_DISPLAY_ADDR], | |
2532 | + xprt->address_strings[RPC_DISPLAY_PORT], | |
2533 | + xprt->address_strings[RPC_DISPLAY_PROTO]); | |
2534 | + else | |
2535 | + dprintk("RPC: set up xprt to %s (autobind) via %s\n", | |
2536 | + xprt->address_strings[RPC_DISPLAY_ADDR], | |
2537 | + xprt->address_strings[RPC_DISPLAY_PROTO]); | |
2538 | + | |
2539 | + /* | |
2540 | + * Since we don't want connections for the backchannel, we set | |
2541 | + * the xprt status to connected | |
2542 | + */ | |
2543 | + xprt_set_connected(xprt); | |
2544 | + | |
2545 | + | |
2546 | + if (try_module_get(THIS_MODULE)) | |
2547 | + return xprt; | |
2548 | + kfree(xprt->slot); | |
2549 | + kfree(xprt); | |
2550 | + return ERR_PTR(-EINVAL); | |
2551 | +} | |
2552 | + | |
2471 | 2553 | static struct xprt_class xs_udp_transport = { |
2472 | 2554 | .list = LIST_HEAD_INIT(xs_udp_transport.list), |
2473 | 2555 | .name = "udp", |
2474 | 2556 | .owner = THIS_MODULE, |
2475 | - .ident = IPPROTO_UDP, | |
2557 | + .ident = XPRT_TRANSPORT_UDP, | |
2476 | 2558 | .setup = xs_setup_udp, |
2477 | 2559 | }; |
2478 | 2560 | |
2479 | 2561 | |
... | ... | @@ -2480,10 +2562,18 @@ |
2480 | 2562 | .list = LIST_HEAD_INIT(xs_tcp_transport.list), |
2481 | 2563 | .name = "tcp", |
2482 | 2564 | .owner = THIS_MODULE, |
2483 | - .ident = IPPROTO_TCP, | |
2565 | + .ident = XPRT_TRANSPORT_TCP, | |
2484 | 2566 | .setup = xs_setup_tcp, |
2485 | 2567 | }; |
2486 | 2568 | |
2569 | +static struct xprt_class xs_bc_tcp_transport = { | |
2570 | + .list = LIST_HEAD_INIT(xs_bc_tcp_transport.list), | |
2571 | + .name = "tcp NFSv4.1 backchannel", | |
2572 | + .owner = THIS_MODULE, | |
2573 | + .ident = XPRT_TRANSPORT_BC_TCP, | |
2574 | + .setup = xs_setup_bc_tcp, | |
2575 | +}; | |
2576 | + | |
2487 | 2577 | /** |
2488 | 2578 | * init_socket_xprt - set up xprtsock's sysctls, register with RPC client |
2489 | 2579 | * |
... | ... | @@ -2497,6 +2587,7 @@ |
2497 | 2587 | |
2498 | 2588 | xprt_register_transport(&xs_udp_transport); |
2499 | 2589 | xprt_register_transport(&xs_tcp_transport); |
2590 | + xprt_register_transport(&xs_bc_tcp_transport); | |
2500 | 2591 | |
2501 | 2592 | return 0; |
2502 | 2593 | } |
... | ... | @@ -2516,6 +2607,7 @@ |
2516 | 2607 | |
2517 | 2608 | xprt_unregister_transport(&xs_udp_transport); |
2518 | 2609 | xprt_unregister_transport(&xs_tcp_transport); |
2610 | + xprt_unregister_transport(&xs_bc_tcp_transport); | |
2519 | 2611 | } |
2520 | 2612 | |
2521 | 2613 | static int param_set_uint_minmax(const char *val, struct kernel_param *kp, |