aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/nfsd/nfs3proc.c14
-rw-r--r--fs/nfsd/nfs3xdr.c13
-rw-r--r--fs/nfsd/nfs4xdr.c6
-rw-r--r--fs/nfsd/nfsproc.c6
-rw-r--r--fs/nfsd/nfsxdr.c10
-rw-r--r--include/linux/nfsd/const.h15
-rw-r--r--include/linux/sunrpc/auth.h3
-rw-r--r--include/linux/sunrpc/msg_prot.h40
-rw-r--r--include/linux/sunrpc/svc.h23
-rw-r--r--include/linux/sunrpc/xprt.h8
-rw-r--r--net/sunrpc/svc.c15
11 files changed, 119 insertions, 34 deletions
diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c
index 0c4fab018791..a5ebc7dbb384 100644
--- a/fs/nfsd/nfs3proc.c
+++ b/fs/nfsd/nfs3proc.c
@@ -160,6 +160,7 @@ nfsd3_proc_read(struct svc_rqst *rqstp, struct nfsd3_readargs *argp,
160 struct nfsd3_readres *resp) 160 struct nfsd3_readres *resp)
161{ 161{
162 int nfserr; 162 int nfserr;
163 u32 max_blocksize = svc_max_payload(rqstp);
163 164
164 dprintk("nfsd: READ(3) %s %lu bytes at %lu\n", 165 dprintk("nfsd: READ(3) %s %lu bytes at %lu\n",
165 SVCFH_fmt(&argp->fh), 166 SVCFH_fmt(&argp->fh),
@@ -172,8 +173,8 @@ nfsd3_proc_read(struct svc_rqst *rqstp, struct nfsd3_readargs *argp,
172 */ 173 */
173 174
174 resp->count = argp->count; 175 resp->count = argp->count;
175 if (NFSSVC_MAXBLKSIZE < resp->count) 176 if (max_blocksize < resp->count)
176 resp->count = NFSSVC_MAXBLKSIZE; 177 resp->count = max_blocksize;
177 178
178 svc_reserve(rqstp, ((1 + NFS3_POST_OP_ATTR_WORDS + 3)<<2) + resp->count +4); 179 svc_reserve(rqstp, ((1 + NFS3_POST_OP_ATTR_WORDS + 3)<<2) + resp->count +4);
179 180
@@ -538,15 +539,16 @@ nfsd3_proc_fsinfo(struct svc_rqst * rqstp, struct nfsd_fhandle *argp,
538 struct nfsd3_fsinfores *resp) 539 struct nfsd3_fsinfores *resp)
539{ 540{
540 int nfserr; 541 int nfserr;
542 u32 max_blocksize = svc_max_payload(rqstp);
541 543
542 dprintk("nfsd: FSINFO(3) %s\n", 544 dprintk("nfsd: FSINFO(3) %s\n",
543 SVCFH_fmt(&argp->fh)); 545 SVCFH_fmt(&argp->fh));
544 546
545 resp->f_rtmax = NFSSVC_MAXBLKSIZE; 547 resp->f_rtmax = max_blocksize;
546 resp->f_rtpref = NFSSVC_MAXBLKSIZE; 548 resp->f_rtpref = max_blocksize;
547 resp->f_rtmult = PAGE_SIZE; 549 resp->f_rtmult = PAGE_SIZE;
548 resp->f_wtmax = NFSSVC_MAXBLKSIZE; 550 resp->f_wtmax = max_blocksize;
549 resp->f_wtpref = NFSSVC_MAXBLKSIZE; 551 resp->f_wtpref = max_blocksize;
550 resp->f_wtmult = PAGE_SIZE; 552 resp->f_wtmult = PAGE_SIZE;
551 resp->f_dtpref = PAGE_SIZE; 553 resp->f_dtpref = PAGE_SIZE;
552 resp->f_maxfilesize = ~(u32) 0; 554 resp->f_maxfilesize = ~(u32) 0;
diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c
index 4b9aefbcc93c..247d518248bf 100644
--- a/fs/nfsd/nfs3xdr.c
+++ b/fs/nfsd/nfs3xdr.c
@@ -330,6 +330,7 @@ nfs3svc_decode_readargs(struct svc_rqst *rqstp, u32 *p,
330{ 330{
331 unsigned int len; 331 unsigned int len;
332 int v,pn; 332 int v,pn;
333 u32 max_blocksize = svc_max_payload(rqstp);
333 334
334 if (!(p = decode_fh(p, &args->fh)) 335 if (!(p = decode_fh(p, &args->fh))
335 || !(p = xdr_decode_hyper(p, &args->offset))) 336 || !(p = xdr_decode_hyper(p, &args->offset)))
@@ -337,8 +338,8 @@ nfs3svc_decode_readargs(struct svc_rqst *rqstp, u32 *p,
337 338
338 len = args->count = ntohl(*p++); 339 len = args->count = ntohl(*p++);
339 340
340 if (len > NFSSVC_MAXBLKSIZE) 341 if (len > max_blocksize)
341 len = NFSSVC_MAXBLKSIZE; 342 len = max_blocksize;
342 343
343 /* set up the kvec */ 344 /* set up the kvec */
344 v=0; 345 v=0;
@@ -358,6 +359,7 @@ nfs3svc_decode_writeargs(struct svc_rqst *rqstp, u32 *p,
358 struct nfsd3_writeargs *args) 359 struct nfsd3_writeargs *args)
359{ 360{
360 unsigned int len, v, hdr; 361 unsigned int len, v, hdr;
362 u32 max_blocksize = svc_max_payload(rqstp);
361 363
362 if (!(p = decode_fh(p, &args->fh)) 364 if (!(p = decode_fh(p, &args->fh))
363 || !(p = xdr_decode_hyper(p, &args->offset))) 365 || !(p = xdr_decode_hyper(p, &args->offset)))
@@ -375,8 +377,8 @@ nfs3svc_decode_writeargs(struct svc_rqst *rqstp, u32 *p,
375 rqstp->rq_vec[0].iov_base = (void*)p; 377 rqstp->rq_vec[0].iov_base = (void*)p;
376 rqstp->rq_vec[0].iov_len = rqstp->rq_arg.head[0].iov_len - hdr; 378 rqstp->rq_vec[0].iov_len = rqstp->rq_arg.head[0].iov_len - hdr;
377 379
378 if (len > NFSSVC_MAXBLKSIZE) 380 if (len > max_blocksize)
379 len = NFSSVC_MAXBLKSIZE; 381 len = max_blocksize;
380 v= 0; 382 v= 0;
381 while (len > rqstp->rq_vec[v].iov_len) { 383 while (len > rqstp->rq_vec[v].iov_len) {
382 len -= rqstp->rq_vec[v].iov_len; 384 len -= rqstp->rq_vec[v].iov_len;
@@ -564,6 +566,7 @@ nfs3svc_decode_readdirplusargs(struct svc_rqst *rqstp, u32 *p,
564 struct nfsd3_readdirargs *args) 566 struct nfsd3_readdirargs *args)
565{ 567{
566 int len, pn; 568 int len, pn;
569 u32 max_blocksize = svc_max_payload(rqstp);
567 570
568 if (!(p = decode_fh(p, &args->fh))) 571 if (!(p = decode_fh(p, &args->fh)))
569 return 0; 572 return 0;
@@ -572,7 +575,7 @@ nfs3svc_decode_readdirplusargs(struct svc_rqst *rqstp, u32 *p,
572 args->dircount = ntohl(*p++); 575 args->dircount = ntohl(*p++);
573 args->count = ntohl(*p++); 576 args->count = ntohl(*p++);
574 577
575 len = (args->count > NFSSVC_MAXBLKSIZE) ? NFSSVC_MAXBLKSIZE : 578 len = (args->count > max_blocksize) ? max_blocksize :
576 args->count; 579 args->count;
577 args->count = len; 580 args->count = len;
578 581
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index df341956254e..4cfacc557b40 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -1536,12 +1536,12 @@ out_acl:
1536 if (bmval0 & FATTR4_WORD0_MAXREAD) { 1536 if (bmval0 & FATTR4_WORD0_MAXREAD) {
1537 if ((buflen -= 8) < 0) 1537 if ((buflen -= 8) < 0)
1538 goto out_resource; 1538 goto out_resource;
1539 WRITE64((u64) NFSSVC_MAXBLKSIZE); 1539 WRITE64((u64) svc_max_payload(rqstp));
1540 } 1540 }
1541 if (bmval0 & FATTR4_WORD0_MAXWRITE) { 1541 if (bmval0 & FATTR4_WORD0_MAXWRITE) {
1542 if ((buflen -= 8) < 0) 1542 if ((buflen -= 8) < 0)
1543 goto out_resource; 1543 goto out_resource;
1544 WRITE64((u64) NFSSVC_MAXBLKSIZE); 1544 WRITE64((u64) svc_max_payload(rqstp));
1545 } 1545 }
1546 if (bmval1 & FATTR4_WORD1_MODE) { 1546 if (bmval1 & FATTR4_WORD1_MODE) {
1547 if ((buflen -= 4) < 0) 1547 if ((buflen -= 4) < 0)
@@ -2055,7 +2055,7 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, int nfserr,
2055 2055
2056 RESERVE_SPACE(8); /* eof flag and byte count */ 2056 RESERVE_SPACE(8); /* eof flag and byte count */
2057 2057
2058 maxcount = NFSSVC_MAXBLKSIZE; 2058 maxcount = svc_max_payload(resp->rqstp);
2059 if (maxcount > read->rd_length) 2059 if (maxcount > read->rd_length)
2060 maxcount = read->rd_length; 2060 maxcount = read->rd_length;
2061 2061
diff --git a/fs/nfsd/nfsproc.c b/fs/nfsd/nfsproc.c
index ca4973150218..9ee1dab5d44a 100644
--- a/fs/nfsd/nfsproc.c
+++ b/fs/nfsd/nfsproc.c
@@ -146,13 +146,13 @@ nfsd_proc_read(struct svc_rqst *rqstp, struct nfsd_readargs *argp,
146 * status, 17 words for fattr, and 1 word for the byte count. 146 * status, 17 words for fattr, and 1 word for the byte count.
147 */ 147 */
148 148
149 if (NFSSVC_MAXBLKSIZE < argp->count) { 149 if (NFSSVC_MAXBLKSIZE_V2 < argp->count) {
150 printk(KERN_NOTICE 150 printk(KERN_NOTICE
151 "oversized read request from %u.%u.%u.%u:%d (%d bytes)\n", 151 "oversized read request from %u.%u.%u.%u:%d (%d bytes)\n",
152 NIPQUAD(rqstp->rq_addr.sin_addr.s_addr), 152 NIPQUAD(rqstp->rq_addr.sin_addr.s_addr),
153 ntohs(rqstp->rq_addr.sin_port), 153 ntohs(rqstp->rq_addr.sin_port),
154 argp->count); 154 argp->count);
155 argp->count = NFSSVC_MAXBLKSIZE; 155 argp->count = NFSSVC_MAXBLKSIZE_V2;
156 } 156 }
157 svc_reserve(rqstp, (19<<2) + argp->count + 4); 157 svc_reserve(rqstp, (19<<2) + argp->count + 4);
158 158
@@ -553,7 +553,7 @@ static struct svc_procedure nfsd_procedures2[18] = {
553 PROC(none, void, void, none, RC_NOCACHE, ST), 553 PROC(none, void, void, none, RC_NOCACHE, ST),
554 PROC(lookup, diropargs, diropres, fhandle, RC_NOCACHE, ST+FH+AT), 554 PROC(lookup, diropargs, diropres, fhandle, RC_NOCACHE, ST+FH+AT),
555 PROC(readlink, readlinkargs, readlinkres, none, RC_NOCACHE, ST+1+NFS_MAXPATHLEN/4), 555 PROC(readlink, readlinkargs, readlinkres, none, RC_NOCACHE, ST+1+NFS_MAXPATHLEN/4),
556 PROC(read, readargs, readres, fhandle, RC_NOCACHE, ST+AT+1+NFSSVC_MAXBLKSIZE/4), 556 PROC(read, readargs, readres, fhandle, RC_NOCACHE, ST+AT+1+NFSSVC_MAXBLKSIZE_V2/4),
557 PROC(none, void, void, none, RC_NOCACHE, ST), 557 PROC(none, void, void, none, RC_NOCACHE, ST),
558 PROC(write, writeargs, attrstat, fhandle, RC_REPLBUFF, ST+AT), 558 PROC(write, writeargs, attrstat, fhandle, RC_REPLBUFF, ST+AT),
559 PROC(create, createargs, diropres, fhandle, RC_REPLBUFF, ST+FH+AT), 559 PROC(create, createargs, diropres, fhandle, RC_REPLBUFF, ST+FH+AT),
diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c
index ab6745e78d16..1135c0d14557 100644
--- a/fs/nfsd/nfsxdr.c
+++ b/fs/nfsd/nfsxdr.c
@@ -254,8 +254,8 @@ nfssvc_decode_readargs(struct svc_rqst *rqstp, u32 *p,
254 len = args->count = ntohl(*p++); 254 len = args->count = ntohl(*p++);
255 p++; /* totalcount - unused */ 255 p++; /* totalcount - unused */
256 256
257 if (len > NFSSVC_MAXBLKSIZE) 257 if (len > NFSSVC_MAXBLKSIZE_V2)
258 len = NFSSVC_MAXBLKSIZE; 258 len = NFSSVC_MAXBLKSIZE_V2;
259 259
260 /* set up somewhere to store response. 260 /* set up somewhere to store response.
261 * We take pages, put them on reslist and include in iovec 261 * We take pages, put them on reslist and include in iovec
@@ -288,8 +288,8 @@ nfssvc_decode_writeargs(struct svc_rqst *rqstp, u32 *p,
288 rqstp->rq_vec[0].iov_base = (void*)p; 288 rqstp->rq_vec[0].iov_base = (void*)p;
289 rqstp->rq_vec[0].iov_len = rqstp->rq_arg.head[0].iov_len - 289 rqstp->rq_vec[0].iov_len = rqstp->rq_arg.head[0].iov_len -
290 (((void*)p) - rqstp->rq_arg.head[0].iov_base); 290 (((void*)p) - rqstp->rq_arg.head[0].iov_base);
291 if (len > NFSSVC_MAXBLKSIZE) 291 if (len > NFSSVC_MAXBLKSIZE_V2)
292 len = NFSSVC_MAXBLKSIZE; 292 len = NFSSVC_MAXBLKSIZE_V2;
293 v = 0; 293 v = 0;
294 while (len > rqstp->rq_vec[v].iov_len) { 294 while (len > rqstp->rq_vec[v].iov_len) {
295 len -= rqstp->rq_vec[v].iov_len; 295 len -= rqstp->rq_vec[v].iov_len;
@@ -458,7 +458,7 @@ nfssvc_encode_statfsres(struct svc_rqst *rqstp, u32 *p,
458{ 458{
459 struct kstatfs *stat = &resp->stats; 459 struct kstatfs *stat = &resp->stats;
460 460
461 *p++ = htonl(NFSSVC_MAXBLKSIZE); /* max transfer size */ 461 *p++ = htonl(NFSSVC_MAXBLKSIZE_V2); /* max transfer size */
462 *p++ = htonl(stat->f_bsize); 462 *p++ = htonl(stat->f_bsize);
463 *p++ = htonl(stat->f_blocks); 463 *p++ = htonl(stat->f_blocks);
464 *p++ = htonl(stat->f_bfree); 464 *p++ = htonl(stat->f_bfree);
diff --git a/include/linux/nfsd/const.h b/include/linux/nfsd/const.h
index b75bb1b38d09..adbddf007898 100644
--- a/include/linux/nfsd/const.h
+++ b/include/linux/nfsd/const.h
@@ -13,6 +13,7 @@
13#include <linux/nfs2.h> 13#include <linux/nfs2.h>
14#include <linux/nfs3.h> 14#include <linux/nfs3.h>
15#include <linux/nfs4.h> 15#include <linux/nfs4.h>
16#include <linux/sunrpc/msg_prot.h>
16 17
17/* 18/*
18 * Maximum protocol version supported by knfsd 19 * Maximum protocol version supported by knfsd
@@ -23,6 +24,8 @@
23 * Maximum blocksize supported by daemon currently at 32K 24 * Maximum blocksize supported by daemon currently at 32K
24 */ 25 */
25#define NFSSVC_MAXBLKSIZE (32*1024) 26#define NFSSVC_MAXBLKSIZE (32*1024)
27/* NFSv2 is limited by the protocol specification, see RFC 1094 */
28#define NFSSVC_MAXBLKSIZE_V2 (8*1024)
26 29
27#ifdef __KERNEL__ 30#ifdef __KERNEL__
28 31
@@ -30,7 +33,17 @@
30# define NFS_SUPER_MAGIC 0x6969 33# define NFS_SUPER_MAGIC 0x6969
31#endif 34#endif
32 35
33#define NFSD_BUFSIZE (1024 + NFSSVC_MAXBLKSIZE) 36/*
37 * Largest number of bytes we need to allocate for an NFS
38 * call or reply. Used to control buffer sizes. We use
39 * the length of v3 WRITE, READDIR and READDIR replies
40 * which are an RPC header, up to 26 XDR units of reply
41 * data, and some page data.
42 *
43 * Note that accuracy here doesn't matter too much as the
44 * size is rounded up to a page size when allocating space.
45 */
46#define NFSD_BUFSIZE ((RPC_MAX_HEADER_WITH_AUTH+26)*XDR_UNIT + NFSSVC_MAXBLKSIZE)
34 47
35#ifdef CONFIG_NFSD_V4 48#ifdef CONFIG_NFSD_V4
36# define NFSSVC_XDRSIZE NFS4_SVC_XDRSIZE 49# define NFSSVC_XDRSIZE NFS4_SVC_XDRSIZE
diff --git a/include/linux/sunrpc/auth.h b/include/linux/sunrpc/auth.h
index 862c0d8c8381..534cdc7be58d 100644
--- a/include/linux/sunrpc/auth.h
+++ b/include/linux/sunrpc/auth.h
@@ -20,9 +20,6 @@
20/* size of the nodename buffer */ 20/* size of the nodename buffer */
21#define UNX_MAXNODENAME 32 21#define UNX_MAXNODENAME 32
22 22
23/* Maximum size (in bytes) of an rpc credential or verifier */
24#define RPC_MAX_AUTH_SIZE (400)
25
26/* Work around the lack of a VFS credential */ 23/* Work around the lack of a VFS credential */
27struct auth_cred { 24struct auth_cred {
28 uid_t uid; 25 uid_t uid;
diff --git a/include/linux/sunrpc/msg_prot.h b/include/linux/sunrpc/msg_prot.h
index 8d10d148834e..1e65f2dd80e5 100644
--- a/include/linux/sunrpc/msg_prot.h
+++ b/include/linux/sunrpc/msg_prot.h
@@ -11,6 +11,9 @@
11 11
12#define RPC_VERSION 2 12#define RPC_VERSION 2
13 13
14/* size of an XDR encoding unit in bytes, i.e. 32bit */
15#define XDR_UNIT (4)
16
14/* spec defines authentication flavor as an unsigned 32 bit integer */ 17/* spec defines authentication flavor as an unsigned 32 bit integer */
15typedef u32 rpc_authflavor_t; 18typedef u32 rpc_authflavor_t;
16 19
@@ -34,6 +37,9 @@ enum rpc_auth_flavors {
34 RPC_AUTH_GSS_SPKMP = 390011, 37 RPC_AUTH_GSS_SPKMP = 390011,
35}; 38};
36 39
40/* Maximum size (in bytes) of an rpc credential or verifier */
41#define RPC_MAX_AUTH_SIZE (400)
42
37enum rpc_msg_type { 43enum rpc_msg_type {
38 RPC_CALL = 0, 44 RPC_CALL = 0,
39 RPC_REPLY = 1 45 RPC_REPLY = 1
@@ -101,5 +107,39 @@ typedef __be32 rpc_fraghdr;
101#define RPC_FRAGMENT_SIZE_MASK (~RPC_LAST_STREAM_FRAGMENT) 107#define RPC_FRAGMENT_SIZE_MASK (~RPC_LAST_STREAM_FRAGMENT)
102#define RPC_MAX_FRAGMENT_SIZE ((1U << 31) - 1) 108#define RPC_MAX_FRAGMENT_SIZE ((1U << 31) - 1)
103 109
110/*
111 * RPC call and reply header size as number of 32bit words (verifier
112 * size computed separately, see below)
113 */
114#define RPC_CALLHDRSIZE (6)
115#define RPC_REPHDRSIZE (4)
116
117
118/*
119 * Maximum RPC header size, including authentication,
120 * as number of 32bit words (see RFCs 1831, 1832).
121 *
122 * xid 1 xdr unit = 4 bytes
123 * mtype 1
124 * rpc_version 1
125 * program 1
126 * prog_version 1
127 * procedure 1
128 * cred {
129 * flavor 1
130 * length 1
131 * body<RPC_MAX_AUTH_SIZE> 100 xdr units = 400 bytes
132 * }
133 * verf {
134 * flavor 1
135 * length 1
136 * body<RPC_MAX_AUTH_SIZE> 100 xdr units = 400 bytes
137 * }
138 * TOTAL 210 xdr units = 840 bytes
139 */
140#define RPC_MAX_HEADER_WITH_AUTH \
141 (RPC_CALLHDRSIZE + 2*(2+RPC_MAX_AUTH_SIZE/4))
142
143
104#endif /* __KERNEL__ */ 144#endif /* __KERNEL__ */
105#endif /* _LINUX_SUNRPC_MSGPROT_H_ */ 145#endif /* _LINUX_SUNRPC_MSGPROT_H_ */
diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h
index cb0ed9beb227..74e52c245da4 100644
--- a/include/linux/sunrpc/svc.h
+++ b/include/linux/sunrpc/svc.h
@@ -13,6 +13,7 @@
13#include <linux/in.h> 13#include <linux/in.h>
14#include <linux/sunrpc/types.h> 14#include <linux/sunrpc/types.h>
15#include <linux/sunrpc/xdr.h> 15#include <linux/sunrpc/xdr.h>
16#include <linux/sunrpc/auth.h>
16#include <linux/sunrpc/svcauth.h> 17#include <linux/sunrpc/svcauth.h>
17#include <linux/wait.h> 18#include <linux/wait.h>
18#include <linux/mm.h> 19#include <linux/mm.h>
@@ -95,8 +96,28 @@ static inline void svc_get(struct svc_serv *serv)
95 * Maximum payload size supported by a kernel RPC server. 96 * Maximum payload size supported by a kernel RPC server.
96 * This is use to determine the max number of pages nfsd is 97 * This is use to determine the max number of pages nfsd is
97 * willing to return in a single READ operation. 98 * willing to return in a single READ operation.
99 *
100 * These happen to all be powers of 2, which is not strictly
101 * necessary but helps enforce the real limitation, which is
102 * that they should be multiples of PAGE_CACHE_SIZE.
103 *
104 * For UDP transports, a block plus NFS,RPC, and UDP headers
105 * has to fit into the IP datagram limit of 64K. The largest
106 * feasible number for all known page sizes is probably 48K,
107 * but we choose 32K here. This is the same as the historical
108 * Linux limit; someone who cares more about NFS/UDP performance
109 * can test a larger number.
110 *
111 * For TCP transports we have more freedom. A size of 1MB is
112 * chosen to match the client limit. Other OSes are known to
113 * have larger limits, but those numbers are probably beyond
114 * the point of diminishing returns.
98 */ 115 */
99#define RPCSVC_MAXPAYLOAD (64*1024u) 116#define RPCSVC_MAXPAYLOAD (1*1024*1024u)
117#define RPCSVC_MAXPAYLOAD_TCP RPCSVC_MAXPAYLOAD
118#define RPCSVC_MAXPAYLOAD_UDP (32*1024u)
119
120extern u32 svc_max_payload(const struct svc_rqst *rqstp);
100 121
101/* 122/*
102 * RPC Requsts and replies are stored in one or more pages. 123 * RPC Requsts and replies are stored in one or more pages.
diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h
index 6cf626580752..60394fbc4c70 100644
--- a/include/linux/sunrpc/xprt.h
+++ b/include/linux/sunrpc/xprt.h
@@ -15,6 +15,7 @@
15#include <linux/kref.h> 15#include <linux/kref.h>
16#include <linux/sunrpc/sched.h> 16#include <linux/sunrpc/sched.h>
17#include <linux/sunrpc/xdr.h> 17#include <linux/sunrpc/xdr.h>
18#include <linux/sunrpc/msg_prot.h>
18 19
19extern unsigned int xprt_udp_slot_table_entries; 20extern unsigned int xprt_udp_slot_table_entries;
20extern unsigned int xprt_tcp_slot_table_entries; 21extern unsigned int xprt_tcp_slot_table_entries;
@@ -24,13 +25,6 @@ extern unsigned int xprt_tcp_slot_table_entries;
24#define RPC_MAX_SLOT_TABLE (128U) 25#define RPC_MAX_SLOT_TABLE (128U)
25 26
26/* 27/*
27 * RPC call and reply header size as number of 32bit words (verifier
28 * size computed separately)
29 */
30#define RPC_CALLHDRSIZE 6
31#define RPC_REPHDRSIZE 4
32
33/*
34 * Parameters for choosing a free port 28 * Parameters for choosing a free port
35 */ 29 */
36extern unsigned int xprt_min_resvport; 30extern unsigned int xprt_min_resvport;
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index f4a509a925b5..b252401c8601 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -919,3 +919,18 @@ err_bad:
919 svc_putnl(resv, ntohl(rpc_stat)); 919 svc_putnl(resv, ntohl(rpc_stat));
920 goto sendit; 920 goto sendit;
921} 921}
922
923/*
924 * Return (transport-specific) limit on the rpc payload.
925 */
926u32 svc_max_payload(const struct svc_rqst *rqstp)
927{
928 int max = RPCSVC_MAXPAYLOAD_TCP;
929
930 if (rqstp->rq_sock->sk_sock->type == SOCK_DGRAM)
931 max = RPCSVC_MAXPAYLOAD_UDP;
932 if (rqstp->rq_server->sv_bufsz < max)
933 max = rqstp->rq_server->sv_bufsz;
934 return max;
935}
936EXPORT_SYMBOL_GPL(svc_max_payload);