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.c106
1 files changed, 56 insertions, 50 deletions
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index 03827cef1fa7..0f679df7d072 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -84,7 +84,11 @@ static struct lock_class_key svc_slock_key[2];
84static void svc_reclassify_socket(struct socket *sock) 84static void svc_reclassify_socket(struct socket *sock)
85{ 85{
86 struct sock *sk = sock->sk; 86 struct sock *sk = sock->sk;
87 BUG_ON(sock_owned_by_user(sk)); 87
88 WARN_ON_ONCE(sock_owned_by_user(sk));
89 if (sock_owned_by_user(sk))
90 return;
91
88 switch (sk->sk_family) { 92 switch (sk->sk_family) {
89 case AF_INET: 93 case AF_INET:
90 sock_lock_init_class_and_name(sk, "slock-AF_INET-NFSD", 94 sock_lock_init_class_and_name(sk, "slock-AF_INET-NFSD",
@@ -461,7 +465,7 @@ static int svc_udp_get_dest_address4(struct svc_rqst *rqstp,
461} 465}
462 466
463/* 467/*
464 * See net/ipv6/datagram.c : datagram_recv_ctl 468 * See net/ipv6/datagram.c : ip6_datagram_recv_ctl
465 */ 469 */
466static int svc_udp_get_dest_address6(struct svc_rqst *rqstp, 470static int svc_udp_get_dest_address6(struct svc_rqst *rqstp,
467 struct cmsghdr *cmh) 471 struct cmsghdr *cmh)
@@ -601,6 +605,7 @@ static int svc_udp_recvfrom(struct svc_rqst *rqstp)
601 rqstp->rq_respages = rqstp->rq_pages + 1 + 605 rqstp->rq_respages = rqstp->rq_pages + 1 +
602 DIV_ROUND_UP(rqstp->rq_arg.page_len, PAGE_SIZE); 606 DIV_ROUND_UP(rqstp->rq_arg.page_len, PAGE_SIZE);
603 } 607 }
608 rqstp->rq_next_page = rqstp->rq_respages+1;
604 609
605 if (serv->sv_stats) 610 if (serv->sv_stats)
606 serv->sv_stats->netudpcnt++; 611 serv->sv_stats->netudpcnt++;
@@ -874,9 +879,9 @@ static unsigned int svc_tcp_restore_pages(struct svc_sock *svsk, struct svc_rqst
874{ 879{
875 unsigned int i, len, npages; 880 unsigned int i, len, npages;
876 881
877 if (svsk->sk_tcplen <= sizeof(rpc_fraghdr)) 882 if (svsk->sk_datalen == 0)
878 return 0; 883 return 0;
879 len = svsk->sk_tcplen - sizeof(rpc_fraghdr); 884 len = svsk->sk_datalen;
880 npages = (len + PAGE_SIZE - 1) >> PAGE_SHIFT; 885 npages = (len + PAGE_SIZE - 1) >> PAGE_SHIFT;
881 for (i = 0; i < npages; i++) { 886 for (i = 0; i < npages; i++) {
882 if (rqstp->rq_pages[i] != NULL) 887 if (rqstp->rq_pages[i] != NULL)
@@ -893,9 +898,9 @@ static void svc_tcp_save_pages(struct svc_sock *svsk, struct svc_rqst *rqstp)
893{ 898{
894 unsigned int i, len, npages; 899 unsigned int i, len, npages;
895 900
896 if (svsk->sk_tcplen <= sizeof(rpc_fraghdr)) 901 if (svsk->sk_datalen == 0)
897 return; 902 return;
898 len = svsk->sk_tcplen - sizeof(rpc_fraghdr); 903 len = svsk->sk_datalen;
899 npages = (len + PAGE_SIZE - 1) >> PAGE_SHIFT; 904 npages = (len + PAGE_SIZE - 1) >> PAGE_SHIFT;
900 for (i = 0; i < npages; i++) { 905 for (i = 0; i < npages; i++) {
901 svsk->sk_pages[i] = rqstp->rq_pages[i]; 906 svsk->sk_pages[i] = rqstp->rq_pages[i];
@@ -907,9 +912,9 @@ static void svc_tcp_clear_pages(struct svc_sock *svsk)
907{ 912{
908 unsigned int i, len, npages; 913 unsigned int i, len, npages;
909 914
910 if (svsk->sk_tcplen <= sizeof(rpc_fraghdr)) 915 if (svsk->sk_datalen == 0)
911 goto out; 916 goto out;
912 len = svsk->sk_tcplen - sizeof(rpc_fraghdr); 917 len = svsk->sk_datalen;
913 npages = (len + PAGE_SIZE - 1) >> PAGE_SHIFT; 918 npages = (len + PAGE_SIZE - 1) >> PAGE_SHIFT;
914 for (i = 0; i < npages; i++) { 919 for (i = 0; i < npages; i++) {
915 BUG_ON(svsk->sk_pages[i] == NULL); 920 BUG_ON(svsk->sk_pages[i] == NULL);
@@ -918,13 +923,12 @@ static void svc_tcp_clear_pages(struct svc_sock *svsk)
918 } 923 }
919out: 924out:
920 svsk->sk_tcplen = 0; 925 svsk->sk_tcplen = 0;
926 svsk->sk_datalen = 0;
921} 927}
922 928
923/* 929/*
924 * Receive data. 930 * Receive fragment record header.
925 * If we haven't gotten the record length yet, get the next four bytes. 931 * If we haven't gotten the record length yet, get the next four bytes.
926 * Otherwise try to gobble up as much as possible up to the complete
927 * record length.
928 */ 932 */
929static int svc_tcp_recv_record(struct svc_sock *svsk, struct svc_rqst *rqstp) 933static int svc_tcp_recv_record(struct svc_sock *svsk, struct svc_rqst *rqstp)
930{ 934{
@@ -950,32 +954,16 @@ static int svc_tcp_recv_record(struct svc_sock *svsk, struct svc_rqst *rqstp)
950 return -EAGAIN; 954 return -EAGAIN;
951 } 955 }
952 956
953 svsk->sk_reclen = ntohl(svsk->sk_reclen); 957 dprintk("svc: TCP record, %d bytes\n", svc_sock_reclen(svsk));
954 if (!(svsk->sk_reclen & RPC_LAST_STREAM_FRAGMENT)) { 958 if (svc_sock_reclen(svsk) + svsk->sk_datalen >
955 /* FIXME: technically, a record can be fragmented, 959 serv->sv_max_mesg) {
956 * and non-terminal fragments will not have the top 960 net_notice_ratelimited("RPC: fragment too large: %d\n",
957 * bit set in the fragment length header. 961 svc_sock_reclen(svsk));
958 * But apparently no known nfs clients send fragmented
959 * records. */
960 net_notice_ratelimited("RPC: multiple fragments per record not supported\n");
961 goto err_delete;
962 }
963
964 svsk->sk_reclen &= RPC_FRAGMENT_SIZE_MASK;
965 dprintk("svc: TCP record, %d bytes\n", svsk->sk_reclen);
966 if (svsk->sk_reclen > serv->sv_max_mesg) {
967 net_notice_ratelimited("RPC: fragment too large: 0x%08lx\n",
968 (unsigned long)svsk->sk_reclen);
969 goto err_delete; 962 goto err_delete;
970 } 963 }
971 } 964 }
972 965
973 if (svsk->sk_reclen < 8) 966 return svc_sock_reclen(svsk);
974 goto err_delete; /* client is nuts. */
975
976 len = svsk->sk_reclen;
977
978 return len;
979error: 967error:
980 dprintk("RPC: TCP recv_record got %d\n", len); 968 dprintk("RPC: TCP recv_record got %d\n", len);
981 return len; 969 return len;
@@ -1019,7 +1007,7 @@ static int receive_cb_reply(struct svc_sock *svsk, struct svc_rqst *rqstp)
1019 if (dst->iov_len < src->iov_len) 1007 if (dst->iov_len < src->iov_len)
1020 return -EAGAIN; /* whatever; just giving up. */ 1008 return -EAGAIN; /* whatever; just giving up. */
1021 memcpy(dst->iov_base, src->iov_base, src->iov_len); 1009 memcpy(dst->iov_base, src->iov_base, src->iov_len);
1022 xprt_complete_rqst(req->rq_task, svsk->sk_reclen); 1010 xprt_complete_rqst(req->rq_task, rqstp->rq_arg.len);
1023 rqstp->rq_arg.len = 0; 1011 rqstp->rq_arg.len = 0;
1024 return 0; 1012 return 0;
1025} 1013}
@@ -1038,6 +1026,17 @@ static int copy_pages_to_kvecs(struct kvec *vec, struct page **pages, int len)
1038 return i; 1026 return i;
1039} 1027}
1040 1028
1029static void svc_tcp_fragment_received(struct svc_sock *svsk)
1030{
1031 /* If we have more data, signal svc_xprt_enqueue() to try again */
1032 if (svc_recv_available(svsk) > sizeof(rpc_fraghdr))
1033 set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags);
1034 dprintk("svc: TCP %s record (%d bytes)\n",
1035 svc_sock_final_rec(svsk) ? "final" : "nonfinal",
1036 svc_sock_reclen(svsk));
1037 svsk->sk_tcplen = 0;
1038 svsk->sk_reclen = 0;
1039}
1041 1040
1042/* 1041/*
1043 * Receive data from a TCP socket. 1042 * Receive data from a TCP socket.
@@ -1064,29 +1063,39 @@ static int svc_tcp_recvfrom(struct svc_rqst *rqstp)
1064 goto error; 1063 goto error;
1065 1064
1066 base = svc_tcp_restore_pages(svsk, rqstp); 1065 base = svc_tcp_restore_pages(svsk, rqstp);
1067 want = svsk->sk_reclen - base; 1066 want = svc_sock_reclen(svsk) - (svsk->sk_tcplen - sizeof(rpc_fraghdr));
1068 1067
1069 vec = rqstp->rq_vec; 1068 vec = rqstp->rq_vec;
1070 1069
1071 pnum = copy_pages_to_kvecs(&vec[0], &rqstp->rq_pages[0], 1070 pnum = copy_pages_to_kvecs(&vec[0], &rqstp->rq_pages[0],
1072 svsk->sk_reclen); 1071 svsk->sk_datalen + want);
1073 1072
1074 rqstp->rq_respages = &rqstp->rq_pages[pnum]; 1073 rqstp->rq_respages = &rqstp->rq_pages[pnum];
1074 rqstp->rq_next_page = rqstp->rq_respages + 1;
1075 1075
1076 /* Now receive data */ 1076 /* Now receive data */
1077 len = svc_partial_recvfrom(rqstp, vec, pnum, want, base); 1077 len = svc_partial_recvfrom(rqstp, vec, pnum, want, base);
1078 if (len >= 0) 1078 if (len >= 0) {
1079 svsk->sk_tcplen += len; 1079 svsk->sk_tcplen += len;
1080 if (len != want) { 1080 svsk->sk_datalen += len;
1081 }
1082 if (len != want || !svc_sock_final_rec(svsk)) {
1081 svc_tcp_save_pages(svsk, rqstp); 1083 svc_tcp_save_pages(svsk, rqstp);
1082 if (len < 0 && len != -EAGAIN) 1084 if (len < 0 && len != -EAGAIN)
1083 goto err_other; 1085 goto err_delete;
1084 dprintk("svc: incomplete TCP record (%d of %d)\n", 1086 if (len == want)
1085 svsk->sk_tcplen, svsk->sk_reclen); 1087 svc_tcp_fragment_received(svsk);
1088 else
1089 dprintk("svc: incomplete TCP record (%d of %d)\n",
1090 (int)(svsk->sk_tcplen - sizeof(rpc_fraghdr)),
1091 svc_sock_reclen(svsk));
1086 goto err_noclose; 1092 goto err_noclose;
1087 } 1093 }
1088 1094
1089 rqstp->rq_arg.len = svsk->sk_reclen; 1095 if (svc_sock_reclen(svsk) < 8)
1096 goto err_delete; /* client is nuts. */
1097
1098 rqstp->rq_arg.len = svsk->sk_datalen;
1090 rqstp->rq_arg.page_base = 0; 1099 rqstp->rq_arg.page_base = 0;
1091 if (rqstp->rq_arg.len <= rqstp->rq_arg.head[0].iov_len) { 1100 if (rqstp->rq_arg.len <= rqstp->rq_arg.head[0].iov_len) {
1092 rqstp->rq_arg.head[0].iov_len = rqstp->rq_arg.len; 1101 rqstp->rq_arg.head[0].iov_len = rqstp->rq_arg.len;
@@ -1103,11 +1112,8 @@ static int svc_tcp_recvfrom(struct svc_rqst *rqstp)
1103 len = receive_cb_reply(svsk, rqstp); 1112 len = receive_cb_reply(svsk, rqstp);
1104 1113
1105 /* Reset TCP read info */ 1114 /* Reset TCP read info */
1106 svsk->sk_reclen = 0; 1115 svsk->sk_datalen = 0;
1107 svsk->sk_tcplen = 0; 1116 svc_tcp_fragment_received(svsk);
1108 /* If we have more data, signal svc_xprt_enqueue() to try again */
1109 if (svc_recv_available(svsk) > sizeof(rpc_fraghdr))
1110 set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags);
1111 1117
1112 if (len < 0) 1118 if (len < 0)
1113 goto error; 1119 goto error;
@@ -1116,15 +1122,14 @@ static int svc_tcp_recvfrom(struct svc_rqst *rqstp)
1116 if (serv->sv_stats) 1122 if (serv->sv_stats)
1117 serv->sv_stats->nettcpcnt++; 1123 serv->sv_stats->nettcpcnt++;
1118 1124
1119 dprintk("svc: TCP complete record (%d bytes)\n", rqstp->rq_arg.len);
1120 return rqstp->rq_arg.len; 1125 return rqstp->rq_arg.len;
1121 1126
1122error: 1127error:
1123 if (len != -EAGAIN) 1128 if (len != -EAGAIN)
1124 goto err_other; 1129 goto err_delete;
1125 dprintk("RPC: TCP recvfrom got EAGAIN\n"); 1130 dprintk("RPC: TCP recvfrom got EAGAIN\n");
1126 return 0; 1131 return 0;
1127err_other: 1132err_delete:
1128 printk(KERN_NOTICE "%s: recvfrom returned errno %d\n", 1133 printk(KERN_NOTICE "%s: recvfrom returned errno %d\n",
1129 svsk->sk_xprt.xpt_server->sv_name, -len); 1134 svsk->sk_xprt.xpt_server->sv_name, -len);
1130 set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags); 1135 set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags);
@@ -1301,6 +1306,7 @@ static void svc_tcp_init(struct svc_sock *svsk, struct svc_serv *serv)
1301 1306
1302 svsk->sk_reclen = 0; 1307 svsk->sk_reclen = 0;
1303 svsk->sk_tcplen = 0; 1308 svsk->sk_tcplen = 0;
1309 svsk->sk_datalen = 0;
1304 memset(&svsk->sk_pages[0], 0, sizeof(svsk->sk_pages)); 1310 memset(&svsk->sk_pages[0], 0, sizeof(svsk->sk_pages));
1305 1311
1306 tcp_sk(sk)->nonagle |= TCP_NAGLE_OFF; 1312 tcp_sk(sk)->nonagle |= TCP_NAGLE_OFF;