aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd/nfs3xdr.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfsd/nfs3xdr.c')
-rw-r--r--fs/nfsd/nfs3xdr.c55
1 files changed, 20 insertions, 35 deletions
diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c
index 43fb360784b7..10f6e7dcf633 100644
--- a/fs/nfsd/nfs3xdr.c
+++ b/fs/nfsd/nfs3xdr.c
@@ -239,7 +239,7 @@ static __be32 *
239encode_post_op_attr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp) 239encode_post_op_attr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp)
240{ 240{
241 struct dentry *dentry = fhp->fh_dentry; 241 struct dentry *dentry = fhp->fh_dentry;
242 if (dentry && dentry->d_inode != NULL) { 242 if (dentry && dentry->d_inode) {
243 int err; 243 int err;
244 struct kstat stat; 244 struct kstat stat;
245 245
@@ -300,9 +300,9 @@ int
300nfs3svc_decode_sattrargs(struct svc_rqst *rqstp, __be32 *p, 300nfs3svc_decode_sattrargs(struct svc_rqst *rqstp, __be32 *p,
301 struct nfsd3_sattrargs *args) 301 struct nfsd3_sattrargs *args)
302{ 302{
303 if (!(p = decode_fh(p, &args->fh)) 303 if (!(p = decode_fh(p, &args->fh)))
304 || !(p = decode_sattr3(p, &args->attrs)))
305 return 0; 304 return 0;
305 p = decode_sattr3(p, &args->attrs);
306 306
307 if ((args->check_guard = ntohl(*p++)) != 0) { 307 if ((args->check_guard = ntohl(*p++)) != 0) {
308 struct timespec time; 308 struct timespec time;
@@ -343,9 +343,9 @@ nfs3svc_decode_readargs(struct svc_rqst *rqstp, __be32 *p,
343 int v,pn; 343 int v,pn;
344 u32 max_blocksize = svc_max_payload(rqstp); 344 u32 max_blocksize = svc_max_payload(rqstp);
345 345
346 if (!(p = decode_fh(p, &args->fh)) 346 if (!(p = decode_fh(p, &args->fh)))
347 || !(p = xdr_decode_hyper(p, &args->offset)))
348 return 0; 347 return 0;
348 p = xdr_decode_hyper(p, &args->offset);
349 349
350 len = args->count = ntohl(*p++); 350 len = args->count = ntohl(*p++);
351 351
@@ -372,9 +372,9 @@ nfs3svc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p,
372 unsigned int len, v, hdr, dlen; 372 unsigned int len, v, hdr, dlen;
373 u32 max_blocksize = svc_max_payload(rqstp); 373 u32 max_blocksize = svc_max_payload(rqstp);
374 374
375 if (!(p = decode_fh(p, &args->fh)) 375 if (!(p = decode_fh(p, &args->fh)))
376 || !(p = xdr_decode_hyper(p, &args->offset)))
377 return 0; 376 return 0;
377 p = xdr_decode_hyper(p, &args->offset);
378 378
379 args->count = ntohl(*p++); 379 args->count = ntohl(*p++);
380 args->stable = ntohl(*p++); 380 args->stable = ntohl(*p++);
@@ -388,29 +388,16 @@ nfs3svc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p,
388 /* 388 /*
389 * Check to make sure that we got the right number of 389 * Check to make sure that we got the right number of
390 * bytes. 390 * bytes.
391 *
392 * If more than one page was used, then compute the length
393 * of the data in the request as the total size of the
394 * request minus the transport protocol headers minus the
395 * RPC protocol headers minus the NFS protocol fields
396 * already consumed. If the request fits into a single
397 * page, then compete the length of the data as the size
398 * of the NFS portion of the request minus the NFS
399 * protocol fields already consumed.
400 */ 391 */
401 hdr = (void*)p - rqstp->rq_arg.head[0].iov_base; 392 hdr = (void*)p - rqstp->rq_arg.head[0].iov_base;
402 if (rqstp->rq_respages != rqstp->rq_pages + 1) { 393 dlen = rqstp->rq_arg.head[0].iov_len + rqstp->rq_arg.page_len
403 dlen = rqstp->rq_arg.len - 394 - hdr;
404 (PAGE_SIZE - rqstp->rq_arg.head[0].iov_len) - hdr;
405 } else {
406 dlen = rqstp->rq_arg.head[0].iov_len - hdr;
407 }
408 /* 395 /*
409 * Round the length of the data which was specified up to 396 * Round the length of the data which was specified up to
410 * the next multiple of XDR units and then compare that 397 * the next multiple of XDR units and then compare that
411 * against the length which was actually received. 398 * against the length which was actually received.
412 */ 399 */
413 if (dlen != ((len + 3) & ~0x3)) 400 if (dlen != XDR_QUADLEN(len)*4)
414 return 0; 401 return 0;
415 402
416 if (args->count > max_blocksize) { 403 if (args->count > max_blocksize) {
@@ -442,8 +429,7 @@ nfs3svc_decode_createargs(struct svc_rqst *rqstp, __be32 *p,
442 switch (args->createmode = ntohl(*p++)) { 429 switch (args->createmode = ntohl(*p++)) {
443 case NFS3_CREATE_UNCHECKED: 430 case NFS3_CREATE_UNCHECKED:
444 case NFS3_CREATE_GUARDED: 431 case NFS3_CREATE_GUARDED:
445 if (!(p = decode_sattr3(p, &args->attrs))) 432 p = decode_sattr3(p, &args->attrs);
446 return 0;
447 break; 433 break;
448 case NFS3_CREATE_EXCLUSIVE: 434 case NFS3_CREATE_EXCLUSIVE:
449 args->verf = p; 435 args->verf = p;
@@ -459,10 +445,10 @@ int
459nfs3svc_decode_mkdirargs(struct svc_rqst *rqstp, __be32 *p, 445nfs3svc_decode_mkdirargs(struct svc_rqst *rqstp, __be32 *p,
460 struct nfsd3_createargs *args) 446 struct nfsd3_createargs *args)
461{ 447{
462 if (!(p = decode_fh(p, &args->fh)) 448 if (!(p = decode_fh(p, &args->fh)) ||
463 || !(p = decode_filename(p, &args->name, &args->len)) 449 !(p = decode_filename(p, &args->name, &args->len)))
464 || !(p = decode_sattr3(p, &args->attrs)))
465 return 0; 450 return 0;
451 p = decode_sattr3(p, &args->attrs);
466 452
467 return xdr_argsize_check(rqstp, p); 453 return xdr_argsize_check(rqstp, p);
468} 454}
@@ -476,11 +462,12 @@ nfs3svc_decode_symlinkargs(struct svc_rqst *rqstp, __be32 *p,
476 char *old, *new; 462 char *old, *new;
477 struct kvec *vec; 463 struct kvec *vec;
478 464
479 if (!(p = decode_fh(p, &args->ffh)) 465 if (!(p = decode_fh(p, &args->ffh)) ||
480 || !(p = decode_filename(p, &args->fname, &args->flen)) 466 !(p = decode_filename(p, &args->fname, &args->flen))
481 || !(p = decode_sattr3(p, &args->attrs))
482 ) 467 )
483 return 0; 468 return 0;
469 p = decode_sattr3(p, &args->attrs);
470
484 /* now decode the pathname, which might be larger than the first page. 471 /* now decode the pathname, which might be larger than the first page.
485 * As we have to check for nul's anyway, we copy it into a new page 472 * As we have to check for nul's anyway, we copy it into a new page
486 * This page appears in the rq_res.pages list, but as pages_len is always 473 * This page appears in the rq_res.pages list, but as pages_len is always
@@ -530,10 +517,8 @@ nfs3svc_decode_mknodargs(struct svc_rqst *rqstp, __be32 *p,
530 args->ftype = ntohl(*p++); 517 args->ftype = ntohl(*p++);
531 518
532 if (args->ftype == NF3BLK || args->ftype == NF3CHR 519 if (args->ftype == NF3BLK || args->ftype == NF3CHR
533 || args->ftype == NF3SOCK || args->ftype == NF3FIFO) { 520 || args->ftype == NF3SOCK || args->ftype == NF3FIFO)
534 if (!(p = decode_sattr3(p, &args->attrs))) 521 p = decode_sattr3(p, &args->attrs);
535 return 0;
536 }
537 522
538 if (args->ftype == NF3BLK || args->ftype == NF3CHR) { 523 if (args->ftype == NF3BLK || args->ftype == NF3CHR) {
539 args->major = ntohl(*p++); 524 args->major = ntohl(*p++);