aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorTrond Myklebust <trond.myklebust@fys.uio.no>2005-11-09 21:45:24 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2005-11-09 22:31:33 -0500
commit940e3318c36394939d805e797d7be39ddaaa7911 (patch)
treeaa0bab66b2bde96f01150504909d3ef5de41a7d1 /net
parente4d76e1c0b15590f2ad9bba89426c2520cd22ca6 (diff)
[PATCH] SUNRPC: don't reencode when looping in call transmit.
If the call to xprt_transmit() fails due to socket buffer space exhaustion, we do not need to re-encode the RPC message when we loop back through call_transmit. Re-encoding can actually end up triggering the WARN_ON() in call_decode() if we re-encode something like a read() request and auth->au_rslack has changed. It can also cause us to increment the RPCSEC_GSS sequence number beyond the limits of the allowed window. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'net')
-rw-r--r--net/sunrpc/clnt.c32
1 files changed, 29 insertions, 3 deletions
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index 702ede309b06..61c3abeaccae 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -55,6 +55,7 @@ static void call_bind(struct rpc_task *task);
55static void call_bind_status(struct rpc_task *task); 55static void call_bind_status(struct rpc_task *task);
56static void call_transmit(struct rpc_task *task); 56static void call_transmit(struct rpc_task *task);
57static void call_status(struct rpc_task *task); 57static void call_status(struct rpc_task *task);
58static void call_transmit_status(struct rpc_task *task);
58static void call_refresh(struct rpc_task *task); 59static void call_refresh(struct rpc_task *task);
59static void call_refreshresult(struct rpc_task *task); 60static void call_refreshresult(struct rpc_task *task);
60static void call_timeout(struct rpc_task *task); 61static void call_timeout(struct rpc_task *task);
@@ -672,6 +673,18 @@ call_allocate(struct rpc_task *task)
672 rpc_exit(task, -ERESTARTSYS); 673 rpc_exit(task, -ERESTARTSYS);
673} 674}
674 675
676static inline int
677rpc_task_need_encode(struct rpc_task *task)
678{
679 return task->tk_rqstp->rq_snd_buf.len == 0;
680}
681
682static inline void
683rpc_task_force_reencode(struct rpc_task *task)
684{
685 task->tk_rqstp->rq_snd_buf.len = 0;
686}
687
675/* 688/*
676 * 3. Encode arguments of an RPC call 689 * 3. Encode arguments of an RPC call
677 */ 690 */
@@ -867,12 +880,14 @@ call_transmit(struct rpc_task *task)
867 if (task->tk_status != 0) 880 if (task->tk_status != 0)
868 return; 881 return;
869 /* Encode here so that rpcsec_gss can use correct sequence number. */ 882 /* Encode here so that rpcsec_gss can use correct sequence number. */
870 if (task->tk_rqstp->rq_bytes_sent == 0) { 883 if (rpc_task_need_encode(task)) {
884 task->tk_rqstp->rq_bytes_sent = 0;
871 call_encode(task); 885 call_encode(task);
872 /* Did the encode result in an error condition? */ 886 /* Did the encode result in an error condition? */
873 if (task->tk_status != 0) 887 if (task->tk_status != 0)
874 goto out_nosend; 888 goto out_nosend;
875 } 889 }
890 task->tk_action = call_transmit_status;
876 xprt_transmit(task); 891 xprt_transmit(task);
877 if (task->tk_status < 0) 892 if (task->tk_status < 0)
878 return; 893 return;
@@ -884,6 +899,7 @@ call_transmit(struct rpc_task *task)
884out_nosend: 899out_nosend:
885 /* release socket write lock before attempting to handle error */ 900 /* release socket write lock before attempting to handle error */
886 xprt_abort_transmit(task); 901 xprt_abort_transmit(task);
902 rpc_task_force_reencode(task);
887} 903}
888 904
889/* 905/*
@@ -915,7 +931,6 @@ call_status(struct rpc_task *task)
915 break; 931 break;
916 case -ECONNREFUSED: 932 case -ECONNREFUSED:
917 case -ENOTCONN: 933 case -ENOTCONN:
918 req->rq_bytes_sent = 0;
919 if (clnt->cl_autobind) 934 if (clnt->cl_autobind)
920 clnt->cl_port = 0; 935 clnt->cl_port = 0;
921 task->tk_action = call_bind; 936 task->tk_action = call_bind;
@@ -937,7 +952,18 @@ call_status(struct rpc_task *task)
937} 952}
938 953
939/* 954/*
940 * 6a. Handle RPC timeout 955 * 6a. Handle transmission errors.
956 */
957static void
958call_transmit_status(struct rpc_task *task)
959{
960 if (task->tk_status != -EAGAIN)
961 rpc_task_force_reencode(task);
962 call_status(task);
963}
964
965/*
966 * 6b. Handle RPC timeout
941 * We do not release the request slot, so we keep using the 967 * We do not release the request slot, so we keep using the
942 * same XID for all retransmits. 968 * same XID for all retransmits.
943 */ 969 */