.. | .. |
---|
71 | 71 | } |
---|
72 | 72 | |
---|
73 | 73 | static __be32 * |
---|
74 | | -decode_sattr(__be32 *p, struct iattr *iap) |
---|
| 74 | +decode_sattr(__be32 *p, struct iattr *iap, struct user_namespace *userns) |
---|
75 | 75 | { |
---|
76 | 76 | u32 tmp, tmp1; |
---|
77 | 77 | |
---|
.. | .. |
---|
86 | 86 | iap->ia_mode = tmp; |
---|
87 | 87 | } |
---|
88 | 88 | if ((tmp = ntohl(*p++)) != (u32)-1) { |
---|
89 | | - iap->ia_uid = make_kuid(&init_user_ns, tmp); |
---|
| 89 | + iap->ia_uid = make_kuid(userns, tmp); |
---|
90 | 90 | if (uid_valid(iap->ia_uid)) |
---|
91 | 91 | iap->ia_valid |= ATTR_UID; |
---|
92 | 92 | } |
---|
93 | 93 | if ((tmp = ntohl(*p++)) != (u32)-1) { |
---|
94 | | - iap->ia_gid = make_kgid(&init_user_ns, tmp); |
---|
| 94 | + iap->ia_gid = make_kgid(userns, tmp); |
---|
95 | 95 | if (gid_valid(iap->ia_gid)) |
---|
96 | 96 | iap->ia_valid |= ATTR_GID; |
---|
97 | 97 | } |
---|
.. | .. |
---|
129 | 129 | encode_fattr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp, |
---|
130 | 130 | struct kstat *stat) |
---|
131 | 131 | { |
---|
| 132 | + struct user_namespace *userns = nfsd_user_namespace(rqstp); |
---|
132 | 133 | struct dentry *dentry = fhp->fh_dentry; |
---|
133 | 134 | int type; |
---|
134 | 135 | struct timespec64 time; |
---|
.. | .. |
---|
139 | 140 | *p++ = htonl(nfs_ftypes[type >> 12]); |
---|
140 | 141 | *p++ = htonl((u32) stat->mode); |
---|
141 | 142 | *p++ = htonl((u32) stat->nlink); |
---|
142 | | - *p++ = htonl((u32) from_kuid(&init_user_ns, stat->uid)); |
---|
143 | | - *p++ = htonl((u32) from_kgid(&init_user_ns, stat->gid)); |
---|
| 143 | + *p++ = htonl((u32) from_kuid_munged(userns, stat->uid)); |
---|
| 144 | + *p++ = htonl((u32) from_kgid_munged(userns, stat->gid)); |
---|
144 | 145 | |
---|
145 | 146 | if (S_ISLNK(type) && stat->size > NFS_MAXPATHLEN) { |
---|
146 | 147 | *p++ = htonl(NFS_MAXPATHLEN); |
---|
.. | .. |
---|
216 | 217 | p = decode_fh(p, &args->fh); |
---|
217 | 218 | if (!p) |
---|
218 | 219 | return 0; |
---|
219 | | - p = decode_sattr(p, &args->attrs); |
---|
| 220 | + p = decode_sattr(p, &args->attrs, nfsd_user_namespace(rqstp)); |
---|
220 | 221 | |
---|
221 | 222 | return xdr_argsize_check(rqstp, p); |
---|
222 | 223 | } |
---|
.. | .. |
---|
319 | 320 | if ( !(p = decode_fh(p, &args->fh)) |
---|
320 | 321 | || !(p = decode_filename(p, &args->name, &args->len))) |
---|
321 | 322 | return 0; |
---|
322 | | - p = decode_sattr(p, &args->attrs); |
---|
| 323 | + p = decode_sattr(p, &args->attrs, nfsd_user_namespace(rqstp)); |
---|
323 | 324 | |
---|
324 | 325 | return xdr_argsize_check(rqstp, p); |
---|
325 | 326 | } |
---|
.. | .. |
---|
398 | 399 | return 0; |
---|
399 | 400 | p += xdrlen; |
---|
400 | 401 | } |
---|
401 | | - decode_sattr(p, &args->attrs); |
---|
| 402 | + decode_sattr(p, &args->attrs, nfsd_user_namespace(rqstp)); |
---|
402 | 403 | |
---|
403 | 404 | return 1; |
---|
404 | 405 | } |
---|
.. | .. |
---|
429 | 430 | } |
---|
430 | 431 | |
---|
431 | 432 | int |
---|
| 433 | +nfssvc_encode_stat(struct svc_rqst *rqstp, __be32 *p) |
---|
| 434 | +{ |
---|
| 435 | + struct nfsd_stat *resp = rqstp->rq_resp; |
---|
| 436 | + |
---|
| 437 | + *p++ = resp->status; |
---|
| 438 | + return xdr_ressize_check(rqstp, p); |
---|
| 439 | +} |
---|
| 440 | + |
---|
| 441 | +int |
---|
432 | 442 | nfssvc_encode_attrstat(struct svc_rqst *rqstp, __be32 *p) |
---|
433 | 443 | { |
---|
434 | 444 | struct nfsd_attrstat *resp = rqstp->rq_resp; |
---|
435 | 445 | |
---|
| 446 | + *p++ = resp->status; |
---|
| 447 | + if (resp->status != nfs_ok) |
---|
| 448 | + goto out; |
---|
436 | 449 | p = encode_fattr(rqstp, p, &resp->fh, &resp->stat); |
---|
| 450 | +out: |
---|
437 | 451 | return xdr_ressize_check(rqstp, p); |
---|
438 | 452 | } |
---|
439 | 453 | |
---|
.. | .. |
---|
442 | 456 | { |
---|
443 | 457 | struct nfsd_diropres *resp = rqstp->rq_resp; |
---|
444 | 458 | |
---|
| 459 | + *p++ = resp->status; |
---|
| 460 | + if (resp->status != nfs_ok) |
---|
| 461 | + goto out; |
---|
445 | 462 | p = encode_fh(p, &resp->fh); |
---|
446 | 463 | p = encode_fattr(rqstp, p, &resp->fh, &resp->stat); |
---|
| 464 | +out: |
---|
447 | 465 | return xdr_ressize_check(rqstp, p); |
---|
448 | 466 | } |
---|
449 | 467 | |
---|
.. | .. |
---|
451 | 469 | nfssvc_encode_readlinkres(struct svc_rqst *rqstp, __be32 *p) |
---|
452 | 470 | { |
---|
453 | 471 | struct nfsd_readlinkres *resp = rqstp->rq_resp; |
---|
| 472 | + |
---|
| 473 | + *p++ = resp->status; |
---|
| 474 | + if (resp->status != nfs_ok) |
---|
| 475 | + return xdr_ressize_check(rqstp, p); |
---|
454 | 476 | |
---|
455 | 477 | *p++ = htonl(resp->len); |
---|
456 | 478 | xdr_ressize_check(rqstp, p); |
---|
.. | .. |
---|
468 | 490 | nfssvc_encode_readres(struct svc_rqst *rqstp, __be32 *p) |
---|
469 | 491 | { |
---|
470 | 492 | struct nfsd_readres *resp = rqstp->rq_resp; |
---|
| 493 | + |
---|
| 494 | + *p++ = resp->status; |
---|
| 495 | + if (resp->status != nfs_ok) |
---|
| 496 | + return xdr_ressize_check(rqstp, p); |
---|
471 | 497 | |
---|
472 | 498 | p = encode_fattr(rqstp, p, &resp->fh, &resp->stat); |
---|
473 | 499 | *p++ = htonl(resp->count); |
---|
.. | .. |
---|
489 | 515 | { |
---|
490 | 516 | struct nfsd_readdirres *resp = rqstp->rq_resp; |
---|
491 | 517 | |
---|
| 518 | + *p++ = resp->status; |
---|
| 519 | + if (resp->status != nfs_ok) |
---|
| 520 | + return xdr_ressize_check(rqstp, p); |
---|
| 521 | + |
---|
492 | 522 | xdr_ressize_check(rqstp, p); |
---|
493 | 523 | p = resp->buffer; |
---|
494 | 524 | *p++ = 0; /* no more entries */ |
---|
.. | .. |
---|
503 | 533 | { |
---|
504 | 534 | struct nfsd_statfsres *resp = rqstp->rq_resp; |
---|
505 | 535 | struct kstatfs *stat = &resp->stats; |
---|
| 536 | + |
---|
| 537 | + *p++ = resp->status; |
---|
| 538 | + if (resp->status != nfs_ok) |
---|
| 539 | + return xdr_ressize_check(rqstp, p); |
---|
506 | 540 | |
---|
507 | 541 | *p++ = htonl(NFSSVC_MAXBLKSIZE_V2); /* max transfer size */ |
---|
508 | 542 | *p++ = htonl(stat->f_bsize); |
---|
.. | .. |
---|
560 | 594 | /* |
---|
561 | 595 | * XDR release functions |
---|
562 | 596 | */ |
---|
563 | | -void |
---|
564 | | -nfssvc_release_fhandle(struct svc_rqst *rqstp) |
---|
| 597 | +void nfssvc_release_attrstat(struct svc_rqst *rqstp) |
---|
565 | 598 | { |
---|
566 | | - struct nfsd_fhandle *resp = rqstp->rq_resp; |
---|
| 599 | + struct nfsd_attrstat *resp = rqstp->rq_resp; |
---|
| 600 | + |
---|
| 601 | + fh_put(&resp->fh); |
---|
| 602 | +} |
---|
| 603 | + |
---|
| 604 | +void nfssvc_release_diropres(struct svc_rqst *rqstp) |
---|
| 605 | +{ |
---|
| 606 | + struct nfsd_diropres *resp = rqstp->rq_resp; |
---|
| 607 | + |
---|
| 608 | + fh_put(&resp->fh); |
---|
| 609 | +} |
---|
| 610 | + |
---|
| 611 | +void nfssvc_release_readres(struct svc_rqst *rqstp) |
---|
| 612 | +{ |
---|
| 613 | + struct nfsd_readres *resp = rqstp->rq_resp; |
---|
567 | 614 | |
---|
568 | 615 | fh_put(&resp->fh); |
---|
569 | 616 | } |
---|