aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/sunrpc/svcsock.c79
1 files changed, 51 insertions, 28 deletions
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index 99a826dcc32e..76a380d37de4 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -854,21 +854,15 @@ failed:
854} 854}
855 855
856/* 856/*
857 * Receive data from a TCP socket. 857 * Receive data.
858 * If we haven't gotten the record length yet, get the next four bytes.
859 * Otherwise try to gobble up as much as possible up to the complete
860 * record length.
858 */ 861 */
859static int svc_tcp_recvfrom(struct svc_rqst *rqstp) 862static int svc_tcp_recv_record(struct svc_sock *svsk, struct svc_rqst *rqstp)
860{ 863{
861 struct svc_sock *svsk =
862 container_of(rqstp->rq_xprt, struct svc_sock, sk_xprt);
863 struct svc_serv *serv = svsk->sk_xprt.xpt_server; 864 struct svc_serv *serv = svsk->sk_xprt.xpt_server;
864 int len; 865 int len;
865 struct kvec *vec;
866 int pnum, vlen;
867
868 dprintk("svc: tcp_recv %p data %d conn %d close %d\n",
869 svsk, test_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags),
870 test_bit(XPT_CONN, &svsk->sk_xprt.xpt_flags),
871 test_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags));
872 866
873 if (test_and_clear_bit(XPT_CHNGBUF, &svsk->sk_xprt.xpt_flags)) 867 if (test_and_clear_bit(XPT_CHNGBUF, &svsk->sk_xprt.xpt_flags))
874 /* sndbuf needs to have room for one request 868 /* sndbuf needs to have room for one request
@@ -889,10 +883,6 @@ static int svc_tcp_recvfrom(struct svc_rqst *rqstp)
889 883
890 clear_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags); 884 clear_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags);
891 885
892 /* Receive data. If we haven't got the record length yet, get
893 * the next four bytes. Otherwise try to gobble up as much as
894 * possible up to the complete record length.
895 */
896 if (svsk->sk_tcplen < sizeof(rpc_fraghdr)) { 886 if (svsk->sk_tcplen < sizeof(rpc_fraghdr)) {
897 int want = sizeof(rpc_fraghdr) - svsk->sk_tcplen; 887 int want = sizeof(rpc_fraghdr) - svsk->sk_tcplen;
898 struct kvec iov; 888 struct kvec iov;
@@ -907,7 +897,7 @@ static int svc_tcp_recvfrom(struct svc_rqst *rqstp)
907 dprintk("svc: short recvfrom while reading record " 897 dprintk("svc: short recvfrom while reading record "
908 "length (%d of %d)\n", len, want); 898 "length (%d of %d)\n", len, want);
909 svc_xprt_received(&svsk->sk_xprt); 899 svc_xprt_received(&svsk->sk_xprt);
910 return -EAGAIN; /* record header not complete */ 900 goto err_again; /* record header not complete */
911 } 901 }
912 902
913 svsk->sk_reclen = ntohl(svsk->sk_reclen); 903 svsk->sk_reclen = ntohl(svsk->sk_reclen);
@@ -922,6 +912,7 @@ static int svc_tcp_recvfrom(struct svc_rqst *rqstp)
922 "per record not supported\n"); 912 "per record not supported\n");
923 goto err_delete; 913 goto err_delete;
924 } 914 }
915
925 svsk->sk_reclen &= RPC_FRAGMENT_SIZE_MASK; 916 svsk->sk_reclen &= RPC_FRAGMENT_SIZE_MASK;
926 dprintk("svc: TCP record, %d bytes\n", svsk->sk_reclen); 917 dprintk("svc: TCP record, %d bytes\n", svsk->sk_reclen);
927 if (svsk->sk_reclen > serv->sv_max_mesg) { 918 if (svsk->sk_reclen > serv->sv_max_mesg) {
@@ -942,11 +933,45 @@ static int svc_tcp_recvfrom(struct svc_rqst *rqstp)
942 dprintk("svc: incomplete TCP record (%d of %d)\n", 933 dprintk("svc: incomplete TCP record (%d of %d)\n",
943 len, svsk->sk_reclen); 934 len, svsk->sk_reclen);
944 svc_xprt_received(&svsk->sk_xprt); 935 svc_xprt_received(&svsk->sk_xprt);
945 return -EAGAIN; /* record not complete */ 936 goto err_again; /* record not complete */
946 } 937 }
947 len = svsk->sk_reclen; 938 len = svsk->sk_reclen;
948 set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags); 939 set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags);
949 940
941 return len;
942 error:
943 if (len == -EAGAIN) {
944 dprintk("RPC: TCP recv_record got EAGAIN\n");
945 svc_xprt_received(&svsk->sk_xprt);
946 }
947 return len;
948 err_delete:
949 set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags);
950 err_again:
951 return -EAGAIN;
952}
953
954/*
955 * Receive data from a TCP socket.
956 */
957static int svc_tcp_recvfrom(struct svc_rqst *rqstp)
958{
959 struct svc_sock *svsk =
960 container_of(rqstp->rq_xprt, struct svc_sock, sk_xprt);
961 struct svc_serv *serv = svsk->sk_xprt.xpt_server;
962 int len;
963 struct kvec *vec;
964 int pnum, vlen;
965
966 dprintk("svc: tcp_recv %p data %d conn %d close %d\n",
967 svsk, test_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags),
968 test_bit(XPT_CONN, &svsk->sk_xprt.xpt_flags),
969 test_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags));
970
971 len = svc_tcp_recv_record(svsk, rqstp);
972 if (len < 0)
973 goto error;
974
950 vec = rqstp->rq_vec; 975 vec = rqstp->rq_vec;
951 vec[0] = rqstp->rq_arg.head[0]; 976 vec[0] = rqstp->rq_arg.head[0];
952 vlen = PAGE_SIZE; 977 vlen = PAGE_SIZE;
@@ -962,7 +987,7 @@ static int svc_tcp_recvfrom(struct svc_rqst *rqstp)
962 /* Now receive data */ 987 /* Now receive data */
963 len = svc_recvfrom(rqstp, vec, pnum, len); 988 len = svc_recvfrom(rqstp, vec, pnum, len);
964 if (len < 0) 989 if (len < 0)
965 goto error; 990 goto err_again;
966 991
967 dprintk("svc: TCP complete record (%d bytes)\n", len); 992 dprintk("svc: TCP complete record (%d bytes)\n", len);
968 rqstp->rq_arg.len = len; 993 rqstp->rq_arg.len = len;
@@ -988,21 +1013,19 @@ static int svc_tcp_recvfrom(struct svc_rqst *rqstp)
988 1013
989 return len; 1014 return len;
990 1015
991 err_delete: 1016err_again:
992 set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags);
993 return -EAGAIN;
994
995 error:
996 if (len == -EAGAIN) { 1017 if (len == -EAGAIN) {
997 dprintk("RPC: TCP recvfrom got EAGAIN\n"); 1018 dprintk("RPC: TCP recvfrom got EAGAIN\n");
998 svc_xprt_received(&svsk->sk_xprt); 1019 svc_xprt_received(&svsk->sk_xprt);
999 } else { 1020 return len;
1021 }
1022error:
1023 if (len != -EAGAIN) {
1000 printk(KERN_NOTICE "%s: recvfrom returned errno %d\n", 1024 printk(KERN_NOTICE "%s: recvfrom returned errno %d\n",
1001 svsk->sk_xprt.xpt_server->sv_name, -len); 1025 svsk->sk_xprt.xpt_server->sv_name, -len);
1002 goto err_delete; 1026 set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags);
1003 } 1027 }
1004 1028 return -EAGAIN;
1005 return len;
1006} 1029}
1007 1030
1008/* 1031/*