aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc
diff options
context:
space:
mode:
Diffstat (limited to 'net/sunrpc')
-rw-r--r--net/sunrpc/svcsock.c50
1 files changed, 25 insertions, 25 deletions
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index 2b09e2306bfa..38ec968ca1c6 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -949,20 +949,11 @@ static int svc_tcp_recv_record(struct svc_sock *svsk, struct svc_rqst *rqstp)
949 return -EAGAIN; 949 return -EAGAIN;
950 } 950 }
951 951
952 if (!(svc_sock_final_rec(svsk))) {
953 /* FIXME: technically, a record can be fragmented,
954 * and non-terminal fragments will not have the top
955 * bit set in the fragment length header.
956 * But apparently no known nfs clients send fragmented
957 * records. */
958 net_notice_ratelimited("RPC: multiple fragments per record not supported\n");
959 goto err_delete;
960 }
961
962 dprintk("svc: TCP record, %d bytes\n", svc_sock_reclen(svsk)); 952 dprintk("svc: TCP record, %d bytes\n", svc_sock_reclen(svsk));
963 if (svc_sock_reclen(svsk) > serv->sv_max_mesg) { 953 if (svc_sock_reclen(svsk) + svsk->sk_datalen >
954 serv->sv_max_mesg) {
964 net_notice_ratelimited("RPC: fragment too large: 0x%08lx\n", 955 net_notice_ratelimited("RPC: fragment too large: 0x%08lx\n",
965 (unsigned long)svc_sock_reclen(svsk)); 956 (unsigned long)svsk->sk_reclen);
966 goto err_delete; 957 goto err_delete;
967 } 958 }
968 } 959 }
@@ -1030,6 +1021,17 @@ static int copy_pages_to_kvecs(struct kvec *vec, struct page **pages, int len)
1030 return i; 1021 return i;
1031} 1022}
1032 1023
1024static void svc_tcp_fragment_received(struct svc_sock *svsk)
1025{
1026 /* If we have more data, signal svc_xprt_enqueue() to try again */
1027 if (svc_recv_available(svsk) > sizeof(rpc_fraghdr))
1028 set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags);
1029 dprintk("svc: TCP %s record (%d bytes)\n",
1030 svc_sock_final_rec(svsk) ? "final" : "nonfinal",
1031 svc_sock_reclen(svsk));
1032 svsk->sk_tcplen = 0;
1033 svsk->sk_reclen = 0;
1034}
1033 1035
1034/* 1036/*
1035 * Receive data from a TCP socket. 1037 * Receive data from a TCP socket.
@@ -1056,12 +1058,12 @@ static int svc_tcp_recvfrom(struct svc_rqst *rqstp)
1056 goto error; 1058 goto error;
1057 1059
1058 base = svc_tcp_restore_pages(svsk, rqstp); 1060 base = svc_tcp_restore_pages(svsk, rqstp);
1059 want = svc_sock_reclen(svsk) - base; 1061 want = svc_sock_reclen(svsk) - (svsk->sk_tcplen - sizeof(rpc_fraghdr));
1060 1062
1061 vec = rqstp->rq_vec; 1063 vec = rqstp->rq_vec;
1062 1064
1063 pnum = copy_pages_to_kvecs(&vec[0], &rqstp->rq_pages[0], 1065 pnum = copy_pages_to_kvecs(&vec[0], &rqstp->rq_pages[0],
1064 svc_sock_reclen(svsk)); 1066 svsk->sk_datalen + want);
1065 1067
1066 rqstp->rq_respages = &rqstp->rq_pages[pnum]; 1068 rqstp->rq_respages = &rqstp->rq_pages[pnum];
1067 1069
@@ -1071,20 +1073,23 @@ static int svc_tcp_recvfrom(struct svc_rqst *rqstp)
1071 svsk->sk_tcplen += len; 1073 svsk->sk_tcplen += len;
1072 svsk->sk_datalen += len; 1074 svsk->sk_datalen += len;
1073 } 1075 }
1074 if (len != want) { 1076 if (len != want || !svc_sock_final_rec(svsk)) {
1075 svc_tcp_save_pages(svsk, rqstp); 1077 svc_tcp_save_pages(svsk, rqstp);
1076 if (len < 0 && len != -EAGAIN) 1078 if (len < 0 && len != -EAGAIN)
1077 goto err_delete; 1079 goto err_delete;
1078 dprintk("svc: incomplete TCP record (%d of %d)\n", 1080 if (len == want)
1079 svsk->sk_tcplen - sizeof(rpc_fraghdr), 1081 svc_tcp_fragment_received(svsk);
1080 svc_sock_reclen(svsk)); 1082 else
1083 dprintk("svc: incomplete TCP record (%ld of %d)\n",
1084 svsk->sk_tcplen - sizeof(rpc_fraghdr),
1085 svc_sock_reclen(svsk));
1081 goto err_noclose; 1086 goto err_noclose;
1082 } 1087 }
1083 1088
1084 if (svc_sock_reclen(svsk) < 8) 1089 if (svc_sock_reclen(svsk) < 8)
1085 goto err_delete; /* client is nuts. */ 1090 goto err_delete; /* client is nuts. */
1086 1091
1087 rqstp->rq_arg.len = svc_sock_reclen(svsk); 1092 rqstp->rq_arg.len = svsk->sk_datalen;
1088 rqstp->rq_arg.page_base = 0; 1093 rqstp->rq_arg.page_base = 0;
1089 if (rqstp->rq_arg.len <= rqstp->rq_arg.head[0].iov_len) { 1094 if (rqstp->rq_arg.len <= rqstp->rq_arg.head[0].iov_len) {
1090 rqstp->rq_arg.head[0].iov_len = rqstp->rq_arg.len; 1095 rqstp->rq_arg.head[0].iov_len = rqstp->rq_arg.len;
@@ -1101,12 +1106,8 @@ static int svc_tcp_recvfrom(struct svc_rqst *rqstp)
1101 len = receive_cb_reply(svsk, rqstp); 1106 len = receive_cb_reply(svsk, rqstp);
1102 1107
1103 /* Reset TCP read info */ 1108 /* Reset TCP read info */
1104 svsk->sk_reclen = 0;
1105 svsk->sk_tcplen = 0;
1106 svsk->sk_datalen = 0; 1109 svsk->sk_datalen = 0;
1107 /* If we have more data, signal svc_xprt_enqueue() to try again */ 1110 svc_tcp_fragment_received(svsk);
1108 if (svc_recv_available(svsk) > sizeof(rpc_fraghdr))
1109 set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags);
1110 1111
1111 if (len < 0) 1112 if (len < 0)
1112 goto error; 1113 goto error;
@@ -1115,7 +1116,6 @@ static int svc_tcp_recvfrom(struct svc_rqst *rqstp)
1115 if (serv->sv_stats) 1116 if (serv->sv_stats)
1116 serv->sv_stats->nettcpcnt++; 1117 serv->sv_stats->nettcpcnt++;
1117 1118
1118 dprintk("svc: TCP complete record (%d bytes)\n", rqstp->rq_arg.len);
1119 return rqstp->rq_arg.len; 1119 return rqstp->rq_arg.len;
1120 1120
1121error: 1121error: