aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChuck Lever <chuck.lever@oracle.com>2008-04-14 12:27:30 -0400
committerJ. Bruce Fields <bfields@citi.umich.edu>2008-04-23 16:13:43 -0400
commitc0401ea008fb7c785a93428752d69dccafb127ec (patch)
treec24c8c6e8871ecba8906098c0360bf3980fedf73
parentb7872fe86db78cc96c85a13338ea6e3fe1aef610 (diff)
SUNRPC: Update RPC server's TCP record marker decoder
Clean up: Update the RPC server's TCP record marker decoder to match the constructs used by the RPC client's TCP socket transport. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
-rw-r--r--include/linux/sunrpc/svcsock.h4
-rw-r--r--net/sunrpc/svcsock.c24
2 files changed, 14 insertions, 14 deletions
diff --git a/include/linux/sunrpc/svcsock.h b/include/linux/sunrpc/svcsock.h
index 206f092ad4c7..8cff696dedf5 100644
--- a/include/linux/sunrpc/svcsock.h
+++ b/include/linux/sunrpc/svcsock.h
@@ -26,8 +26,8 @@ struct svc_sock {
26 void (*sk_owspace)(struct sock *); 26 void (*sk_owspace)(struct sock *);
27 27
28 /* private TCP part */ 28 /* private TCP part */
29 int sk_reclen; /* length of record */ 29 u32 sk_reclen; /* length of record */
30 int sk_tcplen; /* current read length */ 30 u32 sk_tcplen; /* current read length */
31}; 31};
32 32
33/* 33/*
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index 8b1bda3ea5c1..3e65719f1ef6 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -46,6 +46,7 @@
46#include <linux/sunrpc/types.h> 46#include <linux/sunrpc/types.h>
47#include <linux/sunrpc/clnt.h> 47#include <linux/sunrpc/clnt.h>
48#include <linux/sunrpc/xdr.h> 48#include <linux/sunrpc/xdr.h>
49#include <linux/sunrpc/msg_prot.h>
49#include <linux/sunrpc/svcsock.h> 50#include <linux/sunrpc/svcsock.h>
50#include <linux/sunrpc/stats.h> 51#include <linux/sunrpc/stats.h>
51 52
@@ -823,8 +824,8 @@ static int svc_tcp_recvfrom(struct svc_rqst *rqstp)
823 * the next four bytes. Otherwise try to gobble up as much as 824 * the next four bytes. Otherwise try to gobble up as much as
824 * possible up to the complete record length. 825 * possible up to the complete record length.
825 */ 826 */
826 if (svsk->sk_tcplen < 4) { 827 if (svsk->sk_tcplen < sizeof(rpc_fraghdr)) {
827 unsigned long want = 4 - svsk->sk_tcplen; 828 int want = sizeof(rpc_fraghdr) - svsk->sk_tcplen;
828 struct kvec iov; 829 struct kvec iov;
829 830
830 iov.iov_base = ((char *) &svsk->sk_reclen) + svsk->sk_tcplen; 831 iov.iov_base = ((char *) &svsk->sk_reclen) + svsk->sk_tcplen;
@@ -834,32 +835,31 @@ static int svc_tcp_recvfrom(struct svc_rqst *rqstp)
834 svsk->sk_tcplen += len; 835 svsk->sk_tcplen += len;
835 836
836 if (len < want) { 837 if (len < want) {
837 dprintk("svc: short recvfrom while reading record length (%d of %lu)\n", 838 dprintk("svc: short recvfrom while reading record "
838 len, want); 839 "length (%d of %d)\n", len, want);
839 svc_xprt_received(&svsk->sk_xprt); 840 svc_xprt_received(&svsk->sk_xprt);
840 return -EAGAIN; /* record header not complete */ 841 return -EAGAIN; /* record header not complete */
841 } 842 }
842 843
843 svsk->sk_reclen = ntohl(svsk->sk_reclen); 844 svsk->sk_reclen = ntohl(svsk->sk_reclen);
844 if (!(svsk->sk_reclen & 0x80000000)) { 845 if (!(svsk->sk_reclen & RPC_LAST_STREAM_FRAGMENT)) {
845 /* FIXME: technically, a record can be fragmented, 846 /* FIXME: technically, a record can be fragmented,
846 * and non-terminal fragments will not have the top 847 * and non-terminal fragments will not have the top
847 * bit set in the fragment length header. 848 * bit set in the fragment length header.
848 * But apparently no known nfs clients send fragmented 849 * But apparently no known nfs clients send fragmented
849 * records. */ 850 * records. */
850 if (net_ratelimit()) 851 if (net_ratelimit())
851 printk(KERN_NOTICE "RPC: bad TCP reclen 0x%08lx" 852 printk(KERN_NOTICE "RPC: multiple fragments "
852 " (non-terminal)\n", 853 "per record not supported\n");
853 (unsigned long) svsk->sk_reclen);
854 goto err_delete; 854 goto err_delete;
855 } 855 }
856 svsk->sk_reclen &= 0x7fffffff; 856 svsk->sk_reclen &= RPC_FRAGMENT_SIZE_MASK;
857 dprintk("svc: TCP record, %d bytes\n", svsk->sk_reclen); 857 dprintk("svc: TCP record, %d bytes\n", svsk->sk_reclen);
858 if (svsk->sk_reclen > serv->sv_max_mesg) { 858 if (svsk->sk_reclen > serv->sv_max_mesg) {
859 if (net_ratelimit()) 859 if (net_ratelimit())
860 printk(KERN_NOTICE "RPC: bad TCP reclen 0x%08lx" 860 printk(KERN_NOTICE "RPC: "
861 " (large)\n", 861 "fragment too large: 0x%08lx\n",
862 (unsigned long) svsk->sk_reclen); 862 (unsigned long)svsk->sk_reclen);
863 goto err_delete; 863 goto err_delete;
864 } 864 }
865 } 865 }