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