diff options
author | Alexandros Batsakis <batsakis@netapp.com> | 2009-09-10 10:33:30 -0400 |
---|---|---|
committer | J. Bruce Fields <bfields@citi.umich.edu> | 2009-09-13 15:46:15 -0400 |
commit | f300baba5a1536070d6d77bf0c8c4ca999bb4f0f (patch) | |
tree | 648d0020d9a9325cfcb07571d9f11a5c797ee900 | |
parent | 908329f2c08b8b5af7b394f709b0ee9c43b93041 (diff) |
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>
-rw-r--r-- | include/linux/sunrpc/clnt.h | 1 | ||||
-rw-r--r-- | include/linux/sunrpc/xprt.h | 18 | ||||
-rw-r--r-- | include/linux/sunrpc/xprtrdma.h | 5 | ||||
-rw-r--r-- | include/linux/sunrpc/xprtsock.h | 11 | ||||
-rw-r--r-- | net/sunrpc/clnt.c | 1 | ||||
-rw-r--r-- | net/sunrpc/xprtsock.c | 96 |
6 files changed, 114 insertions, 18 deletions
diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h index 3d025588e56e..8ed9642a5a76 100644 --- a/include/linux/sunrpc/clnt.h +++ b/include/linux/sunrpc/clnt.h | |||
@@ -114,6 +114,7 @@ struct rpc_create_args { | |||
114 | rpc_authflavor_t authflavor; | 114 | rpc_authflavor_t authflavor; |
115 | unsigned long flags; | 115 | unsigned long flags; |
116 | char *client_name; | 116 | char *client_name; |
117 | struct svc_xprt *bc_xprt; /* NFSv4.1 backchannel */ | ||
117 | }; | 118 | }; |
118 | 119 | ||
119 | /* Values for "flags" field */ | 120 | /* Values for "flags" field */ |
diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h index 228d694dbb90..6f9457a75b8f 100644 --- a/include/linux/sunrpc/xprt.h +++ b/include/linux/sunrpc/xprt.h | |||
@@ -124,6 +124,23 @@ struct rpc_xprt_ops { | |||
124 | void (*print_stats)(struct rpc_xprt *xprt, struct seq_file *seq); | 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 | struct rpc_xprt { | 144 | struct rpc_xprt { |
128 | struct kref kref; /* Reference count */ | 145 | struct kref kref; /* Reference count */ |
129 | struct rpc_xprt_ops * ops; /* transport methods */ | 146 | struct rpc_xprt_ops * ops; /* transport methods */ |
@@ -232,6 +249,7 @@ struct xprt_create { | |||
232 | struct sockaddr * srcaddr; /* optional local address */ | 249 | struct sockaddr * srcaddr; /* optional local address */ |
233 | struct sockaddr * dstaddr; /* remote peer address */ | 250 | struct sockaddr * dstaddr; /* remote peer address */ |
234 | size_t addrlen; | 251 | size_t addrlen; |
252 | struct svc_xprt *bc_xprt; /* NFSv4.1 backchannel */ | ||
235 | }; | 253 | }; |
236 | 254 | ||
237 | struct xprt_class { | 255 | struct xprt_class { |
diff --git a/include/linux/sunrpc/xprtrdma.h b/include/linux/sunrpc/xprtrdma.h index 54a379c9e8eb..c2f04e1ae159 100644 --- a/include/linux/sunrpc/xprtrdma.h +++ b/include/linux/sunrpc/xprtrdma.h | |||
@@ -41,11 +41,6 @@ | |||
41 | #define _LINUX_SUNRPC_XPRTRDMA_H | 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 | * rpcbind (v3+) RDMA netid. | 44 | * rpcbind (v3+) RDMA netid. |
50 | */ | 45 | */ |
51 | #define RPCBIND_NETID_RDMA "rdma" | 46 | #define RPCBIND_NETID_RDMA "rdma" |
diff --git a/include/linux/sunrpc/xprtsock.h b/include/linux/sunrpc/xprtsock.h index c2a46c45c8f7..3f14a02e9cc0 100644 --- a/include/linux/sunrpc/xprtsock.h +++ b/include/linux/sunrpc/xprtsock.h | |||
@@ -13,17 +13,6 @@ int init_socket_xprt(void); | |||
13 | void cleanup_socket_xprt(void); | 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 | * RPC slot table sizes for UDP, TCP transports | 16 | * RPC slot table sizes for UDP, TCP transports |
28 | */ | 17 | */ |
29 | extern unsigned int xprt_udp_slot_table_entries; | 18 | extern unsigned int xprt_udp_slot_table_entries; |
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index c1e467e1b07d..7389804e3bb7 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c | |||
@@ -288,6 +288,7 @@ struct rpc_clnt *rpc_create(struct rpc_create_args *args) | |||
288 | .srcaddr = args->saddress, | 288 | .srcaddr = args->saddress, |
289 | .dstaddr = args->address, | 289 | .dstaddr = args->address, |
290 | .addrlen = args->addrsize, | 290 | .addrlen = args->addrsize, |
291 | .bc_xprt = args->bc_xprt, | ||
291 | }; | 292 | }; |
292 | char servername[48]; | 293 | char servername[48]; |
293 | 294 | ||
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index d9a2b815714e..bee415465754 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c | |||
@@ -2468,11 +2468,93 @@ static struct rpc_xprt *xs_setup_tcp(struct xprt_create *args) | |||
2468 | return ERR_PTR(-EINVAL); | 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 | static struct xprt_class xs_udp_transport = { | 2553 | static struct xprt_class xs_udp_transport = { |
2472 | .list = LIST_HEAD_INIT(xs_udp_transport.list), | 2554 | .list = LIST_HEAD_INIT(xs_udp_transport.list), |
2473 | .name = "udp", | 2555 | .name = "udp", |
2474 | .owner = THIS_MODULE, | 2556 | .owner = THIS_MODULE, |
2475 | .ident = IPPROTO_UDP, | 2557 | .ident = XPRT_TRANSPORT_UDP, |
2476 | .setup = xs_setup_udp, | 2558 | .setup = xs_setup_udp, |
2477 | }; | 2559 | }; |
2478 | 2560 | ||
@@ -2480,10 +2562,18 @@ static struct xprt_class xs_tcp_transport = { | |||
2480 | .list = LIST_HEAD_INIT(xs_tcp_transport.list), | 2562 | .list = LIST_HEAD_INIT(xs_tcp_transport.list), |
2481 | .name = "tcp", | 2563 | .name = "tcp", |
2482 | .owner = THIS_MODULE, | 2564 | .owner = THIS_MODULE, |
2483 | .ident = IPPROTO_TCP, | 2565 | .ident = XPRT_TRANSPORT_TCP, |
2484 | .setup = xs_setup_tcp, | 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 | * init_socket_xprt - set up xprtsock's sysctls, register with RPC client | 2578 | * init_socket_xprt - set up xprtsock's sysctls, register with RPC client |
2489 | * | 2579 | * |
@@ -2497,6 +2587,7 @@ int init_socket_xprt(void) | |||
2497 | 2587 | ||
2498 | xprt_register_transport(&xs_udp_transport); | 2588 | xprt_register_transport(&xs_udp_transport); |
2499 | xprt_register_transport(&xs_tcp_transport); | 2589 | xprt_register_transport(&xs_tcp_transport); |
2590 | xprt_register_transport(&xs_bc_tcp_transport); | ||
2500 | 2591 | ||
2501 | return 0; | 2592 | return 0; |
2502 | } | 2593 | } |
@@ -2516,6 +2607,7 @@ void cleanup_socket_xprt(void) | |||
2516 | 2607 | ||
2517 | xprt_unregister_transport(&xs_udp_transport); | 2608 | xprt_unregister_transport(&xs_udp_transport); |
2518 | xprt_unregister_transport(&xs_tcp_transport); | 2609 | xprt_unregister_transport(&xs_tcp_transport); |
2610 | xprt_unregister_transport(&xs_bc_tcp_transport); | ||
2519 | } | 2611 | } |
2520 | 2612 | ||
2521 | static int param_set_uint_minmax(const char *val, struct kernel_param *kp, | 2613 | static int param_set_uint_minmax(const char *val, struct kernel_param *kp, |