diff options
Diffstat (limited to 'net/sunrpc')
-rw-r--r-- | net/sunrpc/clnt.c | 32 | ||||
-rw-r--r-- | net/sunrpc/socklib.c | 5 | ||||
-rw-r--r-- | net/sunrpc/svcsock.c | 9 |
3 files changed, 37 insertions, 9 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); | |||
55 | static void call_bind_status(struct rpc_task *task); | 55 | static void call_bind_status(struct rpc_task *task); |
56 | static void call_transmit(struct rpc_task *task); | 56 | static void call_transmit(struct rpc_task *task); |
57 | static void call_status(struct rpc_task *task); | 57 | static void call_status(struct rpc_task *task); |
58 | static void call_transmit_status(struct rpc_task *task); | ||
58 | static void call_refresh(struct rpc_task *task); | 59 | static void call_refresh(struct rpc_task *task); |
59 | static void call_refreshresult(struct rpc_task *task); | 60 | static void call_refreshresult(struct rpc_task *task); |
60 | static void call_timeout(struct rpc_task *task); | 61 | static 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 | ||
676 | static inline int | ||
677 | rpc_task_need_encode(struct rpc_task *task) | ||
678 | { | ||
679 | return task->tk_rqstp->rq_snd_buf.len == 0; | ||
680 | } | ||
681 | |||
682 | static inline void | ||
683 | rpc_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) | |||
884 | out_nosend: | 899 | out_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 | */ | ||
957 | static void | ||
958 | call_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 | */ |
diff --git a/net/sunrpc/socklib.c b/net/sunrpc/socklib.c index 8f97e90f36c8..eb330d4f66d6 100644 --- a/net/sunrpc/socklib.c +++ b/net/sunrpc/socklib.c | |||
@@ -6,6 +6,9 @@ | |||
6 | * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de> | 6 | * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de> |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include <linux/compiler.h> | ||
10 | #include <linux/netdevice.h> | ||
11 | #include <linux/skbuff.h> | ||
9 | #include <linux/types.h> | 12 | #include <linux/types.h> |
10 | #include <linux/pagemap.h> | 13 | #include <linux/pagemap.h> |
11 | #include <linux/udp.h> | 14 | #include <linux/udp.h> |
@@ -165,6 +168,8 @@ int csum_partial_copy_to_xdr(struct xdr_buf *xdr, struct sk_buff *skb) | |||
165 | return -1; | 168 | return -1; |
166 | if ((unsigned short)csum_fold(desc.csum)) | 169 | if ((unsigned short)csum_fold(desc.csum)) |
167 | return -1; | 170 | return -1; |
171 | if (unlikely(skb->ip_summed == CHECKSUM_HW)) | ||
172 | netdev_rx_csum_fault(skb->dev); | ||
168 | return 0; | 173 | return 0; |
169 | no_checksum: | 174 | no_checksum: |
170 | if (xdr_partial_copy_from_skb(xdr, 0, &desc, skb_read_bits) < 0) | 175 | if (xdr_partial_copy_from_skb(xdr, 0, &desc, skb_read_bits) < 0) |
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index f16e7cdd6150..e50e7cf43737 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c | |||
@@ -623,12 +623,9 @@ svc_udp_recvfrom(struct svc_rqst *rqstp) | |||
623 | /* we can use it in-place */ | 623 | /* we can use it in-place */ |
624 | rqstp->rq_arg.head[0].iov_base = skb->data + sizeof(struct udphdr); | 624 | rqstp->rq_arg.head[0].iov_base = skb->data + sizeof(struct udphdr); |
625 | rqstp->rq_arg.head[0].iov_len = len; | 625 | rqstp->rq_arg.head[0].iov_len = len; |
626 | if (skb->ip_summed != CHECKSUM_UNNECESSARY) { | 626 | if (skb_checksum_complete(skb)) { |
627 | if ((unsigned short)csum_fold(skb_checksum(skb, 0, skb->len, skb->csum))) { | 627 | skb_free_datagram(svsk->sk_sk, skb); |
628 | skb_free_datagram(svsk->sk_sk, skb); | 628 | return 0; |
629 | return 0; | ||
630 | } | ||
631 | skb->ip_summed = CHECKSUM_UNNECESSARY; | ||
632 | } | 629 | } |
633 | rqstp->rq_skbuff = skb; | 630 | rqstp->rq_skbuff = skb; |
634 | } | 631 | } |