diff options
Diffstat (limited to 'fs/nfsd/nfs3xdr.c')
-rw-r--r-- | fs/nfsd/nfs3xdr.c | 55 |
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 * | |||
239 | encode_post_op_attr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp) | 239 | encode_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 | |||
300 | nfs3svc_decode_sattrargs(struct svc_rqst *rqstp, __be32 *p, | 300 | nfs3svc_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 | |||
459 | nfs3svc_decode_mkdirargs(struct svc_rqst *rqstp, __be32 *p, | 445 | nfs3svc_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++); |