aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc
diff options
context:
space:
mode:
authorJ. Bruce Fields <bfields@redhat.com>2012-12-03 16:45:35 -0500
committerJ. Bruce Fields <bfields@redhat.com>2012-12-04 07:49:14 -0500
commit8af345f58ac9b350bb23c1457c613381d9f00472 (patch)
tree5713862546aad1e24784079ef4eae8edfc37de83 /net/sunrpc
parent6a72ae2e23922bc96e8f3de24a5203be6edc2539 (diff)
svcrpc: track rpc data length separately from sk_tcplen
Keep a separate field, sk_datalen, that tracks only the data contained in a fragment, not including the fragment header. For now, this is always just max(0, sk_tcplen - 4), but after we allow multiple fragments sk_datalen will accumulate the total rpc data size while sk_tcplen only tracks progress receiving the current fragment. Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'net/sunrpc')
-rw-r--r--net/sunrpc/svcsock.c19
1 files changed, 12 insertions, 7 deletions
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index 1db42b1ffe28..2b09e2306bfa 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -874,9 +874,9 @@ static unsigned int svc_tcp_restore_pages(struct svc_sock *svsk, struct svc_rqst
874{ 874{
875 unsigned int i, len, npages; 875 unsigned int i, len, npages;
876 876
877 if (svsk->sk_tcplen <= sizeof(rpc_fraghdr)) 877 if (svsk->sk_datalen == 0)
878 return 0; 878 return 0;
879 len = svsk->sk_tcplen - sizeof(rpc_fraghdr); 879 len = svsk->sk_datalen;
880 npages = (len + PAGE_SIZE - 1) >> PAGE_SHIFT; 880 npages = (len + PAGE_SIZE - 1) >> PAGE_SHIFT;
881 for (i = 0; i < npages; i++) { 881 for (i = 0; i < npages; i++) {
882 if (rqstp->rq_pages[i] != NULL) 882 if (rqstp->rq_pages[i] != NULL)
@@ -893,9 +893,9 @@ static void svc_tcp_save_pages(struct svc_sock *svsk, struct svc_rqst *rqstp)
893{ 893{
894 unsigned int i, len, npages; 894 unsigned int i, len, npages;
895 895
896 if (svsk->sk_tcplen <= sizeof(rpc_fraghdr)) 896 if (svsk->sk_datalen == 0)
897 return; 897 return;
898 len = svsk->sk_tcplen - sizeof(rpc_fraghdr); 898 len = svsk->sk_datalen;
899 npages = (len + PAGE_SIZE - 1) >> PAGE_SHIFT; 899 npages = (len + PAGE_SIZE - 1) >> PAGE_SHIFT;
900 for (i = 0; i < npages; i++) { 900 for (i = 0; i < npages; i++) {
901 svsk->sk_pages[i] = rqstp->rq_pages[i]; 901 svsk->sk_pages[i] = rqstp->rq_pages[i];
@@ -907,9 +907,9 @@ static void svc_tcp_clear_pages(struct svc_sock *svsk)
907{ 907{
908 unsigned int i, len, npages; 908 unsigned int i, len, npages;
909 909
910 if (svsk->sk_tcplen <= sizeof(rpc_fraghdr)) 910 if (svsk->sk_datalen == 0)
911 goto out; 911 goto out;
912 len = svsk->sk_tcplen - sizeof(rpc_fraghdr); 912 len = svsk->sk_datalen;
913 npages = (len + PAGE_SIZE - 1) >> PAGE_SHIFT; 913 npages = (len + PAGE_SIZE - 1) >> PAGE_SHIFT;
914 for (i = 0; i < npages; i++) { 914 for (i = 0; i < npages; i++) {
915 BUG_ON(svsk->sk_pages[i] == NULL); 915 BUG_ON(svsk->sk_pages[i] == NULL);
@@ -918,6 +918,7 @@ static void svc_tcp_clear_pages(struct svc_sock *svsk)
918 } 918 }
919out: 919out:
920 svsk->sk_tcplen = 0; 920 svsk->sk_tcplen = 0;
921 svsk->sk_datalen = 0;
921} 922}
922 923
923/* 924/*
@@ -1066,8 +1067,10 @@ static int svc_tcp_recvfrom(struct svc_rqst *rqstp)
1066 1067
1067 /* Now receive data */ 1068 /* Now receive data */
1068 len = svc_partial_recvfrom(rqstp, vec, pnum, want, base); 1069 len = svc_partial_recvfrom(rqstp, vec, pnum, want, base);
1069 if (len >= 0) 1070 if (len >= 0) {
1070 svsk->sk_tcplen += len; 1071 svsk->sk_tcplen += len;
1072 svsk->sk_datalen += len;
1073 }
1071 if (len != want) { 1074 if (len != want) {
1072 svc_tcp_save_pages(svsk, rqstp); 1075 svc_tcp_save_pages(svsk, rqstp);
1073 if (len < 0 && len != -EAGAIN) 1076 if (len < 0 && len != -EAGAIN)
@@ -1100,6 +1103,7 @@ static int svc_tcp_recvfrom(struct svc_rqst *rqstp)
1100 /* Reset TCP read info */ 1103 /* Reset TCP read info */
1101 svsk->sk_reclen = 0; 1104 svsk->sk_reclen = 0;
1102 svsk->sk_tcplen = 0; 1105 svsk->sk_tcplen = 0;
1106 svsk->sk_datalen = 0;
1103 /* If we have more data, signal svc_xprt_enqueue() to try again */ 1107 /* If we have more data, signal svc_xprt_enqueue() to try again */
1104 if (svc_recv_available(svsk) > sizeof(rpc_fraghdr)) 1108 if (svc_recv_available(svsk) > sizeof(rpc_fraghdr))
1105 set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags); 1109 set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags);
@@ -1296,6 +1300,7 @@ static void svc_tcp_init(struct svc_sock *svsk, struct svc_serv *serv)
1296 1300
1297 svsk->sk_reclen = 0; 1301 svsk->sk_reclen = 0;
1298 svsk->sk_tcplen = 0; 1302 svsk->sk_tcplen = 0;
1303 svsk->sk_datalen = 0;
1299 memset(&svsk->sk_pages[0], 0, sizeof(svsk->sk_pages)); 1304 memset(&svsk->sk_pages[0], 0, sizeof(svsk->sk_pages));
1300 1305
1301 tcp_sk(sk)->nonagle |= TCP_NAGLE_OFF; 1306 tcp_sk(sk)->nonagle |= TCP_NAGLE_OFF;