]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - fs/nfsd/nfs4xdr.c
NFSD: Added TEST_STATEID operation
[karo-tx-linux.git] / fs / nfsd / nfs4xdr.c
1 /*
2  *  Server-side XDR for NFSv4
3  *
4  *  Copyright (c) 2002 The Regents of the University of Michigan.
5  *  All rights reserved.
6  *
7  *  Kendrick Smith <kmsmith@umich.edu>
8  *  Andy Adamson   <andros@umich.edu>
9  *
10  *  Redistribution and use in source and binary forms, with or without
11  *  modification, are permitted provided that the following conditions
12  *  are met:
13  *
14  *  1. Redistributions of source code must retain the above copyright
15  *     notice, this list of conditions and the following disclaimer.
16  *  2. Redistributions in binary form must reproduce the above copyright
17  *     notice, this list of conditions and the following disclaimer in the
18  *     documentation and/or other materials provided with the distribution.
19  *  3. Neither the name of the University nor the names of its
20  *     contributors may be used to endorse or promote products derived
21  *     from this software without specific prior written permission.
22  *
23  *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
24  *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
25  *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26  *  DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27  *  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
30  *  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31  *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32  *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33  *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34  *
35  * TODO: Neil Brown made the following observation:  We currently
36  * initially reserve NFSD_BUFSIZE space on the transmit queue and
37  * never release any of that until the request is complete.
38  * It would be good to calculate a new maximum response size while
39  * decoding the COMPOUND, and call svc_reserve with this number
40  * at the end of nfs4svc_decode_compoundargs.
41  */
42
43 #include <linux/slab.h>
44 #include <linux/namei.h>
45 #include <linux/statfs.h>
46 #include <linux/utsname.h>
47 #include <linux/pagemap.h>
48 #include <linux/sunrpc/svcauth_gss.h>
49
50 #include "idmap.h"
51 #include "acl.h"
52 #include "xdr4.h"
53 #include "vfs.h"
54 #include "state.h"
55
56 #define NFSDDBG_FACILITY                NFSDDBG_XDR
57
58 /*
59  * As per referral draft, the fsid for a referral MUST be different from the fsid of the containing
60  * directory in order to indicate to the client that a filesystem boundary is present
61  * We use a fixed fsid for a referral
62  */
63 #define NFS4_REFERRAL_FSID_MAJOR        0x8000000ULL
64 #define NFS4_REFERRAL_FSID_MINOR        0x8000000ULL
65
66 static __be32
67 check_filename(char *str, int len, __be32 err)
68 {
69         int i;
70
71         if (len == 0)
72                 return nfserr_inval;
73         if (isdotent(str, len))
74                 return err;
75         for (i = 0; i < len; i++)
76                 if (str[i] == '/')
77                         return err;
78         return 0;
79 }
80
81 #define DECODE_HEAD                             \
82         __be32 *p;                              \
83         __be32 status
84 #define DECODE_TAIL                             \
85         status = 0;                             \
86 out:                                            \
87         return status;                          \
88 xdr_error:                                      \
89         dprintk("NFSD: xdr error (%s:%d)\n",    \
90                         __FILE__, __LINE__);    \
91         status = nfserr_bad_xdr;                \
92         goto out
93
94 #define READ32(x)         (x) = ntohl(*p++)
95 #define READ64(x)         do {                  \
96         (x) = (u64)ntohl(*p++) << 32;           \
97         (x) |= ntohl(*p++);                     \
98 } while (0)
99 #define READTIME(x)       do {                  \
100         p++;                                    \
101         (x) = ntohl(*p++);                      \
102         p++;                                    \
103 } while (0)
104 #define READMEM(x,nbytes) do {                  \
105         x = (char *)p;                          \
106         p += XDR_QUADLEN(nbytes);               \
107 } while (0)
108 #define SAVEMEM(x,nbytes) do {                  \
109         if (!(x = (p==argp->tmp || p == argp->tmpp) ? \
110                 savemem(argp, p, nbytes) :      \
111                 (char *)p)) {                   \
112                 dprintk("NFSD: xdr error (%s:%d)\n", \
113                                 __FILE__, __LINE__); \
114                 goto xdr_error;                 \
115                 }                               \
116         p += XDR_QUADLEN(nbytes);               \
117 } while (0)
118 #define COPYMEM(x,nbytes) do {                  \
119         memcpy((x), p, nbytes);                 \
120         p += XDR_QUADLEN(nbytes);               \
121 } while (0)
122
123 /* READ_BUF, read_buf(): nbytes must be <= PAGE_SIZE */
124 #define READ_BUF(nbytes)  do {                  \
125         if (nbytes <= (u32)((char *)argp->end - (char *)argp->p)) {     \
126                 p = argp->p;                    \
127                 argp->p += XDR_QUADLEN(nbytes); \
128         } else if (!(p = read_buf(argp, nbytes))) { \
129                 dprintk("NFSD: xdr error (%s:%d)\n", \
130                                 __FILE__, __LINE__); \
131                 goto xdr_error;                 \
132         }                                       \
133 } while (0)
134
135 static void save_buf(struct nfsd4_compoundargs *argp, struct nfsd4_saved_compoundargs *savep)
136 {
137         savep->p        = argp->p;
138         savep->end      = argp->end;
139         savep->pagelen  = argp->pagelen;
140         savep->pagelist = argp->pagelist;
141 }
142
143 static void restore_buf(struct nfsd4_compoundargs *argp, struct nfsd4_saved_compoundargs *savep)
144 {
145         argp->p        = savep->p;
146         argp->end      = savep->end;
147         argp->pagelen  = savep->pagelen;
148         argp->pagelist = savep->pagelist;
149 }
150
151 static __be32 *read_buf(struct nfsd4_compoundargs *argp, u32 nbytes)
152 {
153         /* We want more bytes than seem to be available.
154          * Maybe we need a new page, maybe we have just run out
155          */
156         unsigned int avail = (char *)argp->end - (char *)argp->p;
157         __be32 *p;
158         if (avail + argp->pagelen < nbytes)
159                 return NULL;
160         if (avail + PAGE_SIZE < nbytes) /* need more than a page !! */
161                 return NULL;
162         /* ok, we can do it with the current plus the next page */
163         if (nbytes <= sizeof(argp->tmp))
164                 p = argp->tmp;
165         else {
166                 kfree(argp->tmpp);
167                 p = argp->tmpp = kmalloc(nbytes, GFP_KERNEL);
168                 if (!p)
169                         return NULL;
170                 
171         }
172         /*
173          * The following memcpy is safe because read_buf is always
174          * called with nbytes > avail, and the two cases above both
175          * guarantee p points to at least nbytes bytes.
176          */
177         memcpy(p, argp->p, avail);
178         /* step to next page */
179         argp->p = page_address(argp->pagelist[0]);
180         argp->pagelist++;
181         if (argp->pagelen < PAGE_SIZE) {
182                 argp->end = argp->p + (argp->pagelen>>2);
183                 argp->pagelen = 0;
184         } else {
185                 argp->end = argp->p + (PAGE_SIZE>>2);
186                 argp->pagelen -= PAGE_SIZE;
187         }
188         memcpy(((char*)p)+avail, argp->p, (nbytes - avail));
189         argp->p += XDR_QUADLEN(nbytes - avail);
190         return p;
191 }
192
193 static int zero_clientid(clientid_t *clid)
194 {
195         return (clid->cl_boot == 0) && (clid->cl_id == 0);
196 }
197
198 static int
199 defer_free(struct nfsd4_compoundargs *argp,
200                 void (*release)(const void *), void *p)
201 {
202         struct tmpbuf *tb;
203
204         tb = kmalloc(sizeof(*tb), GFP_KERNEL);
205         if (!tb)
206                 return -ENOMEM;
207         tb->buf = p;
208         tb->release = release;
209         tb->next = argp->to_free;
210         argp->to_free = tb;
211         return 0;
212 }
213
214 static char *savemem(struct nfsd4_compoundargs *argp, __be32 *p, int nbytes)
215 {
216         if (p == argp->tmp) {
217                 p = kmalloc(nbytes, GFP_KERNEL);
218                 if (!p)
219                         return NULL;
220                 memcpy(p, argp->tmp, nbytes);
221         } else {
222                 BUG_ON(p != argp->tmpp);
223                 argp->tmpp = NULL;
224         }
225         if (defer_free(argp, kfree, p)) {
226                 kfree(p);
227                 return NULL;
228         } else
229                 return (char *)p;
230 }
231
232 static __be32
233 nfsd4_decode_bitmap(struct nfsd4_compoundargs *argp, u32 *bmval)
234 {
235         u32 bmlen;
236         DECODE_HEAD;
237
238         bmval[0] = 0;
239         bmval[1] = 0;
240         bmval[2] = 0;
241
242         READ_BUF(4);
243         READ32(bmlen);
244         if (bmlen > 1000)
245                 goto xdr_error;
246
247         READ_BUF(bmlen << 2);
248         if (bmlen > 0)
249                 READ32(bmval[0]);
250         if (bmlen > 1)
251                 READ32(bmval[1]);
252         if (bmlen > 2)
253                 READ32(bmval[2]);
254
255         DECODE_TAIL;
256 }
257
258 static __be32
259 nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
260                    struct iattr *iattr, struct nfs4_acl **acl)
261 {
262         int expected_len, len = 0;
263         u32 dummy32;
264         char *buf;
265         int host_err;
266
267         DECODE_HEAD;
268         iattr->ia_valid = 0;
269         if ((status = nfsd4_decode_bitmap(argp, bmval)))
270                 return status;
271
272         READ_BUF(4);
273         READ32(expected_len);
274
275         if (bmval[0] & FATTR4_WORD0_SIZE) {
276                 READ_BUF(8);
277                 len += 8;
278                 READ64(iattr->ia_size);
279                 iattr->ia_valid |= ATTR_SIZE;
280         }
281         if (bmval[0] & FATTR4_WORD0_ACL) {
282                 int nace;
283                 struct nfs4_ace *ace;
284
285                 READ_BUF(4); len += 4;
286                 READ32(nace);
287
288                 if (nace > NFS4_ACL_MAX)
289                         return nfserr_resource;
290
291                 *acl = nfs4_acl_new(nace);
292                 if (*acl == NULL) {
293                         host_err = -ENOMEM;
294                         goto out_nfserr;
295                 }
296                 defer_free(argp, kfree, *acl);
297
298                 (*acl)->naces = nace;
299                 for (ace = (*acl)->aces; ace < (*acl)->aces + nace; ace++) {
300                         READ_BUF(16); len += 16;
301                         READ32(ace->type);
302                         READ32(ace->flag);
303                         READ32(ace->access_mask);
304                         READ32(dummy32);
305                         READ_BUF(dummy32);
306                         len += XDR_QUADLEN(dummy32) << 2;
307                         READMEM(buf, dummy32);
308                         ace->whotype = nfs4_acl_get_whotype(buf, dummy32);
309                         status = nfs_ok;
310                         if (ace->whotype != NFS4_ACL_WHO_NAMED)
311                                 ace->who = 0;
312                         else if (ace->flag & NFS4_ACE_IDENTIFIER_GROUP)
313                                 status = nfsd_map_name_to_gid(argp->rqstp,
314                                                 buf, dummy32, &ace->who);
315                         else
316                                 status = nfsd_map_name_to_uid(argp->rqstp,
317                                                 buf, dummy32, &ace->who);
318                         if (status)
319                                 return status;
320                 }
321         } else
322                 *acl = NULL;
323         if (bmval[1] & FATTR4_WORD1_MODE) {
324                 READ_BUF(4);
325                 len += 4;
326                 READ32(iattr->ia_mode);
327                 iattr->ia_mode &= (S_IFMT | S_IALLUGO);
328                 iattr->ia_valid |= ATTR_MODE;
329         }
330         if (bmval[1] & FATTR4_WORD1_OWNER) {
331                 READ_BUF(4);
332                 len += 4;
333                 READ32(dummy32);
334                 READ_BUF(dummy32);
335                 len += (XDR_QUADLEN(dummy32) << 2);
336                 READMEM(buf, dummy32);
337                 if ((status = nfsd_map_name_to_uid(argp->rqstp, buf, dummy32, &iattr->ia_uid)))
338                         return status;
339                 iattr->ia_valid |= ATTR_UID;
340         }
341         if (bmval[1] & FATTR4_WORD1_OWNER_GROUP) {
342                 READ_BUF(4);
343                 len += 4;
344                 READ32(dummy32);
345                 READ_BUF(dummy32);
346                 len += (XDR_QUADLEN(dummy32) << 2);
347                 READMEM(buf, dummy32);
348                 if ((status = nfsd_map_name_to_gid(argp->rqstp, buf, dummy32, &iattr->ia_gid)))
349                         return status;
350                 iattr->ia_valid |= ATTR_GID;
351         }
352         if (bmval[1] & FATTR4_WORD1_TIME_ACCESS_SET) {
353                 READ_BUF(4);
354                 len += 4;
355                 READ32(dummy32);
356                 switch (dummy32) {
357                 case NFS4_SET_TO_CLIENT_TIME:
358                         /* We require the high 32 bits of 'seconds' to be 0, and we ignore
359                            all 32 bits of 'nseconds'. */
360                         READ_BUF(12);
361                         len += 12;
362                         READ32(dummy32);
363                         if (dummy32)
364                                 return nfserr_inval;
365                         READ32(iattr->ia_atime.tv_sec);
366                         READ32(iattr->ia_atime.tv_nsec);
367                         if (iattr->ia_atime.tv_nsec >= (u32)1000000000)
368                                 return nfserr_inval;
369                         iattr->ia_valid |= (ATTR_ATIME | ATTR_ATIME_SET);
370                         break;
371                 case NFS4_SET_TO_SERVER_TIME:
372                         iattr->ia_valid |= ATTR_ATIME;
373                         break;
374                 default:
375                         goto xdr_error;
376                 }
377         }
378         if (bmval[1] & FATTR4_WORD1_TIME_MODIFY_SET) {
379                 READ_BUF(4);
380                 len += 4;
381                 READ32(dummy32);
382                 switch (dummy32) {
383                 case NFS4_SET_TO_CLIENT_TIME:
384                         /* We require the high 32 bits of 'seconds' to be 0, and we ignore
385                            all 32 bits of 'nseconds'. */
386                         READ_BUF(12);
387                         len += 12;
388                         READ32(dummy32);
389                         if (dummy32)
390                                 return nfserr_inval;
391                         READ32(iattr->ia_mtime.tv_sec);
392                         READ32(iattr->ia_mtime.tv_nsec);
393                         if (iattr->ia_mtime.tv_nsec >= (u32)1000000000)
394                                 return nfserr_inval;
395                         iattr->ia_valid |= (ATTR_MTIME | ATTR_MTIME_SET);
396                         break;
397                 case NFS4_SET_TO_SERVER_TIME:
398                         iattr->ia_valid |= ATTR_MTIME;
399                         break;
400                 default:
401                         goto xdr_error;
402                 }
403         }
404         if (bmval[0] & ~NFSD_WRITEABLE_ATTRS_WORD0
405             || bmval[1] & ~NFSD_WRITEABLE_ATTRS_WORD1
406             || bmval[2] & ~NFSD_WRITEABLE_ATTRS_WORD2)
407                 READ_BUF(expected_len - len);
408         else if (len != expected_len)
409                 goto xdr_error;
410
411         DECODE_TAIL;
412
413 out_nfserr:
414         status = nfserrno(host_err);
415         goto out;
416 }
417
418 static __be32
419 nfsd4_decode_stateid(struct nfsd4_compoundargs *argp, stateid_t *sid)
420 {
421         DECODE_HEAD;
422
423         READ_BUF(sizeof(stateid_t));
424         READ32(sid->si_generation);
425         COPYMEM(&sid->si_opaque, sizeof(stateid_opaque_t));
426
427         DECODE_TAIL;
428 }
429
430 static __be32
431 nfsd4_decode_access(struct nfsd4_compoundargs *argp, struct nfsd4_access *access)
432 {
433         DECODE_HEAD;
434
435         READ_BUF(4);
436         READ32(access->ac_req_access);
437
438         DECODE_TAIL;
439 }
440
441 static __be32 nfsd4_decode_bind_conn_to_session(struct nfsd4_compoundargs *argp, struct nfsd4_bind_conn_to_session *bcts)
442 {
443         DECODE_HEAD;
444
445         READ_BUF(NFS4_MAX_SESSIONID_LEN + 8);
446         COPYMEM(bcts->sessionid.data, NFS4_MAX_SESSIONID_LEN);
447         READ32(bcts->dir);
448         /* XXX: skipping ctsa_use_conn_in_rdma_mode.  Perhaps Tom Tucker
449          * could help us figure out we should be using it. */
450         DECODE_TAIL;
451 }
452
453 static __be32
454 nfsd4_decode_close(struct nfsd4_compoundargs *argp, struct nfsd4_close *close)
455 {
456         DECODE_HEAD;
457
458         close->cl_stateowner = NULL;
459         READ_BUF(4);
460         READ32(close->cl_seqid);
461         return nfsd4_decode_stateid(argp, &close->cl_stateid);
462
463         DECODE_TAIL;
464 }
465
466
467 static __be32
468 nfsd4_decode_commit(struct nfsd4_compoundargs *argp, struct nfsd4_commit *commit)
469 {
470         DECODE_HEAD;
471
472         READ_BUF(12);
473         READ64(commit->co_offset);
474         READ32(commit->co_count);
475
476         DECODE_TAIL;
477 }
478
479 static __be32
480 nfsd4_decode_create(struct nfsd4_compoundargs *argp, struct nfsd4_create *create)
481 {
482         DECODE_HEAD;
483
484         READ_BUF(4);
485         READ32(create->cr_type);
486         switch (create->cr_type) {
487         case NF4LNK:
488                 READ_BUF(4);
489                 READ32(create->cr_linklen);
490                 READ_BUF(create->cr_linklen);
491                 SAVEMEM(create->cr_linkname, create->cr_linklen);
492                 break;
493         case NF4BLK:
494         case NF4CHR:
495                 READ_BUF(8);
496                 READ32(create->cr_specdata1);
497                 READ32(create->cr_specdata2);
498                 break;
499         case NF4SOCK:
500         case NF4FIFO:
501         case NF4DIR:
502         default:
503                 break;
504         }
505
506         READ_BUF(4);
507         READ32(create->cr_namelen);
508         READ_BUF(create->cr_namelen);
509         SAVEMEM(create->cr_name, create->cr_namelen);
510         if ((status = check_filename(create->cr_name, create->cr_namelen, nfserr_inval)))
511                 return status;
512
513         status = nfsd4_decode_fattr(argp, create->cr_bmval, &create->cr_iattr,
514                                     &create->cr_acl);
515         if (status)
516                 goto out;
517
518         DECODE_TAIL;
519 }
520
521 static inline __be32
522 nfsd4_decode_delegreturn(struct nfsd4_compoundargs *argp, struct nfsd4_delegreturn *dr)
523 {
524         return nfsd4_decode_stateid(argp, &dr->dr_stateid);
525 }
526
527 static inline __be32
528 nfsd4_decode_getattr(struct nfsd4_compoundargs *argp, struct nfsd4_getattr *getattr)
529 {
530         return nfsd4_decode_bitmap(argp, getattr->ga_bmval);
531 }
532
533 static __be32
534 nfsd4_decode_link(struct nfsd4_compoundargs *argp, struct nfsd4_link *link)
535 {
536         DECODE_HEAD;
537
538         READ_BUF(4);
539         READ32(link->li_namelen);
540         READ_BUF(link->li_namelen);
541         SAVEMEM(link->li_name, link->li_namelen);
542         if ((status = check_filename(link->li_name, link->li_namelen, nfserr_inval)))
543                 return status;
544
545         DECODE_TAIL;
546 }
547
548 static __be32
549 nfsd4_decode_lock(struct nfsd4_compoundargs *argp, struct nfsd4_lock *lock)
550 {
551         DECODE_HEAD;
552
553         lock->lk_replay_owner = NULL;
554         /*
555         * type, reclaim(boolean), offset, length, new_lock_owner(boolean)
556         */
557         READ_BUF(28);
558         READ32(lock->lk_type);
559         if ((lock->lk_type < NFS4_READ_LT) || (lock->lk_type > NFS4_WRITEW_LT))
560                 goto xdr_error;
561         READ32(lock->lk_reclaim);
562         READ64(lock->lk_offset);
563         READ64(lock->lk_length);
564         READ32(lock->lk_is_new);
565
566         if (lock->lk_is_new) {
567                 READ_BUF(4);
568                 READ32(lock->lk_new_open_seqid);
569                 status = nfsd4_decode_stateid(argp, &lock->lk_new_open_stateid);
570                 if (status)
571                         return status;
572                 READ_BUF(8 + sizeof(clientid_t));
573                 READ32(lock->lk_new_lock_seqid);
574                 COPYMEM(&lock->lk_new_clientid, sizeof(clientid_t));
575                 READ32(lock->lk_new_owner.len);
576                 READ_BUF(lock->lk_new_owner.len);
577                 READMEM(lock->lk_new_owner.data, lock->lk_new_owner.len);
578         } else {
579                 status = nfsd4_decode_stateid(argp, &lock->lk_old_lock_stateid);
580                 if (status)
581                         return status;
582                 READ_BUF(4);
583                 READ32(lock->lk_old_lock_seqid);
584         }
585
586         DECODE_TAIL;
587 }
588
589 static __be32
590 nfsd4_decode_lockt(struct nfsd4_compoundargs *argp, struct nfsd4_lockt *lockt)
591 {
592         DECODE_HEAD;
593                         
594         READ_BUF(32);
595         READ32(lockt->lt_type);
596         if((lockt->lt_type < NFS4_READ_LT) || (lockt->lt_type > NFS4_WRITEW_LT))
597                 goto xdr_error;
598         READ64(lockt->lt_offset);
599         READ64(lockt->lt_length);
600         COPYMEM(&lockt->lt_clientid, 8);
601         READ32(lockt->lt_owner.len);
602         READ_BUF(lockt->lt_owner.len);
603         READMEM(lockt->lt_owner.data, lockt->lt_owner.len);
604
605         DECODE_TAIL;
606 }
607
608 static __be32
609 nfsd4_decode_locku(struct nfsd4_compoundargs *argp, struct nfsd4_locku *locku)
610 {
611         DECODE_HEAD;
612
613         locku->lu_stateowner = NULL;
614         READ_BUF(8);
615         READ32(locku->lu_type);
616         if ((locku->lu_type < NFS4_READ_LT) || (locku->lu_type > NFS4_WRITEW_LT))
617                 goto xdr_error;
618         READ32(locku->lu_seqid);
619         status = nfsd4_decode_stateid(argp, &locku->lu_stateid);
620         if (status)
621                 return status;
622         READ_BUF(16);
623         READ64(locku->lu_offset);
624         READ64(locku->lu_length);
625
626         DECODE_TAIL;
627 }
628
629 static __be32
630 nfsd4_decode_lookup(struct nfsd4_compoundargs *argp, struct nfsd4_lookup *lookup)
631 {
632         DECODE_HEAD;
633
634         READ_BUF(4);
635         READ32(lookup->lo_len);
636         READ_BUF(lookup->lo_len);
637         SAVEMEM(lookup->lo_name, lookup->lo_len);
638         if ((status = check_filename(lookup->lo_name, lookup->lo_len, nfserr_noent)))
639                 return status;
640
641         DECODE_TAIL;
642 }
643
644 static __be32
645 nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
646 {
647         DECODE_HEAD;
648
649         memset(open->op_bmval, 0, sizeof(open->op_bmval));
650         open->op_iattr.ia_valid = 0;
651         open->op_stateowner = NULL;
652
653         /* seqid, share_access, share_deny, clientid, ownerlen */
654         READ_BUF(16 + sizeof(clientid_t));
655         READ32(open->op_seqid);
656         READ32(open->op_share_access);
657         READ32(open->op_share_deny);
658         COPYMEM(&open->op_clientid, sizeof(clientid_t));
659         READ32(open->op_owner.len);
660
661         /* owner, open_flag */
662         READ_BUF(open->op_owner.len + 4);
663         SAVEMEM(open->op_owner.data, open->op_owner.len);
664         READ32(open->op_create);
665         switch (open->op_create) {
666         case NFS4_OPEN_NOCREATE:
667                 break;
668         case NFS4_OPEN_CREATE:
669                 READ_BUF(4);
670                 READ32(open->op_createmode);
671                 switch (open->op_createmode) {
672                 case NFS4_CREATE_UNCHECKED:
673                 case NFS4_CREATE_GUARDED:
674                         status = nfsd4_decode_fattr(argp, open->op_bmval,
675                                 &open->op_iattr, &open->op_acl);
676                         if (status)
677                                 goto out;
678                         break;
679                 case NFS4_CREATE_EXCLUSIVE:
680                         READ_BUF(8);
681                         COPYMEM(open->op_verf.data, 8);
682                         break;
683                 case NFS4_CREATE_EXCLUSIVE4_1:
684                         if (argp->minorversion < 1)
685                                 goto xdr_error;
686                         READ_BUF(8);
687                         COPYMEM(open->op_verf.data, 8);
688                         status = nfsd4_decode_fattr(argp, open->op_bmval,
689                                 &open->op_iattr, &open->op_acl);
690                         if (status)
691                                 goto out;
692                         break;
693                 default:
694                         goto xdr_error;
695                 }
696                 break;
697         default:
698                 goto xdr_error;
699         }
700
701         /* open_claim */
702         READ_BUF(4);
703         READ32(open->op_claim_type);
704         switch (open->op_claim_type) {
705         case NFS4_OPEN_CLAIM_NULL:
706         case NFS4_OPEN_CLAIM_DELEGATE_PREV:
707                 READ_BUF(4);
708                 READ32(open->op_fname.len);
709                 READ_BUF(open->op_fname.len);
710                 SAVEMEM(open->op_fname.data, open->op_fname.len);
711                 if ((status = check_filename(open->op_fname.data, open->op_fname.len, nfserr_inval)))
712                         return status;
713                 break;
714         case NFS4_OPEN_CLAIM_PREVIOUS:
715                 READ_BUF(4);
716                 READ32(open->op_delegate_type);
717                 break;
718         case NFS4_OPEN_CLAIM_DELEGATE_CUR:
719                 status = nfsd4_decode_stateid(argp, &open->op_delegate_stateid);
720                 if (status)
721                         return status;
722                 READ_BUF(4);
723                 READ32(open->op_fname.len);
724                 READ_BUF(open->op_fname.len);
725                 SAVEMEM(open->op_fname.data, open->op_fname.len);
726                 if ((status = check_filename(open->op_fname.data, open->op_fname.len, nfserr_inval)))
727                         return status;
728                 break;
729         default:
730                 goto xdr_error;
731         }
732
733         DECODE_TAIL;
734 }
735
736 static __be32
737 nfsd4_decode_open_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_open_confirm *open_conf)
738 {
739         DECODE_HEAD;
740                     
741         open_conf->oc_stateowner = NULL;
742         status = nfsd4_decode_stateid(argp, &open_conf->oc_req_stateid);
743         if (status)
744                 return status;
745         READ_BUF(4);
746         READ32(open_conf->oc_seqid);
747                                                         
748         DECODE_TAIL;
749 }
750
751 static __be32
752 nfsd4_decode_open_downgrade(struct nfsd4_compoundargs *argp, struct nfsd4_open_downgrade *open_down)
753 {
754         DECODE_HEAD;
755                     
756         open_down->od_stateowner = NULL;
757         status = nfsd4_decode_stateid(argp, &open_down->od_stateid);
758         if (status)
759                 return status;
760         READ_BUF(12);
761         READ32(open_down->od_seqid);
762         READ32(open_down->od_share_access);
763         READ32(open_down->od_share_deny);
764                                                         
765         DECODE_TAIL;
766 }
767
768 static __be32
769 nfsd4_decode_putfh(struct nfsd4_compoundargs *argp, struct nfsd4_putfh *putfh)
770 {
771         DECODE_HEAD;
772
773         READ_BUF(4);
774         READ32(putfh->pf_fhlen);
775         if (putfh->pf_fhlen > NFS4_FHSIZE)
776                 goto xdr_error;
777         READ_BUF(putfh->pf_fhlen);
778         SAVEMEM(putfh->pf_fhval, putfh->pf_fhlen);
779
780         DECODE_TAIL;
781 }
782
783 static __be32
784 nfsd4_decode_read(struct nfsd4_compoundargs *argp, struct nfsd4_read *read)
785 {
786         DECODE_HEAD;
787
788         status = nfsd4_decode_stateid(argp, &read->rd_stateid);
789         if (status)
790                 return status;
791         READ_BUF(12);
792         READ64(read->rd_offset);
793         READ32(read->rd_length);
794
795         DECODE_TAIL;
796 }
797
798 static __be32
799 nfsd4_decode_readdir(struct nfsd4_compoundargs *argp, struct nfsd4_readdir *readdir)
800 {
801         DECODE_HEAD;
802
803         READ_BUF(24);
804         READ64(readdir->rd_cookie);
805         COPYMEM(readdir->rd_verf.data, sizeof(readdir->rd_verf.data));
806         READ32(readdir->rd_dircount);    /* just in case you needed a useless field... */
807         READ32(readdir->rd_maxcount);
808         if ((status = nfsd4_decode_bitmap(argp, readdir->rd_bmval)))
809                 goto out;
810
811         DECODE_TAIL;
812 }
813
814 static __be32
815 nfsd4_decode_remove(struct nfsd4_compoundargs *argp, struct nfsd4_remove *remove)
816 {
817         DECODE_HEAD;
818
819         READ_BUF(4);
820         READ32(remove->rm_namelen);
821         READ_BUF(remove->rm_namelen);
822         SAVEMEM(remove->rm_name, remove->rm_namelen);
823         if ((status = check_filename(remove->rm_name, remove->rm_namelen, nfserr_noent)))
824                 return status;
825
826         DECODE_TAIL;
827 }
828
829 static __be32
830 nfsd4_decode_rename(struct nfsd4_compoundargs *argp, struct nfsd4_rename *rename)
831 {
832         DECODE_HEAD;
833
834         READ_BUF(4);
835         READ32(rename->rn_snamelen);
836         READ_BUF(rename->rn_snamelen + 4);
837         SAVEMEM(rename->rn_sname, rename->rn_snamelen);
838         READ32(rename->rn_tnamelen);
839         READ_BUF(rename->rn_tnamelen);
840         SAVEMEM(rename->rn_tname, rename->rn_tnamelen);
841         if ((status = check_filename(rename->rn_sname, rename->rn_snamelen, nfserr_noent)))
842                 return status;
843         if ((status = check_filename(rename->rn_tname, rename->rn_tnamelen, nfserr_inval)))
844                 return status;
845
846         DECODE_TAIL;
847 }
848
849 static __be32
850 nfsd4_decode_renew(struct nfsd4_compoundargs *argp, clientid_t *clientid)
851 {
852         DECODE_HEAD;
853
854         READ_BUF(sizeof(clientid_t));
855         COPYMEM(clientid, sizeof(clientid_t));
856
857         DECODE_TAIL;
858 }
859
860 static __be32
861 nfsd4_decode_secinfo(struct nfsd4_compoundargs *argp,
862                      struct nfsd4_secinfo *secinfo)
863 {
864         DECODE_HEAD;
865
866         READ_BUF(4);
867         READ32(secinfo->si_namelen);
868         READ_BUF(secinfo->si_namelen);
869         SAVEMEM(secinfo->si_name, secinfo->si_namelen);
870         status = check_filename(secinfo->si_name, secinfo->si_namelen,
871                                                                 nfserr_noent);
872         if (status)
873                 return status;
874         DECODE_TAIL;
875 }
876
877 static __be32
878 nfsd4_decode_secinfo_no_name(struct nfsd4_compoundargs *argp,
879                      struct nfsd4_secinfo_no_name *sin)
880 {
881         DECODE_HEAD;
882
883         READ_BUF(4);
884         READ32(sin->sin_style);
885         DECODE_TAIL;
886 }
887
888 static __be32
889 nfsd4_decode_setattr(struct nfsd4_compoundargs *argp, struct nfsd4_setattr *setattr)
890 {
891         __be32 status;
892
893         status = nfsd4_decode_stateid(argp, &setattr->sa_stateid);
894         if (status)
895                 return status;
896         return nfsd4_decode_fattr(argp, setattr->sa_bmval, &setattr->sa_iattr,
897                                   &setattr->sa_acl);
898 }
899
900 static __be32
901 nfsd4_decode_setclientid(struct nfsd4_compoundargs *argp, struct nfsd4_setclientid *setclientid)
902 {
903         DECODE_HEAD;
904
905         READ_BUF(12);
906         COPYMEM(setclientid->se_verf.data, 8);
907         READ32(setclientid->se_namelen);
908
909         READ_BUF(setclientid->se_namelen + 8);
910         SAVEMEM(setclientid->se_name, setclientid->se_namelen);
911         READ32(setclientid->se_callback_prog);
912         READ32(setclientid->se_callback_netid_len);
913
914         READ_BUF(setclientid->se_callback_netid_len + 4);
915         SAVEMEM(setclientid->se_callback_netid_val, setclientid->se_callback_netid_len);
916         READ32(setclientid->se_callback_addr_len);
917
918         READ_BUF(setclientid->se_callback_addr_len + 4);
919         SAVEMEM(setclientid->se_callback_addr_val, setclientid->se_callback_addr_len);
920         READ32(setclientid->se_callback_ident);
921
922         DECODE_TAIL;
923 }
924
925 static __be32
926 nfsd4_decode_setclientid_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_setclientid_confirm *scd_c)
927 {
928         DECODE_HEAD;
929
930         READ_BUF(8 + sizeof(nfs4_verifier));
931         COPYMEM(&scd_c->sc_clientid, 8);
932         COPYMEM(&scd_c->sc_confirm, sizeof(nfs4_verifier));
933
934         DECODE_TAIL;
935 }
936
937 /* Also used for NVERIFY */
938 static __be32
939 nfsd4_decode_verify(struct nfsd4_compoundargs *argp, struct nfsd4_verify *verify)
940 {
941 #if 0
942         struct nfsd4_compoundargs save = {
943                 .p = argp->p,
944                 .end = argp->end,
945                 .rqstp = argp->rqstp,
946         };
947         u32             ve_bmval[2];
948         struct iattr    ve_iattr;           /* request */
949         struct nfs4_acl *ve_acl;            /* request */
950 #endif
951         DECODE_HEAD;
952
953         if ((status = nfsd4_decode_bitmap(argp, verify->ve_bmval)))
954                 goto out;
955
956         /* For convenience's sake, we compare raw xdr'd attributes in
957          * nfsd4_proc_verify; however we still decode here just to return
958          * correct error in case of bad xdr. */
959 #if 0
960         status = nfsd4_decode_fattr(ve_bmval, &ve_iattr, &ve_acl);
961         if (status == nfserr_inval) {
962                 status = nfserrno(status);
963                 goto out;
964         }
965 #endif
966         READ_BUF(4);
967         READ32(verify->ve_attrlen);
968         READ_BUF(verify->ve_attrlen);
969         SAVEMEM(verify->ve_attrval, verify->ve_attrlen);
970
971         DECODE_TAIL;
972 }
973
974 static __be32
975 nfsd4_decode_write(struct nfsd4_compoundargs *argp, struct nfsd4_write *write)
976 {
977         int avail;
978         int v;
979         int len;
980         DECODE_HEAD;
981
982         status = nfsd4_decode_stateid(argp, &write->wr_stateid);
983         if (status)
984                 return status;
985         READ_BUF(16);
986         READ64(write->wr_offset);
987         READ32(write->wr_stable_how);
988         if (write->wr_stable_how > 2)
989                 goto xdr_error;
990         READ32(write->wr_buflen);
991
992         /* Sorry .. no magic macros for this.. *
993          * READ_BUF(write->wr_buflen);
994          * SAVEMEM(write->wr_buf, write->wr_buflen);
995          */
996         avail = (char*)argp->end - (char*)argp->p;
997         if (avail + argp->pagelen < write->wr_buflen) {
998                 dprintk("NFSD: xdr error (%s:%d)\n",
999                                 __FILE__, __LINE__);
1000                 goto xdr_error;
1001         }
1002         argp->rqstp->rq_vec[0].iov_base = p;
1003         argp->rqstp->rq_vec[0].iov_len = avail;
1004         v = 0;
1005         len = write->wr_buflen;
1006         while (len > argp->rqstp->rq_vec[v].iov_len) {
1007                 len -= argp->rqstp->rq_vec[v].iov_len;
1008                 v++;
1009                 argp->rqstp->rq_vec[v].iov_base = page_address(argp->pagelist[0]);
1010                 argp->pagelist++;
1011                 if (argp->pagelen >= PAGE_SIZE) {
1012                         argp->rqstp->rq_vec[v].iov_len = PAGE_SIZE;
1013                         argp->pagelen -= PAGE_SIZE;
1014                 } else {
1015                         argp->rqstp->rq_vec[v].iov_len = argp->pagelen;
1016                         argp->pagelen -= len;
1017                 }
1018         }
1019         argp->end = (__be32*) (argp->rqstp->rq_vec[v].iov_base + argp->rqstp->rq_vec[v].iov_len);
1020         argp->p = (__be32*)  (argp->rqstp->rq_vec[v].iov_base + (XDR_QUADLEN(len) << 2));
1021         argp->rqstp->rq_vec[v].iov_len = len;
1022         write->wr_vlen = v+1;
1023
1024         DECODE_TAIL;
1025 }
1026
1027 static __be32
1028 nfsd4_decode_release_lockowner(struct nfsd4_compoundargs *argp, struct nfsd4_release_lockowner *rlockowner)
1029 {
1030         DECODE_HEAD;
1031
1032         READ_BUF(12);
1033         COPYMEM(&rlockowner->rl_clientid, sizeof(clientid_t));
1034         READ32(rlockowner->rl_owner.len);
1035         READ_BUF(rlockowner->rl_owner.len);
1036         READMEM(rlockowner->rl_owner.data, rlockowner->rl_owner.len);
1037
1038         if (argp->minorversion && !zero_clientid(&rlockowner->rl_clientid))
1039                 return nfserr_inval;
1040         DECODE_TAIL;
1041 }
1042
1043 static __be32
1044 nfsd4_decode_exchange_id(struct nfsd4_compoundargs *argp,
1045                          struct nfsd4_exchange_id *exid)
1046 {
1047         int dummy, tmp;
1048         DECODE_HEAD;
1049
1050         READ_BUF(NFS4_VERIFIER_SIZE);
1051         COPYMEM(exid->verifier.data, NFS4_VERIFIER_SIZE);
1052
1053         READ_BUF(4);
1054         READ32(exid->clname.len);
1055
1056         READ_BUF(exid->clname.len);
1057         SAVEMEM(exid->clname.data, exid->clname.len);
1058
1059         READ_BUF(4);
1060         READ32(exid->flags);
1061
1062         /* Ignore state_protect4_a */
1063         READ_BUF(4);
1064         READ32(exid->spa_how);
1065         switch (exid->spa_how) {
1066         case SP4_NONE:
1067                 break;
1068         case SP4_MACH_CRED:
1069                 /* spo_must_enforce */
1070                 READ_BUF(4);
1071                 READ32(dummy);
1072                 READ_BUF(dummy * 4);
1073                 p += dummy;
1074
1075                 /* spo_must_allow */
1076                 READ_BUF(4);
1077                 READ32(dummy);
1078                 READ_BUF(dummy * 4);
1079                 p += dummy;
1080                 break;
1081         case SP4_SSV:
1082                 /* ssp_ops */
1083                 READ_BUF(4);
1084                 READ32(dummy);
1085                 READ_BUF(dummy * 4);
1086                 p += dummy;
1087
1088                 READ_BUF(4);
1089                 READ32(dummy);
1090                 READ_BUF(dummy * 4);
1091                 p += dummy;
1092
1093                 /* ssp_hash_algs<> */
1094                 READ_BUF(4);
1095                 READ32(tmp);
1096                 while (tmp--) {
1097                         READ_BUF(4);
1098                         READ32(dummy);
1099                         READ_BUF(dummy);
1100                         p += XDR_QUADLEN(dummy);
1101                 }
1102
1103                 /* ssp_encr_algs<> */
1104                 READ_BUF(4);
1105                 READ32(tmp);
1106                 while (tmp--) {
1107                         READ_BUF(4);
1108                         READ32(dummy);
1109                         READ_BUF(dummy);
1110                         p += XDR_QUADLEN(dummy);
1111                 }
1112
1113                 /* ssp_window and ssp_num_gss_handles */
1114                 READ_BUF(8);
1115                 READ32(dummy);
1116                 READ32(dummy);
1117                 break;
1118         default:
1119                 goto xdr_error;
1120         }
1121
1122         /* Ignore Implementation ID */
1123         READ_BUF(4);    /* nfs_impl_id4 array length */
1124         READ32(dummy);
1125
1126         if (dummy > 1)
1127                 goto xdr_error;
1128
1129         if (dummy == 1) {
1130                 /* nii_domain */
1131                 READ_BUF(4);
1132                 READ32(dummy);
1133                 READ_BUF(dummy);
1134                 p += XDR_QUADLEN(dummy);
1135
1136                 /* nii_name */
1137                 READ_BUF(4);
1138                 READ32(dummy);
1139                 READ_BUF(dummy);
1140                 p += XDR_QUADLEN(dummy);
1141
1142                 /* nii_date */
1143                 READ_BUF(12);
1144                 p += 3;
1145         }
1146         DECODE_TAIL;
1147 }
1148
1149 static __be32
1150 nfsd4_decode_create_session(struct nfsd4_compoundargs *argp,
1151                             struct nfsd4_create_session *sess)
1152 {
1153         DECODE_HEAD;
1154
1155         u32 dummy;
1156         char *machine_name;
1157         int i;
1158         int nr_secflavs;
1159
1160         READ_BUF(16);
1161         COPYMEM(&sess->clientid, 8);
1162         READ32(sess->seqid);
1163         READ32(sess->flags);
1164
1165         /* Fore channel attrs */
1166         READ_BUF(28);
1167         READ32(dummy); /* headerpadsz is always 0 */
1168         READ32(sess->fore_channel.maxreq_sz);
1169         READ32(sess->fore_channel.maxresp_sz);
1170         READ32(sess->fore_channel.maxresp_cached);
1171         READ32(sess->fore_channel.maxops);
1172         READ32(sess->fore_channel.maxreqs);
1173         READ32(sess->fore_channel.nr_rdma_attrs);
1174         if (sess->fore_channel.nr_rdma_attrs == 1) {
1175                 READ_BUF(4);
1176                 READ32(sess->fore_channel.rdma_attrs);
1177         } else if (sess->fore_channel.nr_rdma_attrs > 1) {
1178                 dprintk("Too many fore channel attr bitmaps!\n");
1179                 goto xdr_error;
1180         }
1181
1182         /* Back channel attrs */
1183         READ_BUF(28);
1184         READ32(dummy); /* headerpadsz is always 0 */
1185         READ32(sess->back_channel.maxreq_sz);
1186         READ32(sess->back_channel.maxresp_sz);
1187         READ32(sess->back_channel.maxresp_cached);
1188         READ32(sess->back_channel.maxops);
1189         READ32(sess->back_channel.maxreqs);
1190         READ32(sess->back_channel.nr_rdma_attrs);
1191         if (sess->back_channel.nr_rdma_attrs == 1) {
1192                 READ_BUF(4);
1193                 READ32(sess->back_channel.rdma_attrs);
1194         } else if (sess->back_channel.nr_rdma_attrs > 1) {
1195                 dprintk("Too many back channel attr bitmaps!\n");
1196                 goto xdr_error;
1197         }
1198
1199         READ_BUF(8);
1200         READ32(sess->callback_prog);
1201
1202         /* callback_sec_params4 */
1203         READ32(nr_secflavs);
1204         for (i = 0; i < nr_secflavs; ++i) {
1205                 READ_BUF(4);
1206                 READ32(dummy);
1207                 switch (dummy) {
1208                 case RPC_AUTH_NULL:
1209                         /* Nothing to read */
1210                         break;
1211                 case RPC_AUTH_UNIX:
1212                         READ_BUF(8);
1213                         /* stamp */
1214                         READ32(dummy);
1215
1216                         /* machine name */
1217                         READ32(dummy);
1218                         READ_BUF(dummy);
1219                         SAVEMEM(machine_name, dummy);
1220
1221                         /* uid, gid */
1222                         READ_BUF(8);
1223                         READ32(sess->uid);
1224                         READ32(sess->gid);
1225
1226                         /* more gids */
1227                         READ_BUF(4);
1228                         READ32(dummy);
1229                         READ_BUF(dummy * 4);
1230                         break;
1231                 case RPC_AUTH_GSS:
1232                         dprintk("RPC_AUTH_GSS callback secflavor "
1233                                 "not supported!\n");
1234                         READ_BUF(8);
1235                         /* gcbp_service */
1236                         READ32(dummy);
1237                         /* gcbp_handle_from_server */
1238                         READ32(dummy);
1239                         READ_BUF(dummy);
1240                         p += XDR_QUADLEN(dummy);
1241                         /* gcbp_handle_from_client */
1242                         READ_BUF(4);
1243                         READ32(dummy);
1244                         READ_BUF(dummy);
1245                         break;
1246                 default:
1247                         dprintk("Illegal callback secflavor\n");
1248                         return nfserr_inval;
1249                 }
1250         }
1251         DECODE_TAIL;
1252 }
1253
1254 static __be32
1255 nfsd4_decode_destroy_session(struct nfsd4_compoundargs *argp,
1256                              struct nfsd4_destroy_session *destroy_session)
1257 {
1258         DECODE_HEAD;
1259         READ_BUF(NFS4_MAX_SESSIONID_LEN);
1260         COPYMEM(destroy_session->sessionid.data, NFS4_MAX_SESSIONID_LEN);
1261
1262         DECODE_TAIL;
1263 }
1264
1265 static __be32
1266 nfsd4_decode_free_stateid(struct nfsd4_compoundargs *argp,
1267                           struct nfsd4_free_stateid *free_stateid)
1268 {
1269         DECODE_HEAD;
1270
1271         READ_BUF(sizeof(stateid_t));
1272         READ32(free_stateid->fr_stateid.si_generation);
1273         COPYMEM(&free_stateid->fr_stateid.si_opaque, sizeof(stateid_opaque_t));
1274
1275         DECODE_TAIL;
1276 }
1277
1278 static __be32
1279 nfsd4_decode_sequence(struct nfsd4_compoundargs *argp,
1280                       struct nfsd4_sequence *seq)
1281 {
1282         DECODE_HEAD;
1283
1284         READ_BUF(NFS4_MAX_SESSIONID_LEN + 16);
1285         COPYMEM(seq->sessionid.data, NFS4_MAX_SESSIONID_LEN);
1286         READ32(seq->seqid);
1287         READ32(seq->slotid);
1288         READ32(seq->maxslots);
1289         READ32(seq->cachethis);
1290
1291         DECODE_TAIL;
1292 }
1293
1294 static __be32
1295 nfsd4_decode_test_stateid(struct nfsd4_compoundargs *argp, struct nfsd4_test_stateid *test_stateid)
1296 {
1297         unsigned int nbytes;
1298         stateid_t si;
1299         int i;
1300         __be32 *p;
1301         __be32 status;
1302
1303         READ_BUF(4);
1304         test_stateid->ts_num_ids = ntohl(*p++);
1305
1306         nbytes = test_stateid->ts_num_ids * sizeof(stateid_t);
1307         if (nbytes > (u32)((char *)argp->end - (char *)argp->p))
1308                 goto xdr_error;
1309
1310         test_stateid->ts_saved_args = argp;
1311         save_buf(argp, &test_stateid->ts_savedp);
1312
1313         for (i = 0; i < test_stateid->ts_num_ids; i++) {
1314                 status = nfsd4_decode_stateid(argp, &si);
1315                 if (status)
1316                         return status;
1317         }
1318
1319         status = 0;
1320 out:
1321         return status;
1322 xdr_error:
1323         dprintk("NFSD: xdr error (%s:%d)\n", __FILE__, __LINE__);
1324         status = nfserr_bad_xdr;
1325         goto out;
1326 }
1327
1328 static __be32 nfsd4_decode_reclaim_complete(struct nfsd4_compoundargs *argp, struct nfsd4_reclaim_complete *rc)
1329 {
1330         DECODE_HEAD;
1331
1332         READ_BUF(4);
1333         READ32(rc->rca_one_fs);
1334
1335         DECODE_TAIL;
1336 }
1337
1338 static __be32
1339 nfsd4_decode_noop(struct nfsd4_compoundargs *argp, void *p)
1340 {
1341         return nfs_ok;
1342 }
1343
1344 static __be32
1345 nfsd4_decode_notsupp(struct nfsd4_compoundargs *argp, void *p)
1346 {
1347         return nfserr_notsupp;
1348 }
1349
1350 typedef __be32(*nfsd4_dec)(struct nfsd4_compoundargs *argp, void *);
1351
1352 static nfsd4_dec nfsd4_dec_ops[] = {
1353         [OP_ACCESS]             = (nfsd4_dec)nfsd4_decode_access,
1354         [OP_CLOSE]              = (nfsd4_dec)nfsd4_decode_close,
1355         [OP_COMMIT]             = (nfsd4_dec)nfsd4_decode_commit,
1356         [OP_CREATE]             = (nfsd4_dec)nfsd4_decode_create,
1357         [OP_DELEGPURGE]         = (nfsd4_dec)nfsd4_decode_notsupp,
1358         [OP_DELEGRETURN]        = (nfsd4_dec)nfsd4_decode_delegreturn,
1359         [OP_GETATTR]            = (nfsd4_dec)nfsd4_decode_getattr,
1360         [OP_GETFH]              = (nfsd4_dec)nfsd4_decode_noop,
1361         [OP_LINK]               = (nfsd4_dec)nfsd4_decode_link,
1362         [OP_LOCK]               = (nfsd4_dec)nfsd4_decode_lock,
1363         [OP_LOCKT]              = (nfsd4_dec)nfsd4_decode_lockt,
1364         [OP_LOCKU]              = (nfsd4_dec)nfsd4_decode_locku,
1365         [OP_LOOKUP]             = (nfsd4_dec)nfsd4_decode_lookup,
1366         [OP_LOOKUPP]            = (nfsd4_dec)nfsd4_decode_noop,
1367         [OP_NVERIFY]            = (nfsd4_dec)nfsd4_decode_verify,
1368         [OP_OPEN]               = (nfsd4_dec)nfsd4_decode_open,
1369         [OP_OPENATTR]           = (nfsd4_dec)nfsd4_decode_notsupp,
1370         [OP_OPEN_CONFIRM]       = (nfsd4_dec)nfsd4_decode_open_confirm,
1371         [OP_OPEN_DOWNGRADE]     = (nfsd4_dec)nfsd4_decode_open_downgrade,
1372         [OP_PUTFH]              = (nfsd4_dec)nfsd4_decode_putfh,
1373         [OP_PUTPUBFH]           = (nfsd4_dec)nfsd4_decode_noop,
1374         [OP_PUTROOTFH]          = (nfsd4_dec)nfsd4_decode_noop,
1375         [OP_READ]               = (nfsd4_dec)nfsd4_decode_read,
1376         [OP_READDIR]            = (nfsd4_dec)nfsd4_decode_readdir,
1377         [OP_READLINK]           = (nfsd4_dec)nfsd4_decode_noop,
1378         [OP_REMOVE]             = (nfsd4_dec)nfsd4_decode_remove,
1379         [OP_RENAME]             = (nfsd4_dec)nfsd4_decode_rename,
1380         [OP_RENEW]              = (nfsd4_dec)nfsd4_decode_renew,
1381         [OP_RESTOREFH]          = (nfsd4_dec)nfsd4_decode_noop,
1382         [OP_SAVEFH]             = (nfsd4_dec)nfsd4_decode_noop,
1383         [OP_SECINFO]            = (nfsd4_dec)nfsd4_decode_secinfo,
1384         [OP_SETATTR]            = (nfsd4_dec)nfsd4_decode_setattr,
1385         [OP_SETCLIENTID]        = (nfsd4_dec)nfsd4_decode_setclientid,
1386         [OP_SETCLIENTID_CONFIRM] = (nfsd4_dec)nfsd4_decode_setclientid_confirm,
1387         [OP_VERIFY]             = (nfsd4_dec)nfsd4_decode_verify,
1388         [OP_WRITE]              = (nfsd4_dec)nfsd4_decode_write,
1389         [OP_RELEASE_LOCKOWNER]  = (nfsd4_dec)nfsd4_decode_release_lockowner,
1390 };
1391
1392 static nfsd4_dec nfsd41_dec_ops[] = {
1393         [OP_ACCESS]             = (nfsd4_dec)nfsd4_decode_access,
1394         [OP_CLOSE]              = (nfsd4_dec)nfsd4_decode_close,
1395         [OP_COMMIT]             = (nfsd4_dec)nfsd4_decode_commit,
1396         [OP_CREATE]             = (nfsd4_dec)nfsd4_decode_create,
1397         [OP_DELEGPURGE]         = (nfsd4_dec)nfsd4_decode_notsupp,
1398         [OP_DELEGRETURN]        = (nfsd4_dec)nfsd4_decode_delegreturn,
1399         [OP_GETATTR]            = (nfsd4_dec)nfsd4_decode_getattr,
1400         [OP_GETFH]              = (nfsd4_dec)nfsd4_decode_noop,
1401         [OP_LINK]               = (nfsd4_dec)nfsd4_decode_link,
1402         [OP_LOCK]               = (nfsd4_dec)nfsd4_decode_lock,
1403         [OP_LOCKT]              = (nfsd4_dec)nfsd4_decode_lockt,
1404         [OP_LOCKU]              = (nfsd4_dec)nfsd4_decode_locku,
1405         [OP_LOOKUP]             = (nfsd4_dec)nfsd4_decode_lookup,
1406         [OP_LOOKUPP]            = (nfsd4_dec)nfsd4_decode_noop,
1407         [OP_NVERIFY]            = (nfsd4_dec)nfsd4_decode_verify,
1408         [OP_OPEN]               = (nfsd4_dec)nfsd4_decode_open,
1409         [OP_OPENATTR]           = (nfsd4_dec)nfsd4_decode_notsupp,
1410         [OP_OPEN_CONFIRM]       = (nfsd4_dec)nfsd4_decode_notsupp,
1411         [OP_OPEN_DOWNGRADE]     = (nfsd4_dec)nfsd4_decode_open_downgrade,
1412         [OP_PUTFH]              = (nfsd4_dec)nfsd4_decode_putfh,
1413         [OP_PUTPUBFH]           = (nfsd4_dec)nfsd4_decode_notsupp,
1414         [OP_PUTROOTFH]          = (nfsd4_dec)nfsd4_decode_noop,
1415         [OP_READ]               = (nfsd4_dec)nfsd4_decode_read,
1416         [OP_READDIR]            = (nfsd4_dec)nfsd4_decode_readdir,
1417         [OP_READLINK]           = (nfsd4_dec)nfsd4_decode_noop,
1418         [OP_REMOVE]             = (nfsd4_dec)nfsd4_decode_remove,
1419         [OP_RENAME]             = (nfsd4_dec)nfsd4_decode_rename,
1420         [OP_RENEW]              = (nfsd4_dec)nfsd4_decode_notsupp,
1421         [OP_RESTOREFH]          = (nfsd4_dec)nfsd4_decode_noop,
1422         [OP_SAVEFH]             = (nfsd4_dec)nfsd4_decode_noop,
1423         [OP_SECINFO]            = (nfsd4_dec)nfsd4_decode_secinfo,
1424         [OP_SETATTR]            = (nfsd4_dec)nfsd4_decode_setattr,
1425         [OP_SETCLIENTID]        = (nfsd4_dec)nfsd4_decode_notsupp,
1426         [OP_SETCLIENTID_CONFIRM]= (nfsd4_dec)nfsd4_decode_notsupp,
1427         [OP_VERIFY]             = (nfsd4_dec)nfsd4_decode_verify,
1428         [OP_WRITE]              = (nfsd4_dec)nfsd4_decode_write,
1429         [OP_RELEASE_LOCKOWNER]  = (nfsd4_dec)nfsd4_decode_notsupp,
1430
1431         /* new operations for NFSv4.1 */
1432         [OP_BACKCHANNEL_CTL]    = (nfsd4_dec)nfsd4_decode_notsupp,
1433         [OP_BIND_CONN_TO_SESSION]= (nfsd4_dec)nfsd4_decode_bind_conn_to_session,
1434         [OP_EXCHANGE_ID]        = (nfsd4_dec)nfsd4_decode_exchange_id,
1435         [OP_CREATE_SESSION]     = (nfsd4_dec)nfsd4_decode_create_session,
1436         [OP_DESTROY_SESSION]    = (nfsd4_dec)nfsd4_decode_destroy_session,
1437         [OP_FREE_STATEID]       = (nfsd4_dec)nfsd4_decode_free_stateid,
1438         [OP_GET_DIR_DELEGATION] = (nfsd4_dec)nfsd4_decode_notsupp,
1439         [OP_GETDEVICEINFO]      = (nfsd4_dec)nfsd4_decode_notsupp,
1440         [OP_GETDEVICELIST]      = (nfsd4_dec)nfsd4_decode_notsupp,
1441         [OP_LAYOUTCOMMIT]       = (nfsd4_dec)nfsd4_decode_notsupp,
1442         [OP_LAYOUTGET]          = (nfsd4_dec)nfsd4_decode_notsupp,
1443         [OP_LAYOUTRETURN]       = (nfsd4_dec)nfsd4_decode_notsupp,
1444         [OP_SECINFO_NO_NAME]    = (nfsd4_dec)nfsd4_decode_secinfo_no_name,
1445         [OP_SEQUENCE]           = (nfsd4_dec)nfsd4_decode_sequence,
1446         [OP_SET_SSV]            = (nfsd4_dec)nfsd4_decode_notsupp,
1447         [OP_TEST_STATEID]       = (nfsd4_dec)nfsd4_decode_test_stateid,
1448         [OP_WANT_DELEGATION]    = (nfsd4_dec)nfsd4_decode_notsupp,
1449         [OP_DESTROY_CLIENTID]   = (nfsd4_dec)nfsd4_decode_notsupp,
1450         [OP_RECLAIM_COMPLETE]   = (nfsd4_dec)nfsd4_decode_reclaim_complete,
1451 };
1452
1453 struct nfsd4_minorversion_ops {
1454         nfsd4_dec *decoders;
1455         int nops;
1456 };
1457
1458 static struct nfsd4_minorversion_ops nfsd4_minorversion[] = {
1459         [0] = { nfsd4_dec_ops, ARRAY_SIZE(nfsd4_dec_ops) },
1460         [1] = { nfsd41_dec_ops, ARRAY_SIZE(nfsd41_dec_ops) },
1461 };
1462
1463 static __be32
1464 nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
1465 {
1466         DECODE_HEAD;
1467         struct nfsd4_op *op;
1468         struct nfsd4_minorversion_ops *ops;
1469         int i;
1470
1471         /*
1472          * XXX: According to spec, we should check the tag
1473          * for UTF-8 compliance.  I'm postponing this for
1474          * now because it seems that some clients do use
1475          * binary tags.
1476          */
1477         READ_BUF(4);
1478         READ32(argp->taglen);
1479         READ_BUF(argp->taglen + 8);
1480         SAVEMEM(argp->tag, argp->taglen);
1481         READ32(argp->minorversion);
1482         READ32(argp->opcnt);
1483
1484         if (argp->taglen > NFSD4_MAX_TAGLEN)
1485                 goto xdr_error;
1486         if (argp->opcnt > 100)
1487                 goto xdr_error;
1488
1489         if (argp->opcnt > ARRAY_SIZE(argp->iops)) {
1490                 argp->ops = kmalloc(argp->opcnt * sizeof(*argp->ops), GFP_KERNEL);
1491                 if (!argp->ops) {
1492                         argp->ops = argp->iops;
1493                         dprintk("nfsd: couldn't allocate room for COMPOUND\n");
1494                         goto xdr_error;
1495                 }
1496         }
1497
1498         if (argp->minorversion >= ARRAY_SIZE(nfsd4_minorversion))
1499                 argp->opcnt = 0;
1500
1501         ops = &nfsd4_minorversion[argp->minorversion];
1502         for (i = 0; i < argp->opcnt; i++) {
1503                 op = &argp->ops[i];
1504                 op->replay = NULL;
1505
1506                 /*
1507                  * We can't use READ_BUF() here because we need to handle
1508                  * a missing opcode as an OP_WRITE + 1. So we need to check
1509                  * to see if we're truly at the end of our buffer or if there
1510                  * is another page we need to flip to.
1511                  */
1512
1513                 if (argp->p == argp->end) {
1514                         if (argp->pagelen < 4) {
1515                                 /* There isn't an opcode still on the wire */
1516                                 op->opnum = OP_WRITE + 1;
1517                                 op->status = nfserr_bad_xdr;
1518                                 argp->opcnt = i+1;
1519                                 break;
1520                         }
1521
1522                         /*
1523                          * False alarm. We just hit a page boundary, but there
1524                          * is still data available.  Move pointer across page
1525                          * boundary.  *snip from READ_BUF*
1526                          */
1527                         argp->p = page_address(argp->pagelist[0]);
1528                         argp->pagelist++;
1529                         if (argp->pagelen < PAGE_SIZE) {
1530                                 argp->end = argp->p + (argp->pagelen>>2);
1531                                 argp->pagelen = 0;
1532                         } else {
1533                                 argp->end = argp->p + (PAGE_SIZE>>2);
1534                                 argp->pagelen -= PAGE_SIZE;
1535                         }
1536                 }
1537                 op->opnum = ntohl(*argp->p++);
1538
1539                 if (op->opnum >= FIRST_NFS4_OP && op->opnum <= LAST_NFS4_OP)
1540                         op->status = ops->decoders[op->opnum](argp, &op->u);
1541                 else {
1542                         op->opnum = OP_ILLEGAL;
1543                         op->status = nfserr_op_illegal;
1544                 }
1545
1546                 if (op->status) {
1547                         argp->opcnt = i+1;
1548                         break;
1549                 }
1550         }
1551
1552         DECODE_TAIL;
1553 }
1554
1555 #define WRITE32(n)               *p++ = htonl(n)
1556 #define WRITE64(n)               do {                           \
1557         *p++ = htonl((u32)((n) >> 32));                         \
1558         *p++ = htonl((u32)(n));                                 \
1559 } while (0)
1560 #define WRITEMEM(ptr,nbytes)     do { if (nbytes > 0) {         \
1561         *(p + XDR_QUADLEN(nbytes) -1) = 0;                      \
1562         memcpy(p, ptr, nbytes);                                 \
1563         p += XDR_QUADLEN(nbytes);                               \
1564 }} while (0)
1565
1566 static void write32(__be32 **p, u32 n)
1567 {
1568         *(*p)++ = n;
1569 }
1570
1571 static void write64(__be32 **p, u64 n)
1572 {
1573         write32(p, (u32)(n >> 32));
1574         write32(p, (u32)n);
1575 }
1576
1577 static void write_change(__be32 **p, struct kstat *stat, struct inode *inode)
1578 {
1579         if (IS_I_VERSION(inode)) {
1580                 write64(p, inode->i_version);
1581         } else {
1582                 write32(p, stat->ctime.tv_sec);
1583                 write32(p, stat->ctime.tv_nsec);
1584         }
1585 }
1586
1587 static void write_cinfo(__be32 **p, struct nfsd4_change_info *c)
1588 {
1589         write32(p, c->atomic);
1590         if (c->change_supported) {
1591                 write64(p, c->before_change);
1592                 write64(p, c->after_change);
1593         } else {
1594                 write32(p, c->before_ctime_sec);
1595                 write32(p, c->before_ctime_nsec);
1596                 write32(p, c->after_ctime_sec);
1597                 write32(p, c->after_ctime_nsec);
1598         }
1599 }
1600
1601 #define RESERVE_SPACE(nbytes)   do {                            \
1602         p = resp->p;                                            \
1603         BUG_ON(p + XDR_QUADLEN(nbytes) > resp->end);            \
1604 } while (0)
1605 #define ADJUST_ARGS()           resp->p = p
1606
1607 /*
1608  * Header routine to setup seqid operation replay cache
1609  */
1610 #define ENCODE_SEQID_OP_HEAD                                    \
1611         __be32 *save;                                           \
1612                                                                 \
1613         save = resp->p;
1614
1615 /*
1616  * Routine for encoding the result of a "seqid-mutating" NFSv4 operation.  This
1617  * is where sequence id's are incremented, and the replay cache is filled.
1618  * Note that we increment sequence id's here, at the last moment, so we're sure
1619  * we know whether the error to be returned is a sequence id mutating error.
1620  */
1621
1622 #define ENCODE_SEQID_OP_TAIL(stateowner) do {                   \
1623         if (seqid_mutating_err(nfserr) && stateowner) {         \
1624                 stateowner->so_seqid++;                         \
1625                 stateowner->so_replay.rp_status = nfserr;       \
1626                 stateowner->so_replay.rp_buflen =               \
1627                           (((char *)(resp)->p - (char *)save)); \
1628                 memcpy(stateowner->so_replay.rp_buf, save,      \
1629                         stateowner->so_replay.rp_buflen);       \
1630         } } while (0);
1631
1632 /* Encode as an array of strings the string given with components
1633  * separated @sep.
1634  */
1635 static __be32 nfsd4_encode_components(char sep, char *components,
1636                                    __be32 **pp, int *buflen)
1637 {
1638         __be32 *p = *pp;
1639         __be32 *countp = p;
1640         int strlen, count=0;
1641         char *str, *end;
1642
1643         dprintk("nfsd4_encode_components(%s)\n", components);
1644         if ((*buflen -= 4) < 0)
1645                 return nfserr_resource;
1646         WRITE32(0); /* We will fill this in with @count later */
1647         end = str = components;
1648         while (*end) {
1649                 for (; *end && (*end != sep); end++)
1650                         ; /* Point to end of component */
1651                 strlen = end - str;
1652                 if (strlen) {
1653                         if ((*buflen -= ((XDR_QUADLEN(strlen) << 2) + 4)) < 0)
1654                                 return nfserr_resource;
1655                         WRITE32(strlen);
1656                         WRITEMEM(str, strlen);
1657                         count++;
1658                 }
1659                 else
1660                         end++;
1661                 str = end;
1662         }
1663         *pp = p;
1664         p = countp;
1665         WRITE32(count);
1666         return 0;
1667 }
1668
1669 /*
1670  * encode a location element of a fs_locations structure
1671  */
1672 static __be32 nfsd4_encode_fs_location4(struct nfsd4_fs_location *location,
1673                                     __be32 **pp, int *buflen)
1674 {
1675         __be32 status;
1676         __be32 *p = *pp;
1677
1678         status = nfsd4_encode_components(':', location->hosts, &p, buflen);
1679         if (status)
1680                 return status;
1681         status = nfsd4_encode_components('/', location->path, &p, buflen);
1682         if (status)
1683                 return status;
1684         *pp = p;
1685         return 0;
1686 }
1687
1688 /*
1689  * Return the path to an export point in the pseudo filesystem namespace
1690  * Returned string is safe to use as long as the caller holds a reference
1691  * to @exp.
1692  */
1693 static char *nfsd4_path(struct svc_rqst *rqstp, struct svc_export *exp, __be32 *stat)
1694 {
1695         struct svc_fh tmp_fh;
1696         char *path = NULL, *rootpath;
1697         size_t rootlen;
1698
1699         fh_init(&tmp_fh, NFS4_FHSIZE);
1700         *stat = exp_pseudoroot(rqstp, &tmp_fh);
1701         if (*stat)
1702                 return NULL;
1703         rootpath = tmp_fh.fh_export->ex_pathname;
1704
1705         path = exp->ex_pathname;
1706
1707         rootlen = strlen(rootpath);
1708         if (strncmp(path, rootpath, rootlen)) {
1709                 dprintk("nfsd: fs_locations failed;"
1710                         "%s is not contained in %s\n", path, rootpath);
1711                 *stat = nfserr_notsupp;
1712                 path = NULL;
1713                 goto out;
1714         }
1715         path += rootlen;
1716 out:
1717         fh_put(&tmp_fh);
1718         return path;
1719 }
1720
1721 /*
1722  *  encode a fs_locations structure
1723  */
1724 static __be32 nfsd4_encode_fs_locations(struct svc_rqst *rqstp,
1725                                      struct svc_export *exp,
1726                                      __be32 **pp, int *buflen)
1727 {
1728         __be32 status;
1729         int i;
1730         __be32 *p = *pp;
1731         struct nfsd4_fs_locations *fslocs = &exp->ex_fslocs;
1732         char *root = nfsd4_path(rqstp, exp, &status);
1733
1734         if (status)
1735                 return status;
1736         status = nfsd4_encode_components('/', root, &p, buflen);
1737         if (status)
1738                 return status;
1739         if ((*buflen -= 4) < 0)
1740                 return nfserr_resource;
1741         WRITE32(fslocs->locations_count);
1742         for (i=0; i<fslocs->locations_count; i++) {
1743                 status = nfsd4_encode_fs_location4(&fslocs->locations[i],
1744                                                    &p, buflen);
1745                 if (status)
1746                         return status;
1747         }
1748         *pp = p;
1749         return 0;
1750 }
1751
1752 static u32 nfs4_ftypes[16] = {
1753         NF4BAD,  NF4FIFO, NF4CHR, NF4BAD,
1754         NF4DIR,  NF4BAD,  NF4BLK, NF4BAD,
1755         NF4REG,  NF4BAD,  NF4LNK, NF4BAD,
1756         NF4SOCK, NF4BAD,  NF4LNK, NF4BAD,
1757 };
1758
1759 static __be32
1760 nfsd4_encode_name(struct svc_rqst *rqstp, int whotype, uid_t id, int group,
1761                         __be32 **p, int *buflen)
1762 {
1763         int status;
1764
1765         if (*buflen < (XDR_QUADLEN(IDMAP_NAMESZ) << 2) + 4)
1766                 return nfserr_resource;
1767         if (whotype != NFS4_ACL_WHO_NAMED)
1768                 status = nfs4_acl_write_who(whotype, (u8 *)(*p + 1));
1769         else if (group)
1770                 status = nfsd_map_gid_to_name(rqstp, id, (u8 *)(*p + 1));
1771         else
1772                 status = nfsd_map_uid_to_name(rqstp, id, (u8 *)(*p + 1));
1773         if (status < 0)
1774                 return nfserrno(status);
1775         *p = xdr_encode_opaque(*p, NULL, status);
1776         *buflen -= (XDR_QUADLEN(status) << 2) + 4;
1777         BUG_ON(*buflen < 0);
1778         return 0;
1779 }
1780
1781 static inline __be32
1782 nfsd4_encode_user(struct svc_rqst *rqstp, uid_t uid, __be32 **p, int *buflen)
1783 {
1784         return nfsd4_encode_name(rqstp, NFS4_ACL_WHO_NAMED, uid, 0, p, buflen);
1785 }
1786
1787 static inline __be32
1788 nfsd4_encode_group(struct svc_rqst *rqstp, uid_t gid, __be32 **p, int *buflen)
1789 {
1790         return nfsd4_encode_name(rqstp, NFS4_ACL_WHO_NAMED, gid, 1, p, buflen);
1791 }
1792
1793 static inline __be32
1794 nfsd4_encode_aclname(struct svc_rqst *rqstp, int whotype, uid_t id, int group,
1795                 __be32 **p, int *buflen)
1796 {
1797         return nfsd4_encode_name(rqstp, whotype, id, group, p, buflen);
1798 }
1799
1800 #define WORD0_ABSENT_FS_ATTRS (FATTR4_WORD0_FS_LOCATIONS | FATTR4_WORD0_FSID | \
1801                               FATTR4_WORD0_RDATTR_ERROR)
1802 #define WORD1_ABSENT_FS_ATTRS FATTR4_WORD1_MOUNTED_ON_FILEID
1803
1804 static __be32 fattr_handle_absent_fs(u32 *bmval0, u32 *bmval1, u32 *rdattr_err)
1805 {
1806         /* As per referral draft:  */
1807         if (*bmval0 & ~WORD0_ABSENT_FS_ATTRS ||
1808             *bmval1 & ~WORD1_ABSENT_FS_ATTRS) {
1809                 if (*bmval0 & FATTR4_WORD0_RDATTR_ERROR ||
1810                     *bmval0 & FATTR4_WORD0_FS_LOCATIONS)
1811                         *rdattr_err = NFSERR_MOVED;
1812                 else
1813                         return nfserr_moved;
1814         }
1815         *bmval0 &= WORD0_ABSENT_FS_ATTRS;
1816         *bmval1 &= WORD1_ABSENT_FS_ATTRS;
1817         return 0;
1818 }
1819
1820 /*
1821  * Note: @fhp can be NULL; in this case, we might have to compose the filehandle
1822  * ourselves.
1823  *
1824  * @countp is the buffer size in _words_; upon successful return this becomes
1825  * replaced with the number of words written.
1826  */
1827 __be32
1828 nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
1829                 struct dentry *dentry, __be32 *buffer, int *countp, u32 *bmval,
1830                 struct svc_rqst *rqstp, int ignore_crossmnt)
1831 {
1832         u32 bmval0 = bmval[0];
1833         u32 bmval1 = bmval[1];
1834         u32 bmval2 = bmval[2];
1835         struct kstat stat;
1836         struct svc_fh tempfh;
1837         struct kstatfs statfs;
1838         int buflen = *countp << 2;
1839         __be32 *attrlenp;
1840         u32 dummy;
1841         u64 dummy64;
1842         u32 rdattr_err = 0;
1843         __be32 *p = buffer;
1844         __be32 status;
1845         int err;
1846         int aclsupport = 0;
1847         struct nfs4_acl *acl = NULL;
1848         struct nfsd4_compoundres *resp = rqstp->rq_resp;
1849         u32 minorversion = resp->cstate.minorversion;
1850         struct path path = {
1851                 .mnt    = exp->ex_path.mnt,
1852                 .dentry = dentry,
1853         };
1854
1855         BUG_ON(bmval1 & NFSD_WRITEONLY_ATTRS_WORD1);
1856         BUG_ON(bmval0 & ~nfsd_suppattrs0(minorversion));
1857         BUG_ON(bmval1 & ~nfsd_suppattrs1(minorversion));
1858         BUG_ON(bmval2 & ~nfsd_suppattrs2(minorversion));
1859
1860         if (exp->ex_fslocs.migrated) {
1861                 BUG_ON(bmval[2]);
1862                 status = fattr_handle_absent_fs(&bmval0, &bmval1, &rdattr_err);
1863                 if (status)
1864                         goto out;
1865         }
1866
1867         err = vfs_getattr(exp->ex_path.mnt, dentry, &stat);
1868         if (err)
1869                 goto out_nfserr;
1870         if ((bmval0 & (FATTR4_WORD0_FILES_FREE | FATTR4_WORD0_FILES_TOTAL |
1871                         FATTR4_WORD0_MAXNAME)) ||
1872             (bmval1 & (FATTR4_WORD1_SPACE_AVAIL | FATTR4_WORD1_SPACE_FREE |
1873                        FATTR4_WORD1_SPACE_TOTAL))) {
1874                 err = vfs_statfs(&path, &statfs);
1875                 if (err)
1876                         goto out_nfserr;
1877         }
1878         if ((bmval0 & (FATTR4_WORD0_FILEHANDLE | FATTR4_WORD0_FSID)) && !fhp) {
1879                 fh_init(&tempfh, NFS4_FHSIZE);
1880                 status = fh_compose(&tempfh, exp, dentry, NULL);
1881                 if (status)
1882                         goto out;
1883                 fhp = &tempfh;
1884         }
1885         if (bmval0 & (FATTR4_WORD0_ACL | FATTR4_WORD0_ACLSUPPORT
1886                         | FATTR4_WORD0_SUPPORTED_ATTRS)) {
1887                 err = nfsd4_get_nfs4_acl(rqstp, dentry, &acl);
1888                 aclsupport = (err == 0);
1889                 if (bmval0 & FATTR4_WORD0_ACL) {
1890                         if (err == -EOPNOTSUPP)
1891                                 bmval0 &= ~FATTR4_WORD0_ACL;
1892                         else if (err == -EINVAL) {
1893                                 status = nfserr_attrnotsupp;
1894                                 goto out;
1895                         } else if (err != 0)
1896                                 goto out_nfserr;
1897                 }
1898         }
1899
1900         if (bmval2) {
1901                 if ((buflen -= 16) < 0)
1902                         goto out_resource;
1903                 WRITE32(3);
1904                 WRITE32(bmval0);
1905                 WRITE32(bmval1);
1906                 WRITE32(bmval2);
1907         } else if (bmval1) {
1908                 if ((buflen -= 12) < 0)
1909                         goto out_resource;
1910                 WRITE32(2);
1911                 WRITE32(bmval0);
1912                 WRITE32(bmval1);
1913         } else {
1914                 if ((buflen -= 8) < 0)
1915                         goto out_resource;
1916                 WRITE32(1);
1917                 WRITE32(bmval0);
1918         }
1919         attrlenp = p++;                /* to be backfilled later */
1920
1921         if (bmval0 & FATTR4_WORD0_SUPPORTED_ATTRS) {
1922                 u32 word0 = nfsd_suppattrs0(minorversion);
1923                 u32 word1 = nfsd_suppattrs1(minorversion);
1924                 u32 word2 = nfsd_suppattrs2(minorversion);
1925
1926                 if (!aclsupport)
1927                         word0 &= ~FATTR4_WORD0_ACL;
1928                 if (!word2) {
1929                         if ((buflen -= 12) < 0)
1930                                 goto out_resource;
1931                         WRITE32(2);
1932                         WRITE32(word0);
1933                         WRITE32(word1);
1934                 } else {
1935                         if ((buflen -= 16) < 0)
1936                                 goto out_resource;
1937                         WRITE32(3);
1938                         WRITE32(word0);
1939                         WRITE32(word1);
1940                         WRITE32(word2);
1941                 }
1942         }
1943         if (bmval0 & FATTR4_WORD0_TYPE) {
1944                 if ((buflen -= 4) < 0)
1945                         goto out_resource;
1946                 dummy = nfs4_ftypes[(stat.mode & S_IFMT) >> 12];
1947                 if (dummy == NF4BAD)
1948                         goto out_serverfault;
1949                 WRITE32(dummy);
1950         }
1951         if (bmval0 & FATTR4_WORD0_FH_EXPIRE_TYPE) {
1952                 if ((buflen -= 4) < 0)
1953                         goto out_resource;
1954                 if (exp->ex_flags & NFSEXP_NOSUBTREECHECK)
1955                         WRITE32(NFS4_FH_PERSISTENT);
1956                 else
1957                         WRITE32(NFS4_FH_PERSISTENT|NFS4_FH_VOL_RENAME);
1958         }
1959         if (bmval0 & FATTR4_WORD0_CHANGE) {
1960                 if ((buflen -= 8) < 0)
1961                         goto out_resource;
1962                 write_change(&p, &stat, dentry->d_inode);
1963         }
1964         if (bmval0 & FATTR4_WORD0_SIZE) {
1965                 if ((buflen -= 8) < 0)
1966                         goto out_resource;
1967                 WRITE64(stat.size);
1968         }
1969         if (bmval0 & FATTR4_WORD0_LINK_SUPPORT) {
1970                 if ((buflen -= 4) < 0)
1971                         goto out_resource;
1972                 WRITE32(1);
1973         }
1974         if (bmval0 & FATTR4_WORD0_SYMLINK_SUPPORT) {
1975                 if ((buflen -= 4) < 0)
1976                         goto out_resource;
1977                 WRITE32(1);
1978         }
1979         if (bmval0 & FATTR4_WORD0_NAMED_ATTR) {
1980                 if ((buflen -= 4) < 0)
1981                         goto out_resource;
1982                 WRITE32(0);
1983         }
1984         if (bmval0 & FATTR4_WORD0_FSID) {
1985                 if ((buflen -= 16) < 0)
1986                         goto out_resource;
1987                 if (exp->ex_fslocs.migrated) {
1988                         WRITE64(NFS4_REFERRAL_FSID_MAJOR);
1989                         WRITE64(NFS4_REFERRAL_FSID_MINOR);
1990                 } else switch(fsid_source(fhp)) {
1991                 case FSIDSOURCE_FSID:
1992                         WRITE64((u64)exp->ex_fsid);
1993                         WRITE64((u64)0);
1994                         break;
1995                 case FSIDSOURCE_DEV:
1996                         WRITE32(0);
1997                         WRITE32(MAJOR(stat.dev));
1998                         WRITE32(0);
1999                         WRITE32(MINOR(stat.dev));
2000                         break;
2001                 case FSIDSOURCE_UUID:
2002                         WRITEMEM(exp->ex_uuid, 16);
2003                         break;
2004                 }
2005         }
2006         if (bmval0 & FATTR4_WORD0_UNIQUE_HANDLES) {
2007                 if ((buflen -= 4) < 0)
2008                         goto out_resource;
2009                 WRITE32(0);
2010         }
2011         if (bmval0 & FATTR4_WORD0_LEASE_TIME) {
2012                 if ((buflen -= 4) < 0)
2013                         goto out_resource;
2014                 WRITE32(nfsd4_lease);
2015         }
2016         if (bmval0 & FATTR4_WORD0_RDATTR_ERROR) {
2017                 if ((buflen -= 4) < 0)
2018                         goto out_resource;
2019                 WRITE32(rdattr_err);
2020         }
2021         if (bmval0 & FATTR4_WORD0_ACL) {
2022                 struct nfs4_ace *ace;
2023
2024                 if (acl == NULL) {
2025                         if ((buflen -= 4) < 0)
2026                                 goto out_resource;
2027
2028                         WRITE32(0);
2029                         goto out_acl;
2030                 }
2031                 if ((buflen -= 4) < 0)
2032                         goto out_resource;
2033                 WRITE32(acl->naces);
2034
2035                 for (ace = acl->aces; ace < acl->aces + acl->naces; ace++) {
2036                         if ((buflen -= 4*3) < 0)
2037                                 goto out_resource;
2038                         WRITE32(ace->type);
2039                         WRITE32(ace->flag);
2040                         WRITE32(ace->access_mask & NFS4_ACE_MASK_ALL);
2041                         status = nfsd4_encode_aclname(rqstp, ace->whotype,
2042                                 ace->who, ace->flag & NFS4_ACE_IDENTIFIER_GROUP,
2043                                 &p, &buflen);
2044                         if (status == nfserr_resource)
2045                                 goto out_resource;
2046                         if (status)
2047                                 goto out;
2048                 }
2049         }
2050 out_acl:
2051         if (bmval0 & FATTR4_WORD0_ACLSUPPORT) {
2052                 if ((buflen -= 4) < 0)
2053                         goto out_resource;
2054                 WRITE32(aclsupport ?
2055                         ACL4_SUPPORT_ALLOW_ACL|ACL4_SUPPORT_DENY_ACL : 0);
2056         }
2057         if (bmval0 & FATTR4_WORD0_CANSETTIME) {
2058                 if ((buflen -= 4) < 0)
2059                         goto out_resource;
2060                 WRITE32(1);
2061         }
2062         if (bmval0 & FATTR4_WORD0_CASE_INSENSITIVE) {
2063                 if ((buflen -= 4) < 0)
2064                         goto out_resource;
2065                 WRITE32(1);
2066         }
2067         if (bmval0 & FATTR4_WORD0_CASE_PRESERVING) {
2068                 if ((buflen -= 4) < 0)
2069                         goto out_resource;
2070                 WRITE32(1);
2071         }
2072         if (bmval0 & FATTR4_WORD0_CHOWN_RESTRICTED) {
2073                 if ((buflen -= 4) < 0)
2074                         goto out_resource;
2075                 WRITE32(1);
2076         }
2077         if (bmval0 & FATTR4_WORD0_FILEHANDLE) {
2078                 buflen -= (XDR_QUADLEN(fhp->fh_handle.fh_size) << 2) + 4;
2079                 if (buflen < 0)
2080                         goto out_resource;
2081                 WRITE32(fhp->fh_handle.fh_size);
2082                 WRITEMEM(&fhp->fh_handle.fh_base, fhp->fh_handle.fh_size);
2083         }
2084         if (bmval0 & FATTR4_WORD0_FILEID) {
2085                 if ((buflen -= 8) < 0)
2086                         goto out_resource;
2087                 WRITE64(stat.ino);
2088         }
2089         if (bmval0 & FATTR4_WORD0_FILES_AVAIL) {
2090                 if ((buflen -= 8) < 0)
2091                         goto out_resource;
2092                 WRITE64((u64) statfs.f_ffree);
2093         }
2094         if (bmval0 & FATTR4_WORD0_FILES_FREE) {
2095                 if ((buflen -= 8) < 0)
2096                         goto out_resource;
2097                 WRITE64((u64) statfs.f_ffree);
2098         }
2099         if (bmval0 & FATTR4_WORD0_FILES_TOTAL) {
2100                 if ((buflen -= 8) < 0)
2101                         goto out_resource;
2102                 WRITE64((u64) statfs.f_files);
2103         }
2104         if (bmval0 & FATTR4_WORD0_FS_LOCATIONS) {
2105                 status = nfsd4_encode_fs_locations(rqstp, exp, &p, &buflen);
2106                 if (status == nfserr_resource)
2107                         goto out_resource;
2108                 if (status)
2109                         goto out;
2110         }
2111         if (bmval0 & FATTR4_WORD0_HOMOGENEOUS) {
2112                 if ((buflen -= 4) < 0)
2113                         goto out_resource;
2114                 WRITE32(1);
2115         }
2116         if (bmval0 & FATTR4_WORD0_MAXFILESIZE) {
2117                 if ((buflen -= 8) < 0)
2118                         goto out_resource;
2119                 WRITE64(~(u64)0);
2120         }
2121         if (bmval0 & FATTR4_WORD0_MAXLINK) {
2122                 if ((buflen -= 4) < 0)
2123                         goto out_resource;
2124                 WRITE32(255);
2125         }
2126         if (bmval0 & FATTR4_WORD0_MAXNAME) {
2127                 if ((buflen -= 4) < 0)
2128                         goto out_resource;
2129                 WRITE32(statfs.f_namelen);
2130         }
2131         if (bmval0 & FATTR4_WORD0_MAXREAD) {
2132                 if ((buflen -= 8) < 0)
2133                         goto out_resource;
2134                 WRITE64((u64) svc_max_payload(rqstp));
2135         }
2136         if (bmval0 & FATTR4_WORD0_MAXWRITE) {
2137                 if ((buflen -= 8) < 0)
2138                         goto out_resource;
2139                 WRITE64((u64) svc_max_payload(rqstp));
2140         }
2141         if (bmval1 & FATTR4_WORD1_MODE) {
2142                 if ((buflen -= 4) < 0)
2143                         goto out_resource;
2144                 WRITE32(stat.mode & S_IALLUGO);
2145         }
2146         if (bmval1 & FATTR4_WORD1_NO_TRUNC) {
2147                 if ((buflen -= 4) < 0)
2148                         goto out_resource;
2149                 WRITE32(1);
2150         }
2151         if (bmval1 & FATTR4_WORD1_NUMLINKS) {
2152                 if ((buflen -= 4) < 0)
2153                         goto out_resource;
2154                 WRITE32(stat.nlink);
2155         }
2156         if (bmval1 & FATTR4_WORD1_OWNER) {
2157                 status = nfsd4_encode_user(rqstp, stat.uid, &p, &buflen);
2158                 if (status == nfserr_resource)
2159                         goto out_resource;
2160                 if (status)
2161                         goto out;
2162         }
2163         if (bmval1 & FATTR4_WORD1_OWNER_GROUP) {
2164                 status = nfsd4_encode_group(rqstp, stat.gid, &p, &buflen);
2165                 if (status == nfserr_resource)
2166                         goto out_resource;
2167                 if (status)
2168                         goto out;
2169         }
2170         if (bmval1 & FATTR4_WORD1_RAWDEV) {
2171                 if ((buflen -= 8) < 0)
2172                         goto out_resource;
2173                 WRITE32((u32) MAJOR(stat.rdev));
2174                 WRITE32((u32) MINOR(stat.rdev));
2175         }
2176         if (bmval1 & FATTR4_WORD1_SPACE_AVAIL) {
2177                 if ((buflen -= 8) < 0)
2178                         goto out_resource;
2179                 dummy64 = (u64)statfs.f_bavail * (u64)statfs.f_bsize;
2180                 WRITE64(dummy64);
2181         }
2182         if (bmval1 & FATTR4_WORD1_SPACE_FREE) {
2183                 if ((buflen -= 8) < 0)
2184                         goto out_resource;
2185                 dummy64 = (u64)statfs.f_bfree * (u64)statfs.f_bsize;
2186                 WRITE64(dummy64);
2187         }
2188         if (bmval1 & FATTR4_WORD1_SPACE_TOTAL) {
2189                 if ((buflen -= 8) < 0)
2190                         goto out_resource;
2191                 dummy64 = (u64)statfs.f_blocks * (u64)statfs.f_bsize;
2192                 WRITE64(dummy64);
2193         }
2194         if (bmval1 & FATTR4_WORD1_SPACE_USED) {
2195                 if ((buflen -= 8) < 0)
2196                         goto out_resource;
2197                 dummy64 = (u64)stat.blocks << 9;
2198                 WRITE64(dummy64);
2199         }
2200         if (bmval1 & FATTR4_WORD1_TIME_ACCESS) {
2201                 if ((buflen -= 12) < 0)
2202                         goto out_resource;
2203                 WRITE32(0);
2204                 WRITE32(stat.atime.tv_sec);
2205                 WRITE32(stat.atime.tv_nsec);
2206         }
2207         if (bmval1 & FATTR4_WORD1_TIME_DELTA) {
2208                 if ((buflen -= 12) < 0)
2209                         goto out_resource;
2210                 WRITE32(0);
2211                 WRITE32(1);
2212                 WRITE32(0);
2213         }
2214         if (bmval1 & FATTR4_WORD1_TIME_METADATA) {
2215                 if ((buflen -= 12) < 0)
2216                         goto out_resource;
2217                 WRITE32(0);
2218                 WRITE32(stat.ctime.tv_sec);
2219                 WRITE32(stat.ctime.tv_nsec);
2220         }
2221         if (bmval1 & FATTR4_WORD1_TIME_MODIFY) {
2222                 if ((buflen -= 12) < 0)
2223                         goto out_resource;
2224                 WRITE32(0);
2225                 WRITE32(stat.mtime.tv_sec);
2226                 WRITE32(stat.mtime.tv_nsec);
2227         }
2228         if (bmval1 & FATTR4_WORD1_MOUNTED_ON_FILEID) {
2229                 if ((buflen -= 8) < 0)
2230                         goto out_resource;
2231                 /*
2232                  * Get parent's attributes if not ignoring crossmount
2233                  * and this is the root of a cross-mounted filesystem.
2234                  */
2235                 if (ignore_crossmnt == 0 &&
2236                     dentry == exp->ex_path.mnt->mnt_root) {
2237                         struct path path = exp->ex_path;
2238                         path_get(&path);
2239                         while (follow_up(&path)) {
2240                                 if (path.dentry != path.mnt->mnt_root)
2241                                         break;
2242                         }
2243                         err = vfs_getattr(path.mnt, path.dentry, &stat);
2244                         path_put(&path);
2245                         if (err)
2246                                 goto out_nfserr;
2247                 }
2248                 WRITE64(stat.ino);
2249         }
2250         if (bmval2 & FATTR4_WORD2_SUPPATTR_EXCLCREAT) {
2251                 WRITE32(3);
2252                 WRITE32(NFSD_SUPPATTR_EXCLCREAT_WORD0);
2253                 WRITE32(NFSD_SUPPATTR_EXCLCREAT_WORD1);
2254                 WRITE32(NFSD_SUPPATTR_EXCLCREAT_WORD2);
2255         }
2256
2257         *attrlenp = htonl((char *)p - (char *)attrlenp - 4);
2258         *countp = p - buffer;
2259         status = nfs_ok;
2260
2261 out:
2262         kfree(acl);
2263         if (fhp == &tempfh)
2264                 fh_put(&tempfh);
2265         return status;
2266 out_nfserr:
2267         status = nfserrno(err);
2268         goto out;
2269 out_resource:
2270         *countp = 0;
2271         status = nfserr_resource;
2272         goto out;
2273 out_serverfault:
2274         status = nfserr_serverfault;
2275         goto out;
2276 }
2277
2278 static inline int attributes_need_mount(u32 *bmval)
2279 {
2280         if (bmval[0] & ~(FATTR4_WORD0_RDATTR_ERROR | FATTR4_WORD0_LEASE_TIME))
2281                 return 1;
2282         if (bmval[1] & ~FATTR4_WORD1_MOUNTED_ON_FILEID)
2283                 return 1;
2284         return 0;
2285 }
2286
2287 static __be32
2288 nfsd4_encode_dirent_fattr(struct nfsd4_readdir *cd,
2289                 const char *name, int namlen, __be32 *p, int *buflen)
2290 {
2291         struct svc_export *exp = cd->rd_fhp->fh_export;
2292         struct dentry *dentry;
2293         __be32 nfserr;
2294         int ignore_crossmnt = 0;
2295
2296         dentry = lookup_one_len(name, cd->rd_fhp->fh_dentry, namlen);
2297         if (IS_ERR(dentry))
2298                 return nfserrno(PTR_ERR(dentry));
2299         if (!dentry->d_inode) {
2300                 /*
2301                  * nfsd_buffered_readdir drops the i_mutex between
2302                  * readdir and calling this callback, leaving a window
2303                  * where this directory entry could have gone away.
2304                  */
2305                 dput(dentry);
2306                 return nfserr_noent;
2307         }
2308
2309         exp_get(exp);
2310         /*
2311          * In the case of a mountpoint, the client may be asking for
2312          * attributes that are only properties of the underlying filesystem
2313          * as opposed to the cross-mounted file system. In such a case,
2314          * we will not follow the cross mount and will fill the attribtutes
2315          * directly from the mountpoint dentry.
2316          */
2317         if (nfsd_mountpoint(dentry, exp)) {
2318                 int err;
2319
2320                 if (!(exp->ex_flags & NFSEXP_V4ROOT)
2321                                 && !attributes_need_mount(cd->rd_bmval)) {
2322                         ignore_crossmnt = 1;
2323                         goto out_encode;
2324                 }
2325                 /*
2326                  * Why the heck aren't we just using nfsd_lookup??
2327                  * Different "."/".." handling?  Something else?
2328                  * At least, add a comment here to explain....
2329                  */
2330                 err = nfsd_cross_mnt(cd->rd_rqstp, &dentry, &exp);
2331                 if (err) {
2332                         nfserr = nfserrno(err);
2333                         goto out_put;
2334                 }
2335                 nfserr = check_nfsd_access(exp, cd->rd_rqstp);
2336                 if (nfserr)
2337                         goto out_put;
2338
2339         }
2340 out_encode:
2341         nfserr = nfsd4_encode_fattr(NULL, exp, dentry, p, buflen, cd->rd_bmval,
2342                                         cd->rd_rqstp, ignore_crossmnt);
2343 out_put:
2344         dput(dentry);
2345         exp_put(exp);
2346         return nfserr;
2347 }
2348
2349 static __be32 *
2350 nfsd4_encode_rdattr_error(__be32 *p, int buflen, __be32 nfserr)
2351 {
2352         __be32 *attrlenp;
2353
2354         if (buflen < 6)
2355                 return NULL;
2356         *p++ = htonl(2);
2357         *p++ = htonl(FATTR4_WORD0_RDATTR_ERROR); /* bmval0 */
2358         *p++ = htonl(0);                         /* bmval1 */
2359
2360         attrlenp = p++;
2361         *p++ = nfserr;       /* no htonl */
2362         *attrlenp = htonl((char *)p - (char *)attrlenp - 4);
2363         return p;
2364 }
2365
2366 static int
2367 nfsd4_encode_dirent(void *ccdv, const char *name, int namlen,
2368                     loff_t offset, u64 ino, unsigned int d_type)
2369 {
2370         struct readdir_cd *ccd = ccdv;
2371         struct nfsd4_readdir *cd = container_of(ccd, struct nfsd4_readdir, common);
2372         int buflen;
2373         __be32 *p = cd->buffer;
2374         __be32 *cookiep;
2375         __be32 nfserr = nfserr_toosmall;
2376
2377         /* In nfsv4, "." and ".." never make it onto the wire.. */
2378         if (name && isdotent(name, namlen)) {
2379                 cd->common.err = nfs_ok;
2380                 return 0;
2381         }
2382
2383         if (cd->offset)
2384                 xdr_encode_hyper(cd->offset, (u64) offset);
2385
2386         buflen = cd->buflen - 4 - XDR_QUADLEN(namlen);
2387         if (buflen < 0)
2388                 goto fail;
2389
2390         *p++ = xdr_one;                             /* mark entry present */
2391         cookiep = p;
2392         p = xdr_encode_hyper(p, NFS_OFFSET_MAX);    /* offset of next entry */
2393         p = xdr_encode_array(p, name, namlen);      /* name length & name */
2394
2395         nfserr = nfsd4_encode_dirent_fattr(cd, name, namlen, p, &buflen);
2396         switch (nfserr) {
2397         case nfs_ok:
2398                 p += buflen;
2399                 break;
2400         case nfserr_resource:
2401                 nfserr = nfserr_toosmall;
2402                 goto fail;
2403         case nfserr_noent:
2404                 goto skip_entry;
2405         default:
2406                 /*
2407                  * If the client requested the RDATTR_ERROR attribute,
2408                  * we stuff the error code into this attribute
2409                  * and continue.  If this attribute was not requested,
2410                  * then in accordance with the spec, we fail the
2411                  * entire READDIR operation(!)
2412                  */
2413                 if (!(cd->rd_bmval[0] & FATTR4_WORD0_RDATTR_ERROR))
2414                         goto fail;
2415                 p = nfsd4_encode_rdattr_error(p, buflen, nfserr);
2416                 if (p == NULL) {
2417                         nfserr = nfserr_toosmall;
2418                         goto fail;
2419                 }
2420         }
2421         cd->buflen -= (p - cd->buffer);
2422         cd->buffer = p;
2423         cd->offset = cookiep;
2424 skip_entry:
2425         cd->common.err = nfs_ok;
2426         return 0;
2427 fail:
2428         cd->common.err = nfserr;
2429         return -EINVAL;
2430 }
2431
2432 static void
2433 nfsd4_encode_stateid(struct nfsd4_compoundres *resp, stateid_t *sid)
2434 {
2435         __be32 *p;
2436
2437         RESERVE_SPACE(sizeof(stateid_t));
2438         WRITE32(sid->si_generation);
2439         WRITEMEM(&sid->si_opaque, sizeof(stateid_opaque_t));
2440         ADJUST_ARGS();
2441 }
2442
2443 static __be32
2444 nfsd4_encode_access(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_access *access)
2445 {
2446         __be32 *p;
2447
2448         if (!nfserr) {
2449                 RESERVE_SPACE(8);
2450                 WRITE32(access->ac_supported);
2451                 WRITE32(access->ac_resp_access);
2452                 ADJUST_ARGS();
2453         }
2454         return nfserr;
2455 }
2456
2457 static __be32 nfsd4_encode_bind_conn_to_session(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_bind_conn_to_session *bcts)
2458 {
2459         __be32 *p;
2460
2461         if (!nfserr) {
2462                 RESERVE_SPACE(NFS4_MAX_SESSIONID_LEN + 8);
2463                 WRITEMEM(bcts->sessionid.data, NFS4_MAX_SESSIONID_LEN);
2464                 WRITE32(bcts->dir);
2465                 /* XXX: ? */
2466                 WRITE32(0);
2467                 ADJUST_ARGS();
2468         }
2469         return nfserr;
2470 }
2471
2472 static __be32
2473 nfsd4_encode_close(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_close *close)
2474 {
2475         ENCODE_SEQID_OP_HEAD;
2476
2477         if (!nfserr)
2478                 nfsd4_encode_stateid(resp, &close->cl_stateid);
2479
2480         ENCODE_SEQID_OP_TAIL(close->cl_stateowner);
2481         return nfserr;
2482 }
2483
2484
2485 static __be32
2486 nfsd4_encode_commit(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_commit *commit)
2487 {
2488         __be32 *p;
2489
2490         if (!nfserr) {
2491                 RESERVE_SPACE(8);
2492                 WRITEMEM(commit->co_verf.data, 8);
2493                 ADJUST_ARGS();
2494         }
2495         return nfserr;
2496 }
2497
2498 static __be32
2499 nfsd4_encode_create(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_create *create)
2500 {
2501         __be32 *p;
2502
2503         if (!nfserr) {
2504                 RESERVE_SPACE(32);
2505                 write_cinfo(&p, &create->cr_cinfo);
2506                 WRITE32(2);
2507                 WRITE32(create->cr_bmval[0]);
2508                 WRITE32(create->cr_bmval[1]);
2509                 ADJUST_ARGS();
2510         }
2511         return nfserr;
2512 }
2513
2514 static __be32
2515 nfsd4_encode_getattr(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_getattr *getattr)
2516 {
2517         struct svc_fh *fhp = getattr->ga_fhp;
2518         int buflen;
2519
2520         if (nfserr)
2521                 return nfserr;
2522
2523         buflen = resp->end - resp->p - (COMPOUND_ERR_SLACK_SPACE >> 2);
2524         nfserr = nfsd4_encode_fattr(fhp, fhp->fh_export, fhp->fh_dentry,
2525                                     resp->p, &buflen, getattr->ga_bmval,
2526                                     resp->rqstp, 0);
2527         if (!nfserr)
2528                 resp->p += buflen;
2529         return nfserr;
2530 }
2531
2532 static __be32
2533 nfsd4_encode_getfh(struct nfsd4_compoundres *resp, __be32 nfserr, struct svc_fh **fhpp)
2534 {
2535         struct svc_fh *fhp = *fhpp;
2536         unsigned int len;
2537         __be32 *p;
2538
2539         if (!nfserr) {
2540                 len = fhp->fh_handle.fh_size;
2541                 RESERVE_SPACE(len + 4);
2542                 WRITE32(len);
2543                 WRITEMEM(&fhp->fh_handle.fh_base, len);
2544                 ADJUST_ARGS();
2545         }
2546         return nfserr;
2547 }
2548
2549 /*
2550 * Including all fields other than the name, a LOCK4denied structure requires
2551 *   8(clientid) + 4(namelen) + 8(offset) + 8(length) + 4(type) = 32 bytes.
2552 */
2553 static void
2554 nfsd4_encode_lock_denied(struct nfsd4_compoundres *resp, struct nfsd4_lock_denied *ld)
2555 {
2556         __be32 *p;
2557
2558         RESERVE_SPACE(32 + XDR_LEN(ld->ld_sop ? ld->ld_sop->so_owner.len : 0));
2559         WRITE64(ld->ld_start);
2560         WRITE64(ld->ld_length);
2561         WRITE32(ld->ld_type);
2562         if (ld->ld_sop) {
2563                 WRITEMEM(&ld->ld_clientid, 8);
2564                 WRITE32(ld->ld_sop->so_owner.len);
2565                 WRITEMEM(ld->ld_sop->so_owner.data, ld->ld_sop->so_owner.len);
2566                 kref_put(&ld->ld_sop->so_ref, nfs4_free_stateowner);
2567         }  else {  /* non - nfsv4 lock in conflict, no clientid nor owner */
2568                 WRITE64((u64)0); /* clientid */
2569                 WRITE32(0); /* length of owner name */
2570         }
2571         ADJUST_ARGS();
2572 }
2573
2574 static __be32
2575 nfsd4_encode_lock(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_lock *lock)
2576 {
2577         ENCODE_SEQID_OP_HEAD;
2578
2579         if (!nfserr)
2580                 nfsd4_encode_stateid(resp, &lock->lk_resp_stateid);
2581         else if (nfserr == nfserr_denied)
2582                 nfsd4_encode_lock_denied(resp, &lock->lk_denied);
2583
2584         ENCODE_SEQID_OP_TAIL(lock->lk_replay_owner);
2585         return nfserr;
2586 }
2587
2588 static __be32
2589 nfsd4_encode_lockt(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_lockt *lockt)
2590 {
2591         if (nfserr == nfserr_denied)
2592                 nfsd4_encode_lock_denied(resp, &lockt->lt_denied);
2593         return nfserr;
2594 }
2595
2596 static __be32
2597 nfsd4_encode_locku(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_locku *locku)
2598 {
2599         ENCODE_SEQID_OP_HEAD;
2600
2601         if (!nfserr)
2602                 nfsd4_encode_stateid(resp, &locku->lu_stateid);
2603
2604         ENCODE_SEQID_OP_TAIL(locku->lu_stateowner);
2605         return nfserr;
2606 }
2607
2608
2609 static __be32
2610 nfsd4_encode_link(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_link *link)
2611 {
2612         __be32 *p;
2613
2614         if (!nfserr) {
2615                 RESERVE_SPACE(20);
2616                 write_cinfo(&p, &link->li_cinfo);
2617                 ADJUST_ARGS();
2618         }
2619         return nfserr;
2620 }
2621
2622
2623 static __be32
2624 nfsd4_encode_open(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open *open)
2625 {
2626         __be32 *p;
2627         ENCODE_SEQID_OP_HEAD;
2628
2629         if (nfserr)
2630                 goto out;
2631
2632         nfsd4_encode_stateid(resp, &open->op_stateid);
2633         RESERVE_SPACE(40);
2634         write_cinfo(&p, &open->op_cinfo);
2635         WRITE32(open->op_rflags);
2636         WRITE32(2);
2637         WRITE32(open->op_bmval[0]);
2638         WRITE32(open->op_bmval[1]);
2639         WRITE32(open->op_delegate_type);
2640         ADJUST_ARGS();
2641
2642         switch (open->op_delegate_type) {
2643         case NFS4_OPEN_DELEGATE_NONE:
2644                 break;
2645         case NFS4_OPEN_DELEGATE_READ:
2646                 nfsd4_encode_stateid(resp, &open->op_delegate_stateid);
2647                 RESERVE_SPACE(20);
2648                 WRITE32(open->op_recall);
2649
2650                 /*
2651                  * TODO: ACE's in delegations
2652                  */
2653                 WRITE32(NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE);
2654                 WRITE32(0);
2655                 WRITE32(0);
2656                 WRITE32(0);   /* XXX: is NULL principal ok? */
2657                 ADJUST_ARGS();
2658                 break;
2659         case NFS4_OPEN_DELEGATE_WRITE:
2660                 nfsd4_encode_stateid(resp, &open->op_delegate_stateid);
2661                 RESERVE_SPACE(32);
2662                 WRITE32(0);
2663
2664                 /*
2665                  * TODO: space_limit's in delegations
2666                  */
2667                 WRITE32(NFS4_LIMIT_SIZE);
2668                 WRITE32(~(u32)0);
2669                 WRITE32(~(u32)0);
2670
2671                 /*
2672                  * TODO: ACE's in delegations
2673                  */
2674                 WRITE32(NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE);
2675                 WRITE32(0);
2676                 WRITE32(0);
2677                 WRITE32(0);   /* XXX: is NULL principal ok? */
2678                 ADJUST_ARGS();
2679                 break;
2680         default:
2681                 BUG();
2682         }
2683         /* XXX save filehandle here */
2684 out:
2685         ENCODE_SEQID_OP_TAIL(open->op_stateowner);
2686         return nfserr;
2687 }
2688
2689 static __be32
2690 nfsd4_encode_open_confirm(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open_confirm *oc)
2691 {
2692         ENCODE_SEQID_OP_HEAD;
2693
2694         if (!nfserr)
2695                 nfsd4_encode_stateid(resp, &oc->oc_resp_stateid);
2696
2697         ENCODE_SEQID_OP_TAIL(oc->oc_stateowner);
2698         return nfserr;
2699 }
2700
2701 static __be32
2702 nfsd4_encode_open_downgrade(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open_downgrade *od)
2703 {
2704         ENCODE_SEQID_OP_HEAD;
2705
2706         if (!nfserr)
2707                 nfsd4_encode_stateid(resp, &od->od_stateid);
2708
2709         ENCODE_SEQID_OP_TAIL(od->od_stateowner);
2710         return nfserr;
2711 }
2712
2713 static __be32
2714 nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr,
2715                   struct nfsd4_read *read)
2716 {
2717         u32 eof;
2718         int v, pn;
2719         unsigned long maxcount; 
2720         long len;
2721         __be32 *p;
2722
2723         if (nfserr)
2724                 return nfserr;
2725         if (resp->xbuf->page_len)
2726                 return nfserr_resource;
2727
2728         RESERVE_SPACE(8); /* eof flag and byte count */
2729
2730         maxcount = svc_max_payload(resp->rqstp);
2731         if (maxcount > read->rd_length)
2732                 maxcount = read->rd_length;
2733
2734         len = maxcount;
2735         v = 0;
2736         while (len > 0) {
2737                 pn = resp->rqstp->rq_resused++;
2738                 resp->rqstp->rq_vec[v].iov_base =
2739                         page_address(resp->rqstp->rq_respages[pn]);
2740                 resp->rqstp->rq_vec[v].iov_len =
2741                         len < PAGE_SIZE ? len : PAGE_SIZE;
2742                 v++;
2743                 len -= PAGE_SIZE;
2744         }
2745         read->rd_vlen = v;
2746
2747         nfserr = nfsd_read_file(read->rd_rqstp, read->rd_fhp, read->rd_filp,
2748                         read->rd_offset, resp->rqstp->rq_vec, read->rd_vlen,
2749                         &maxcount);
2750
2751         if (nfserr == nfserr_symlink)
2752                 nfserr = nfserr_inval;
2753         if (nfserr)
2754                 return nfserr;
2755         eof = (read->rd_offset + maxcount >=
2756                read->rd_fhp->fh_dentry->d_inode->i_size);
2757
2758         WRITE32(eof);
2759         WRITE32(maxcount);
2760         ADJUST_ARGS();
2761         resp->xbuf->head[0].iov_len = (char*)p
2762                                         - (char*)resp->xbuf->head[0].iov_base;
2763         resp->xbuf->page_len = maxcount;
2764
2765         /* Use rest of head for padding and remaining ops: */
2766         resp->xbuf->tail[0].iov_base = p;
2767         resp->xbuf->tail[0].iov_len = 0;
2768         if (maxcount&3) {
2769                 RESERVE_SPACE(4);
2770                 WRITE32(0);
2771                 resp->xbuf->tail[0].iov_base += maxcount&3;
2772                 resp->xbuf->tail[0].iov_len = 4 - (maxcount&3);
2773                 ADJUST_ARGS();
2774         }
2775         return 0;
2776 }
2777
2778 static __be32
2779 nfsd4_encode_readlink(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_readlink *readlink)
2780 {
2781         int maxcount;
2782         char *page;
2783         __be32 *p;
2784
2785         if (nfserr)
2786                 return nfserr;
2787         if (resp->xbuf->page_len)
2788                 return nfserr_resource;
2789
2790         page = page_address(resp->rqstp->rq_respages[resp->rqstp->rq_resused++]);
2791
2792         maxcount = PAGE_SIZE;
2793         RESERVE_SPACE(4);
2794
2795         /*
2796          * XXX: By default, the ->readlink() VFS op will truncate symlinks
2797          * if they would overflow the buffer.  Is this kosher in NFSv4?  If
2798          * not, one easy fix is: if ->readlink() precisely fills the buffer,
2799          * assume that truncation occurred, and return NFS4ERR_RESOURCE.
2800          */
2801         nfserr = nfsd_readlink(readlink->rl_rqstp, readlink->rl_fhp, page, &maxcount);
2802         if (nfserr == nfserr_isdir)
2803                 return nfserr_inval;
2804         if (nfserr)
2805                 return nfserr;
2806
2807         WRITE32(maxcount);
2808         ADJUST_ARGS();
2809         resp->xbuf->head[0].iov_len = (char*)p
2810                                 - (char*)resp->xbuf->head[0].iov_base;
2811         resp->xbuf->page_len = maxcount;
2812
2813         /* Use rest of head for padding and remaining ops: */
2814         resp->xbuf->tail[0].iov_base = p;
2815         resp->xbuf->tail[0].iov_len = 0;
2816         if (maxcount&3) {
2817                 RESERVE_SPACE(4);
2818                 WRITE32(0);
2819                 resp->xbuf->tail[0].iov_base += maxcount&3;
2820                 resp->xbuf->tail[0].iov_len = 4 - (maxcount&3);
2821                 ADJUST_ARGS();
2822         }
2823         return 0;
2824 }
2825
2826 static __be32
2827 nfsd4_encode_readdir(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_readdir *readdir)
2828 {
2829         int maxcount;
2830         loff_t offset;
2831         __be32 *page, *savep, *tailbase;
2832         __be32 *p;
2833
2834         if (nfserr)
2835                 return nfserr;
2836         if (resp->xbuf->page_len)
2837                 return nfserr_resource;
2838
2839         RESERVE_SPACE(8);  /* verifier */
2840         savep = p;
2841
2842         /* XXX: Following NFSv3, we ignore the READDIR verifier for now. */
2843         WRITE32(0);
2844         WRITE32(0);
2845         ADJUST_ARGS();
2846         resp->xbuf->head[0].iov_len = ((char*)resp->p) - (char*)resp->xbuf->head[0].iov_base;
2847         tailbase = p;
2848
2849         maxcount = PAGE_SIZE;
2850         if (maxcount > readdir->rd_maxcount)
2851                 maxcount = readdir->rd_maxcount;
2852
2853         /*
2854          * Convert from bytes to words, account for the two words already
2855          * written, make sure to leave two words at the end for the next
2856          * pointer and eof field.
2857          */
2858         maxcount = (maxcount >> 2) - 4;
2859         if (maxcount < 0) {
2860                 nfserr =  nfserr_toosmall;
2861                 goto err_no_verf;
2862         }
2863
2864         page = page_address(resp->rqstp->rq_respages[resp->rqstp->rq_resused++]);
2865         readdir->common.err = 0;
2866         readdir->buflen = maxcount;
2867         readdir->buffer = page;
2868         readdir->offset = NULL;
2869
2870         offset = readdir->rd_cookie;
2871         nfserr = nfsd_readdir(readdir->rd_rqstp, readdir->rd_fhp,
2872                               &offset,
2873                               &readdir->common, nfsd4_encode_dirent);
2874         if (nfserr == nfs_ok &&
2875             readdir->common.err == nfserr_toosmall &&
2876             readdir->buffer == page) 
2877                 nfserr = nfserr_toosmall;
2878         if (nfserr == nfserr_symlink)
2879                 nfserr = nfserr_notdir;
2880         if (nfserr)
2881                 goto err_no_verf;
2882
2883         if (readdir->offset)
2884                 xdr_encode_hyper(readdir->offset, offset);
2885
2886         p = readdir->buffer;
2887         *p++ = 0;       /* no more entries */
2888         *p++ = htonl(readdir->common.err == nfserr_eof);
2889         resp->xbuf->page_len = ((char*)p) - (char*)page_address(
2890                 resp->rqstp->rq_respages[resp->rqstp->rq_resused-1]);
2891
2892         /* Use rest of head for padding and remaining ops: */
2893         resp->xbuf->tail[0].iov_base = tailbase;
2894         resp->xbuf->tail[0].iov_len = 0;
2895         resp->p = resp->xbuf->tail[0].iov_base;
2896         resp->end = resp->p + (PAGE_SIZE - resp->xbuf->head[0].iov_len)/4;
2897
2898         return 0;
2899 err_no_verf:
2900         p = savep;
2901         ADJUST_ARGS();
2902         return nfserr;
2903 }
2904
2905 static __be32
2906 nfsd4_encode_remove(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_remove *remove)
2907 {
2908         __be32 *p;
2909
2910         if (!nfserr) {
2911                 RESERVE_SPACE(20);
2912                 write_cinfo(&p, &remove->rm_cinfo);
2913                 ADJUST_ARGS();
2914         }
2915         return nfserr;
2916 }
2917
2918 static __be32
2919 nfsd4_encode_rename(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_rename *rename)
2920 {
2921         __be32 *p;
2922
2923         if (!nfserr) {
2924                 RESERVE_SPACE(40);
2925                 write_cinfo(&p, &rename->rn_sinfo);
2926                 write_cinfo(&p, &rename->rn_tinfo);
2927                 ADJUST_ARGS();
2928         }
2929         return nfserr;
2930 }
2931
2932 static __be32
2933 nfsd4_do_encode_secinfo(struct nfsd4_compoundres *resp,
2934                          __be32 nfserr,struct svc_export *exp)
2935 {
2936         int i = 0;
2937         u32 nflavs;
2938         struct exp_flavor_info *flavs;
2939         struct exp_flavor_info def_flavs[2];
2940         __be32 *p;
2941
2942         if (nfserr)
2943                 goto out;
2944         if (exp->ex_nflavors) {
2945                 flavs = exp->ex_flavors;
2946                 nflavs = exp->ex_nflavors;
2947         } else { /* Handling of some defaults in absence of real secinfo: */
2948                 flavs = def_flavs;
2949                 if (exp->ex_client->flavour->flavour == RPC_AUTH_UNIX) {
2950                         nflavs = 2;
2951                         flavs[0].pseudoflavor = RPC_AUTH_UNIX;
2952                         flavs[1].pseudoflavor = RPC_AUTH_NULL;
2953                 } else if (exp->ex_client->flavour->flavour == RPC_AUTH_GSS) {
2954                         nflavs = 1;
2955                         flavs[0].pseudoflavor
2956                                         = svcauth_gss_flavor(exp->ex_client);
2957                 } else {
2958                         nflavs = 1;
2959                         flavs[0].pseudoflavor
2960                                         = exp->ex_client->flavour->flavour;
2961                 }
2962         }
2963
2964         RESERVE_SPACE(4);
2965         WRITE32(nflavs);
2966         ADJUST_ARGS();
2967         for (i = 0; i < nflavs; i++) {
2968                 u32 flav = flavs[i].pseudoflavor;
2969                 struct gss_api_mech *gm = gss_mech_get_by_pseudoflavor(flav);
2970
2971                 if (gm) {
2972                         RESERVE_SPACE(4);
2973                         WRITE32(RPC_AUTH_GSS);
2974                         ADJUST_ARGS();
2975                         RESERVE_SPACE(4 + gm->gm_oid.len);
2976                         WRITE32(gm->gm_oid.len);
2977                         WRITEMEM(gm->gm_oid.data, gm->gm_oid.len);
2978                         ADJUST_ARGS();
2979                         RESERVE_SPACE(4);
2980                         WRITE32(0); /* qop */
2981                         ADJUST_ARGS();
2982                         RESERVE_SPACE(4);
2983                         WRITE32(gss_pseudoflavor_to_service(gm, flav));
2984                         ADJUST_ARGS();
2985                         gss_mech_put(gm);
2986                 } else {
2987                         RESERVE_SPACE(4);
2988                         WRITE32(flav);
2989                         ADJUST_ARGS();
2990                 }
2991         }
2992 out:
2993         if (exp)
2994                 exp_put(exp);
2995         return nfserr;
2996 }
2997
2998 static __be32
2999 nfsd4_encode_secinfo(struct nfsd4_compoundres *resp, __be32 nfserr,
3000                      struct nfsd4_secinfo *secinfo)
3001 {
3002         return nfsd4_do_encode_secinfo(resp, nfserr, secinfo->si_exp);
3003 }
3004
3005 static __be32
3006 nfsd4_encode_secinfo_no_name(struct nfsd4_compoundres *resp, __be32 nfserr,
3007                      struct nfsd4_secinfo_no_name *secinfo)
3008 {
3009         return nfsd4_do_encode_secinfo(resp, nfserr, secinfo->sin_exp);
3010 }
3011
3012 /*
3013  * The SETATTR encode routine is special -- it always encodes a bitmap,
3014  * regardless of the error status.
3015  */
3016 static __be32
3017 nfsd4_encode_setattr(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_setattr *setattr)
3018 {
3019         __be32 *p;
3020
3021         RESERVE_SPACE(12);
3022         if (nfserr) {
3023                 WRITE32(2);
3024                 WRITE32(0);
3025                 WRITE32(0);
3026         }
3027         else {
3028                 WRITE32(2);
3029                 WRITE32(setattr->sa_bmval[0]);
3030                 WRITE32(setattr->sa_bmval[1]);
3031         }
3032         ADJUST_ARGS();
3033         return nfserr;
3034 }
3035
3036 static __be32
3037 nfsd4_encode_setclientid(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_setclientid *scd)
3038 {
3039         __be32 *p;
3040
3041         if (!nfserr) {
3042                 RESERVE_SPACE(8 + sizeof(nfs4_verifier));
3043                 WRITEMEM(&scd->se_clientid, 8);
3044                 WRITEMEM(&scd->se_confirm, sizeof(nfs4_verifier));
3045                 ADJUST_ARGS();
3046         }
3047         else if (nfserr == nfserr_clid_inuse) {
3048                 RESERVE_SPACE(8);
3049                 WRITE32(0);
3050                 WRITE32(0);
3051                 ADJUST_ARGS();
3052         }
3053         return nfserr;
3054 }
3055
3056 static __be32
3057 nfsd4_encode_write(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_write *write)
3058 {
3059         __be32 *p;
3060
3061         if (!nfserr) {
3062                 RESERVE_SPACE(16);
3063                 WRITE32(write->wr_bytes_written);
3064                 WRITE32(write->wr_how_written);
3065                 WRITEMEM(write->wr_verifier.data, 8);
3066                 ADJUST_ARGS();
3067         }
3068         return nfserr;
3069 }
3070
3071 static __be32
3072 nfsd4_encode_exchange_id(struct nfsd4_compoundres *resp, int nfserr,
3073                          struct nfsd4_exchange_id *exid)
3074 {
3075         __be32 *p;
3076         char *major_id;
3077         char *server_scope;
3078         int major_id_sz;
3079         int server_scope_sz;
3080         uint64_t minor_id = 0;
3081
3082         if (nfserr)
3083                 return nfserr;
3084
3085         major_id = utsname()->nodename;
3086         major_id_sz = strlen(major_id);
3087         server_scope = utsname()->nodename;
3088         server_scope_sz = strlen(server_scope);
3089
3090         RESERVE_SPACE(
3091                 8 /* eir_clientid */ +
3092                 4 /* eir_sequenceid */ +
3093                 4 /* eir_flags */ +
3094                 4 /* spr_how (SP4_NONE) */ +
3095                 8 /* so_minor_id */ +
3096                 4 /* so_major_id.len */ +
3097                 (XDR_QUADLEN(major_id_sz) * 4) +
3098                 4 /* eir_server_scope.len */ +
3099                 (XDR_QUADLEN(server_scope_sz) * 4) +
3100                 4 /* eir_server_impl_id.count (0) */);
3101
3102         WRITEMEM(&exid->clientid, 8);
3103         WRITE32(exid->seqid);
3104         WRITE32(exid->flags);
3105
3106         /* state_protect4_r. Currently only support SP4_NONE */
3107         BUG_ON(exid->spa_how != SP4_NONE);
3108         WRITE32(exid->spa_how);
3109
3110         /* The server_owner struct */
3111         WRITE64(minor_id);      /* Minor id */
3112         /* major id */
3113         WRITE32(major_id_sz);
3114         WRITEMEM(major_id, major_id_sz);
3115
3116         /* Server scope */
3117         WRITE32(server_scope_sz);
3118         WRITEMEM(server_scope, server_scope_sz);
3119
3120         /* Implementation id */
3121         WRITE32(0);     /* zero length nfs_impl_id4 array */
3122         ADJUST_ARGS();
3123         return 0;
3124 }
3125
3126 static __be32
3127 nfsd4_encode_create_session(struct nfsd4_compoundres *resp, int nfserr,
3128                             struct nfsd4_create_session *sess)
3129 {
3130         __be32 *p;
3131
3132         if (nfserr)
3133                 return nfserr;
3134
3135         RESERVE_SPACE(24);
3136         WRITEMEM(sess->sessionid.data, NFS4_MAX_SESSIONID_LEN);
3137         WRITE32(sess->seqid);
3138         WRITE32(sess->flags);
3139         ADJUST_ARGS();
3140
3141         RESERVE_SPACE(28);
3142         WRITE32(0); /* headerpadsz */
3143         WRITE32(sess->fore_channel.maxreq_sz);
3144         WRITE32(sess->fore_channel.maxresp_sz);
3145         WRITE32(sess->fore_channel.maxresp_cached);
3146         WRITE32(sess->fore_channel.maxops);
3147         WRITE32(sess->fore_channel.maxreqs);
3148         WRITE32(sess->fore_channel.nr_rdma_attrs);
3149         ADJUST_ARGS();
3150
3151         if (sess->fore_channel.nr_rdma_attrs) {
3152                 RESERVE_SPACE(4);
3153                 WRITE32(sess->fore_channel.rdma_attrs);
3154                 ADJUST_ARGS();
3155         }
3156
3157         RESERVE_SPACE(28);
3158         WRITE32(0); /* headerpadsz */
3159         WRITE32(sess->back_channel.maxreq_sz);
3160         WRITE32(sess->back_channel.maxresp_sz);
3161         WRITE32(sess->back_channel.maxresp_cached);
3162         WRITE32(sess->back_channel.maxops);
3163         WRITE32(sess->back_channel.maxreqs);
3164         WRITE32(sess->back_channel.nr_rdma_attrs);
3165         ADJUST_ARGS();
3166
3167         if (sess->back_channel.nr_rdma_attrs) {
3168                 RESERVE_SPACE(4);
3169                 WRITE32(sess->back_channel.rdma_attrs);
3170                 ADJUST_ARGS();
3171         }
3172         return 0;
3173 }
3174
3175 static __be32
3176 nfsd4_encode_destroy_session(struct nfsd4_compoundres *resp, int nfserr,
3177                              struct nfsd4_destroy_session *destroy_session)
3178 {
3179         return nfserr;
3180 }
3181
3182 static __be32
3183 nfsd4_encode_free_stateid(struct nfsd4_compoundres *resp, int nfserr,
3184                           struct nfsd4_free_stateid *free_stateid)
3185 {
3186         __be32 *p;
3187
3188         if (nfserr)
3189                 return nfserr;
3190
3191         RESERVE_SPACE(4);
3192         WRITE32(nfserr);
3193         ADJUST_ARGS();
3194         return nfserr;
3195 }
3196
3197 static __be32
3198 nfsd4_encode_sequence(struct nfsd4_compoundres *resp, int nfserr,
3199                       struct nfsd4_sequence *seq)
3200 {
3201         __be32 *p;
3202
3203         if (nfserr)
3204                 return nfserr;
3205
3206         RESERVE_SPACE(NFS4_MAX_SESSIONID_LEN + 20);
3207         WRITEMEM(seq->sessionid.data, NFS4_MAX_SESSIONID_LEN);
3208         WRITE32(seq->seqid);
3209         WRITE32(seq->slotid);
3210         WRITE32(seq->maxslots);
3211         /* For now: target_maxslots = maxslots */
3212         WRITE32(seq->maxslots);
3213         WRITE32(seq->status_flags);
3214
3215         ADJUST_ARGS();
3216         resp->cstate.datap = p; /* DRC cache data pointer */
3217         return 0;
3218 }
3219
3220 __be32
3221 nfsd4_encode_test_stateid(struct nfsd4_compoundres *resp, int nfserr,
3222                           struct nfsd4_test_stateid *test_stateid)
3223 {
3224         struct nfsd4_compoundargs *argp;
3225         stateid_t si;
3226         __be32 *p;
3227         int i;
3228         int valid;
3229
3230         restore_buf(test_stateid->ts_saved_args, &test_stateid->ts_savedp);
3231         argp = test_stateid->ts_saved_args;
3232
3233         RESERVE_SPACE(4);
3234         *p++ = htonl(test_stateid->ts_num_ids);
3235         resp->p = p;
3236
3237         nfs4_lock_state();
3238         for (i = 0; i < test_stateid->ts_num_ids; i++) {
3239                 nfsd4_decode_stateid(argp, &si);
3240                 valid = nfs4_validate_stateid(&si, test_stateid->ts_has_session);
3241                 RESERVE_SPACE(4);
3242                 *p++ = htonl(valid);
3243                 resp->p = p;
3244         }
3245         nfs4_unlock_state();
3246
3247         return nfserr;
3248 }
3249
3250 static __be32
3251 nfsd4_encode_noop(struct nfsd4_compoundres *resp, __be32 nfserr, void *p)
3252 {
3253         return nfserr;
3254 }
3255
3256 typedef __be32(* nfsd4_enc)(struct nfsd4_compoundres *, __be32, void *);
3257
3258 /*
3259  * Note: nfsd4_enc_ops vector is shared for v4.0 and v4.1
3260  * since we don't need to filter out obsolete ops as this is
3261  * done in the decoding phase.
3262  */
3263 static nfsd4_enc nfsd4_enc_ops[] = {
3264         [OP_ACCESS]             = (nfsd4_enc)nfsd4_encode_access,
3265         [OP_CLOSE]              = (nfsd4_enc)nfsd4_encode_close,
3266         [OP_COMMIT]             = (nfsd4_enc)nfsd4_encode_commit,
3267         [OP_CREATE]             = (nfsd4_enc)nfsd4_encode_create,
3268         [OP_DELEGPURGE]         = (nfsd4_enc)nfsd4_encode_noop,
3269         [OP_DELEGRETURN]        = (nfsd4_enc)nfsd4_encode_noop,
3270         [OP_GETATTR]            = (nfsd4_enc)nfsd4_encode_getattr,
3271         [OP_GETFH]              = (nfsd4_enc)nfsd4_encode_getfh,
3272         [OP_LINK]               = (nfsd4_enc)nfsd4_encode_link,
3273         [OP_LOCK]               = (nfsd4_enc)nfsd4_encode_lock,
3274         [OP_LOCKT]              = (nfsd4_enc)nfsd4_encode_lockt,
3275         [OP_LOCKU]              = (nfsd4_enc)nfsd4_encode_locku,
3276         [OP_LOOKUP]             = (nfsd4_enc)nfsd4_encode_noop,
3277         [OP_LOOKUPP]            = (nfsd4_enc)nfsd4_encode_noop,
3278         [OP_NVERIFY]            = (nfsd4_enc)nfsd4_encode_noop,
3279         [OP_OPEN]               = (nfsd4_enc)nfsd4_encode_open,
3280         [OP_OPENATTR]           = (nfsd4_enc)nfsd4_encode_noop,
3281         [OP_OPEN_CONFIRM]       = (nfsd4_enc)nfsd4_encode_open_confirm,
3282         [OP_OPEN_DOWNGRADE]     = (nfsd4_enc)nfsd4_encode_open_downgrade,
3283         [OP_PUTFH]              = (nfsd4_enc)nfsd4_encode_noop,
3284         [OP_PUTPUBFH]           = (nfsd4_enc)nfsd4_encode_noop,
3285         [OP_PUTROOTFH]          = (nfsd4_enc)nfsd4_encode_noop,
3286         [OP_READ]               = (nfsd4_enc)nfsd4_encode_read,
3287         [OP_READDIR]            = (nfsd4_enc)nfsd4_encode_readdir,
3288         [OP_READLINK]           = (nfsd4_enc)nfsd4_encode_readlink,
3289         [OP_REMOVE]             = (nfsd4_enc)nfsd4_encode_remove,
3290         [OP_RENAME]             = (nfsd4_enc)nfsd4_encode_rename,
3291         [OP_RENEW]              = (nfsd4_enc)nfsd4_encode_noop,
3292         [OP_RESTOREFH]          = (nfsd4_enc)nfsd4_encode_noop,
3293         [OP_SAVEFH]             = (nfsd4_enc)nfsd4_encode_noop,
3294         [OP_SECINFO]            = (nfsd4_enc)nfsd4_encode_secinfo,
3295         [OP_SETATTR]            = (nfsd4_enc)nfsd4_encode_setattr,
3296         [OP_SETCLIENTID]        = (nfsd4_enc)nfsd4_encode_setclientid,
3297         [OP_SETCLIENTID_CONFIRM] = (nfsd4_enc)nfsd4_encode_noop,
3298         [OP_VERIFY]             = (nfsd4_enc)nfsd4_encode_noop,
3299         [OP_WRITE]              = (nfsd4_enc)nfsd4_encode_write,
3300         [OP_RELEASE_LOCKOWNER]  = (nfsd4_enc)nfsd4_encode_noop,
3301
3302         /* NFSv4.1 operations */
3303         [OP_BACKCHANNEL_CTL]    = (nfsd4_enc)nfsd4_encode_noop,
3304         [OP_BIND_CONN_TO_SESSION] = (nfsd4_enc)nfsd4_encode_bind_conn_to_session,
3305         [OP_EXCHANGE_ID]        = (nfsd4_enc)nfsd4_encode_exchange_id,
3306         [OP_CREATE_SESSION]     = (nfsd4_enc)nfsd4_encode_create_session,
3307         [OP_DESTROY_SESSION]    = (nfsd4_enc)nfsd4_encode_destroy_session,
3308         [OP_FREE_STATEID]       = (nfsd4_enc)nfsd4_encode_free_stateid,
3309         [OP_GET_DIR_DELEGATION] = (nfsd4_enc)nfsd4_encode_noop,
3310         [OP_GETDEVICEINFO]      = (nfsd4_enc)nfsd4_encode_noop,
3311         [OP_GETDEVICELIST]      = (nfsd4_enc)nfsd4_encode_noop,
3312         [OP_LAYOUTCOMMIT]       = (nfsd4_enc)nfsd4_encode_noop,
3313         [OP_LAYOUTGET]          = (nfsd4_enc)nfsd4_encode_noop,
3314         [OP_LAYOUTRETURN]       = (nfsd4_enc)nfsd4_encode_noop,
3315         [OP_SECINFO_NO_NAME]    = (nfsd4_enc)nfsd4_encode_secinfo_no_name,
3316         [OP_SEQUENCE]           = (nfsd4_enc)nfsd4_encode_sequence,
3317         [OP_SET_SSV]            = (nfsd4_enc)nfsd4_encode_noop,
3318         [OP_TEST_STATEID]       = (nfsd4_enc)nfsd4_encode_test_stateid,
3319         [OP_WANT_DELEGATION]    = (nfsd4_enc)nfsd4_encode_noop,
3320         [OP_DESTROY_CLIENTID]   = (nfsd4_enc)nfsd4_encode_noop,
3321         [OP_RECLAIM_COMPLETE]   = (nfsd4_enc)nfsd4_encode_noop,
3322 };
3323
3324 /*
3325  * Calculate the total amount of memory that the compound response has taken
3326  * after encoding the current operation.
3327  *
3328  * pad: add on 8 bytes for the next operation's op_code and status so that
3329  * there is room to cache a failure on the next operation.
3330  *
3331  * Compare this length to the session se_fmaxresp_cached.
3332  *
3333  * Our se_fmaxresp_cached will always be a multiple of PAGE_SIZE, and so
3334  * will be at least a page and will therefore hold the xdr_buf head.
3335  */
3336 static int nfsd4_check_drc_limit(struct nfsd4_compoundres *resp)
3337 {
3338         int status = 0;
3339         struct xdr_buf *xb = &resp->rqstp->rq_res;
3340         struct nfsd4_compoundargs *args = resp->rqstp->rq_argp;
3341         struct nfsd4_session *session = NULL;
3342         struct nfsd4_slot *slot = resp->cstate.slot;
3343         u32 length, tlen = 0, pad = 8;
3344
3345         if (!nfsd4_has_session(&resp->cstate))
3346                 return status;
3347
3348         session = resp->cstate.session;
3349         if (session == NULL || slot->sl_cachethis == 0)
3350                 return status;
3351
3352         if (resp->opcnt >= args->opcnt)
3353                 pad = 0; /* this is the last operation */
3354
3355         if (xb->page_len == 0) {
3356                 length = (char *)resp->p - (char *)xb->head[0].iov_base + pad;
3357         } else {
3358                 if (xb->tail[0].iov_base && xb->tail[0].iov_len > 0)
3359                         tlen = (char *)resp->p - (char *)xb->tail[0].iov_base;
3360
3361                 length = xb->head[0].iov_len + xb->page_len + tlen + pad;
3362         }
3363         dprintk("%s length %u, xb->page_len %u tlen %u pad %u\n", __func__,
3364                 length, xb->page_len, tlen, pad);
3365
3366         if (length <= session->se_fchannel.maxresp_cached)
3367                 return status;
3368         else
3369                 return nfserr_rep_too_big_to_cache;
3370 }
3371
3372 void
3373 nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op)
3374 {
3375         __be32 *statp;
3376         __be32 *p;
3377
3378         RESERVE_SPACE(8);
3379         WRITE32(op->opnum);
3380         statp = p++;    /* to be backfilled at the end */
3381         ADJUST_ARGS();
3382
3383         if (op->opnum == OP_ILLEGAL)
3384                 goto status;
3385         BUG_ON(op->opnum < 0 || op->opnum >= ARRAY_SIZE(nfsd4_enc_ops) ||
3386                !nfsd4_enc_ops[op->opnum]);
3387         op->status = nfsd4_enc_ops[op->opnum](resp, op->status, &op->u);
3388         /* nfsd4_check_drc_limit guarantees enough room for error status */
3389         if (!op->status && nfsd4_check_drc_limit(resp))
3390                 op->status = nfserr_rep_too_big_to_cache;
3391 status:
3392         /*
3393          * Note: We write the status directly, instead of using WRITE32(),
3394          * since it is already in network byte order.
3395          */
3396         *statp = op->status;
3397 }
3398
3399 /* 
3400  * Encode the reply stored in the stateowner reply cache 
3401  * 
3402  * XDR note: do not encode rp->rp_buflen: the buffer contains the
3403  * previously sent already encoded operation.
3404  *
3405  * called with nfs4_lock_state() held
3406  */
3407 void
3408 nfsd4_encode_replay(struct nfsd4_compoundres *resp, struct nfsd4_op *op)
3409 {
3410         __be32 *p;
3411         struct nfs4_replay *rp = op->replay;
3412
3413         BUG_ON(!rp);
3414
3415         RESERVE_SPACE(8);
3416         WRITE32(op->opnum);
3417         *p++ = rp->rp_status;  /* already xdr'ed */
3418         ADJUST_ARGS();
3419
3420         RESERVE_SPACE(rp->rp_buflen);
3421         WRITEMEM(rp->rp_buf, rp->rp_buflen);
3422         ADJUST_ARGS();
3423 }
3424
3425 int
3426 nfs4svc_encode_voidres(struct svc_rqst *rqstp, __be32 *p, void *dummy)
3427 {
3428         return xdr_ressize_check(rqstp, p);
3429 }
3430
3431 void nfsd4_release_compoundargs(struct nfsd4_compoundargs *args)
3432 {
3433         if (args->ops != args->iops) {
3434                 kfree(args->ops);
3435                 args->ops = args->iops;
3436         }
3437         kfree(args->tmpp);
3438         args->tmpp = NULL;
3439         while (args->to_free) {
3440                 struct tmpbuf *tb = args->to_free;
3441                 args->to_free = tb->next;
3442                 tb->release(tb->buf);
3443                 kfree(tb);
3444         }
3445 }
3446
3447 int
3448 nfs4svc_decode_compoundargs(struct svc_rqst *rqstp, __be32 *p, struct nfsd4_compoundargs *args)
3449 {
3450         __be32 status;
3451
3452         args->p = p;
3453         args->end = rqstp->rq_arg.head[0].iov_base + rqstp->rq_arg.head[0].iov_len;
3454         args->pagelist = rqstp->rq_arg.pages;
3455         args->pagelen = rqstp->rq_arg.page_len;
3456         args->tmpp = NULL;
3457         args->to_free = NULL;
3458         args->ops = args->iops;
3459         args->rqstp = rqstp;
3460
3461         status = nfsd4_decode_compound(args);
3462         if (status) {
3463                 nfsd4_release_compoundargs(args);
3464         }
3465         return !status;
3466 }
3467
3468 int
3469 nfs4svc_encode_compoundres(struct svc_rqst *rqstp, __be32 *p, struct nfsd4_compoundres *resp)
3470 {
3471         /*
3472          * All that remains is to write the tag and operation count...
3473          */
3474         struct nfsd4_compound_state *cs = &resp->cstate;
3475         struct kvec *iov;
3476         p = resp->tagp;
3477         *p++ = htonl(resp->taglen);
3478         memcpy(p, resp->tag, resp->taglen);
3479         p += XDR_QUADLEN(resp->taglen);
3480         *p++ = htonl(resp->opcnt);
3481
3482         if (rqstp->rq_res.page_len) 
3483                 iov = &rqstp->rq_res.tail[0];
3484         else
3485                 iov = &rqstp->rq_res.head[0];
3486         iov->iov_len = ((char*)resp->p) - (char*)iov->iov_base;
3487         BUG_ON(iov->iov_len > PAGE_SIZE);
3488         if (nfsd4_has_session(cs)) {
3489                 if (cs->status != nfserr_replay_cache) {
3490                         nfsd4_store_cache_entry(resp);
3491                         dprintk("%s: SET SLOT STATE TO AVAILABLE\n", __func__);
3492                         cs->slot->sl_inuse = false;
3493                 }
3494                 /* Renew the clientid on success and on replay */
3495                 release_session_client(cs->session);
3496                 nfsd4_put_session(cs->session);
3497         }
3498         return 1;
3499 }
3500
3501 /*
3502  * Local variables:
3503  *  c-basic-offset: 8
3504  * End:
3505  */