Commit f300baba5a1536070d6d77bf0c8c4ca999bb4f0f

Authored by Alexandros Batsakis
Committed by J. Bruce Fields
1 parent 908329f2c0

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
... ... @@ -114,6 +114,7 @@
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 */
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
... ... @@ -41,11 +41,6 @@
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"
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;
... ... @@ -288,6 +288,7 @@
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  
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,