diff options
author | Alexandros Batsakis <batsakis@netapp.com> | 2009-08-19 20:34:19 -0400 |
---|---|---|
committer | J. Bruce Fields <bfields@citi.umich.edu> | 2009-08-24 18:13:10 -0400 |
commit | 8f55f3c0a013c42fb733997da54a3326c74601e8 (patch) | |
tree | 4de48f8902ebbd79f7edad72b356fa19f4370544 /net/sunrpc/svcsock.c | |
parent | fbf4665f41b02e757ab9d9198df65e319388e728 (diff) |
nfsd41: sunrpc: svc_tcp_recv_record()
Factor functionality out of svc_tcp_recvfrom() to simplify routine
Signed-off-by: Alexandros Batsakis <batsakis@netapp.com>
Signed-off-by: Ricardo Labiaga <Ricardo.Labiaga@netapp.com>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
Diffstat (limited to 'net/sunrpc/svcsock.c')
-rw-r--r-- | net/sunrpc/svcsock.c | 79 |
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 | */ |
859 | static int svc_tcp_recvfrom(struct svc_rqst *rqstp) | 862 | static 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 | */ | ||
957 | static 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: | 1016 | err_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 | } | ||
1022 | error: | ||
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 | /* |