diff options
Diffstat (limited to 'net/sunrpc/xprtsock.c')
-rw-r--r-- | net/sunrpc/xprtsock.c | 242 |
1 files changed, 240 insertions, 2 deletions
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 62438f3a914d..bee415465754 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <linux/tcp.h> | 32 | #include <linux/tcp.h> |
33 | #include <linux/sunrpc/clnt.h> | 33 | #include <linux/sunrpc/clnt.h> |
34 | #include <linux/sunrpc/sched.h> | 34 | #include <linux/sunrpc/sched.h> |
35 | #include <linux/sunrpc/svcsock.h> | ||
35 | #include <linux/sunrpc/xprtsock.h> | 36 | #include <linux/sunrpc/xprtsock.h> |
36 | #include <linux/file.h> | 37 | #include <linux/file.h> |
37 | #ifdef CONFIG_NFS_V4_1 | 38 | #ifdef CONFIG_NFS_V4_1 |
@@ -43,6 +44,7 @@ | |||
43 | #include <net/udp.h> | 44 | #include <net/udp.h> |
44 | #include <net/tcp.h> | 45 | #include <net/tcp.h> |
45 | 46 | ||
47 | #include "sunrpc.h" | ||
46 | /* | 48 | /* |
47 | * xprtsock tunables | 49 | * xprtsock tunables |
48 | */ | 50 | */ |
@@ -2098,6 +2100,134 @@ static void xs_tcp_print_stats(struct rpc_xprt *xprt, struct seq_file *seq) | |||
2098 | xprt->stat.bklog_u); | 2100 | xprt->stat.bklog_u); |
2099 | } | 2101 | } |
2100 | 2102 | ||
2103 | /* | ||
2104 | * Allocate a bunch of pages for a scratch buffer for the rpc code. The reason | ||
2105 | * we allocate pages instead doing a kmalloc like rpc_malloc is because we want | ||
2106 | * to use the server side send routines. | ||
2107 | */ | ||
2108 | void *bc_malloc(struct rpc_task *task, size_t size) | ||
2109 | { | ||
2110 | struct page *page; | ||
2111 | struct rpc_buffer *buf; | ||
2112 | |||
2113 | BUG_ON(size > PAGE_SIZE - sizeof(struct rpc_buffer)); | ||
2114 | page = alloc_page(GFP_KERNEL); | ||
2115 | |||
2116 | if (!page) | ||
2117 | return NULL; | ||
2118 | |||
2119 | buf = page_address(page); | ||
2120 | buf->len = PAGE_SIZE; | ||
2121 | |||
2122 | return buf->data; | ||
2123 | } | ||
2124 | |||
2125 | /* | ||
2126 | * Free the space allocated in the bc_alloc routine | ||
2127 | */ | ||
2128 | void bc_free(void *buffer) | ||
2129 | { | ||
2130 | struct rpc_buffer *buf; | ||
2131 | |||
2132 | if (!buffer) | ||
2133 | return; | ||
2134 | |||
2135 | buf = container_of(buffer, struct rpc_buffer, data); | ||
2136 | free_page((unsigned long)buf); | ||
2137 | } | ||
2138 | |||
2139 | /* | ||
2140 | * Use the svc_sock to send the callback. Must be called with svsk->sk_mutex | ||
2141 | * held. Borrows heavily from svc_tcp_sendto and xs_tcp_send_request. | ||
2142 | */ | ||
2143 | static int bc_sendto(struct rpc_rqst *req) | ||
2144 | { | ||
2145 | int len; | ||
2146 | struct xdr_buf *xbufp = &req->rq_snd_buf; | ||
2147 | struct rpc_xprt *xprt = req->rq_xprt; | ||
2148 | struct sock_xprt *transport = | ||
2149 | container_of(xprt, struct sock_xprt, xprt); | ||
2150 | struct socket *sock = transport->sock; | ||
2151 | unsigned long headoff; | ||
2152 | unsigned long tailoff; | ||
2153 | |||
2154 | /* | ||
2155 | * Set up the rpc header and record marker stuff | ||
2156 | */ | ||
2157 | xs_encode_tcp_record_marker(xbufp); | ||
2158 | |||
2159 | tailoff = (unsigned long)xbufp->tail[0].iov_base & ~PAGE_MASK; | ||
2160 | headoff = (unsigned long)xbufp->head[0].iov_base & ~PAGE_MASK; | ||
2161 | len = svc_send_common(sock, xbufp, | ||
2162 | virt_to_page(xbufp->head[0].iov_base), headoff, | ||
2163 | xbufp->tail[0].iov_base, tailoff); | ||
2164 | |||
2165 | if (len != xbufp->len) { | ||
2166 | printk(KERN_NOTICE "Error sending entire callback!\n"); | ||
2167 | len = -EAGAIN; | ||
2168 | } | ||
2169 | |||
2170 | return len; | ||
2171 | } | ||
2172 | |||
2173 | /* | ||
2174 | * The send routine. Borrows from svc_send | ||
2175 | */ | ||
2176 | static int bc_send_request(struct rpc_task *task) | ||
2177 | { | ||
2178 | struct rpc_rqst *req = task->tk_rqstp; | ||
2179 | struct svc_xprt *xprt; | ||
2180 | struct svc_sock *svsk; | ||
2181 | u32 len; | ||
2182 | |||
2183 | dprintk("sending request with xid: %08x\n", ntohl(req->rq_xid)); | ||
2184 | /* | ||
2185 | * Get the server socket associated with this callback xprt | ||
2186 | */ | ||
2187 | xprt = req->rq_xprt->bc_xprt; | ||
2188 | svsk = container_of(xprt, struct svc_sock, sk_xprt); | ||
2189 | |||
2190 | /* | ||
2191 | * Grab the mutex to serialize data as the connection is shared | ||
2192 | * with the fore channel | ||
2193 | */ | ||
2194 | if (!mutex_trylock(&xprt->xpt_mutex)) { | ||
2195 | rpc_sleep_on(&xprt->xpt_bc_pending, task, NULL); | ||
2196 | if (!mutex_trylock(&xprt->xpt_mutex)) | ||
2197 | return -EAGAIN; | ||
2198 | rpc_wake_up_queued_task(&xprt->xpt_bc_pending, task); | ||
2199 | } | ||
2200 | if (test_bit(XPT_DEAD, &xprt->xpt_flags)) | ||
2201 | len = -ENOTCONN; | ||
2202 | else | ||
2203 | len = bc_sendto(req); | ||
2204 | mutex_unlock(&xprt->xpt_mutex); | ||
2205 | |||
2206 | if (len > 0) | ||
2207 | len = 0; | ||
2208 | |||
2209 | return len; | ||
2210 | } | ||
2211 | |||
2212 | /* | ||
2213 | * The close routine. Since this is client initiated, we do nothing | ||
2214 | */ | ||
2215 | |||
2216 | static void bc_close(struct rpc_xprt *xprt) | ||
2217 | { | ||
2218 | return; | ||
2219 | } | ||
2220 | |||
2221 | /* | ||
2222 | * The xprt destroy routine. Again, because this connection is client | ||
2223 | * initiated, we do nothing | ||
2224 | */ | ||
2225 | |||
2226 | static void bc_destroy(struct rpc_xprt *xprt) | ||
2227 | { | ||
2228 | return; | ||
2229 | } | ||
2230 | |||
2101 | static struct rpc_xprt_ops xs_udp_ops = { | 2231 | static struct rpc_xprt_ops xs_udp_ops = { |
2102 | .set_buffer_size = xs_udp_set_buffer_size, | 2232 | .set_buffer_size = xs_udp_set_buffer_size, |
2103 | .reserve_xprt = xprt_reserve_xprt_cong, | 2233 | .reserve_xprt = xprt_reserve_xprt_cong, |
@@ -2134,6 +2264,22 @@ static struct rpc_xprt_ops xs_tcp_ops = { | |||
2134 | .print_stats = xs_tcp_print_stats, | 2264 | .print_stats = xs_tcp_print_stats, |
2135 | }; | 2265 | }; |
2136 | 2266 | ||
2267 | /* | ||
2268 | * The rpc_xprt_ops for the server backchannel | ||
2269 | */ | ||
2270 | |||
2271 | static struct rpc_xprt_ops bc_tcp_ops = { | ||
2272 | .reserve_xprt = xprt_reserve_xprt, | ||
2273 | .release_xprt = xprt_release_xprt, | ||
2274 | .buf_alloc = bc_malloc, | ||
2275 | .buf_free = bc_free, | ||
2276 | .send_request = bc_send_request, | ||
2277 | .set_retrans_timeout = xprt_set_retrans_timeout_def, | ||
2278 | .close = bc_close, | ||
2279 | .destroy = bc_destroy, | ||
2280 | .print_stats = xs_tcp_print_stats, | ||
2281 | }; | ||
2282 | |||
2137 | static struct rpc_xprt *xs_setup_xprt(struct xprt_create *args, | 2283 | static struct rpc_xprt *xs_setup_xprt(struct xprt_create *args, |
2138 | unsigned int slot_table_size) | 2284 | unsigned int slot_table_size) |
2139 | { | 2285 | { |
@@ -2322,11 +2468,93 @@ static struct rpc_xprt *xs_setup_tcp(struct xprt_create *args) | |||
2322 | return ERR_PTR(-EINVAL); | 2468 | return ERR_PTR(-EINVAL); |
2323 | } | 2469 | } |
2324 | 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 | |||
2325 | static struct xprt_class xs_udp_transport = { | 2553 | static struct xprt_class xs_udp_transport = { |
2326 | .list = LIST_HEAD_INIT(xs_udp_transport.list), | 2554 | .list = LIST_HEAD_INIT(xs_udp_transport.list), |
2327 | .name = "udp", | 2555 | .name = "udp", |
2328 | .owner = THIS_MODULE, | 2556 | .owner = THIS_MODULE, |
2329 | .ident = IPPROTO_UDP, | 2557 | .ident = XPRT_TRANSPORT_UDP, |
2330 | .setup = xs_setup_udp, | 2558 | .setup = xs_setup_udp, |
2331 | }; | 2559 | }; |
2332 | 2560 | ||
@@ -2334,10 +2562,18 @@ static struct xprt_class xs_tcp_transport = { | |||
2334 | .list = LIST_HEAD_INIT(xs_tcp_transport.list), | 2562 | .list = LIST_HEAD_INIT(xs_tcp_transport.list), |
2335 | .name = "tcp", | 2563 | .name = "tcp", |
2336 | .owner = THIS_MODULE, | 2564 | .owner = THIS_MODULE, |
2337 | .ident = IPPROTO_TCP, | 2565 | .ident = XPRT_TRANSPORT_TCP, |
2338 | .setup = xs_setup_tcp, | 2566 | .setup = xs_setup_tcp, |
2339 | }; | 2567 | }; |
2340 | 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 | |||
2341 | /** | 2577 | /** |
2342 | * 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 |
2343 | * | 2579 | * |
@@ -2351,6 +2587,7 @@ int init_socket_xprt(void) | |||
2351 | 2587 | ||
2352 | xprt_register_transport(&xs_udp_transport); | 2588 | xprt_register_transport(&xs_udp_transport); |
2353 | xprt_register_transport(&xs_tcp_transport); | 2589 | xprt_register_transport(&xs_tcp_transport); |
2590 | xprt_register_transport(&xs_bc_tcp_transport); | ||
2354 | 2591 | ||
2355 | return 0; | 2592 | return 0; |
2356 | } | 2593 | } |
@@ -2370,6 +2607,7 @@ void cleanup_socket_xprt(void) | |||
2370 | 2607 | ||
2371 | xprt_unregister_transport(&xs_udp_transport); | 2608 | xprt_unregister_transport(&xs_udp_transport); |
2372 | xprt_unregister_transport(&xs_tcp_transport); | 2609 | xprt_unregister_transport(&xs_tcp_transport); |
2610 | xprt_unregister_transport(&xs_bc_tcp_transport); | ||
2373 | } | 2611 | } |
2374 | 2612 | ||
2375 | 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, |