diff options
Diffstat (limited to 'net/sunrpc/xprtsock.c')
-rw-r--r-- | net/sunrpc/xprtsock.c | 60 |
1 files changed, 48 insertions, 12 deletions
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 72abb735893..b60b75082f3 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c | |||
@@ -37,7 +37,7 @@ | |||
37 | #include <linux/sunrpc/svcsock.h> | 37 | #include <linux/sunrpc/svcsock.h> |
38 | #include <linux/sunrpc/xprtsock.h> | 38 | #include <linux/sunrpc/xprtsock.h> |
39 | #include <linux/file.h> | 39 | #include <linux/file.h> |
40 | #ifdef CONFIG_NFS_V4_1 | 40 | #ifdef CONFIG_SUNRPC_BACKCHANNEL |
41 | #include <linux/sunrpc/bc_xprt.h> | 41 | #include <linux/sunrpc/bc_xprt.h> |
42 | #endif | 42 | #endif |
43 | 43 | ||
@@ -54,7 +54,8 @@ static void xs_close(struct rpc_xprt *xprt); | |||
54 | * xprtsock tunables | 54 | * xprtsock tunables |
55 | */ | 55 | */ |
56 | unsigned int xprt_udp_slot_table_entries = RPC_DEF_SLOT_TABLE; | 56 | unsigned int xprt_udp_slot_table_entries = RPC_DEF_SLOT_TABLE; |
57 | unsigned int xprt_tcp_slot_table_entries = RPC_DEF_SLOT_TABLE; | 57 | unsigned int xprt_tcp_slot_table_entries = RPC_MIN_SLOT_TABLE; |
58 | unsigned int xprt_max_tcp_slot_table_entries = RPC_MAX_SLOT_TABLE; | ||
58 | 59 | ||
59 | unsigned int xprt_min_resvport = RPC_DEF_MIN_RESVPORT; | 60 | unsigned int xprt_min_resvport = RPC_DEF_MIN_RESVPORT; |
60 | unsigned int xprt_max_resvport = RPC_DEF_MAX_RESVPORT; | 61 | unsigned int xprt_max_resvport = RPC_DEF_MAX_RESVPORT; |
@@ -75,6 +76,7 @@ static unsigned int xs_tcp_fin_timeout __read_mostly = XS_TCP_LINGER_TO; | |||
75 | 76 | ||
76 | static unsigned int min_slot_table_size = RPC_MIN_SLOT_TABLE; | 77 | static unsigned int min_slot_table_size = RPC_MIN_SLOT_TABLE; |
77 | static unsigned int max_slot_table_size = RPC_MAX_SLOT_TABLE; | 78 | static unsigned int max_slot_table_size = RPC_MAX_SLOT_TABLE; |
79 | static unsigned int max_tcp_slot_table_limit = RPC_MAX_SLOT_TABLE_LIMIT; | ||
78 | static unsigned int xprt_min_resvport_limit = RPC_MIN_RESVPORT; | 80 | static unsigned int xprt_min_resvport_limit = RPC_MIN_RESVPORT; |
79 | static unsigned int xprt_max_resvport_limit = RPC_MAX_RESVPORT; | 81 | static unsigned int xprt_max_resvport_limit = RPC_MAX_RESVPORT; |
80 | 82 | ||
@@ -104,6 +106,15 @@ static ctl_table xs_tunables_table[] = { | |||
104 | .extra2 = &max_slot_table_size | 106 | .extra2 = &max_slot_table_size |
105 | }, | 107 | }, |
106 | { | 108 | { |
109 | .procname = "tcp_max_slot_table_entries", | ||
110 | .data = &xprt_max_tcp_slot_table_entries, | ||
111 | .maxlen = sizeof(unsigned int), | ||
112 | .mode = 0644, | ||
113 | .proc_handler = proc_dointvec_minmax, | ||
114 | .extra1 = &min_slot_table_size, | ||
115 | .extra2 = &max_tcp_slot_table_limit | ||
116 | }, | ||
117 | { | ||
107 | .procname = "min_resvport", | 118 | .procname = "min_resvport", |
108 | .data = &xprt_min_resvport, | 119 | .data = &xprt_min_resvport, |
109 | .maxlen = sizeof(unsigned int), | 120 | .maxlen = sizeof(unsigned int), |
@@ -485,7 +496,7 @@ static int xs_nospace(struct rpc_task *task) | |||
485 | struct rpc_rqst *req = task->tk_rqstp; | 496 | struct rpc_rqst *req = task->tk_rqstp; |
486 | struct rpc_xprt *xprt = req->rq_xprt; | 497 | struct rpc_xprt *xprt = req->rq_xprt; |
487 | struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt); | 498 | struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt); |
488 | int ret = 0; | 499 | int ret = -EAGAIN; |
489 | 500 | ||
490 | dprintk("RPC: %5u xmit incomplete (%u left of %u)\n", | 501 | dprintk("RPC: %5u xmit incomplete (%u left of %u)\n", |
491 | task->tk_pid, req->rq_slen - req->rq_bytes_sent, | 502 | task->tk_pid, req->rq_slen - req->rq_bytes_sent, |
@@ -497,7 +508,6 @@ static int xs_nospace(struct rpc_task *task) | |||
497 | /* Don't race with disconnect */ | 508 | /* Don't race with disconnect */ |
498 | if (xprt_connected(xprt)) { | 509 | if (xprt_connected(xprt)) { |
499 | if (test_bit(SOCK_ASYNC_NOSPACE, &transport->sock->flags)) { | 510 | if (test_bit(SOCK_ASYNC_NOSPACE, &transport->sock->flags)) { |
500 | ret = -EAGAIN; | ||
501 | /* | 511 | /* |
502 | * Notify TCP that we're limited by the application | 512 | * Notify TCP that we're limited by the application |
503 | * window size | 513 | * window size |
@@ -755,6 +765,8 @@ static void xs_tcp_release_xprt(struct rpc_xprt *xprt, struct rpc_task *task) | |||
755 | if (task == NULL) | 765 | if (task == NULL) |
756 | goto out_release; | 766 | goto out_release; |
757 | req = task->tk_rqstp; | 767 | req = task->tk_rqstp; |
768 | if (req == NULL) | ||
769 | goto out_release; | ||
758 | if (req->rq_bytes_sent == 0) | 770 | if (req->rq_bytes_sent == 0) |
759 | goto out_release; | 771 | goto out_release; |
760 | if (req->rq_bytes_sent == req->rq_snd_buf.len) | 772 | if (req->rq_bytes_sent == req->rq_snd_buf.len) |
@@ -1236,7 +1248,7 @@ static inline int xs_tcp_read_reply(struct rpc_xprt *xprt, | |||
1236 | return 0; | 1248 | return 0; |
1237 | } | 1249 | } |
1238 | 1250 | ||
1239 | #if defined(CONFIG_NFS_V4_1) | 1251 | #if defined(CONFIG_SUNRPC_BACKCHANNEL) |
1240 | /* | 1252 | /* |
1241 | * Obtains an rpc_rqst previously allocated and invokes the common | 1253 | * Obtains an rpc_rqst previously allocated and invokes the common |
1242 | * tcp read code to read the data. The result is placed in the callback | 1254 | * tcp read code to read the data. The result is placed in the callback |
@@ -1299,7 +1311,7 @@ static inline int _xs_tcp_read_data(struct rpc_xprt *xprt, | |||
1299 | { | 1311 | { |
1300 | return xs_tcp_read_reply(xprt, desc); | 1312 | return xs_tcp_read_reply(xprt, desc); |
1301 | } | 1313 | } |
1302 | #endif /* CONFIG_NFS_V4_1 */ | 1314 | #endif /* CONFIG_SUNRPC_BACKCHANNEL */ |
1303 | 1315 | ||
1304 | /* | 1316 | /* |
1305 | * Read data off the transport. This can be either an RPC_CALL or an | 1317 | * Read data off the transport. This can be either an RPC_CALL or an |
@@ -2489,7 +2501,8 @@ static int xs_init_anyaddr(const int family, struct sockaddr *sap) | |||
2489 | } | 2501 | } |
2490 | 2502 | ||
2491 | static struct rpc_xprt *xs_setup_xprt(struct xprt_create *args, | 2503 | static struct rpc_xprt *xs_setup_xprt(struct xprt_create *args, |
2492 | unsigned int slot_table_size) | 2504 | unsigned int slot_table_size, |
2505 | unsigned int max_slot_table_size) | ||
2493 | { | 2506 | { |
2494 | struct rpc_xprt *xprt; | 2507 | struct rpc_xprt *xprt; |
2495 | struct sock_xprt *new; | 2508 | struct sock_xprt *new; |
@@ -2499,7 +2512,8 @@ static struct rpc_xprt *xs_setup_xprt(struct xprt_create *args, | |||
2499 | return ERR_PTR(-EBADF); | 2512 | return ERR_PTR(-EBADF); |
2500 | } | 2513 | } |
2501 | 2514 | ||
2502 | xprt = xprt_alloc(args->net, sizeof(*new), slot_table_size); | 2515 | xprt = xprt_alloc(args->net, sizeof(*new), slot_table_size, |
2516 | max_slot_table_size); | ||
2503 | if (xprt == NULL) { | 2517 | if (xprt == NULL) { |
2504 | dprintk("RPC: xs_setup_xprt: couldn't allocate " | 2518 | dprintk("RPC: xs_setup_xprt: couldn't allocate " |
2505 | "rpc_xprt\n"); | 2519 | "rpc_xprt\n"); |
@@ -2541,7 +2555,8 @@ static struct rpc_xprt *xs_setup_local(struct xprt_create *args) | |||
2541 | struct rpc_xprt *xprt; | 2555 | struct rpc_xprt *xprt; |
2542 | struct rpc_xprt *ret; | 2556 | struct rpc_xprt *ret; |
2543 | 2557 | ||
2544 | xprt = xs_setup_xprt(args, xprt_tcp_slot_table_entries); | 2558 | xprt = xs_setup_xprt(args, xprt_tcp_slot_table_entries, |
2559 | xprt_max_tcp_slot_table_entries); | ||
2545 | if (IS_ERR(xprt)) | 2560 | if (IS_ERR(xprt)) |
2546 | return xprt; | 2561 | return xprt; |
2547 | transport = container_of(xprt, struct sock_xprt, xprt); | 2562 | transport = container_of(xprt, struct sock_xprt, xprt); |
@@ -2605,7 +2620,8 @@ static struct rpc_xprt *xs_setup_udp(struct xprt_create *args) | |||
2605 | struct sock_xprt *transport; | 2620 | struct sock_xprt *transport; |
2606 | struct rpc_xprt *ret; | 2621 | struct rpc_xprt *ret; |
2607 | 2622 | ||
2608 | xprt = xs_setup_xprt(args, xprt_udp_slot_table_entries); | 2623 | xprt = xs_setup_xprt(args, xprt_udp_slot_table_entries, |
2624 | xprt_udp_slot_table_entries); | ||
2609 | if (IS_ERR(xprt)) | 2625 | if (IS_ERR(xprt)) |
2610 | return xprt; | 2626 | return xprt; |
2611 | transport = container_of(xprt, struct sock_xprt, xprt); | 2627 | transport = container_of(xprt, struct sock_xprt, xprt); |
@@ -2681,7 +2697,8 @@ static struct rpc_xprt *xs_setup_tcp(struct xprt_create *args) | |||
2681 | struct sock_xprt *transport; | 2697 | struct sock_xprt *transport; |
2682 | struct rpc_xprt *ret; | 2698 | struct rpc_xprt *ret; |
2683 | 2699 | ||
2684 | xprt = xs_setup_xprt(args, xprt_tcp_slot_table_entries); | 2700 | xprt = xs_setup_xprt(args, xprt_tcp_slot_table_entries, |
2701 | xprt_max_tcp_slot_table_entries); | ||
2685 | if (IS_ERR(xprt)) | 2702 | if (IS_ERR(xprt)) |
2686 | return xprt; | 2703 | return xprt; |
2687 | transport = container_of(xprt, struct sock_xprt, xprt); | 2704 | transport = container_of(xprt, struct sock_xprt, xprt); |
@@ -2760,7 +2777,8 @@ static struct rpc_xprt *xs_setup_bc_tcp(struct xprt_create *args) | |||
2760 | */ | 2777 | */ |
2761 | return args->bc_xprt->xpt_bc_xprt; | 2778 | return args->bc_xprt->xpt_bc_xprt; |
2762 | } | 2779 | } |
2763 | xprt = xs_setup_xprt(args, xprt_tcp_slot_table_entries); | 2780 | xprt = xs_setup_xprt(args, xprt_tcp_slot_table_entries, |
2781 | xprt_tcp_slot_table_entries); | ||
2764 | if (IS_ERR(xprt)) | 2782 | if (IS_ERR(xprt)) |
2765 | return xprt; | 2783 | return xprt; |
2766 | transport = container_of(xprt, struct sock_xprt, xprt); | 2784 | transport = container_of(xprt, struct sock_xprt, xprt); |
@@ -2947,8 +2965,26 @@ static struct kernel_param_ops param_ops_slot_table_size = { | |||
2947 | #define param_check_slot_table_size(name, p) \ | 2965 | #define param_check_slot_table_size(name, p) \ |
2948 | __param_check(name, p, unsigned int); | 2966 | __param_check(name, p, unsigned int); |
2949 | 2967 | ||
2968 | static int param_set_max_slot_table_size(const char *val, | ||
2969 | const struct kernel_param *kp) | ||
2970 | { | ||
2971 | return param_set_uint_minmax(val, kp, | ||
2972 | RPC_MIN_SLOT_TABLE, | ||
2973 | RPC_MAX_SLOT_TABLE_LIMIT); | ||
2974 | } | ||
2975 | |||
2976 | static struct kernel_param_ops param_ops_max_slot_table_size = { | ||
2977 | .set = param_set_max_slot_table_size, | ||
2978 | .get = param_get_uint, | ||
2979 | }; | ||
2980 | |||
2981 | #define param_check_max_slot_table_size(name, p) \ | ||
2982 | __param_check(name, p, unsigned int); | ||
2983 | |||
2950 | module_param_named(tcp_slot_table_entries, xprt_tcp_slot_table_entries, | 2984 | module_param_named(tcp_slot_table_entries, xprt_tcp_slot_table_entries, |
2951 | slot_table_size, 0644); | 2985 | slot_table_size, 0644); |
2986 | module_param_named(tcp_max_slot_table_entries, xprt_max_tcp_slot_table_entries, | ||
2987 | max_slot_table_size, 0644); | ||
2952 | module_param_named(udp_slot_table_entries, xprt_udp_slot_table_entries, | 2988 | module_param_named(udp_slot_table_entries, xprt_udp_slot_table_entries, |
2953 | slot_table_size, 0644); | 2989 | slot_table_size, 0644); |
2954 | 2990 | ||