aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc/xprtsock.c
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2008-04-24 14:01:02 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2008-04-24 14:01:02 -0400
commit233607dbbc823caf685e778cabc49fb7f679900b (patch)
tree13840137ee10788061cbec60fcfe8ea4c274558e /net/sunrpc/xprtsock.c
parent3dc5063786b273f1aee545844f6bd4e9651ebffe (diff)
parentb48633bd086d21f4a2a5bea96c7e6c7ba58eb60c (diff)
Merge branch 'devel'
Diffstat (limited to 'net/sunrpc/xprtsock.c')
-rw-r--r--net/sunrpc/xprtsock.c82
1 files changed, 51 insertions, 31 deletions
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index 613daf8c1ff7..ddbe981ab516 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -136,12 +136,6 @@ static ctl_table sunrpc_table[] = {
136#endif 136#endif
137 137
138/* 138/*
139 * How many times to try sending a request on a socket before waiting
140 * for the socket buffer to clear.
141 */
142#define XS_SENDMSG_RETRY (10U)
143
144/*
145 * Time out for an RPC UDP socket connect. UDP socket connects are 139 * Time out for an RPC UDP socket connect. UDP socket connects are
146 * synchronous, but we set a timeout anyway in case of resource 140 * synchronous, but we set a timeout anyway in case of resource
147 * exhaustion on the local host. 141 * exhaustion on the local host.
@@ -516,6 +510,14 @@ out:
516 return sent; 510 return sent;
517} 511}
518 512
513static void xs_nospace_callback(struct rpc_task *task)
514{
515 struct sock_xprt *transport = container_of(task->tk_rqstp->rq_xprt, struct sock_xprt, xprt);
516
517 transport->inet->sk_write_pending--;
518 clear_bit(SOCK_ASYNC_NOSPACE, &transport->sock->flags);
519}
520
519/** 521/**
520 * xs_nospace - place task on wait queue if transmit was incomplete 522 * xs_nospace - place task on wait queue if transmit was incomplete
521 * @task: task to put to sleep 523 * @task: task to put to sleep
@@ -531,20 +533,27 @@ static void xs_nospace(struct rpc_task *task)
531 task->tk_pid, req->rq_slen - req->rq_bytes_sent, 533 task->tk_pid, req->rq_slen - req->rq_bytes_sent,
532 req->rq_slen); 534 req->rq_slen);
533 535
534 if (test_bit(SOCK_ASYNC_NOSPACE, &transport->sock->flags)) { 536 /* Protect against races with write_space */
535 /* Protect against races with write_space */ 537 spin_lock_bh(&xprt->transport_lock);
536 spin_lock_bh(&xprt->transport_lock); 538
537 539 /* Don't race with disconnect */
538 /* Don't race with disconnect */ 540 if (xprt_connected(xprt)) {
539 if (!xprt_connected(xprt)) 541 if (test_bit(SOCK_ASYNC_NOSPACE, &transport->sock->flags)) {
540 task->tk_status = -ENOTCONN; 542 /*
541 else if (test_bit(SOCK_NOSPACE, &transport->sock->flags)) 543 * Notify TCP that we're limited by the application
542 xprt_wait_for_buffer_space(task); 544 * window size
545 */
546 set_bit(SOCK_NOSPACE, &transport->sock->flags);
547 transport->inet->sk_write_pending++;
548 /* ...and wait for more buffer space */
549 xprt_wait_for_buffer_space(task, xs_nospace_callback);
550 }
551 } else {
552 clear_bit(SOCK_ASYNC_NOSPACE, &transport->sock->flags);
553 task->tk_status = -ENOTCONN;
554 }
543 555
544 spin_unlock_bh(&xprt->transport_lock); 556 spin_unlock_bh(&xprt->transport_lock);
545 } else
546 /* Keep holding the socket if it is blocked */
547 rpc_delay(task, HZ>>4);
548} 557}
549 558
550/** 559/**
@@ -588,19 +597,20 @@ static int xs_udp_send_request(struct rpc_task *task)
588 } 597 }
589 598
590 switch (status) { 599 switch (status) {
600 case -EAGAIN:
601 xs_nospace(task);
602 break;
591 case -ENETUNREACH: 603 case -ENETUNREACH:
592 case -EPIPE: 604 case -EPIPE:
593 case -ECONNREFUSED: 605 case -ECONNREFUSED:
594 /* When the server has died, an ICMP port unreachable message 606 /* When the server has died, an ICMP port unreachable message
595 * prompts ECONNREFUSED. */ 607 * prompts ECONNREFUSED. */
596 break; 608 clear_bit(SOCK_ASYNC_NOSPACE, &transport->sock->flags);
597 case -EAGAIN:
598 xs_nospace(task);
599 break; 609 break;
600 default: 610 default:
611 clear_bit(SOCK_ASYNC_NOSPACE, &transport->sock->flags);
601 dprintk("RPC: sendmsg returned unrecognized error %d\n", 612 dprintk("RPC: sendmsg returned unrecognized error %d\n",
602 -status); 613 -status);
603 break;
604 } 614 }
605 615
606 return status; 616 return status;
@@ -650,7 +660,6 @@ static int xs_tcp_send_request(struct rpc_task *task)
650 struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt); 660 struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
651 struct xdr_buf *xdr = &req->rq_snd_buf; 661 struct xdr_buf *xdr = &req->rq_snd_buf;
652 int status; 662 int status;
653 unsigned int retry = 0;
654 663
655 xs_encode_tcp_record_marker(&req->rq_snd_buf); 664 xs_encode_tcp_record_marker(&req->rq_snd_buf);
656 665
@@ -681,9 +690,10 @@ static int xs_tcp_send_request(struct rpc_task *task)
681 return 0; 690 return 0;
682 } 691 }
683 692
693 if (status != 0)
694 continue;
684 status = -EAGAIN; 695 status = -EAGAIN;
685 if (retry++ > XS_SENDMSG_RETRY) 696 break;
686 break;
687 } 697 }
688 698
689 switch (status) { 699 switch (status) {
@@ -695,12 +705,13 @@ static int xs_tcp_send_request(struct rpc_task *task)
695 case -ENOTCONN: 705 case -ENOTCONN:
696 case -EPIPE: 706 case -EPIPE:
697 status = -ENOTCONN; 707 status = -ENOTCONN;
708 clear_bit(SOCK_ASYNC_NOSPACE, &transport->sock->flags);
698 break; 709 break;
699 default: 710 default:
700 dprintk("RPC: sendmsg returned unrecognized error %d\n", 711 dprintk("RPC: sendmsg returned unrecognized error %d\n",
701 -status); 712 -status);
713 clear_bit(SOCK_ASYNC_NOSPACE, &transport->sock->flags);
702 xs_tcp_shutdown(xprt); 714 xs_tcp_shutdown(xprt);
703 break;
704 } 715 }
705 716
706 return status; 717 return status;
@@ -1073,6 +1084,7 @@ static void xs_tcp_data_ready(struct sock *sk, int bytes)
1073{ 1084{
1074 struct rpc_xprt *xprt; 1085 struct rpc_xprt *xprt;
1075 read_descriptor_t rd_desc; 1086 read_descriptor_t rd_desc;
1087 int read;
1076 1088
1077 dprintk("RPC: xs_tcp_data_ready...\n"); 1089 dprintk("RPC: xs_tcp_data_ready...\n");
1078 1090
@@ -1084,8 +1096,10 @@ static void xs_tcp_data_ready(struct sock *sk, int bytes)
1084 1096
1085 /* We use rd_desc to pass struct xprt to xs_tcp_data_recv */ 1097 /* We use rd_desc to pass struct xprt to xs_tcp_data_recv */
1086 rd_desc.arg.data = xprt; 1098 rd_desc.arg.data = xprt;
1087 rd_desc.count = 65536; 1099 do {
1088 tcp_read_sock(sk, &rd_desc, xs_tcp_data_recv); 1100 rd_desc.count = 65536;
1101 read = tcp_read_sock(sk, &rd_desc, xs_tcp_data_recv);
1102 } while (read > 0);
1089out: 1103out:
1090 read_unlock(&sk->sk_callback_lock); 1104 read_unlock(&sk->sk_callback_lock);
1091} 1105}
@@ -1128,6 +1142,7 @@ static void xs_tcp_state_change(struct sock *sk)
1128 break; 1142 break;
1129 case TCP_FIN_WAIT1: 1143 case TCP_FIN_WAIT1:
1130 /* The client initiated a shutdown of the socket */ 1144 /* The client initiated a shutdown of the socket */
1145 xprt->connect_cookie++;
1131 xprt->reestablish_timeout = 0; 1146 xprt->reestablish_timeout = 0;
1132 set_bit(XPRT_CLOSING, &xprt->state); 1147 set_bit(XPRT_CLOSING, &xprt->state);
1133 smp_mb__before_clear_bit(); 1148 smp_mb__before_clear_bit();
@@ -1140,6 +1155,7 @@ static void xs_tcp_state_change(struct sock *sk)
1140 set_bit(XPRT_CLOSING, &xprt->state); 1155 set_bit(XPRT_CLOSING, &xprt->state);
1141 xprt_force_disconnect(xprt); 1156 xprt_force_disconnect(xprt);
1142 case TCP_SYN_SENT: 1157 case TCP_SYN_SENT:
1158 xprt->connect_cookie++;
1143 case TCP_CLOSING: 1159 case TCP_CLOSING:
1144 /* 1160 /*
1145 * If the server closed down the connection, make sure that 1161 * If the server closed down the connection, make sure that
@@ -1186,9 +1202,11 @@ static void xs_udp_write_space(struct sock *sk)
1186 1202
1187 if (unlikely(!(sock = sk->sk_socket))) 1203 if (unlikely(!(sock = sk->sk_socket)))
1188 goto out; 1204 goto out;
1205 clear_bit(SOCK_NOSPACE, &sock->flags);
1206
1189 if (unlikely(!(xprt = xprt_from_sock(sk)))) 1207 if (unlikely(!(xprt = xprt_from_sock(sk))))
1190 goto out; 1208 goto out;
1191 if (unlikely(!test_and_clear_bit(SOCK_NOSPACE, &sock->flags))) 1209 if (test_and_clear_bit(SOCK_ASYNC_NOSPACE, &sock->flags) == 0)
1192 goto out; 1210 goto out;
1193 1211
1194 xprt_write_space(xprt); 1212 xprt_write_space(xprt);
@@ -1219,9 +1237,11 @@ static void xs_tcp_write_space(struct sock *sk)
1219 1237
1220 if (unlikely(!(sock = sk->sk_socket))) 1238 if (unlikely(!(sock = sk->sk_socket)))
1221 goto out; 1239 goto out;
1240 clear_bit(SOCK_NOSPACE, &sock->flags);
1241
1222 if (unlikely(!(xprt = xprt_from_sock(sk)))) 1242 if (unlikely(!(xprt = xprt_from_sock(sk))))
1223 goto out; 1243 goto out;
1224 if (unlikely(!test_and_clear_bit(SOCK_NOSPACE, &sock->flags))) 1244 if (test_and_clear_bit(SOCK_ASYNC_NOSPACE, &sock->flags) == 0)
1225 goto out; 1245 goto out;
1226 1246
1227 xprt_write_space(xprt); 1247 xprt_write_space(xprt);