aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexandros Batsakis <batsakis@netapp.com>2009-09-10 10:33:30 -0400
committerJ. Bruce Fields <bfields@citi.umich.edu>2009-09-13 15:46:15 -0400
commitf300baba5a1536070d6d77bf0c8c4ca999bb4f0f (patch)
tree648d0020d9a9325cfcb07571d9f11a5c797ee900
parent908329f2c08b8b5af7b394f709b0ee9c43b93041 (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.h1
-rw-r--r--include/linux/sunrpc/xprt.h18
-rw-r--r--include/linux/sunrpc/xprtrdma.h5
-rw-r--r--include/linux/sunrpc/xprtsock.h11
-rw-r--r--net/sunrpc/clnt.c1
-rw-r--r--net/sunrpc/xprtsock.c96
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)
137enum 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
127struct rpc_xprt { 144struct 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
237struct xprt_class { 255struct 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);
13void cleanup_socket_xprt(void); 13void 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 */
29extern unsigned int xprt_udp_slot_table_entries; 18extern 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 */
2476static 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
2471static struct xprt_class xs_udp_transport = { 2553static 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
2569static 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
2521static int param_set_uint_minmax(const char *val, struct kernel_param *kp, 2613static int param_set_uint_minmax(const char *val, struct kernel_param *kp,