aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc/svcsock.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sunrpc/svcsock.c')
-rw-r--r--net/sunrpc/svcsock.c50
1 files changed, 32 insertions, 18 deletions
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index b507cd327d9b..c24a8ff33f8f 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -446,15 +446,43 @@ static void svc_write_space(struct sock *sk)
446 } 446 }
447} 447}
448 448
449static int svc_tcp_has_wspace(struct svc_xprt *xprt)
450{
451 struct svc_sock *svsk = container_of(xprt, struct svc_sock, sk_xprt);
452 struct svc_serv *serv = svsk->sk_xprt.xpt_server;
453 int required;
454
455 if (test_bit(XPT_LISTENER, &xprt->xpt_flags))
456 return 1;
457 required = atomic_read(&xprt->xpt_reserved) + serv->sv_max_mesg;
458 if (sk_stream_wspace(svsk->sk_sk) >= required ||
459 (sk_stream_min_wspace(svsk->sk_sk) == 0 &&
460 atomic_read(&xprt->xpt_reserved) == 0))
461 return 1;
462 set_bit(SOCK_NOSPACE, &svsk->sk_sock->flags);
463 return 0;
464}
465
449static void svc_tcp_write_space(struct sock *sk) 466static void svc_tcp_write_space(struct sock *sk)
450{ 467{
468 struct svc_sock *svsk = (struct svc_sock *)(sk->sk_user_data);
451 struct socket *sock = sk->sk_socket; 469 struct socket *sock = sk->sk_socket;
452 470
453 if (sk_stream_is_writeable(sk) && sock) 471 if (!sk_stream_is_writeable(sk) || !sock)
472 return;
473 if (!svsk || svc_tcp_has_wspace(&svsk->sk_xprt))
454 clear_bit(SOCK_NOSPACE, &sock->flags); 474 clear_bit(SOCK_NOSPACE, &sock->flags);
455 svc_write_space(sk); 475 svc_write_space(sk);
456} 476}
457 477
478static void svc_tcp_adjust_wspace(struct svc_xprt *xprt)
479{
480 struct svc_sock *svsk = container_of(xprt, struct svc_sock, sk_xprt);
481
482 if (svc_tcp_has_wspace(xprt))
483 clear_bit(SOCK_NOSPACE, &svsk->sk_sock->flags);
484}
485
458/* 486/*
459 * See net/ipv6/ip_sockglue.c : ip_cmsg_recv_pktinfo 487 * See net/ipv6/ip_sockglue.c : ip_cmsg_recv_pktinfo
460 */ 488 */
@@ -692,6 +720,7 @@ static struct svc_xprt_class svc_udp_class = {
692 .xcl_owner = THIS_MODULE, 720 .xcl_owner = THIS_MODULE,
693 .xcl_ops = &svc_udp_ops, 721 .xcl_ops = &svc_udp_ops,
694 .xcl_max_payload = RPCSVC_MAXPAYLOAD_UDP, 722 .xcl_max_payload = RPCSVC_MAXPAYLOAD_UDP,
723 .xcl_ident = XPRT_TRANSPORT_UDP,
695}; 724};
696 725
697static void svc_udp_init(struct svc_sock *svsk, struct svc_serv *serv) 726static void svc_udp_init(struct svc_sock *svsk, struct svc_serv *serv)
@@ -1197,23 +1226,6 @@ static void svc_tcp_prep_reply_hdr(struct svc_rqst *rqstp)
1197 svc_putnl(resv, 0); 1226 svc_putnl(resv, 0);
1198} 1227}
1199 1228
1200static int svc_tcp_has_wspace(struct svc_xprt *xprt)
1201{
1202 struct svc_sock *svsk = container_of(xprt, struct svc_sock, sk_xprt);
1203 struct svc_serv *serv = svsk->sk_xprt.xpt_server;
1204 int required;
1205
1206 if (test_bit(XPT_LISTENER, &xprt->xpt_flags))
1207 return 1;
1208 required = atomic_read(&xprt->xpt_reserved) + serv->sv_max_mesg;
1209 if (sk_stream_wspace(svsk->sk_sk) >= required ||
1210 (sk_stream_min_wspace(svsk->sk_sk) == 0 &&
1211 atomic_read(&xprt->xpt_reserved) == 0))
1212 return 1;
1213 set_bit(SOCK_NOSPACE, &svsk->sk_sock->flags);
1214 return 0;
1215}
1216
1217static struct svc_xprt *svc_tcp_create(struct svc_serv *serv, 1229static struct svc_xprt *svc_tcp_create(struct svc_serv *serv,
1218 struct net *net, 1230 struct net *net,
1219 struct sockaddr *sa, int salen, 1231 struct sockaddr *sa, int salen,
@@ -1285,6 +1297,7 @@ static struct svc_xprt_ops svc_tcp_ops = {
1285 .xpo_has_wspace = svc_tcp_has_wspace, 1297 .xpo_has_wspace = svc_tcp_has_wspace,
1286 .xpo_accept = svc_tcp_accept, 1298 .xpo_accept = svc_tcp_accept,
1287 .xpo_secure_port = svc_sock_secure_port, 1299 .xpo_secure_port = svc_sock_secure_port,
1300 .xpo_adjust_wspace = svc_tcp_adjust_wspace,
1288}; 1301};
1289 1302
1290static struct svc_xprt_class svc_tcp_class = { 1303static struct svc_xprt_class svc_tcp_class = {
@@ -1292,6 +1305,7 @@ static struct svc_xprt_class svc_tcp_class = {
1292 .xcl_owner = THIS_MODULE, 1305 .xcl_owner = THIS_MODULE,
1293 .xcl_ops = &svc_tcp_ops, 1306 .xcl_ops = &svc_tcp_ops,
1294 .xcl_max_payload = RPCSVC_MAXPAYLOAD_TCP, 1307 .xcl_max_payload = RPCSVC_MAXPAYLOAD_TCP,
1308 .xcl_ident = XPRT_TRANSPORT_TCP,
1295}; 1309};
1296 1310
1297void svc_init_xprt_sock(void) 1311void svc_init_xprt_sock(void)