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.c144
1 files changed, 112 insertions, 32 deletions
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index 40b502b11442..a4fafcbc6ea0 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -387,6 +387,33 @@ static int svc_recvfrom(struct svc_rqst *rqstp, struct kvec *iov, int nr,
387 return len; 387 return len;
388} 388}
389 389
390static int svc_partial_recvfrom(struct svc_rqst *rqstp,
391 struct kvec *iov, int nr,
392 int buflen, unsigned int base)
393{
394 size_t save_iovlen;
395 void __user *save_iovbase;
396 unsigned int i;
397 int ret;
398
399 if (base == 0)
400 return svc_recvfrom(rqstp, iov, nr, buflen);
401
402 for (i = 0; i < nr; i++) {
403 if (iov[i].iov_len > base)
404 break;
405 base -= iov[i].iov_len;
406 }
407 save_iovlen = iov[i].iov_len;
408 save_iovbase = iov[i].iov_base;
409 iov[i].iov_len -= base;
410 iov[i].iov_base += base;
411 ret = svc_recvfrom(rqstp, &iov[i], nr - i, buflen);
412 iov[i].iov_len = save_iovlen;
413 iov[i].iov_base = save_iovbase;
414 return ret;
415}
416
390/* 417/*
391 * Set socket snd and rcv buffer lengths 418 * Set socket snd and rcv buffer lengths
392 */ 419 */
@@ -884,6 +911,56 @@ failed:
884 return NULL; 911 return NULL;
885} 912}
886 913
914static unsigned int svc_tcp_restore_pages(struct svc_sock *svsk, struct svc_rqst *rqstp)
915{
916 unsigned int i, len, npages;
917
918 if (svsk->sk_tcplen <= sizeof(rpc_fraghdr))
919 return 0;
920 len = svsk->sk_tcplen - sizeof(rpc_fraghdr);
921 npages = (len + PAGE_SIZE - 1) >> PAGE_SHIFT;
922 for (i = 0; i < npages; i++) {
923 if (rqstp->rq_pages[i] != NULL)
924 put_page(rqstp->rq_pages[i]);
925 BUG_ON(svsk->sk_pages[i] == NULL);
926 rqstp->rq_pages[i] = svsk->sk_pages[i];
927 svsk->sk_pages[i] = NULL;
928 }
929 rqstp->rq_arg.head[0].iov_base = page_address(rqstp->rq_pages[0]);
930 return len;
931}
932
933static void svc_tcp_save_pages(struct svc_sock *svsk, struct svc_rqst *rqstp)
934{
935 unsigned int i, len, npages;
936
937 if (svsk->sk_tcplen <= sizeof(rpc_fraghdr))
938 return;
939 len = svsk->sk_tcplen - sizeof(rpc_fraghdr);
940 npages = (len + PAGE_SIZE - 1) >> PAGE_SHIFT;
941 for (i = 0; i < npages; i++) {
942 svsk->sk_pages[i] = rqstp->rq_pages[i];
943 rqstp->rq_pages[i] = NULL;
944 }
945}
946
947static void svc_tcp_clear_pages(struct svc_sock *svsk)
948{
949 unsigned int i, len, npages;
950
951 if (svsk->sk_tcplen <= sizeof(rpc_fraghdr))
952 goto out;
953 len = svsk->sk_tcplen - sizeof(rpc_fraghdr);
954 npages = (len + PAGE_SIZE - 1) >> PAGE_SHIFT;
955 for (i = 0; i < npages; i++) {
956 BUG_ON(svsk->sk_pages[i] == NULL);
957 put_page(svsk->sk_pages[i]);
958 svsk->sk_pages[i] = NULL;
959 }
960out:
961 svsk->sk_tcplen = 0;
962}
963
887/* 964/*
888 * Receive data. 965 * Receive data.
889 * If we haven't gotten the record length yet, get the next four bytes. 966 * If we haven't gotten the record length yet, get the next four bytes.
@@ -928,7 +1005,7 @@ static int svc_tcp_recv_record(struct svc_sock *svsk, struct svc_rqst *rqstp)
928 if (len < want) { 1005 if (len < want) {
929 dprintk("svc: short recvfrom while reading record " 1006 dprintk("svc: short recvfrom while reading record "
930 "length (%d of %d)\n", len, want); 1007 "length (%d of %d)\n", len, want);
931 goto err_again; /* record header not complete */ 1008 return -EAGAIN;
932 } 1009 }
933 1010
934 svsk->sk_reclen = ntohl(svsk->sk_reclen); 1011 svsk->sk_reclen = ntohl(svsk->sk_reclen);
@@ -958,26 +1035,14 @@ static int svc_tcp_recv_record(struct svc_sock *svsk, struct svc_rqst *rqstp)
958 if (svsk->sk_reclen < 8) 1035 if (svsk->sk_reclen < 8)
959 goto err_delete; /* client is nuts. */ 1036 goto err_delete; /* client is nuts. */
960 1037
961 /* Check whether enough data is available */
962 len = svc_recv_available(svsk);
963 if (len < 0)
964 goto error;
965
966 if (len < svsk->sk_reclen) {
967 dprintk("svc: incomplete TCP record (%d of %d)\n",
968 len, svsk->sk_reclen);
969 goto err_again; /* record not complete */
970 }
971 len = svsk->sk_reclen; 1038 len = svsk->sk_reclen;
972 1039
973 return len; 1040 return len;
974 error: 1041error:
975 if (len == -EAGAIN) 1042 dprintk("RPC: TCP recv_record got %d\n", len);
976 dprintk("RPC: TCP recv_record got EAGAIN\n");
977 return len; 1043 return len;
978 err_delete: 1044err_delete:
979 set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags); 1045 set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags);
980 err_again:
981 return -EAGAIN; 1046 return -EAGAIN;
982} 1047}
983 1048
@@ -1035,6 +1100,7 @@ static int copy_pages_to_kvecs(struct kvec *vec, struct page **pages, int len)
1035 return i; 1100 return i;
1036} 1101}
1037 1102
1103
1038/* 1104/*
1039 * Receive data from a TCP socket. 1105 * Receive data from a TCP socket.
1040 */ 1106 */
@@ -1045,6 +1111,7 @@ static int svc_tcp_recvfrom(struct svc_rqst *rqstp)
1045 struct svc_serv *serv = svsk->sk_xprt.xpt_server; 1111 struct svc_serv *serv = svsk->sk_xprt.xpt_server;
1046 int len; 1112 int len;
1047 struct kvec *vec; 1113 struct kvec *vec;
1114 unsigned int want, base;
1048 __be32 *p; 1115 __be32 *p;
1049 __be32 calldir; 1116 __be32 calldir;
1050 int pnum; 1117 int pnum;
@@ -1058,6 +1125,9 @@ static int svc_tcp_recvfrom(struct svc_rqst *rqstp)
1058 if (len < 0) 1125 if (len < 0)
1059 goto error; 1126 goto error;
1060 1127
1128 base = svc_tcp_restore_pages(svsk, rqstp);
1129 want = svsk->sk_reclen - base;
1130
1061 vec = rqstp->rq_vec; 1131 vec = rqstp->rq_vec;
1062 1132
1063 pnum = copy_pages_to_kvecs(&vec[0], &rqstp->rq_pages[0], 1133 pnum = copy_pages_to_kvecs(&vec[0], &rqstp->rq_pages[0],
@@ -1066,11 +1136,18 @@ static int svc_tcp_recvfrom(struct svc_rqst *rqstp)
1066 rqstp->rq_respages = &rqstp->rq_pages[pnum]; 1136 rqstp->rq_respages = &rqstp->rq_pages[pnum];
1067 1137
1068 /* Now receive data */ 1138 /* Now receive data */
1069 len = svc_recvfrom(rqstp, vec, pnum, svsk->sk_reclen); 1139 len = svc_partial_recvfrom(rqstp, vec, pnum, want, base);
1070 if (len < 0) 1140 if (len >= 0)
1071 goto err_again; 1141 svsk->sk_tcplen += len;
1142 if (len != want) {
1143 if (len < 0 && len != -EAGAIN)
1144 goto err_other;
1145 svc_tcp_save_pages(svsk, rqstp);
1146 dprintk("svc: incomplete TCP record (%d of %d)\n",
1147 svsk->sk_tcplen, svsk->sk_reclen);
1148 goto err_noclose;
1149 }
1072 1150
1073 dprintk("svc: TCP complete record (%d bytes)\n", svsk->sk_reclen);
1074 rqstp->rq_arg.len = svsk->sk_reclen; 1151 rqstp->rq_arg.len = svsk->sk_reclen;
1075 rqstp->rq_arg.page_base = 0; 1152 rqstp->rq_arg.page_base = 0;
1076 if (rqstp->rq_arg.len <= rqstp->rq_arg.head[0].iov_len) { 1153 if (rqstp->rq_arg.len <= rqstp->rq_arg.head[0].iov_len) {
@@ -1087,7 +1164,7 @@ static int svc_tcp_recvfrom(struct svc_rqst *rqstp)
1087 if (calldir) { 1164 if (calldir) {
1088 len = receive_cb_reply(svsk, rqstp); 1165 len = receive_cb_reply(svsk, rqstp);
1089 if (len < 0) 1166 if (len < 0)
1090 goto err_again; 1167 goto error;
1091 } 1168 }
1092 1169
1093 /* Reset TCP read info */ 1170 /* Reset TCP read info */
@@ -1102,20 +1179,20 @@ static int svc_tcp_recvfrom(struct svc_rqst *rqstp)
1102 if (serv->sv_stats) 1179 if (serv->sv_stats)
1103 serv->sv_stats->nettcpcnt++; 1180 serv->sv_stats->nettcpcnt++;
1104 1181
1182 dprintk("svc: TCP complete record (%d bytes)\n", rqstp->rq_arg.len);
1105 return rqstp->rq_arg.len; 1183 return rqstp->rq_arg.len;
1106 1184
1107err_again:
1108 if (len == -EAGAIN) {
1109 dprintk("RPC: TCP recvfrom got EAGAIN\n");
1110 return len;
1111 }
1112error: 1185error:
1113 if (len != -EAGAIN) { 1186 if (len != -EAGAIN)
1114 printk(KERN_NOTICE "%s: recvfrom returned errno %d\n", 1187 goto err_other;
1115 svsk->sk_xprt.xpt_server->sv_name, -len); 1188 dprintk("RPC: TCP recvfrom got EAGAIN\n");
1116 set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags);
1117 }
1118 return -EAGAIN; 1189 return -EAGAIN;
1190err_other:
1191 printk(KERN_NOTICE "%s: recvfrom returned errno %d\n",
1192 svsk->sk_xprt.xpt_server->sv_name, -len);
1193 set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags);
1194err_noclose:
1195 return -EAGAIN; /* record not complete */
1119} 1196}
1120 1197
1121/* 1198/*
@@ -1286,6 +1363,7 @@ static void svc_tcp_init(struct svc_sock *svsk, struct svc_serv *serv)
1286 1363
1287 svsk->sk_reclen = 0; 1364 svsk->sk_reclen = 0;
1288 svsk->sk_tcplen = 0; 1365 svsk->sk_tcplen = 0;
1366 memset(&svsk->sk_pages[0], 0, sizeof(svsk->sk_pages));
1289 1367
1290 tcp_sk(sk)->nonagle |= TCP_NAGLE_OFF; 1368 tcp_sk(sk)->nonagle |= TCP_NAGLE_OFF;
1291 1369
@@ -1544,8 +1622,10 @@ static void svc_tcp_sock_detach(struct svc_xprt *xprt)
1544 1622
1545 svc_sock_detach(xprt); 1623 svc_sock_detach(xprt);
1546 1624
1547 if (!test_bit(XPT_LISTENER, &xprt->xpt_flags)) 1625 if (!test_bit(XPT_LISTENER, &xprt->xpt_flags)) {
1626 svc_tcp_clear_pages(svsk);
1548 kernel_sock_shutdown(svsk->sk_sock, SHUT_RDWR); 1627 kernel_sock_shutdown(svsk->sk_sock, SHUT_RDWR);
1628 }
1549} 1629}
1550 1630
1551/* 1631/*