Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Alexandros Batsakis and committed by
J. Bruce Fields
f300baba 908329f2

+114 -18
+1
include/linux/sunrpc/clnt.h
··· 114 114 rpc_authflavor_t authflavor; 115 115 unsigned long flags; 116 116 char *client_name; 117 + struct svc_xprt *bc_xprt; /* NFSv4.1 backchannel */ 117 118 }; 118 119 119 120 /* Values for "flags" field */
+18
include/linux/sunrpc/xprt.h
··· 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 */ ··· 249 232 struct sockaddr * srcaddr; /* optional local address */ 250 233 struct sockaddr * dstaddr; /* remote peer address */ 251 234 size_t addrlen; 235 + struct svc_xprt *bc_xprt; /* NFSv4.1 backchannel */ 252 236 }; 253 237 254 238 struct xprt_class {
-5
include/linux/sunrpc/xprtrdma.h
··· 41 41 #define _LINUX_SUNRPC_XPRTRDMA_H 42 42 43 43 /* 44 - * RPC transport identifier for RDMA 45 - */ 46 - #define XPRT_TRANSPORT_RDMA 256 47 - 48 - /* 49 44 * rpcbind (v3+) RDMA netid. 50 45 */ 51 46 #define RPCBIND_NETID_RDMA "rdma"
-11
include/linux/sunrpc/xprtsock.h
··· 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;
+1
net/sunrpc/clnt.c
··· 288 288 .srcaddr = args->saddress, 289 289 .dstaddr = args->address, 290 290 .addrlen = args->addrsize, 291 + .bc_xprt = args->bc_xprt, 291 292 }; 292 293 char servername[48]; 293 294
+94 -2
net/sunrpc/xprtsock.c
··· 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 ··· 2562 2480 .list = LIST_HEAD_INIT(xs_tcp_transport.list), 2563 2481 .name = "tcp", 2564 2482 .owner = THIS_MODULE, 2565 - .ident = IPPROTO_TCP, 2483 + .ident = XPRT_TRANSPORT_TCP, 2566 2484 .setup = xs_setup_tcp, 2485 + }; 2486 + 2487 + static struct xprt_class xs_bc_tcp_transport = { 2488 + .list = LIST_HEAD_INIT(xs_bc_tcp_transport.list), 2489 + .name = "tcp NFSv4.1 backchannel", 2490 + .owner = THIS_MODULE, 2491 + .ident = XPRT_TRANSPORT_BC_TCP, 2492 + .setup = xs_setup_bc_tcp, 2567 2493 }; 2568 2494 2569 2495 /** ··· 2587 2497 2588 2498 xprt_register_transport(&xs_udp_transport); 2589 2499 xprt_register_transport(&xs_tcp_transport); 2500 + xprt_register_transport(&xs_bc_tcp_transport); 2590 2501 2591 2502 return 0; 2592 2503 } ··· 2607 2516 2608 2517 xprt_unregister_transport(&xs_udp_transport); 2609 2518 xprt_unregister_transport(&xs_tcp_transport); 2519 + xprt_unregister_transport(&xs_bc_tcp_transport); 2610 2520 } 2611 2521 2612 2522 static int param_set_uint_minmax(const char *val, struct kernel_param *kp,