aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd/nfs4xdr.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfsd/nfs4xdr.c')
-rw-r--r--fs/nfsd/nfs4xdr.c454
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
63static int 63/*
64check_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
71static __be32
72check_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; \
93out: \ 101out: \
@@ -136,13 +144,13 @@ xdr_error: \
136 } \ 144 } \
137} while (0) 145} while (0)
138 146
139static u32 *read_buf(struct nfsd4_compoundargs *argp, int nbytes) 147static __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
192static char *savemem(struct nfsd4_compoundargs *argp, u32 *p, int nbytes) 200static 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
212static int 220static __be32
213nfsd4_decode_bitmap(struct nfsd4_compoundargs *argp, u32 *bmval) 221nfsd4_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
235static int 243static __be32
236nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, struct iattr *iattr, 244nfsd4_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
408out_nfserr: 417out_nfserr:
409 status = nfserrno(status); 418 status = nfserrno(host_err);
410 goto out; 419 goto out;
411} 420}
412 421
413static int 422static __be32
414nfsd4_decode_access(struct nfsd4_compoundargs *argp, struct nfsd4_access *access) 423nfsd4_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
424static int 433static __be32
425nfsd4_decode_close(struct nfsd4_compoundargs *argp, struct nfsd4_close *close) 434nfsd4_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
439static int 448static __be32
440nfsd4_decode_commit(struct nfsd4_compoundargs *argp, struct nfsd4_commit *commit) 449nfsd4_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
451static int 460static __be32
452nfsd4_decode_create(struct nfsd4_compoundargs *argp, struct nfsd4_create *create) 461nfsd4_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
491static inline int 500static inline __be32
492nfsd4_decode_delegreturn(struct nfsd4_compoundargs *argp, struct nfsd4_delegreturn *dr) 501nfsd4_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
503static inline int 512static inline __be32
504nfsd4_decode_getattr(struct nfsd4_compoundargs *argp, struct nfsd4_getattr *getattr) 513nfsd4_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
509static int 518static __be32
510nfsd4_decode_link(struct nfsd4_compoundargs *argp, struct nfsd4_link *link) 519nfsd4_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
524static int 533static __be32
525nfsd4_decode_lock(struct nfsd4_compoundargs *argp, struct nfsd4_lock *lock) 534nfsd4_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
563static int 572static __be32
564nfsd4_decode_lockt(struct nfsd4_compoundargs *argp, struct nfsd4_lockt *lockt) 573nfsd4_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
582static int 591static __be32
583nfsd4_decode_locku(struct nfsd4_compoundargs *argp, struct nfsd4_locku *locku) 592nfsd4_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
601static int 610static __be32
602nfsd4_decode_lookup(struct nfsd4_compoundargs *argp, struct nfsd4_lookup *lookup) 611nfsd4_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
616static int 625static __be32
617nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open) 626nfsd4_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
694static int 703static __be32
695nfsd4_decode_open_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_open_confirm *open_conf) 704nfsd4_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
708static int 717static __be32
709nfsd4_decode_open_downgrade(struct nfsd4_compoundargs *argp, struct nfsd4_open_downgrade *open_down) 718nfsd4_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
724static int 733static __be32
725nfsd4_decode_putfh(struct nfsd4_compoundargs *argp, struct nfsd4_putfh *putfh) 734nfsd4_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
739static int 748static __be32
740nfsd4_decode_read(struct nfsd4_compoundargs *argp, struct nfsd4_read *read) 749nfsd4_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
753static int 762static __be32
754nfsd4_decode_readdir(struct nfsd4_compoundargs *argp, struct nfsd4_readdir *readdir) 763nfsd4_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
769static int 778static __be32
770nfsd4_decode_remove(struct nfsd4_compoundargs *argp, struct nfsd4_remove *remove) 779nfsd4_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
784static int 793static __be32
785nfsd4_decode_rename(struct nfsd4_compoundargs *argp, struct nfsd4_rename *rename) 794nfsd4_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
804static int 813static __be32
805nfsd4_decode_renew(struct nfsd4_compoundargs *argp, clientid_t *clientid) 814nfsd4_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
815static int 824static __be32
816nfsd4_decode_setattr(struct nfsd4_compoundargs *argp, struct nfsd4_setattr *setattr) 825nfsd4_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
829static int 838static __be32
830nfsd4_decode_setclientid(struct nfsd4_compoundargs *argp, struct nfsd4_setclientid *setclientid) 839nfsd4_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
854static int 863static __be32
855nfsd4_decode_setclientid_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_setclientid_confirm *scd_c) 864nfsd4_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 */
867static int 876static __be32
868nfsd4_decode_verify(struct nfsd4_compoundargs *argp, struct nfsd4_verify *verify) 877nfsd4_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
903static int 912static __be32
904nfsd4_decode_write(struct nfsd4_compoundargs *argp, struct nfsd4_write *write) 913nfsd4_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
954static int 963static __be32
955nfsd4_decode_release_lockowner(struct nfsd4_compoundargs *argp, struct nfsd4_release_lockowner *rlockowner) 964nfsd4_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
968static int 977static __be32
969nfsd4_decode_compound(struct nfsd4_compoundargs *argp) 978nfsd4_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 */
1238static __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 */
1275static __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 */
1296static 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 */
1322static __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
1227static u32 nfs4_ftypes[16] = { 1350static 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
1234static int 1357static __be32
1235nfsd4_encode_name(struct svc_rqst *rqstp, int whotype, uid_t id, int group, 1358nfsd4_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
1256static inline int 1379static inline __be32
1257nfsd4_encode_user(struct svc_rqst *rqstp, uid_t uid, u32 **p, int *buflen) 1380nfsd4_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
1262static inline int 1385static inline __be32
1263nfsd4_encode_group(struct svc_rqst *rqstp, uid_t gid, u32 **p, int *buflen) 1386nfsd4_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
1268static inline int 1391static inline __be32
1269nfsd4_encode_aclname(struct svc_rqst *rqstp, int whotype, uid_t id, int group, 1392nfsd4_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
1402static __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 */
1283int 1425__be32
1284nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp, 1426nfsd4_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;
1654out_nfserr: 1822out_nfserr:
1655 status = nfserrno(status); 1823 status = nfserrno(err);
1656 goto out; 1824 goto out;
1657out_resource: 1825out_resource:
1658 *countp = 0; 1826 *countp = 0;
@@ -1663,13 +1831,13 @@ out_serverfault:
1663 goto out; 1831 goto out;
1664} 1832}
1665 1833
1666static int 1834static __be32
1667nfsd4_encode_dirent_fattr(struct nfsd4_readdir *cd, 1835nfsd4_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
1701static u32 * 1869static __be32 *
1702nfsd4_encode_rdattr_error(u32 *p, int buflen, int nfserr) 1870nfsd4_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
1780static void 1948static void
1781nfsd4_encode_access(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_access *access) 1949nfsd4_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
1793static void 1961static void
1794nfsd4_encode_close(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_close *close) 1962nfsd4_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
1808static void 1976static void
1809nfsd4_encode_commit(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_commit *commit) 1977nfsd4_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
1820static void 1988static void
1821nfsd4_encode_create(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_create *create) 1989nfsd4_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
1835static int 2003static __be32
1836nfsd4_encode_getattr(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_getattr *getattr) 2004nfsd4_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
1854static void 2021static void
1855nfsd4_encode_getfh(struct nfsd4_compoundres *resp, int nfserr, struct svc_fh *fhp) 2022nfsd4_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
1894static void 2061static void
1895nfsd4_encode_lock(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_lock *lock) 2062nfsd4_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
1910static void 2077static void
1911nfsd4_encode_lockt(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_lockt *lockt) 2078nfsd4_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
1917static void 2084static void
1918nfsd4_encode_locku(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_locku *locku) 2085nfsd4_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
1933static void 2100static void
1934nfsd4_encode_link(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_link *link) 2101nfsd4_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
1946static void 2113static void
1947nfsd4_encode_open(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_open *open) 2114nfsd4_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
2011static void 2178static void
2012nfsd4_encode_open_confirm(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_open_confirm *oc) 2179nfsd4_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
2026static void 2193static void
2027nfsd4_encode_open_downgrade(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_open_downgrade *od) 2194nfsd4_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
2041static int 2208static __be32
2042nfsd4_encode_read(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_read *read) 2209nfsd4_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
2104static int 2273static __be32
2105nfsd4_encode_readlink(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_readlink *readlink) 2274nfsd4_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
2154static int 2321static __be32
2155nfsd4_encode_readdir(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_readdir *readdir) 2322nfsd4_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
2234static void 2400static void
2235nfsd4_encode_remove(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_remove *remove) 2401nfsd4_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
2246static void 2412static void
2247nfsd4_encode_rename(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_rename *rename) 2413nfsd4_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 */
2263static void 2429static void
2264nfsd4_encode_setattr(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_setattr *setattr) 2430nfsd4_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
2282static void 2448static void
2283nfsd4_encode_setclientid(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_setclientid *scd) 2449nfsd4_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
2301static void 2467static void
2302nfsd4_encode_write(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_write *write) 2468nfsd4_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
2315void 2481void
2316nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op) 2482nfsd4_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
2455int 2621int
2456nfs4svc_encode_voidres(struct svc_rqst *rqstp, u32 *p, void *dummy) 2622nfs4svc_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
2477int 2643int
2478nfs4svc_decode_compoundargs(struct svc_rqst *rqstp, u32 *p, struct nfsd4_compoundargs *args) 2644nfs4svc_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
2498int 2664int
2499nfs4svc_encode_compoundres(struct svc_rqst *rqstp, u32 *p, struct nfsd4_compoundres *resp) 2665nfs4svc_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...