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