diff options
Diffstat (limited to 'fs/nfsd/nfs4xdr.c')
-rw-r--r-- | fs/nfsd/nfs4xdr.c | 454 |
1 files changed, 310 insertions, 144 deletions
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 5be00436b5b8..f3f239db04bb 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c | |||
@@ -60,8 +60,16 @@ | |||
60 | 60 | ||
61 | #define NFSDDBG_FACILITY NFSDDBG_XDR | 61 | #define NFSDDBG_FACILITY NFSDDBG_XDR |
62 | 62 | ||
63 | static int | 63 | /* |
64 | check_filename(char *str, int len, int err) | 64 | * As per referral draft, the fsid for a referral MUST be different from the fsid of the containing |
65 | * directory in order to indicate to the client that a filesystem boundary is present | ||
66 | * We use a fixed fsid for a referral | ||
67 | */ | ||
68 | #define NFS4_REFERRAL_FSID_MAJOR 0x8000000ULL | ||
69 | #define NFS4_REFERRAL_FSID_MINOR 0x8000000ULL | ||
70 | |||
71 | static __be32 | ||
72 | check_filename(char *str, int len, __be32 err) | ||
65 | { | 73 | { |
66 | int i; | 74 | int i; |
67 | 75 | ||
@@ -86,8 +94,8 @@ check_filename(char *str, int len, int err) | |||
86 | * consistent with the style used in NFSv2/v3... | 94 | * consistent with the style used in NFSv2/v3... |
87 | */ | 95 | */ |
88 | #define DECODE_HEAD \ | 96 | #define DECODE_HEAD \ |
89 | u32 *p; \ | 97 | __be32 *p; \ |
90 | int status | 98 | __be32 status |
91 | #define DECODE_TAIL \ | 99 | #define DECODE_TAIL \ |
92 | status = 0; \ | 100 | status = 0; \ |
93 | out: \ | 101 | out: \ |
@@ -136,13 +144,13 @@ xdr_error: \ | |||
136 | } \ | 144 | } \ |
137 | } while (0) | 145 | } while (0) |
138 | 146 | ||
139 | static u32 *read_buf(struct nfsd4_compoundargs *argp, int nbytes) | 147 | static __be32 *read_buf(struct nfsd4_compoundargs *argp, int nbytes) |
140 | { | 148 | { |
141 | /* We want more bytes than seem to be available. | 149 | /* We want more bytes than seem to be available. |
142 | * Maybe we need a new page, maybe we have just run out | 150 | * Maybe we need a new page, maybe we have just run out |
143 | */ | 151 | */ |
144 | int avail = (char*)argp->end - (char*)argp->p; | 152 | int avail = (char*)argp->end - (char*)argp->p; |
145 | u32 *p; | 153 | __be32 *p; |
146 | if (avail + argp->pagelen < nbytes) | 154 | if (avail + argp->pagelen < nbytes) |
147 | return NULL; | 155 | return NULL; |
148 | if (avail + PAGE_SIZE < nbytes) /* need more than a page !! */ | 156 | if (avail + PAGE_SIZE < nbytes) /* need more than a page !! */ |
@@ -189,7 +197,7 @@ defer_free(struct nfsd4_compoundargs *argp, | |||
189 | return 0; | 197 | return 0; |
190 | } | 198 | } |
191 | 199 | ||
192 | static char *savemem(struct nfsd4_compoundargs *argp, u32 *p, int nbytes) | 200 | static char *savemem(struct nfsd4_compoundargs *argp, __be32 *p, int nbytes) |
193 | { | 201 | { |
194 | void *new = NULL; | 202 | void *new = NULL; |
195 | if (p == argp->tmp) { | 203 | if (p == argp->tmp) { |
@@ -209,7 +217,7 @@ static char *savemem(struct nfsd4_compoundargs *argp, u32 *p, int nbytes) | |||
209 | } | 217 | } |
210 | 218 | ||
211 | 219 | ||
212 | static int | 220 | static __be32 |
213 | nfsd4_decode_bitmap(struct nfsd4_compoundargs *argp, u32 *bmval) | 221 | nfsd4_decode_bitmap(struct nfsd4_compoundargs *argp, u32 *bmval) |
214 | { | 222 | { |
215 | u32 bmlen; | 223 | u32 bmlen; |
@@ -232,13 +240,14 @@ nfsd4_decode_bitmap(struct nfsd4_compoundargs *argp, u32 *bmval) | |||
232 | DECODE_TAIL; | 240 | DECODE_TAIL; |
233 | } | 241 | } |
234 | 242 | ||
235 | static int | 243 | static __be32 |
236 | nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, struct iattr *iattr, | 244 | nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, struct iattr *iattr, |
237 | struct nfs4_acl **acl) | 245 | struct nfs4_acl **acl) |
238 | { | 246 | { |
239 | int expected_len, len = 0; | 247 | int expected_len, len = 0; |
240 | u32 dummy32; | 248 | u32 dummy32; |
241 | char *buf; | 249 | char *buf; |
250 | int host_err; | ||
242 | 251 | ||
243 | DECODE_HEAD; | 252 | DECODE_HEAD; |
244 | iattr->ia_valid = 0; | 253 | iattr->ia_valid = 0; |
@@ -272,7 +281,7 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, struct iattr *ia | |||
272 | 281 | ||
273 | *acl = nfs4_acl_new(); | 282 | *acl = nfs4_acl_new(); |
274 | if (*acl == NULL) { | 283 | if (*acl == NULL) { |
275 | status = -ENOMEM; | 284 | host_err = -ENOMEM; |
276 | goto out_nfserr; | 285 | goto out_nfserr; |
277 | } | 286 | } |
278 | defer_free(argp, (void (*)(const void *))nfs4_acl_free, *acl); | 287 | defer_free(argp, (void (*)(const void *))nfs4_acl_free, *acl); |
@@ -287,20 +296,20 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, struct iattr *ia | |||
287 | len += XDR_QUADLEN(dummy32) << 2; | 296 | len += XDR_QUADLEN(dummy32) << 2; |
288 | READMEM(buf, dummy32); | 297 | READMEM(buf, dummy32); |
289 | ace.whotype = nfs4_acl_get_whotype(buf, dummy32); | 298 | ace.whotype = nfs4_acl_get_whotype(buf, dummy32); |
290 | status = 0; | 299 | host_err = 0; |
291 | if (ace.whotype != NFS4_ACL_WHO_NAMED) | 300 | if (ace.whotype != NFS4_ACL_WHO_NAMED) |
292 | ace.who = 0; | 301 | ace.who = 0; |
293 | else if (ace.flag & NFS4_ACE_IDENTIFIER_GROUP) | 302 | else if (ace.flag & NFS4_ACE_IDENTIFIER_GROUP) |
294 | status = nfsd_map_name_to_gid(argp->rqstp, | 303 | host_err = nfsd_map_name_to_gid(argp->rqstp, |
295 | buf, dummy32, &ace.who); | 304 | buf, dummy32, &ace.who); |
296 | else | 305 | else |
297 | status = nfsd_map_name_to_uid(argp->rqstp, | 306 | host_err = nfsd_map_name_to_uid(argp->rqstp, |
298 | buf, dummy32, &ace.who); | 307 | buf, dummy32, &ace.who); |
299 | if (status) | 308 | if (host_err) |
300 | goto out_nfserr; | 309 | goto out_nfserr; |
301 | status = nfs4_acl_add_ace(*acl, ace.type, ace.flag, | 310 | host_err = nfs4_acl_add_ace(*acl, ace.type, ace.flag, |
302 | ace.access_mask, ace.whotype, ace.who); | 311 | ace.access_mask, ace.whotype, ace.who); |
303 | if (status) | 312 | if (host_err) |
304 | goto out_nfserr; | 313 | goto out_nfserr; |
305 | } | 314 | } |
306 | } else | 315 | } else |
@@ -319,7 +328,7 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, struct iattr *ia | |||
319 | READ_BUF(dummy32); | 328 | READ_BUF(dummy32); |
320 | len += (XDR_QUADLEN(dummy32) << 2); | 329 | len += (XDR_QUADLEN(dummy32) << 2); |
321 | READMEM(buf, dummy32); | 330 | READMEM(buf, dummy32); |
322 | if ((status = nfsd_map_name_to_uid(argp->rqstp, buf, dummy32, &iattr->ia_uid))) | 331 | if ((host_err = nfsd_map_name_to_uid(argp->rqstp, buf, dummy32, &iattr->ia_uid))) |
323 | goto out_nfserr; | 332 | goto out_nfserr; |
324 | iattr->ia_valid |= ATTR_UID; | 333 | iattr->ia_valid |= ATTR_UID; |
325 | } | 334 | } |
@@ -330,7 +339,7 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, struct iattr *ia | |||
330 | READ_BUF(dummy32); | 339 | READ_BUF(dummy32); |
331 | len += (XDR_QUADLEN(dummy32) << 2); | 340 | len += (XDR_QUADLEN(dummy32) << 2); |
332 | READMEM(buf, dummy32); | 341 | READMEM(buf, dummy32); |
333 | if ((status = nfsd_map_name_to_gid(argp->rqstp, buf, dummy32, &iattr->ia_gid))) | 342 | if ((host_err = nfsd_map_name_to_gid(argp->rqstp, buf, dummy32, &iattr->ia_gid))) |
334 | goto out_nfserr; | 343 | goto out_nfserr; |
335 | iattr->ia_valid |= ATTR_GID; | 344 | iattr->ia_valid |= ATTR_GID; |
336 | } | 345 | } |
@@ -406,11 +415,11 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, struct iattr *ia | |||
406 | DECODE_TAIL; | 415 | DECODE_TAIL; |
407 | 416 | ||
408 | out_nfserr: | 417 | out_nfserr: |
409 | status = nfserrno(status); | 418 | status = nfserrno(host_err); |
410 | goto out; | 419 | goto out; |
411 | } | 420 | } |
412 | 421 | ||
413 | static int | 422 | static __be32 |
414 | nfsd4_decode_access(struct nfsd4_compoundargs *argp, struct nfsd4_access *access) | 423 | nfsd4_decode_access(struct nfsd4_compoundargs *argp, struct nfsd4_access *access) |
415 | { | 424 | { |
416 | DECODE_HEAD; | 425 | DECODE_HEAD; |
@@ -421,7 +430,7 @@ nfsd4_decode_access(struct nfsd4_compoundargs *argp, struct nfsd4_access *access | |||
421 | DECODE_TAIL; | 430 | DECODE_TAIL; |
422 | } | 431 | } |
423 | 432 | ||
424 | static int | 433 | static __be32 |
425 | nfsd4_decode_close(struct nfsd4_compoundargs *argp, struct nfsd4_close *close) | 434 | nfsd4_decode_close(struct nfsd4_compoundargs *argp, struct nfsd4_close *close) |
426 | { | 435 | { |
427 | DECODE_HEAD; | 436 | DECODE_HEAD; |
@@ -436,7 +445,7 @@ nfsd4_decode_close(struct nfsd4_compoundargs *argp, struct nfsd4_close *close) | |||
436 | } | 445 | } |
437 | 446 | ||
438 | 447 | ||
439 | static int | 448 | static __be32 |
440 | nfsd4_decode_commit(struct nfsd4_compoundargs *argp, struct nfsd4_commit *commit) | 449 | nfsd4_decode_commit(struct nfsd4_compoundargs *argp, struct nfsd4_commit *commit) |
441 | { | 450 | { |
442 | DECODE_HEAD; | 451 | DECODE_HEAD; |
@@ -448,7 +457,7 @@ nfsd4_decode_commit(struct nfsd4_compoundargs *argp, struct nfsd4_commit *commit | |||
448 | DECODE_TAIL; | 457 | DECODE_TAIL; |
449 | } | 458 | } |
450 | 459 | ||
451 | static int | 460 | static __be32 |
452 | nfsd4_decode_create(struct nfsd4_compoundargs *argp, struct nfsd4_create *create) | 461 | nfsd4_decode_create(struct nfsd4_compoundargs *argp, struct nfsd4_create *create) |
453 | { | 462 | { |
454 | DECODE_HEAD; | 463 | DECODE_HEAD; |
@@ -488,7 +497,7 @@ nfsd4_decode_create(struct nfsd4_compoundargs *argp, struct nfsd4_create *create | |||
488 | DECODE_TAIL; | 497 | DECODE_TAIL; |
489 | } | 498 | } |
490 | 499 | ||
491 | static inline int | 500 | static inline __be32 |
492 | nfsd4_decode_delegreturn(struct nfsd4_compoundargs *argp, struct nfsd4_delegreturn *dr) | 501 | nfsd4_decode_delegreturn(struct nfsd4_compoundargs *argp, struct nfsd4_delegreturn *dr) |
493 | { | 502 | { |
494 | DECODE_HEAD; | 503 | DECODE_HEAD; |
@@ -500,13 +509,13 @@ nfsd4_decode_delegreturn(struct nfsd4_compoundargs *argp, struct nfsd4_delegretu | |||
500 | DECODE_TAIL; | 509 | DECODE_TAIL; |
501 | } | 510 | } |
502 | 511 | ||
503 | static inline int | 512 | static inline __be32 |
504 | nfsd4_decode_getattr(struct nfsd4_compoundargs *argp, struct nfsd4_getattr *getattr) | 513 | nfsd4_decode_getattr(struct nfsd4_compoundargs *argp, struct nfsd4_getattr *getattr) |
505 | { | 514 | { |
506 | return nfsd4_decode_bitmap(argp, getattr->ga_bmval); | 515 | return nfsd4_decode_bitmap(argp, getattr->ga_bmval); |
507 | } | 516 | } |
508 | 517 | ||
509 | static int | 518 | static __be32 |
510 | nfsd4_decode_link(struct nfsd4_compoundargs *argp, struct nfsd4_link *link) | 519 | nfsd4_decode_link(struct nfsd4_compoundargs *argp, struct nfsd4_link *link) |
511 | { | 520 | { |
512 | DECODE_HEAD; | 521 | DECODE_HEAD; |
@@ -521,7 +530,7 @@ nfsd4_decode_link(struct nfsd4_compoundargs *argp, struct nfsd4_link *link) | |||
521 | DECODE_TAIL; | 530 | DECODE_TAIL; |
522 | } | 531 | } |
523 | 532 | ||
524 | static int | 533 | static __be32 |
525 | nfsd4_decode_lock(struct nfsd4_compoundargs *argp, struct nfsd4_lock *lock) | 534 | nfsd4_decode_lock(struct nfsd4_compoundargs *argp, struct nfsd4_lock *lock) |
526 | { | 535 | { |
527 | DECODE_HEAD; | 536 | DECODE_HEAD; |
@@ -560,7 +569,7 @@ nfsd4_decode_lock(struct nfsd4_compoundargs *argp, struct nfsd4_lock *lock) | |||
560 | DECODE_TAIL; | 569 | DECODE_TAIL; |
561 | } | 570 | } |
562 | 571 | ||
563 | static int | 572 | static __be32 |
564 | nfsd4_decode_lockt(struct nfsd4_compoundargs *argp, struct nfsd4_lockt *lockt) | 573 | nfsd4_decode_lockt(struct nfsd4_compoundargs *argp, struct nfsd4_lockt *lockt) |
565 | { | 574 | { |
566 | DECODE_HEAD; | 575 | DECODE_HEAD; |
@@ -579,7 +588,7 @@ nfsd4_decode_lockt(struct nfsd4_compoundargs *argp, struct nfsd4_lockt *lockt) | |||
579 | DECODE_TAIL; | 588 | DECODE_TAIL; |
580 | } | 589 | } |
581 | 590 | ||
582 | static int | 591 | static __be32 |
583 | nfsd4_decode_locku(struct nfsd4_compoundargs *argp, struct nfsd4_locku *locku) | 592 | nfsd4_decode_locku(struct nfsd4_compoundargs *argp, struct nfsd4_locku *locku) |
584 | { | 593 | { |
585 | DECODE_HEAD; | 594 | DECODE_HEAD; |
@@ -598,7 +607,7 @@ nfsd4_decode_locku(struct nfsd4_compoundargs *argp, struct nfsd4_locku *locku) | |||
598 | DECODE_TAIL; | 607 | DECODE_TAIL; |
599 | } | 608 | } |
600 | 609 | ||
601 | static int | 610 | static __be32 |
602 | nfsd4_decode_lookup(struct nfsd4_compoundargs *argp, struct nfsd4_lookup *lookup) | 611 | nfsd4_decode_lookup(struct nfsd4_compoundargs *argp, struct nfsd4_lookup *lookup) |
603 | { | 612 | { |
604 | DECODE_HEAD; | 613 | DECODE_HEAD; |
@@ -613,7 +622,7 @@ nfsd4_decode_lookup(struct nfsd4_compoundargs *argp, struct nfsd4_lookup *lookup | |||
613 | DECODE_TAIL; | 622 | DECODE_TAIL; |
614 | } | 623 | } |
615 | 624 | ||
616 | static int | 625 | static __be32 |
617 | nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open) | 626 | nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open) |
618 | { | 627 | { |
619 | DECODE_HEAD; | 628 | DECODE_HEAD; |
@@ -691,7 +700,7 @@ nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open) | |||
691 | DECODE_TAIL; | 700 | DECODE_TAIL; |
692 | } | 701 | } |
693 | 702 | ||
694 | static int | 703 | static __be32 |
695 | nfsd4_decode_open_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_open_confirm *open_conf) | 704 | nfsd4_decode_open_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_open_confirm *open_conf) |
696 | { | 705 | { |
697 | DECODE_HEAD; | 706 | DECODE_HEAD; |
@@ -705,7 +714,7 @@ nfsd4_decode_open_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_open_con | |||
705 | DECODE_TAIL; | 714 | DECODE_TAIL; |
706 | } | 715 | } |
707 | 716 | ||
708 | static int | 717 | static __be32 |
709 | nfsd4_decode_open_downgrade(struct nfsd4_compoundargs *argp, struct nfsd4_open_downgrade *open_down) | 718 | nfsd4_decode_open_downgrade(struct nfsd4_compoundargs *argp, struct nfsd4_open_downgrade *open_down) |
710 | { | 719 | { |
711 | DECODE_HEAD; | 720 | DECODE_HEAD; |
@@ -721,7 +730,7 @@ nfsd4_decode_open_downgrade(struct nfsd4_compoundargs *argp, struct nfsd4_open_d | |||
721 | DECODE_TAIL; | 730 | DECODE_TAIL; |
722 | } | 731 | } |
723 | 732 | ||
724 | static int | 733 | static __be32 |
725 | nfsd4_decode_putfh(struct nfsd4_compoundargs *argp, struct nfsd4_putfh *putfh) | 734 | nfsd4_decode_putfh(struct nfsd4_compoundargs *argp, struct nfsd4_putfh *putfh) |
726 | { | 735 | { |
727 | DECODE_HEAD; | 736 | DECODE_HEAD; |
@@ -736,7 +745,7 @@ nfsd4_decode_putfh(struct nfsd4_compoundargs *argp, struct nfsd4_putfh *putfh) | |||
736 | DECODE_TAIL; | 745 | DECODE_TAIL; |
737 | } | 746 | } |
738 | 747 | ||
739 | static int | 748 | static __be32 |
740 | nfsd4_decode_read(struct nfsd4_compoundargs *argp, struct nfsd4_read *read) | 749 | nfsd4_decode_read(struct nfsd4_compoundargs *argp, struct nfsd4_read *read) |
741 | { | 750 | { |
742 | DECODE_HEAD; | 751 | DECODE_HEAD; |
@@ -750,7 +759,7 @@ nfsd4_decode_read(struct nfsd4_compoundargs *argp, struct nfsd4_read *read) | |||
750 | DECODE_TAIL; | 759 | DECODE_TAIL; |
751 | } | 760 | } |
752 | 761 | ||
753 | static int | 762 | static __be32 |
754 | nfsd4_decode_readdir(struct nfsd4_compoundargs *argp, struct nfsd4_readdir *readdir) | 763 | nfsd4_decode_readdir(struct nfsd4_compoundargs *argp, struct nfsd4_readdir *readdir) |
755 | { | 764 | { |
756 | DECODE_HEAD; | 765 | DECODE_HEAD; |
@@ -766,7 +775,7 @@ nfsd4_decode_readdir(struct nfsd4_compoundargs *argp, struct nfsd4_readdir *read | |||
766 | DECODE_TAIL; | 775 | DECODE_TAIL; |
767 | } | 776 | } |
768 | 777 | ||
769 | static int | 778 | static __be32 |
770 | nfsd4_decode_remove(struct nfsd4_compoundargs *argp, struct nfsd4_remove *remove) | 779 | nfsd4_decode_remove(struct nfsd4_compoundargs *argp, struct nfsd4_remove *remove) |
771 | { | 780 | { |
772 | DECODE_HEAD; | 781 | DECODE_HEAD; |
@@ -781,7 +790,7 @@ nfsd4_decode_remove(struct nfsd4_compoundargs *argp, struct nfsd4_remove *remove | |||
781 | DECODE_TAIL; | 790 | DECODE_TAIL; |
782 | } | 791 | } |
783 | 792 | ||
784 | static int | 793 | static __be32 |
785 | nfsd4_decode_rename(struct nfsd4_compoundargs *argp, struct nfsd4_rename *rename) | 794 | nfsd4_decode_rename(struct nfsd4_compoundargs *argp, struct nfsd4_rename *rename) |
786 | { | 795 | { |
787 | DECODE_HEAD; | 796 | DECODE_HEAD; |
@@ -801,7 +810,7 @@ nfsd4_decode_rename(struct nfsd4_compoundargs *argp, struct nfsd4_rename *rename | |||
801 | DECODE_TAIL; | 810 | DECODE_TAIL; |
802 | } | 811 | } |
803 | 812 | ||
804 | static int | 813 | static __be32 |
805 | nfsd4_decode_renew(struct nfsd4_compoundargs *argp, clientid_t *clientid) | 814 | nfsd4_decode_renew(struct nfsd4_compoundargs *argp, clientid_t *clientid) |
806 | { | 815 | { |
807 | DECODE_HEAD; | 816 | DECODE_HEAD; |
@@ -812,7 +821,7 @@ nfsd4_decode_renew(struct nfsd4_compoundargs *argp, clientid_t *clientid) | |||
812 | DECODE_TAIL; | 821 | DECODE_TAIL; |
813 | } | 822 | } |
814 | 823 | ||
815 | static int | 824 | static __be32 |
816 | nfsd4_decode_setattr(struct nfsd4_compoundargs *argp, struct nfsd4_setattr *setattr) | 825 | nfsd4_decode_setattr(struct nfsd4_compoundargs *argp, struct nfsd4_setattr *setattr) |
817 | { | 826 | { |
818 | DECODE_HEAD; | 827 | DECODE_HEAD; |
@@ -826,7 +835,7 @@ nfsd4_decode_setattr(struct nfsd4_compoundargs *argp, struct nfsd4_setattr *seta | |||
826 | DECODE_TAIL; | 835 | DECODE_TAIL; |
827 | } | 836 | } |
828 | 837 | ||
829 | static int | 838 | static __be32 |
830 | nfsd4_decode_setclientid(struct nfsd4_compoundargs *argp, struct nfsd4_setclientid *setclientid) | 839 | nfsd4_decode_setclientid(struct nfsd4_compoundargs *argp, struct nfsd4_setclientid *setclientid) |
831 | { | 840 | { |
832 | DECODE_HEAD; | 841 | DECODE_HEAD; |
@@ -851,7 +860,7 @@ nfsd4_decode_setclientid(struct nfsd4_compoundargs *argp, struct nfsd4_setclient | |||
851 | DECODE_TAIL; | 860 | DECODE_TAIL; |
852 | } | 861 | } |
853 | 862 | ||
854 | static int | 863 | static __be32 |
855 | nfsd4_decode_setclientid_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_setclientid_confirm *scd_c) | 864 | nfsd4_decode_setclientid_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_setclientid_confirm *scd_c) |
856 | { | 865 | { |
857 | DECODE_HEAD; | 866 | DECODE_HEAD; |
@@ -864,7 +873,7 @@ nfsd4_decode_setclientid_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_s | |||
864 | } | 873 | } |
865 | 874 | ||
866 | /* Also used for NVERIFY */ | 875 | /* Also used for NVERIFY */ |
867 | static int | 876 | static __be32 |
868 | nfsd4_decode_verify(struct nfsd4_compoundargs *argp, struct nfsd4_verify *verify) | 877 | nfsd4_decode_verify(struct nfsd4_compoundargs *argp, struct nfsd4_verify *verify) |
869 | { | 878 | { |
870 | #if 0 | 879 | #if 0 |
@@ -900,7 +909,7 @@ nfsd4_decode_verify(struct nfsd4_compoundargs *argp, struct nfsd4_verify *verify | |||
900 | DECODE_TAIL; | 909 | DECODE_TAIL; |
901 | } | 910 | } |
902 | 911 | ||
903 | static int | 912 | static __be32 |
904 | nfsd4_decode_write(struct nfsd4_compoundargs *argp, struct nfsd4_write *write) | 913 | nfsd4_decode_write(struct nfsd4_compoundargs *argp, struct nfsd4_write *write) |
905 | { | 914 | { |
906 | int avail; | 915 | int avail; |
@@ -926,32 +935,32 @@ nfsd4_decode_write(struct nfsd4_compoundargs *argp, struct nfsd4_write *write) | |||
926 | printk(KERN_NOTICE "xdr error! (%s:%d)\n", __FILE__, __LINE__); | 935 | printk(KERN_NOTICE "xdr error! (%s:%d)\n", __FILE__, __LINE__); |
927 | goto xdr_error; | 936 | goto xdr_error; |
928 | } | 937 | } |
929 | write->wr_vec[0].iov_base = p; | 938 | argp->rqstp->rq_vec[0].iov_base = p; |
930 | write->wr_vec[0].iov_len = avail; | 939 | argp->rqstp->rq_vec[0].iov_len = avail; |
931 | v = 0; | 940 | v = 0; |
932 | len = write->wr_buflen; | 941 | len = write->wr_buflen; |
933 | while (len > write->wr_vec[v].iov_len) { | 942 | while (len > argp->rqstp->rq_vec[v].iov_len) { |
934 | len -= write->wr_vec[v].iov_len; | 943 | len -= argp->rqstp->rq_vec[v].iov_len; |
935 | v++; | 944 | v++; |
936 | write->wr_vec[v].iov_base = page_address(argp->pagelist[0]); | 945 | argp->rqstp->rq_vec[v].iov_base = page_address(argp->pagelist[0]); |
937 | argp->pagelist++; | 946 | argp->pagelist++; |
938 | if (argp->pagelen >= PAGE_SIZE) { | 947 | if (argp->pagelen >= PAGE_SIZE) { |
939 | write->wr_vec[v].iov_len = PAGE_SIZE; | 948 | argp->rqstp->rq_vec[v].iov_len = PAGE_SIZE; |
940 | argp->pagelen -= PAGE_SIZE; | 949 | argp->pagelen -= PAGE_SIZE; |
941 | } else { | 950 | } else { |
942 | write->wr_vec[v].iov_len = argp->pagelen; | 951 | argp->rqstp->rq_vec[v].iov_len = argp->pagelen; |
943 | argp->pagelen -= len; | 952 | argp->pagelen -= len; |
944 | } | 953 | } |
945 | } | 954 | } |
946 | argp->end = (u32*) (write->wr_vec[v].iov_base + write->wr_vec[v].iov_len); | 955 | argp->end = (__be32*) (argp->rqstp->rq_vec[v].iov_base + argp->rqstp->rq_vec[v].iov_len); |
947 | argp->p = (u32*) (write->wr_vec[v].iov_base + (XDR_QUADLEN(len) << 2)); | 956 | argp->p = (__be32*) (argp->rqstp->rq_vec[v].iov_base + (XDR_QUADLEN(len) << 2)); |
948 | write->wr_vec[v].iov_len = len; | 957 | argp->rqstp->rq_vec[v].iov_len = len; |
949 | write->wr_vlen = v+1; | 958 | write->wr_vlen = v+1; |
950 | 959 | ||
951 | DECODE_TAIL; | 960 | DECODE_TAIL; |
952 | } | 961 | } |
953 | 962 | ||
954 | static int | 963 | static __be32 |
955 | nfsd4_decode_release_lockowner(struct nfsd4_compoundargs *argp, struct nfsd4_release_lockowner *rlockowner) | 964 | nfsd4_decode_release_lockowner(struct nfsd4_compoundargs *argp, struct nfsd4_release_lockowner *rlockowner) |
956 | { | 965 | { |
957 | DECODE_HEAD; | 966 | DECODE_HEAD; |
@@ -965,7 +974,7 @@ nfsd4_decode_release_lockowner(struct nfsd4_compoundargs *argp, struct nfsd4_rel | |||
965 | DECODE_TAIL; | 974 | DECODE_TAIL; |
966 | } | 975 | } |
967 | 976 | ||
968 | static int | 977 | static __be32 |
969 | nfsd4_decode_compound(struct nfsd4_compoundargs *argp) | 978 | nfsd4_decode_compound(struct nfsd4_compoundargs *argp) |
970 | { | 979 | { |
971 | DECODE_HEAD; | 980 | DECODE_HEAD; |
@@ -1171,7 +1180,7 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp) | |||
1171 | * task to translate them into Linux-specific versions which are more | 1180 | * task to translate them into Linux-specific versions which are more |
1172 | * consistent with the style used in NFSv2/v3... | 1181 | * consistent with the style used in NFSv2/v3... |
1173 | */ | 1182 | */ |
1174 | #define ENCODE_HEAD u32 *p | 1183 | #define ENCODE_HEAD __be32 *p |
1175 | 1184 | ||
1176 | #define WRITE32(n) *p++ = htonl(n) | 1185 | #define WRITE32(n) *p++ = htonl(n) |
1177 | #define WRITE64(n) do { \ | 1186 | #define WRITE64(n) do { \ |
@@ -1201,8 +1210,8 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp) | |||
1201 | * Header routine to setup seqid operation replay cache | 1210 | * Header routine to setup seqid operation replay cache |
1202 | */ | 1211 | */ |
1203 | #define ENCODE_SEQID_OP_HEAD \ | 1212 | #define ENCODE_SEQID_OP_HEAD \ |
1204 | u32 *p; \ | 1213 | __be32 *p; \ |
1205 | u32 *save; \ | 1214 | __be32 *save; \ |
1206 | \ | 1215 | \ |
1207 | save = resp->p; | 1216 | save = resp->p; |
1208 | 1217 | ||
@@ -1223,6 +1232,120 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp) | |||
1223 | stateowner->so_replay.rp_buflen); \ | 1232 | stateowner->so_replay.rp_buflen); \ |
1224 | } } while (0); | 1233 | } } while (0); |
1225 | 1234 | ||
1235 | /* Encode as an array of strings the string given with components | ||
1236 | * seperated @sep. | ||
1237 | */ | ||
1238 | static __be32 nfsd4_encode_components(char sep, char *components, | ||
1239 | __be32 **pp, int *buflen) | ||
1240 | { | ||
1241 | __be32 *p = *pp; | ||
1242 | __be32 *countp = p; | ||
1243 | int strlen, count=0; | ||
1244 | char *str, *end; | ||
1245 | |||
1246 | dprintk("nfsd4_encode_components(%s)\n", components); | ||
1247 | if ((*buflen -= 4) < 0) | ||
1248 | return nfserr_resource; | ||
1249 | WRITE32(0); /* We will fill this in with @count later */ | ||
1250 | end = str = components; | ||
1251 | while (*end) { | ||
1252 | for (; *end && (*end != sep); end++) | ||
1253 | ; /* Point to end of component */ | ||
1254 | strlen = end - str; | ||
1255 | if (strlen) { | ||
1256 | if ((*buflen -= ((XDR_QUADLEN(strlen) << 2) + 4)) < 0) | ||
1257 | return nfserr_resource; | ||
1258 | WRITE32(strlen); | ||
1259 | WRITEMEM(str, strlen); | ||
1260 | count++; | ||
1261 | } | ||
1262 | else | ||
1263 | end++; | ||
1264 | str = end; | ||
1265 | } | ||
1266 | *pp = p; | ||
1267 | p = countp; | ||
1268 | WRITE32(count); | ||
1269 | return 0; | ||
1270 | } | ||
1271 | |||
1272 | /* | ||
1273 | * encode a location element of a fs_locations structure | ||
1274 | */ | ||
1275 | static __be32 nfsd4_encode_fs_location4(struct nfsd4_fs_location *location, | ||
1276 | __be32 **pp, int *buflen) | ||
1277 | { | ||
1278 | __be32 status; | ||
1279 | __be32 *p = *pp; | ||
1280 | |||
1281 | status = nfsd4_encode_components(':', location->hosts, &p, buflen); | ||
1282 | if (status) | ||
1283 | return status; | ||
1284 | status = nfsd4_encode_components('/', location->path, &p, buflen); | ||
1285 | if (status) | ||
1286 | return status; | ||
1287 | *pp = p; | ||
1288 | return 0; | ||
1289 | } | ||
1290 | |||
1291 | /* | ||
1292 | * Return the path to an export point in the pseudo filesystem namespace | ||
1293 | * Returned string is safe to use as long as the caller holds a reference | ||
1294 | * to @exp. | ||
1295 | */ | ||
1296 | static char *nfsd4_path(struct svc_rqst *rqstp, struct svc_export *exp, __be32 *stat) | ||
1297 | { | ||
1298 | struct svc_fh tmp_fh; | ||
1299 | char *path, *rootpath; | ||
1300 | |||
1301 | fh_init(&tmp_fh, NFS4_FHSIZE); | ||
1302 | *stat = exp_pseudoroot(rqstp->rq_client, &tmp_fh, &rqstp->rq_chandle); | ||
1303 | if (*stat) | ||
1304 | return NULL; | ||
1305 | rootpath = tmp_fh.fh_export->ex_path; | ||
1306 | |||
1307 | path = exp->ex_path; | ||
1308 | |||
1309 | if (strncmp(path, rootpath, strlen(rootpath))) { | ||
1310 | printk("nfsd: fs_locations failed;" | ||
1311 | "%s is not contained in %s\n", path, rootpath); | ||
1312 | *stat = nfserr_notsupp; | ||
1313 | return NULL; | ||
1314 | } | ||
1315 | |||
1316 | return path + strlen(rootpath); | ||
1317 | } | ||
1318 | |||
1319 | /* | ||
1320 | * encode a fs_locations structure | ||
1321 | */ | ||
1322 | static __be32 nfsd4_encode_fs_locations(struct svc_rqst *rqstp, | ||
1323 | struct svc_export *exp, | ||
1324 | __be32 **pp, int *buflen) | ||
1325 | { | ||
1326 | __be32 status; | ||
1327 | int i; | ||
1328 | __be32 *p = *pp; | ||
1329 | struct nfsd4_fs_locations *fslocs = &exp->ex_fslocs; | ||
1330 | char *root = nfsd4_path(rqstp, exp, &status); | ||
1331 | |||
1332 | if (status) | ||
1333 | return status; | ||
1334 | status = nfsd4_encode_components('/', root, &p, buflen); | ||
1335 | if (status) | ||
1336 | return status; | ||
1337 | if ((*buflen -= 4) < 0) | ||
1338 | return nfserr_resource; | ||
1339 | WRITE32(fslocs->locations_count); | ||
1340 | for (i=0; i<fslocs->locations_count; i++) { | ||
1341 | status = nfsd4_encode_fs_location4(&fslocs->locations[i], | ||
1342 | &p, buflen); | ||
1343 | if (status) | ||
1344 | return status; | ||
1345 | } | ||
1346 | *pp = p; | ||
1347 | return 0; | ||
1348 | } | ||
1226 | 1349 | ||
1227 | static u32 nfs4_ftypes[16] = { | 1350 | static u32 nfs4_ftypes[16] = { |
1228 | NF4BAD, NF4FIFO, NF4CHR, NF4BAD, | 1351 | NF4BAD, NF4FIFO, NF4CHR, NF4BAD, |
@@ -1231,9 +1354,9 @@ static u32 nfs4_ftypes[16] = { | |||
1231 | NF4SOCK, NF4BAD, NF4LNK, NF4BAD, | 1354 | NF4SOCK, NF4BAD, NF4LNK, NF4BAD, |
1232 | }; | 1355 | }; |
1233 | 1356 | ||
1234 | static int | 1357 | static __be32 |
1235 | nfsd4_encode_name(struct svc_rqst *rqstp, int whotype, uid_t id, int group, | 1358 | nfsd4_encode_name(struct svc_rqst *rqstp, int whotype, uid_t id, int group, |
1236 | u32 **p, int *buflen) | 1359 | __be32 **p, int *buflen) |
1237 | { | 1360 | { |
1238 | int status; | 1361 | int status; |
1239 | 1362 | ||
@@ -1253,25 +1376,44 @@ nfsd4_encode_name(struct svc_rqst *rqstp, int whotype, uid_t id, int group, | |||
1253 | return 0; | 1376 | return 0; |
1254 | } | 1377 | } |
1255 | 1378 | ||
1256 | static inline int | 1379 | static inline __be32 |
1257 | nfsd4_encode_user(struct svc_rqst *rqstp, uid_t uid, u32 **p, int *buflen) | 1380 | nfsd4_encode_user(struct svc_rqst *rqstp, uid_t uid, __be32 **p, int *buflen) |
1258 | { | 1381 | { |
1259 | return nfsd4_encode_name(rqstp, NFS4_ACL_WHO_NAMED, uid, 0, p, buflen); | 1382 | return nfsd4_encode_name(rqstp, NFS4_ACL_WHO_NAMED, uid, 0, p, buflen); |
1260 | } | 1383 | } |
1261 | 1384 | ||
1262 | static inline int | 1385 | static inline __be32 |
1263 | nfsd4_encode_group(struct svc_rqst *rqstp, uid_t gid, u32 **p, int *buflen) | 1386 | nfsd4_encode_group(struct svc_rqst *rqstp, uid_t gid, __be32 **p, int *buflen) |
1264 | { | 1387 | { |
1265 | return nfsd4_encode_name(rqstp, NFS4_ACL_WHO_NAMED, gid, 1, p, buflen); | 1388 | return nfsd4_encode_name(rqstp, NFS4_ACL_WHO_NAMED, gid, 1, p, buflen); |
1266 | } | 1389 | } |
1267 | 1390 | ||
1268 | static inline int | 1391 | static inline __be32 |
1269 | nfsd4_encode_aclname(struct svc_rqst *rqstp, int whotype, uid_t id, int group, | 1392 | nfsd4_encode_aclname(struct svc_rqst *rqstp, int whotype, uid_t id, int group, |
1270 | u32 **p, int *buflen) | 1393 | __be32 **p, int *buflen) |
1271 | { | 1394 | { |
1272 | return nfsd4_encode_name(rqstp, whotype, id, group, p, buflen); | 1395 | return nfsd4_encode_name(rqstp, whotype, id, group, p, buflen); |
1273 | } | 1396 | } |
1274 | 1397 | ||
1398 | #define WORD0_ABSENT_FS_ATTRS (FATTR4_WORD0_FS_LOCATIONS | FATTR4_WORD0_FSID | \ | ||
1399 | FATTR4_WORD0_RDATTR_ERROR) | ||
1400 | #define WORD1_ABSENT_FS_ATTRS FATTR4_WORD1_MOUNTED_ON_FILEID | ||
1401 | |||
1402 | static __be32 fattr_handle_absent_fs(u32 *bmval0, u32 *bmval1, u32 *rdattr_err) | ||
1403 | { | ||
1404 | /* As per referral draft: */ | ||
1405 | if (*bmval0 & ~WORD0_ABSENT_FS_ATTRS || | ||
1406 | *bmval1 & ~WORD1_ABSENT_FS_ATTRS) { | ||
1407 | if (*bmval0 & FATTR4_WORD0_RDATTR_ERROR || | ||
1408 | *bmval0 & FATTR4_WORD0_FS_LOCATIONS) | ||
1409 | *rdattr_err = NFSERR_MOVED; | ||
1410 | else | ||
1411 | return nfserr_moved; | ||
1412 | } | ||
1413 | *bmval0 &= WORD0_ABSENT_FS_ATTRS; | ||
1414 | *bmval1 &= WORD1_ABSENT_FS_ATTRS; | ||
1415 | return 0; | ||
1416 | } | ||
1275 | 1417 | ||
1276 | /* | 1418 | /* |
1277 | * Note: @fhp can be NULL; in this case, we might have to compose the filehandle | 1419 | * Note: @fhp can be NULL; in this case, we might have to compose the filehandle |
@@ -1280,9 +1422,9 @@ nfsd4_encode_aclname(struct svc_rqst *rqstp, int whotype, uid_t id, int group, | |||
1280 | * @countp is the buffer size in _words_; upon successful return this becomes | 1422 | * @countp is the buffer size in _words_; upon successful return this becomes |
1281 | * replaced with the number of words written. | 1423 | * replaced with the number of words written. |
1282 | */ | 1424 | */ |
1283 | int | 1425 | __be32 |
1284 | nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp, | 1426 | nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp, |
1285 | struct dentry *dentry, u32 *buffer, int *countp, u32 *bmval, | 1427 | struct dentry *dentry, __be32 *buffer, int *countp, u32 *bmval, |
1286 | struct svc_rqst *rqstp) | 1428 | struct svc_rqst *rqstp) |
1287 | { | 1429 | { |
1288 | u32 bmval0 = bmval[0]; | 1430 | u32 bmval0 = bmval[0]; |
@@ -1291,11 +1433,13 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp, | |||
1291 | struct svc_fh tempfh; | 1433 | struct svc_fh tempfh; |
1292 | struct kstatfs statfs; | 1434 | struct kstatfs statfs; |
1293 | int buflen = *countp << 2; | 1435 | int buflen = *countp << 2; |
1294 | u32 *attrlenp; | 1436 | __be32 *attrlenp; |
1295 | u32 dummy; | 1437 | u32 dummy; |
1296 | u64 dummy64; | 1438 | u64 dummy64; |
1297 | u32 *p = buffer; | 1439 | u32 rdattr_err = 0; |
1298 | int status; | 1440 | __be32 *p = buffer; |
1441 | __be32 status; | ||
1442 | int err; | ||
1299 | int aclsupport = 0; | 1443 | int aclsupport = 0; |
1300 | struct nfs4_acl *acl = NULL; | 1444 | struct nfs4_acl *acl = NULL; |
1301 | 1445 | ||
@@ -1303,14 +1447,20 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp, | |||
1303 | BUG_ON(bmval0 & ~NFSD_SUPPORTED_ATTRS_WORD0); | 1447 | BUG_ON(bmval0 & ~NFSD_SUPPORTED_ATTRS_WORD0); |
1304 | BUG_ON(bmval1 & ~NFSD_SUPPORTED_ATTRS_WORD1); | 1448 | BUG_ON(bmval1 & ~NFSD_SUPPORTED_ATTRS_WORD1); |
1305 | 1449 | ||
1306 | status = vfs_getattr(exp->ex_mnt, dentry, &stat); | 1450 | if (exp->ex_fslocs.migrated) { |
1307 | if (status) | 1451 | status = fattr_handle_absent_fs(&bmval0, &bmval1, &rdattr_err); |
1452 | if (status) | ||
1453 | goto out; | ||
1454 | } | ||
1455 | |||
1456 | err = vfs_getattr(exp->ex_mnt, dentry, &stat); | ||
1457 | if (err) | ||
1308 | goto out_nfserr; | 1458 | goto out_nfserr; |
1309 | if ((bmval0 & (FATTR4_WORD0_FILES_FREE | FATTR4_WORD0_FILES_TOTAL)) || | 1459 | if ((bmval0 & (FATTR4_WORD0_FILES_FREE | FATTR4_WORD0_FILES_TOTAL)) || |
1310 | (bmval1 & (FATTR4_WORD1_SPACE_AVAIL | FATTR4_WORD1_SPACE_FREE | | 1460 | (bmval1 & (FATTR4_WORD1_SPACE_AVAIL | FATTR4_WORD1_SPACE_FREE | |
1311 | FATTR4_WORD1_SPACE_TOTAL))) { | 1461 | FATTR4_WORD1_SPACE_TOTAL))) { |
1312 | status = vfs_statfs(dentry, &statfs); | 1462 | err = vfs_statfs(dentry, &statfs); |
1313 | if (status) | 1463 | if (err) |
1314 | goto out_nfserr; | 1464 | goto out_nfserr; |
1315 | } | 1465 | } |
1316 | if ((bmval0 & (FATTR4_WORD0_FILEHANDLE | FATTR4_WORD0_FSID)) && !fhp) { | 1466 | if ((bmval0 & (FATTR4_WORD0_FILEHANDLE | FATTR4_WORD0_FSID)) && !fhp) { |
@@ -1322,18 +1472,23 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp, | |||
1322 | } | 1472 | } |
1323 | if (bmval0 & (FATTR4_WORD0_ACL | FATTR4_WORD0_ACLSUPPORT | 1473 | if (bmval0 & (FATTR4_WORD0_ACL | FATTR4_WORD0_ACLSUPPORT |
1324 | | FATTR4_WORD0_SUPPORTED_ATTRS)) { | 1474 | | FATTR4_WORD0_SUPPORTED_ATTRS)) { |
1325 | status = nfsd4_get_nfs4_acl(rqstp, dentry, &acl); | 1475 | err = nfsd4_get_nfs4_acl(rqstp, dentry, &acl); |
1326 | aclsupport = (status == 0); | 1476 | aclsupport = (err == 0); |
1327 | if (bmval0 & FATTR4_WORD0_ACL) { | 1477 | if (bmval0 & FATTR4_WORD0_ACL) { |
1328 | if (status == -EOPNOTSUPP) | 1478 | if (err == -EOPNOTSUPP) |
1329 | bmval0 &= ~FATTR4_WORD0_ACL; | 1479 | bmval0 &= ~FATTR4_WORD0_ACL; |
1330 | else if (status == -EINVAL) { | 1480 | else if (err == -EINVAL) { |
1331 | status = nfserr_attrnotsupp; | 1481 | status = nfserr_attrnotsupp; |
1332 | goto out; | 1482 | goto out; |
1333 | } else if (status != 0) | 1483 | } else if (err != 0) |
1334 | goto out_nfserr; | 1484 | goto out_nfserr; |
1335 | } | 1485 | } |
1336 | } | 1486 | } |
1487 | if (bmval0 & FATTR4_WORD0_FS_LOCATIONS) { | ||
1488 | if (exp->ex_fslocs.locations == NULL) { | ||
1489 | bmval0 &= ~FATTR4_WORD0_FS_LOCATIONS; | ||
1490 | } | ||
1491 | } | ||
1337 | if ((buflen -= 16) < 0) | 1492 | if ((buflen -= 16) < 0) |
1338 | goto out_resource; | 1493 | goto out_resource; |
1339 | 1494 | ||
@@ -1343,12 +1498,15 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp, | |||
1343 | attrlenp = p++; /* to be backfilled later */ | 1498 | attrlenp = p++; /* to be backfilled later */ |
1344 | 1499 | ||
1345 | if (bmval0 & FATTR4_WORD0_SUPPORTED_ATTRS) { | 1500 | if (bmval0 & FATTR4_WORD0_SUPPORTED_ATTRS) { |
1501 | u32 word0 = NFSD_SUPPORTED_ATTRS_WORD0; | ||
1346 | if ((buflen -= 12) < 0) | 1502 | if ((buflen -= 12) < 0) |
1347 | goto out_resource; | 1503 | goto out_resource; |
1504 | if (!aclsupport) | ||
1505 | word0 &= ~FATTR4_WORD0_ACL; | ||
1506 | if (!exp->ex_fslocs.locations) | ||
1507 | word0 &= ~FATTR4_WORD0_FS_LOCATIONS; | ||
1348 | WRITE32(2); | 1508 | WRITE32(2); |
1349 | WRITE32(aclsupport ? | 1509 | WRITE32(word0); |
1350 | NFSD_SUPPORTED_ATTRS_WORD0 : | ||
1351 | NFSD_SUPPORTED_ATTRS_WORD0 & ~FATTR4_WORD0_ACL); | ||
1352 | WRITE32(NFSD_SUPPORTED_ATTRS_WORD1); | 1510 | WRITE32(NFSD_SUPPORTED_ATTRS_WORD1); |
1353 | } | 1511 | } |
1354 | if (bmval0 & FATTR4_WORD0_TYPE) { | 1512 | if (bmval0 & FATTR4_WORD0_TYPE) { |
@@ -1402,7 +1560,10 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp, | |||
1402 | if (bmval0 & FATTR4_WORD0_FSID) { | 1560 | if (bmval0 & FATTR4_WORD0_FSID) { |
1403 | if ((buflen -= 16) < 0) | 1561 | if ((buflen -= 16) < 0) |
1404 | goto out_resource; | 1562 | goto out_resource; |
1405 | if (is_fsid(fhp, rqstp->rq_reffh)) { | 1563 | if (exp->ex_fslocs.migrated) { |
1564 | WRITE64(NFS4_REFERRAL_FSID_MAJOR); | ||
1565 | WRITE64(NFS4_REFERRAL_FSID_MINOR); | ||
1566 | } else if (is_fsid(fhp, rqstp->rq_reffh)) { | ||
1406 | WRITE64((u64)exp->ex_fsid); | 1567 | WRITE64((u64)exp->ex_fsid); |
1407 | WRITE64((u64)0); | 1568 | WRITE64((u64)0); |
1408 | } else { | 1569 | } else { |
@@ -1425,7 +1586,7 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp, | |||
1425 | if (bmval0 & FATTR4_WORD0_RDATTR_ERROR) { | 1586 | if (bmval0 & FATTR4_WORD0_RDATTR_ERROR) { |
1426 | if ((buflen -= 4) < 0) | 1587 | if ((buflen -= 4) < 0) |
1427 | goto out_resource; | 1588 | goto out_resource; |
1428 | WRITE32(0); | 1589 | WRITE32(rdattr_err); |
1429 | } | 1590 | } |
1430 | if (bmval0 & FATTR4_WORD0_ACL) { | 1591 | if (bmval0 & FATTR4_WORD0_ACL) { |
1431 | struct nfs4_ace *ace; | 1592 | struct nfs4_ace *ace; |
@@ -1513,6 +1674,13 @@ out_acl: | |||
1513 | goto out_resource; | 1674 | goto out_resource; |
1514 | WRITE64((u64) statfs.f_files); | 1675 | WRITE64((u64) statfs.f_files); |
1515 | } | 1676 | } |
1677 | if (bmval0 & FATTR4_WORD0_FS_LOCATIONS) { | ||
1678 | status = nfsd4_encode_fs_locations(rqstp, exp, &p, &buflen); | ||
1679 | if (status == nfserr_resource) | ||
1680 | goto out_resource; | ||
1681 | if (status) | ||
1682 | goto out; | ||
1683 | } | ||
1516 | if (bmval0 & FATTR4_WORD0_HOMOGENEOUS) { | 1684 | if (bmval0 & FATTR4_WORD0_HOMOGENEOUS) { |
1517 | if ((buflen -= 4) < 0) | 1685 | if ((buflen -= 4) < 0) |
1518 | goto out_resource; | 1686 | goto out_resource; |
@@ -1536,12 +1704,12 @@ out_acl: | |||
1536 | if (bmval0 & FATTR4_WORD0_MAXREAD) { | 1704 | if (bmval0 & FATTR4_WORD0_MAXREAD) { |
1537 | if ((buflen -= 8) < 0) | 1705 | if ((buflen -= 8) < 0) |
1538 | goto out_resource; | 1706 | goto out_resource; |
1539 | WRITE64((u64) NFSSVC_MAXBLKSIZE); | 1707 | WRITE64((u64) svc_max_payload(rqstp)); |
1540 | } | 1708 | } |
1541 | if (bmval0 & FATTR4_WORD0_MAXWRITE) { | 1709 | if (bmval0 & FATTR4_WORD0_MAXWRITE) { |
1542 | if ((buflen -= 8) < 0) | 1710 | if ((buflen -= 8) < 0) |
1543 | goto out_resource; | 1711 | goto out_resource; |
1544 | WRITE64((u64) NFSSVC_MAXBLKSIZE); | 1712 | WRITE64((u64) svc_max_payload(rqstp)); |
1545 | } | 1713 | } |
1546 | if (bmval1 & FATTR4_WORD1_MODE) { | 1714 | if (bmval1 & FATTR4_WORD1_MODE) { |
1547 | if ((buflen -= 4) < 0) | 1715 | if ((buflen -= 4) < 0) |
@@ -1652,7 +1820,7 @@ out: | |||
1652 | fh_put(&tempfh); | 1820 | fh_put(&tempfh); |
1653 | return status; | 1821 | return status; |
1654 | out_nfserr: | 1822 | out_nfserr: |
1655 | status = nfserrno(status); | 1823 | status = nfserrno(err); |
1656 | goto out; | 1824 | goto out; |
1657 | out_resource: | 1825 | out_resource: |
1658 | *countp = 0; | 1826 | *countp = 0; |
@@ -1663,13 +1831,13 @@ out_serverfault: | |||
1663 | goto out; | 1831 | goto out; |
1664 | } | 1832 | } |
1665 | 1833 | ||
1666 | static int | 1834 | static __be32 |
1667 | nfsd4_encode_dirent_fattr(struct nfsd4_readdir *cd, | 1835 | nfsd4_encode_dirent_fattr(struct nfsd4_readdir *cd, |
1668 | const char *name, int namlen, u32 *p, int *buflen) | 1836 | const char *name, int namlen, __be32 *p, int *buflen) |
1669 | { | 1837 | { |
1670 | struct svc_export *exp = cd->rd_fhp->fh_export; | 1838 | struct svc_export *exp = cd->rd_fhp->fh_export; |
1671 | struct dentry *dentry; | 1839 | struct dentry *dentry; |
1672 | int nfserr; | 1840 | __be32 nfserr; |
1673 | 1841 | ||
1674 | dentry = lookup_one_len(name, cd->rd_fhp->fh_dentry, namlen); | 1842 | dentry = lookup_one_len(name, cd->rd_fhp->fh_dentry, namlen); |
1675 | if (IS_ERR(dentry)) | 1843 | if (IS_ERR(dentry)) |
@@ -1698,10 +1866,10 @@ out_put: | |||
1698 | return nfserr; | 1866 | return nfserr; |
1699 | } | 1867 | } |
1700 | 1868 | ||
1701 | static u32 * | 1869 | static __be32 * |
1702 | nfsd4_encode_rdattr_error(u32 *p, int buflen, int nfserr) | 1870 | nfsd4_encode_rdattr_error(__be32 *p, int buflen, __be32 nfserr) |
1703 | { | 1871 | { |
1704 | u32 *attrlenp; | 1872 | __be32 *attrlenp; |
1705 | 1873 | ||
1706 | if (buflen < 6) | 1874 | if (buflen < 6) |
1707 | return NULL; | 1875 | return NULL; |
@@ -1721,8 +1889,8 @@ nfsd4_encode_dirent(struct readdir_cd *ccd, const char *name, int namlen, | |||
1721 | { | 1889 | { |
1722 | struct nfsd4_readdir *cd = container_of(ccd, struct nfsd4_readdir, common); | 1890 | struct nfsd4_readdir *cd = container_of(ccd, struct nfsd4_readdir, common); |
1723 | int buflen; | 1891 | int buflen; |
1724 | u32 *p = cd->buffer; | 1892 | __be32 *p = cd->buffer; |
1725 | int nfserr = nfserr_toosmall; | 1893 | __be32 nfserr = nfserr_toosmall; |
1726 | 1894 | ||
1727 | /* In nfsv4, "." and ".." never make it onto the wire.. */ | 1895 | /* In nfsv4, "." and ".." never make it onto the wire.. */ |
1728 | if (name && isdotent(name, namlen)) { | 1896 | if (name && isdotent(name, namlen)) { |
@@ -1778,7 +1946,7 @@ fail: | |||
1778 | } | 1946 | } |
1779 | 1947 | ||
1780 | static void | 1948 | static void |
1781 | nfsd4_encode_access(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_access *access) | 1949 | nfsd4_encode_access(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_access *access) |
1782 | { | 1950 | { |
1783 | ENCODE_HEAD; | 1951 | ENCODE_HEAD; |
1784 | 1952 | ||
@@ -1791,7 +1959,7 @@ nfsd4_encode_access(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_acc | |||
1791 | } | 1959 | } |
1792 | 1960 | ||
1793 | static void | 1961 | static void |
1794 | nfsd4_encode_close(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_close *close) | 1962 | nfsd4_encode_close(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_close *close) |
1795 | { | 1963 | { |
1796 | ENCODE_SEQID_OP_HEAD; | 1964 | ENCODE_SEQID_OP_HEAD; |
1797 | 1965 | ||
@@ -1806,7 +1974,7 @@ nfsd4_encode_close(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_clos | |||
1806 | 1974 | ||
1807 | 1975 | ||
1808 | static void | 1976 | static void |
1809 | nfsd4_encode_commit(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_commit *commit) | 1977 | nfsd4_encode_commit(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_commit *commit) |
1810 | { | 1978 | { |
1811 | ENCODE_HEAD; | 1979 | ENCODE_HEAD; |
1812 | 1980 | ||
@@ -1818,7 +1986,7 @@ nfsd4_encode_commit(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_com | |||
1818 | } | 1986 | } |
1819 | 1987 | ||
1820 | static void | 1988 | static void |
1821 | nfsd4_encode_create(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_create *create) | 1989 | nfsd4_encode_create(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_create *create) |
1822 | { | 1990 | { |
1823 | ENCODE_HEAD; | 1991 | ENCODE_HEAD; |
1824 | 1992 | ||
@@ -1832,8 +2000,8 @@ nfsd4_encode_create(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_cre | |||
1832 | } | 2000 | } |
1833 | } | 2001 | } |
1834 | 2002 | ||
1835 | static int | 2003 | static __be32 |
1836 | nfsd4_encode_getattr(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_getattr *getattr) | 2004 | nfsd4_encode_getattr(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_getattr *getattr) |
1837 | { | 2005 | { |
1838 | struct svc_fh *fhp = getattr->ga_fhp; | 2006 | struct svc_fh *fhp = getattr->ga_fhp; |
1839 | int buflen; | 2007 | int buflen; |
@@ -1845,14 +2013,13 @@ nfsd4_encode_getattr(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_ge | |||
1845 | nfserr = nfsd4_encode_fattr(fhp, fhp->fh_export, fhp->fh_dentry, | 2013 | nfserr = nfsd4_encode_fattr(fhp, fhp->fh_export, fhp->fh_dentry, |
1846 | resp->p, &buflen, getattr->ga_bmval, | 2014 | resp->p, &buflen, getattr->ga_bmval, |
1847 | resp->rqstp); | 2015 | resp->rqstp); |
1848 | |||
1849 | if (!nfserr) | 2016 | if (!nfserr) |
1850 | resp->p += buflen; | 2017 | resp->p += buflen; |
1851 | return nfserr; | 2018 | return nfserr; |
1852 | } | 2019 | } |
1853 | 2020 | ||
1854 | static void | 2021 | static void |
1855 | nfsd4_encode_getfh(struct nfsd4_compoundres *resp, int nfserr, struct svc_fh *fhp) | 2022 | nfsd4_encode_getfh(struct nfsd4_compoundres *resp, __be32 nfserr, struct svc_fh *fhp) |
1856 | { | 2023 | { |
1857 | unsigned int len; | 2024 | unsigned int len; |
1858 | ENCODE_HEAD; | 2025 | ENCODE_HEAD; |
@@ -1892,7 +2059,7 @@ nfsd4_encode_lock_denied(struct nfsd4_compoundres *resp, struct nfsd4_lock_denie | |||
1892 | } | 2059 | } |
1893 | 2060 | ||
1894 | static void | 2061 | static void |
1895 | nfsd4_encode_lock(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_lock *lock) | 2062 | nfsd4_encode_lock(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_lock *lock) |
1896 | { | 2063 | { |
1897 | ENCODE_SEQID_OP_HEAD; | 2064 | ENCODE_SEQID_OP_HEAD; |
1898 | 2065 | ||
@@ -1908,14 +2075,14 @@ nfsd4_encode_lock(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_lock | |||
1908 | } | 2075 | } |
1909 | 2076 | ||
1910 | static void | 2077 | static void |
1911 | nfsd4_encode_lockt(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_lockt *lockt) | 2078 | nfsd4_encode_lockt(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_lockt *lockt) |
1912 | { | 2079 | { |
1913 | if (nfserr == nfserr_denied) | 2080 | if (nfserr == nfserr_denied) |
1914 | nfsd4_encode_lock_denied(resp, &lockt->lt_denied); | 2081 | nfsd4_encode_lock_denied(resp, &lockt->lt_denied); |
1915 | } | 2082 | } |
1916 | 2083 | ||
1917 | static void | 2084 | static void |
1918 | nfsd4_encode_locku(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_locku *locku) | 2085 | nfsd4_encode_locku(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_locku *locku) |
1919 | { | 2086 | { |
1920 | ENCODE_SEQID_OP_HEAD; | 2087 | ENCODE_SEQID_OP_HEAD; |
1921 | 2088 | ||
@@ -1931,7 +2098,7 @@ nfsd4_encode_locku(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_lock | |||
1931 | 2098 | ||
1932 | 2099 | ||
1933 | static void | 2100 | static void |
1934 | nfsd4_encode_link(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_link *link) | 2101 | nfsd4_encode_link(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_link *link) |
1935 | { | 2102 | { |
1936 | ENCODE_HEAD; | 2103 | ENCODE_HEAD; |
1937 | 2104 | ||
@@ -1944,7 +2111,7 @@ nfsd4_encode_link(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_link | |||
1944 | 2111 | ||
1945 | 2112 | ||
1946 | static void | 2113 | static void |
1947 | nfsd4_encode_open(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_open *open) | 2114 | nfsd4_encode_open(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open *open) |
1948 | { | 2115 | { |
1949 | ENCODE_SEQID_OP_HEAD; | 2116 | ENCODE_SEQID_OP_HEAD; |
1950 | 2117 | ||
@@ -2009,7 +2176,7 @@ out: | |||
2009 | } | 2176 | } |
2010 | 2177 | ||
2011 | static void | 2178 | static void |
2012 | nfsd4_encode_open_confirm(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_open_confirm *oc) | 2179 | nfsd4_encode_open_confirm(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open_confirm *oc) |
2013 | { | 2180 | { |
2014 | ENCODE_SEQID_OP_HEAD; | 2181 | ENCODE_SEQID_OP_HEAD; |
2015 | 2182 | ||
@@ -2024,7 +2191,7 @@ nfsd4_encode_open_confirm(struct nfsd4_compoundres *resp, int nfserr, struct nfs | |||
2024 | } | 2191 | } |
2025 | 2192 | ||
2026 | static void | 2193 | static void |
2027 | nfsd4_encode_open_downgrade(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_open_downgrade *od) | 2194 | nfsd4_encode_open_downgrade(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open_downgrade *od) |
2028 | { | 2195 | { |
2029 | ENCODE_SEQID_OP_HEAD; | 2196 | ENCODE_SEQID_OP_HEAD; |
2030 | 2197 | ||
@@ -2038,8 +2205,9 @@ nfsd4_encode_open_downgrade(struct nfsd4_compoundres *resp, int nfserr, struct n | |||
2038 | ENCODE_SEQID_OP_TAIL(od->od_stateowner); | 2205 | ENCODE_SEQID_OP_TAIL(od->od_stateowner); |
2039 | } | 2206 | } |
2040 | 2207 | ||
2041 | static int | 2208 | static __be32 |
2042 | nfsd4_encode_read(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_read *read) | 2209 | nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr, |
2210 | struct nfsd4_read *read) | ||
2043 | { | 2211 | { |
2044 | u32 eof; | 2212 | u32 eof; |
2045 | int v, pn; | 2213 | int v, pn; |
@@ -2054,31 +2222,33 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_read | |||
2054 | 2222 | ||
2055 | RESERVE_SPACE(8); /* eof flag and byte count */ | 2223 | RESERVE_SPACE(8); /* eof flag and byte count */ |
2056 | 2224 | ||
2057 | maxcount = NFSSVC_MAXBLKSIZE; | 2225 | maxcount = svc_max_payload(resp->rqstp); |
2058 | if (maxcount > read->rd_length) | 2226 | if (maxcount > read->rd_length) |
2059 | maxcount = read->rd_length; | 2227 | maxcount = read->rd_length; |
2060 | 2228 | ||
2061 | len = maxcount; | 2229 | len = maxcount; |
2062 | v = 0; | 2230 | v = 0; |
2063 | while (len > 0) { | 2231 | while (len > 0) { |
2064 | pn = resp->rqstp->rq_resused; | 2232 | pn = resp->rqstp->rq_resused++; |
2065 | svc_take_page(resp->rqstp); | 2233 | resp->rqstp->rq_vec[v].iov_base = |
2066 | read->rd_iov[v].iov_base = page_address(resp->rqstp->rq_respages[pn]); | 2234 | page_address(resp->rqstp->rq_respages[pn]); |
2067 | read->rd_iov[v].iov_len = len < PAGE_SIZE ? len : PAGE_SIZE; | 2235 | resp->rqstp->rq_vec[v].iov_len = |
2236 | len < PAGE_SIZE ? len : PAGE_SIZE; | ||
2068 | v++; | 2237 | v++; |
2069 | len -= PAGE_SIZE; | 2238 | len -= PAGE_SIZE; |
2070 | } | 2239 | } |
2071 | read->rd_vlen = v; | 2240 | read->rd_vlen = v; |
2072 | 2241 | ||
2073 | nfserr = nfsd_read(read->rd_rqstp, read->rd_fhp, read->rd_filp, | 2242 | nfserr = nfsd_read(read->rd_rqstp, read->rd_fhp, read->rd_filp, |
2074 | read->rd_offset, read->rd_iov, read->rd_vlen, | 2243 | read->rd_offset, resp->rqstp->rq_vec, read->rd_vlen, |
2075 | &maxcount); | 2244 | &maxcount); |
2076 | 2245 | ||
2077 | if (nfserr == nfserr_symlink) | 2246 | if (nfserr == nfserr_symlink) |
2078 | nfserr = nfserr_inval; | 2247 | nfserr = nfserr_inval; |
2079 | if (nfserr) | 2248 | if (nfserr) |
2080 | return nfserr; | 2249 | return nfserr; |
2081 | eof = (read->rd_offset + maxcount >= read->rd_fhp->fh_dentry->d_inode->i_size); | 2250 | eof = (read->rd_offset + maxcount >= |
2251 | read->rd_fhp->fh_dentry->d_inode->i_size); | ||
2082 | 2252 | ||
2083 | WRITE32(eof); | 2253 | WRITE32(eof); |
2084 | WRITE32(maxcount); | 2254 | WRITE32(maxcount); |
@@ -2088,7 +2258,6 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_read | |||
2088 | resp->xbuf->page_len = maxcount; | 2258 | resp->xbuf->page_len = maxcount; |
2089 | 2259 | ||
2090 | /* Use rest of head for padding and remaining ops: */ | 2260 | /* Use rest of head for padding and remaining ops: */ |
2091 | resp->rqstp->rq_restailpage = 0; | ||
2092 | resp->xbuf->tail[0].iov_base = p; | 2261 | resp->xbuf->tail[0].iov_base = p; |
2093 | resp->xbuf->tail[0].iov_len = 0; | 2262 | resp->xbuf->tail[0].iov_len = 0; |
2094 | if (maxcount&3) { | 2263 | if (maxcount&3) { |
@@ -2101,8 +2270,8 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_read | |||
2101 | return 0; | 2270 | return 0; |
2102 | } | 2271 | } |
2103 | 2272 | ||
2104 | static int | 2273 | static __be32 |
2105 | nfsd4_encode_readlink(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_readlink *readlink) | 2274 | nfsd4_encode_readlink(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_readlink *readlink) |
2106 | { | 2275 | { |
2107 | int maxcount; | 2276 | int maxcount; |
2108 | char *page; | 2277 | char *page; |
@@ -2113,8 +2282,7 @@ nfsd4_encode_readlink(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_r | |||
2113 | if (resp->xbuf->page_len) | 2282 | if (resp->xbuf->page_len) |
2114 | return nfserr_resource; | 2283 | return nfserr_resource; |
2115 | 2284 | ||
2116 | svc_take_page(resp->rqstp); | 2285 | page = page_address(resp->rqstp->rq_respages[resp->rqstp->rq_resused++]); |
2117 | page = page_address(resp->rqstp->rq_respages[resp->rqstp->rq_resused-1]); | ||
2118 | 2286 | ||
2119 | maxcount = PAGE_SIZE; | 2287 | maxcount = PAGE_SIZE; |
2120 | RESERVE_SPACE(4); | 2288 | RESERVE_SPACE(4); |
@@ -2138,7 +2306,6 @@ nfsd4_encode_readlink(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_r | |||
2138 | resp->xbuf->page_len = maxcount; | 2306 | resp->xbuf->page_len = maxcount; |
2139 | 2307 | ||
2140 | /* Use rest of head for padding and remaining ops: */ | 2308 | /* Use rest of head for padding and remaining ops: */ |
2141 | resp->rqstp->rq_restailpage = 0; | ||
2142 | resp->xbuf->tail[0].iov_base = p; | 2309 | resp->xbuf->tail[0].iov_base = p; |
2143 | resp->xbuf->tail[0].iov_len = 0; | 2310 | resp->xbuf->tail[0].iov_len = 0; |
2144 | if (maxcount&3) { | 2311 | if (maxcount&3) { |
@@ -2151,12 +2318,12 @@ nfsd4_encode_readlink(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_r | |||
2151 | return 0; | 2318 | return 0; |
2152 | } | 2319 | } |
2153 | 2320 | ||
2154 | static int | 2321 | static __be32 |
2155 | nfsd4_encode_readdir(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_readdir *readdir) | 2322 | nfsd4_encode_readdir(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_readdir *readdir) |
2156 | { | 2323 | { |
2157 | int maxcount; | 2324 | int maxcount; |
2158 | loff_t offset; | 2325 | loff_t offset; |
2159 | u32 *page, *savep, *tailbase; | 2326 | __be32 *page, *savep, *tailbase; |
2160 | ENCODE_HEAD; | 2327 | ENCODE_HEAD; |
2161 | 2328 | ||
2162 | if (nfserr) | 2329 | if (nfserr) |
@@ -2189,8 +2356,7 @@ nfsd4_encode_readdir(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_re | |||
2189 | goto err_no_verf; | 2356 | goto err_no_verf; |
2190 | } | 2357 | } |
2191 | 2358 | ||
2192 | svc_take_page(resp->rqstp); | 2359 | page = page_address(resp->rqstp->rq_respages[resp->rqstp->rq_resused++]); |
2193 | page = page_address(resp->rqstp->rq_respages[resp->rqstp->rq_resused-1]); | ||
2194 | readdir->common.err = 0; | 2360 | readdir->common.err = 0; |
2195 | readdir->buflen = maxcount; | 2361 | readdir->buflen = maxcount; |
2196 | readdir->buffer = page; | 2362 | readdir->buffer = page; |
@@ -2215,10 +2381,10 @@ nfsd4_encode_readdir(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_re | |||
2215 | p = readdir->buffer; | 2381 | p = readdir->buffer; |
2216 | *p++ = 0; /* no more entries */ | 2382 | *p++ = 0; /* no more entries */ |
2217 | *p++ = htonl(readdir->common.err == nfserr_eof); | 2383 | *p++ = htonl(readdir->common.err == nfserr_eof); |
2218 | resp->xbuf->page_len = ((char*)p) - (char*)page_address(resp->rqstp->rq_respages[resp->rqstp->rq_resused-1]); | 2384 | resp->xbuf->page_len = ((char*)p) - (char*)page_address( |
2385 | resp->rqstp->rq_respages[resp->rqstp->rq_resused-1]); | ||
2219 | 2386 | ||
2220 | /* Use rest of head for padding and remaining ops: */ | 2387 | /* Use rest of head for padding and remaining ops: */ |
2221 | resp->rqstp->rq_restailpage = 0; | ||
2222 | resp->xbuf->tail[0].iov_base = tailbase; | 2388 | resp->xbuf->tail[0].iov_base = tailbase; |
2223 | resp->xbuf->tail[0].iov_len = 0; | 2389 | resp->xbuf->tail[0].iov_len = 0; |
2224 | resp->p = resp->xbuf->tail[0].iov_base; | 2390 | resp->p = resp->xbuf->tail[0].iov_base; |
@@ -2232,7 +2398,7 @@ err_no_verf: | |||
2232 | } | 2398 | } |
2233 | 2399 | ||
2234 | static void | 2400 | static void |
2235 | nfsd4_encode_remove(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_remove *remove) | 2401 | nfsd4_encode_remove(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_remove *remove) |
2236 | { | 2402 | { |
2237 | ENCODE_HEAD; | 2403 | ENCODE_HEAD; |
2238 | 2404 | ||
@@ -2244,7 +2410,7 @@ nfsd4_encode_remove(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_rem | |||
2244 | } | 2410 | } |
2245 | 2411 | ||
2246 | static void | 2412 | static void |
2247 | nfsd4_encode_rename(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_rename *rename) | 2413 | nfsd4_encode_rename(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_rename *rename) |
2248 | { | 2414 | { |
2249 | ENCODE_HEAD; | 2415 | ENCODE_HEAD; |
2250 | 2416 | ||
@@ -2261,7 +2427,7 @@ nfsd4_encode_rename(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_ren | |||
2261 | * regardless of the error status. | 2427 | * regardless of the error status. |
2262 | */ | 2428 | */ |
2263 | static void | 2429 | static void |
2264 | nfsd4_encode_setattr(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_setattr *setattr) | 2430 | nfsd4_encode_setattr(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_setattr *setattr) |
2265 | { | 2431 | { |
2266 | ENCODE_HEAD; | 2432 | ENCODE_HEAD; |
2267 | 2433 | ||
@@ -2280,7 +2446,7 @@ nfsd4_encode_setattr(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_se | |||
2280 | } | 2446 | } |
2281 | 2447 | ||
2282 | static void | 2448 | static void |
2283 | nfsd4_encode_setclientid(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_setclientid *scd) | 2449 | nfsd4_encode_setclientid(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_setclientid *scd) |
2284 | { | 2450 | { |
2285 | ENCODE_HEAD; | 2451 | ENCODE_HEAD; |
2286 | 2452 | ||
@@ -2299,7 +2465,7 @@ nfsd4_encode_setclientid(struct nfsd4_compoundres *resp, int nfserr, struct nfsd | |||
2299 | } | 2465 | } |
2300 | 2466 | ||
2301 | static void | 2467 | static void |
2302 | nfsd4_encode_write(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_write *write) | 2468 | nfsd4_encode_write(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_write *write) |
2303 | { | 2469 | { |
2304 | ENCODE_HEAD; | 2470 | ENCODE_HEAD; |
2305 | 2471 | ||
@@ -2315,7 +2481,7 @@ nfsd4_encode_write(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_writ | |||
2315 | void | 2481 | void |
2316 | nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op) | 2482 | nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op) |
2317 | { | 2483 | { |
2318 | u32 *statp; | 2484 | __be32 *statp; |
2319 | ENCODE_HEAD; | 2485 | ENCODE_HEAD; |
2320 | 2486 | ||
2321 | RESERVE_SPACE(8); | 2487 | RESERVE_SPACE(8); |
@@ -2453,7 +2619,7 @@ nfsd4_encode_replay(struct nfsd4_compoundres *resp, struct nfsd4_op *op) | |||
2453 | */ | 2619 | */ |
2454 | 2620 | ||
2455 | int | 2621 | int |
2456 | nfs4svc_encode_voidres(struct svc_rqst *rqstp, u32 *p, void *dummy) | 2622 | nfs4svc_encode_voidres(struct svc_rqst *rqstp, __be32 *p, void *dummy) |
2457 | { | 2623 | { |
2458 | return xdr_ressize_check(rqstp, p); | 2624 | return xdr_ressize_check(rqstp, p); |
2459 | } | 2625 | } |
@@ -2475,9 +2641,9 @@ void nfsd4_release_compoundargs(struct nfsd4_compoundargs *args) | |||
2475 | } | 2641 | } |
2476 | 2642 | ||
2477 | int | 2643 | int |
2478 | nfs4svc_decode_compoundargs(struct svc_rqst *rqstp, u32 *p, struct nfsd4_compoundargs *args) | 2644 | nfs4svc_decode_compoundargs(struct svc_rqst *rqstp, __be32 *p, struct nfsd4_compoundargs *args) |
2479 | { | 2645 | { |
2480 | int status; | 2646 | __be32 status; |
2481 | 2647 | ||
2482 | args->p = p; | 2648 | args->p = p; |
2483 | args->end = rqstp->rq_arg.head[0].iov_base + rqstp->rq_arg.head[0].iov_len; | 2649 | args->end = rqstp->rq_arg.head[0].iov_base + rqstp->rq_arg.head[0].iov_len; |
@@ -2496,7 +2662,7 @@ nfs4svc_decode_compoundargs(struct svc_rqst *rqstp, u32 *p, struct nfsd4_compoun | |||
2496 | } | 2662 | } |
2497 | 2663 | ||
2498 | int | 2664 | int |
2499 | nfs4svc_encode_compoundres(struct svc_rqst *rqstp, u32 *p, struct nfsd4_compoundres *resp) | 2665 | nfs4svc_encode_compoundres(struct svc_rqst *rqstp, __be32 *p, struct nfsd4_compoundres *resp) |
2500 | { | 2666 | { |
2501 | /* | 2667 | /* |
2502 | * All that remains is to write the tag and operation count... | 2668 | * All that remains is to write the tag and operation count... |