diff options
-rw-r--r-- | fs/nfsd/nfs3proc.c | 14 | ||||
-rw-r--r-- | fs/nfsd/nfs3xdr.c | 13 | ||||
-rw-r--r-- | fs/nfsd/nfs4xdr.c | 6 | ||||
-rw-r--r-- | fs/nfsd/nfsproc.c | 6 | ||||
-rw-r--r-- | fs/nfsd/nfsxdr.c | 10 | ||||
-rw-r--r-- | include/linux/nfsd/const.h | 15 | ||||
-rw-r--r-- | include/linux/sunrpc/auth.h | 3 | ||||
-rw-r--r-- | include/linux/sunrpc/msg_prot.h | 40 | ||||
-rw-r--r-- | include/linux/sunrpc/svc.h | 23 | ||||
-rw-r--r-- | include/linux/sunrpc/xprt.h | 8 | ||||
-rw-r--r-- | net/sunrpc/svc.c | 15 |
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 */ |
27 | struct auth_cred { | 24 | struct 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 */ |
15 | typedef u32 rpc_authflavor_t; | 18 | typedef 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 | |||
37 | enum rpc_msg_type { | 43 | enum 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 | |||
120 | extern 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 | ||
19 | extern unsigned int xprt_udp_slot_table_entries; | 20 | extern unsigned int xprt_udp_slot_table_entries; |
20 | extern unsigned int xprt_tcp_slot_table_entries; | 21 | extern 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 | */ |
36 | extern unsigned int xprt_min_resvport; | 30 | extern 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 | */ | ||
926 | u32 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 | } | ||
936 | EXPORT_SYMBOL_GPL(svc_max_payload); | ||