Merge branch 'rk_develop-3.10' into rk_develop-3.10-next
[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                 if (found_esc)
1747                         end = next;
1748
1749                 str = end;
1750         }
1751         *pp = p;
1752         p = countp;
1753         WRITE32(count);
1754         return 0;
1755 }
1756
1757 /* Encode as an array of strings the string given with components
1758  * separated @sep.
1759  */
1760 static __be32 nfsd4_encode_components(char sep, char *components,
1761                                    __be32 **pp, int *buflen)
1762 {
1763         return nfsd4_encode_components_esc(sep, components, pp, buflen, 0, 0);
1764 }
1765
1766 /*
1767  * encode a location element of a fs_locations structure
1768  */
1769 static __be32 nfsd4_encode_fs_location4(struct nfsd4_fs_location *location,
1770                                     __be32 **pp, int *buflen)
1771 {
1772         __be32 status;
1773         __be32 *p = *pp;
1774
1775         status = nfsd4_encode_components_esc(':', location->hosts, &p, buflen,
1776                                                 '[', ']');
1777         if (status)
1778                 return status;
1779         status = nfsd4_encode_components('/', location->path, &p, buflen);
1780         if (status)
1781                 return status;
1782         *pp = p;
1783         return 0;
1784 }
1785
1786 /*
1787  * Encode a path in RFC3530 'pathname4' format
1788  */
1789 static __be32 nfsd4_encode_path(const struct path *root,
1790                 const struct path *path, __be32 **pp, int *buflen)
1791 {
1792         struct path cur = {
1793                 .mnt = path->mnt,
1794                 .dentry = path->dentry,
1795         };
1796         __be32 *p = *pp;
1797         struct dentry **components = NULL;
1798         unsigned int ncomponents = 0;
1799         __be32 err = nfserr_jukebox;
1800
1801         dprintk("nfsd4_encode_components(");
1802
1803         path_get(&cur);
1804         /* First walk the path up to the nfsd root, and store the
1805          * dentries/path components in an array.
1806          */
1807         for (;;) {
1808                 if (cur.dentry == root->dentry && cur.mnt == root->mnt)
1809                         break;
1810                 if (cur.dentry == cur.mnt->mnt_root) {
1811                         if (follow_up(&cur))
1812                                 continue;
1813                         goto out_free;
1814                 }
1815                 if ((ncomponents & 15) == 0) {
1816                         struct dentry **new;
1817                         new = krealloc(components,
1818                                         sizeof(*new) * (ncomponents + 16),
1819                                         GFP_KERNEL);
1820                         if (!new)
1821                                 goto out_free;
1822                         components = new;
1823                 }
1824                 components[ncomponents++] = cur.dentry;
1825                 cur.dentry = dget_parent(cur.dentry);
1826         }
1827
1828         *buflen -= 4;
1829         if (*buflen < 0)
1830                 goto out_free;
1831         WRITE32(ncomponents);
1832
1833         while (ncomponents) {
1834                 struct dentry *dentry = components[ncomponents - 1];
1835                 unsigned int len = dentry->d_name.len;
1836
1837                 *buflen -= 4 + (XDR_QUADLEN(len) << 2);
1838                 if (*buflen < 0)
1839                         goto out_free;
1840                 WRITE32(len);
1841                 WRITEMEM(dentry->d_name.name, len);
1842                 dprintk("/%s", dentry->d_name.name);
1843                 dput(dentry);
1844                 ncomponents--;
1845         }
1846
1847         *pp = p;
1848         err = 0;
1849 out_free:
1850         dprintk(")\n");
1851         while (ncomponents)
1852                 dput(components[--ncomponents]);
1853         kfree(components);
1854         path_put(&cur);
1855         return err;
1856 }
1857
1858 static __be32 nfsd4_encode_fsloc_fsroot(struct svc_rqst *rqstp,
1859                 const struct path *path, __be32 **pp, int *buflen)
1860 {
1861         struct svc_export *exp_ps;
1862         __be32 res;
1863
1864         exp_ps = rqst_find_fsidzero_export(rqstp);
1865         if (IS_ERR(exp_ps))
1866                 return nfserrno(PTR_ERR(exp_ps));
1867         res = nfsd4_encode_path(&exp_ps->ex_path, path, pp, buflen);
1868         exp_put(exp_ps);
1869         return res;
1870 }
1871
1872 /*
1873  *  encode a fs_locations structure
1874  */
1875 static __be32 nfsd4_encode_fs_locations(struct svc_rqst *rqstp,
1876                                      struct svc_export *exp,
1877                                      __be32 **pp, int *buflen)
1878 {
1879         __be32 status;
1880         int i;
1881         __be32 *p = *pp;
1882         struct nfsd4_fs_locations *fslocs = &exp->ex_fslocs;
1883
1884         status = nfsd4_encode_fsloc_fsroot(rqstp, &exp->ex_path, &p, buflen);
1885         if (status)
1886                 return status;
1887         if ((*buflen -= 4) < 0)
1888                 return nfserr_resource;
1889         WRITE32(fslocs->locations_count);
1890         for (i=0; i<fslocs->locations_count; i++) {
1891                 status = nfsd4_encode_fs_location4(&fslocs->locations[i],
1892                                                    &p, buflen);
1893                 if (status)
1894                         return status;
1895         }
1896         *pp = p;
1897         return 0;
1898 }
1899
1900 static u32 nfs4_file_type(umode_t mode)
1901 {
1902         switch (mode & S_IFMT) {
1903         case S_IFIFO:   return NF4FIFO;
1904         case S_IFCHR:   return NF4CHR;
1905         case S_IFDIR:   return NF4DIR;
1906         case S_IFBLK:   return NF4BLK;
1907         case S_IFLNK:   return NF4LNK;
1908         case S_IFREG:   return NF4REG;
1909         case S_IFSOCK:  return NF4SOCK;
1910         default:        return NF4BAD;
1911         };
1912 }
1913
1914 static __be32
1915 nfsd4_encode_name(struct svc_rqst *rqstp, int whotype, kuid_t uid, kgid_t gid,
1916                         __be32 **p, int *buflen)
1917 {
1918         int status;
1919
1920         if (*buflen < (XDR_QUADLEN(IDMAP_NAMESZ) << 2) + 4)
1921                 return nfserr_resource;
1922         if (whotype != NFS4_ACL_WHO_NAMED)
1923                 status = nfs4_acl_write_who(whotype, (u8 *)(*p + 1));
1924         else if (gid_valid(gid))
1925                 status = nfsd_map_gid_to_name(rqstp, gid, (u8 *)(*p + 1));
1926         else
1927                 status = nfsd_map_uid_to_name(rqstp, uid, (u8 *)(*p + 1));
1928         if (status < 0)
1929                 return nfserrno(status);
1930         *p = xdr_encode_opaque(*p, NULL, status);
1931         *buflen -= (XDR_QUADLEN(status) << 2) + 4;
1932         BUG_ON(*buflen < 0);
1933         return 0;
1934 }
1935
1936 static inline __be32
1937 nfsd4_encode_user(struct svc_rqst *rqstp, kuid_t user, __be32 **p, int *buflen)
1938 {
1939         return nfsd4_encode_name(rqstp, NFS4_ACL_WHO_NAMED, user, INVALID_GID,
1940                                  p, buflen);
1941 }
1942
1943 static inline __be32
1944 nfsd4_encode_group(struct svc_rqst *rqstp, kgid_t group, __be32 **p, int *buflen)
1945 {
1946         return nfsd4_encode_name(rqstp, NFS4_ACL_WHO_NAMED, INVALID_UID, group,
1947                                  p, buflen);
1948 }
1949
1950 static inline __be32
1951 nfsd4_encode_aclname(struct svc_rqst *rqstp, struct nfs4_ace *ace,
1952                 __be32 **p, int *buflen)
1953 {
1954         kuid_t uid = INVALID_UID;
1955         kgid_t gid = INVALID_GID;
1956
1957         if (ace->whotype == NFS4_ACL_WHO_NAMED) {
1958                 if (ace->flag & NFS4_ACE_IDENTIFIER_GROUP)
1959                         gid = ace->who_gid;
1960                 else
1961                         uid = ace->who_uid;
1962         }
1963         return nfsd4_encode_name(rqstp, ace->whotype, uid, gid, p, buflen);
1964 }
1965
1966 #define WORD0_ABSENT_FS_ATTRS (FATTR4_WORD0_FS_LOCATIONS | FATTR4_WORD0_FSID | \
1967                               FATTR4_WORD0_RDATTR_ERROR)
1968 #define WORD1_ABSENT_FS_ATTRS FATTR4_WORD1_MOUNTED_ON_FILEID
1969
1970 static __be32 fattr_handle_absent_fs(u32 *bmval0, u32 *bmval1, u32 *rdattr_err)
1971 {
1972         /* As per referral draft:  */
1973         if (*bmval0 & ~WORD0_ABSENT_FS_ATTRS ||
1974             *bmval1 & ~WORD1_ABSENT_FS_ATTRS) {
1975                 if (*bmval0 & FATTR4_WORD0_RDATTR_ERROR ||
1976                     *bmval0 & FATTR4_WORD0_FS_LOCATIONS)
1977                         *rdattr_err = NFSERR_MOVED;
1978                 else
1979                         return nfserr_moved;
1980         }
1981         *bmval0 &= WORD0_ABSENT_FS_ATTRS;
1982         *bmval1 &= WORD1_ABSENT_FS_ATTRS;
1983         return 0;
1984 }
1985
1986
1987 static int get_parent_attributes(struct svc_export *exp, struct kstat *stat)
1988 {
1989         struct path path = exp->ex_path;
1990         int err;
1991
1992         path_get(&path);
1993         while (follow_up(&path)) {
1994                 if (path.dentry != path.mnt->mnt_root)
1995                         break;
1996         }
1997         err = vfs_getattr(&path, stat);
1998         path_put(&path);
1999         return err;
2000 }
2001
2002 /*
2003  * Note: @fhp can be NULL; in this case, we might have to compose the filehandle
2004  * ourselves.
2005  *
2006  * countp is the buffer size in _words_
2007  */
2008 __be32
2009 nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
2010                 struct dentry *dentry, __be32 **buffer, int count, u32 *bmval,
2011                 struct svc_rqst *rqstp, int ignore_crossmnt)
2012 {
2013         u32 bmval0 = bmval[0];
2014         u32 bmval1 = bmval[1];
2015         u32 bmval2 = bmval[2];
2016         struct kstat stat;
2017         struct svc_fh tempfh;
2018         struct kstatfs statfs;
2019         int buflen = count << 2;
2020         __be32 *attrlenp;
2021         u32 dummy;
2022         u64 dummy64;
2023         u32 rdattr_err = 0;
2024         __be32 *p = *buffer;
2025         __be32 status;
2026         int err;
2027         int aclsupport = 0;
2028         struct nfs4_acl *acl = NULL;
2029         struct nfsd4_compoundres *resp = rqstp->rq_resp;
2030         u32 minorversion = resp->cstate.minorversion;
2031         struct path path = {
2032                 .mnt    = exp->ex_path.mnt,
2033                 .dentry = dentry,
2034         };
2035         struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
2036
2037         BUG_ON(bmval1 & NFSD_WRITEONLY_ATTRS_WORD1);
2038         BUG_ON(bmval0 & ~nfsd_suppattrs0(minorversion));
2039         BUG_ON(bmval1 & ~nfsd_suppattrs1(minorversion));
2040         BUG_ON(bmval2 & ~nfsd_suppattrs2(minorversion));
2041
2042         if (exp->ex_fslocs.migrated) {
2043                 BUG_ON(bmval[2]);
2044                 status = fattr_handle_absent_fs(&bmval0, &bmval1, &rdattr_err);
2045                 if (status)
2046                         goto out;
2047         }
2048
2049         err = vfs_getattr(&path, &stat);
2050         if (err)
2051                 goto out_nfserr;
2052         if ((bmval0 & (FATTR4_WORD0_FILES_AVAIL | FATTR4_WORD0_FILES_FREE |
2053                         FATTR4_WORD0_FILES_TOTAL | FATTR4_WORD0_MAXNAME)) ||
2054             (bmval1 & (FATTR4_WORD1_SPACE_AVAIL | FATTR4_WORD1_SPACE_FREE |
2055                        FATTR4_WORD1_SPACE_TOTAL))) {
2056                 err = vfs_statfs(&path, &statfs);
2057                 if (err)
2058                         goto out_nfserr;
2059         }
2060         if ((bmval0 & (FATTR4_WORD0_FILEHANDLE | FATTR4_WORD0_FSID)) && !fhp) {
2061                 fh_init(&tempfh, NFS4_FHSIZE);
2062                 status = fh_compose(&tempfh, exp, dentry, NULL);
2063                 if (status)
2064                         goto out;
2065                 fhp = &tempfh;
2066         }
2067         if (bmval0 & (FATTR4_WORD0_ACL | FATTR4_WORD0_ACLSUPPORT
2068                         | FATTR4_WORD0_SUPPORTED_ATTRS)) {
2069                 err = nfsd4_get_nfs4_acl(rqstp, dentry, &acl);
2070                 aclsupport = (err == 0);
2071                 if (bmval0 & FATTR4_WORD0_ACL) {
2072                         if (err == -EOPNOTSUPP)
2073                                 bmval0 &= ~FATTR4_WORD0_ACL;
2074                         else if (err == -EINVAL) {
2075                                 status = nfserr_attrnotsupp;
2076                                 goto out;
2077                         } else if (err != 0)
2078                                 goto out_nfserr;
2079                 }
2080         }
2081
2082         if (bmval2) {
2083                 if ((buflen -= 16) < 0)
2084                         goto out_resource;
2085                 WRITE32(3);
2086                 WRITE32(bmval0);
2087                 WRITE32(bmval1);
2088                 WRITE32(bmval2);
2089         } else if (bmval1) {
2090                 if ((buflen -= 12) < 0)
2091                         goto out_resource;
2092                 WRITE32(2);
2093                 WRITE32(bmval0);
2094                 WRITE32(bmval1);
2095         } else {
2096                 if ((buflen -= 8) < 0)
2097                         goto out_resource;
2098                 WRITE32(1);
2099                 WRITE32(bmval0);
2100         }
2101         attrlenp = p++;                /* to be backfilled later */
2102
2103         if (bmval0 & FATTR4_WORD0_SUPPORTED_ATTRS) {
2104                 u32 word0 = nfsd_suppattrs0(minorversion);
2105                 u32 word1 = nfsd_suppattrs1(minorversion);
2106                 u32 word2 = nfsd_suppattrs2(minorversion);
2107
2108                 if (!aclsupport)
2109                         word0 &= ~FATTR4_WORD0_ACL;
2110                 if (!word2) {
2111                         if ((buflen -= 12) < 0)
2112                                 goto out_resource;
2113                         WRITE32(2);
2114                         WRITE32(word0);
2115                         WRITE32(word1);
2116                 } else {
2117                         if ((buflen -= 16) < 0)
2118                                 goto out_resource;
2119                         WRITE32(3);
2120                         WRITE32(word0);
2121                         WRITE32(word1);
2122                         WRITE32(word2);
2123                 }
2124         }
2125         if (bmval0 & FATTR4_WORD0_TYPE) {
2126                 if ((buflen -= 4) < 0)
2127                         goto out_resource;
2128                 dummy = nfs4_file_type(stat.mode);
2129                 if (dummy == NF4BAD)
2130                         goto out_serverfault;
2131                 WRITE32(dummy);
2132         }
2133         if (bmval0 & FATTR4_WORD0_FH_EXPIRE_TYPE) {
2134                 if ((buflen -= 4) < 0)
2135                         goto out_resource;
2136                 if (exp->ex_flags & NFSEXP_NOSUBTREECHECK)
2137                         WRITE32(NFS4_FH_PERSISTENT);
2138                 else
2139                         WRITE32(NFS4_FH_PERSISTENT|NFS4_FH_VOL_RENAME);
2140         }
2141         if (bmval0 & FATTR4_WORD0_CHANGE) {
2142                 if ((buflen -= 8) < 0)
2143                         goto out_resource;
2144                 write_change(&p, &stat, dentry->d_inode);
2145         }
2146         if (bmval0 & FATTR4_WORD0_SIZE) {
2147                 if ((buflen -= 8) < 0)
2148                         goto out_resource;
2149                 WRITE64(stat.size);
2150         }
2151         if (bmval0 & FATTR4_WORD0_LINK_SUPPORT) {
2152                 if ((buflen -= 4) < 0)
2153                         goto out_resource;
2154                 WRITE32(1);
2155         }
2156         if (bmval0 & FATTR4_WORD0_SYMLINK_SUPPORT) {
2157                 if ((buflen -= 4) < 0)
2158                         goto out_resource;
2159                 WRITE32(1);
2160         }
2161         if (bmval0 & FATTR4_WORD0_NAMED_ATTR) {
2162                 if ((buflen -= 4) < 0)
2163                         goto out_resource;
2164                 WRITE32(0);
2165         }
2166         if (bmval0 & FATTR4_WORD0_FSID) {
2167                 if ((buflen -= 16) < 0)
2168                         goto out_resource;
2169                 if (exp->ex_fslocs.migrated) {
2170                         WRITE64(NFS4_REFERRAL_FSID_MAJOR);
2171                         WRITE64(NFS4_REFERRAL_FSID_MINOR);
2172                 } else switch(fsid_source(fhp)) {
2173                 case FSIDSOURCE_FSID:
2174                         WRITE64((u64)exp->ex_fsid);
2175                         WRITE64((u64)0);
2176                         break;
2177                 case FSIDSOURCE_DEV:
2178                         WRITE32(0);
2179                         WRITE32(MAJOR(stat.dev));
2180                         WRITE32(0);
2181                         WRITE32(MINOR(stat.dev));
2182                         break;
2183                 case FSIDSOURCE_UUID:
2184                         WRITEMEM(exp->ex_uuid, 16);
2185                         break;
2186                 }
2187         }
2188         if (bmval0 & FATTR4_WORD0_UNIQUE_HANDLES) {
2189                 if ((buflen -= 4) < 0)
2190                         goto out_resource;
2191                 WRITE32(0);
2192         }
2193         if (bmval0 & FATTR4_WORD0_LEASE_TIME) {
2194                 if ((buflen -= 4) < 0)
2195                         goto out_resource;
2196                 WRITE32(nn->nfsd4_lease);
2197         }
2198         if (bmval0 & FATTR4_WORD0_RDATTR_ERROR) {
2199                 if ((buflen -= 4) < 0)
2200                         goto out_resource;
2201                 WRITE32(rdattr_err);
2202         }
2203         if (bmval0 & FATTR4_WORD0_ACL) {
2204                 struct nfs4_ace *ace;
2205
2206                 if (acl == NULL) {
2207                         if ((buflen -= 4) < 0)
2208                                 goto out_resource;
2209
2210                         WRITE32(0);
2211                         goto out_acl;
2212                 }
2213                 if ((buflen -= 4) < 0)
2214                         goto out_resource;
2215                 WRITE32(acl->naces);
2216
2217                 for (ace = acl->aces; ace < acl->aces + acl->naces; ace++) {
2218                         if ((buflen -= 4*3) < 0)
2219                                 goto out_resource;
2220                         WRITE32(ace->type);
2221                         WRITE32(ace->flag);
2222                         WRITE32(ace->access_mask & NFS4_ACE_MASK_ALL);
2223                         status = nfsd4_encode_aclname(rqstp, ace, &p, &buflen);
2224                         if (status == nfserr_resource)
2225                                 goto out_resource;
2226                         if (status)
2227                                 goto out;
2228                 }
2229         }
2230 out_acl:
2231         if (bmval0 & FATTR4_WORD0_ACLSUPPORT) {
2232                 if ((buflen -= 4) < 0)
2233                         goto out_resource;
2234                 WRITE32(aclsupport ?
2235                         ACL4_SUPPORT_ALLOW_ACL|ACL4_SUPPORT_DENY_ACL : 0);
2236         }
2237         if (bmval0 & FATTR4_WORD0_CANSETTIME) {
2238                 if ((buflen -= 4) < 0)
2239                         goto out_resource;
2240                 WRITE32(1);
2241         }
2242         if (bmval0 & FATTR4_WORD0_CASE_INSENSITIVE) {
2243                 if ((buflen -= 4) < 0)
2244                         goto out_resource;
2245                 WRITE32(0);
2246         }
2247         if (bmval0 & FATTR4_WORD0_CASE_PRESERVING) {
2248                 if ((buflen -= 4) < 0)
2249                         goto out_resource;
2250                 WRITE32(1);
2251         }
2252         if (bmval0 & FATTR4_WORD0_CHOWN_RESTRICTED) {
2253                 if ((buflen -= 4) < 0)
2254                         goto out_resource;
2255                 WRITE32(1);
2256         }
2257         if (bmval0 & FATTR4_WORD0_FILEHANDLE) {
2258                 buflen -= (XDR_QUADLEN(fhp->fh_handle.fh_size) << 2) + 4;
2259                 if (buflen < 0)
2260                         goto out_resource;
2261                 WRITE32(fhp->fh_handle.fh_size);
2262                 WRITEMEM(&fhp->fh_handle.fh_base, fhp->fh_handle.fh_size);
2263         }
2264         if (bmval0 & FATTR4_WORD0_FILEID) {
2265                 if ((buflen -= 8) < 0)
2266                         goto out_resource;
2267                 WRITE64(stat.ino);
2268         }
2269         if (bmval0 & FATTR4_WORD0_FILES_AVAIL) {
2270                 if ((buflen -= 8) < 0)
2271                         goto out_resource;
2272                 WRITE64((u64) statfs.f_ffree);
2273         }
2274         if (bmval0 & FATTR4_WORD0_FILES_FREE) {
2275                 if ((buflen -= 8) < 0)
2276                         goto out_resource;
2277                 WRITE64((u64) statfs.f_ffree);
2278         }
2279         if (bmval0 & FATTR4_WORD0_FILES_TOTAL) {
2280                 if ((buflen -= 8) < 0)
2281                         goto out_resource;
2282                 WRITE64((u64) statfs.f_files);
2283         }
2284         if (bmval0 & FATTR4_WORD0_FS_LOCATIONS) {
2285                 status = nfsd4_encode_fs_locations(rqstp, exp, &p, &buflen);
2286                 if (status == nfserr_resource)
2287                         goto out_resource;
2288                 if (status)
2289                         goto out;
2290         }
2291         if (bmval0 & FATTR4_WORD0_HOMOGENEOUS) {
2292                 if ((buflen -= 4) < 0)
2293                         goto out_resource;
2294                 WRITE32(1);
2295         }
2296         if (bmval0 & FATTR4_WORD0_MAXFILESIZE) {
2297                 if ((buflen -= 8) < 0)
2298                         goto out_resource;
2299                 WRITE64(~(u64)0);
2300         }
2301         if (bmval0 & FATTR4_WORD0_MAXLINK) {
2302                 if ((buflen -= 4) < 0)
2303                         goto out_resource;
2304                 WRITE32(255);
2305         }
2306         if (bmval0 & FATTR4_WORD0_MAXNAME) {
2307                 if ((buflen -= 4) < 0)
2308                         goto out_resource;
2309                 WRITE32(statfs.f_namelen);
2310         }
2311         if (bmval0 & FATTR4_WORD0_MAXREAD) {
2312                 if ((buflen -= 8) < 0)
2313                         goto out_resource;
2314                 WRITE64((u64) svc_max_payload(rqstp));
2315         }
2316         if (bmval0 & FATTR4_WORD0_MAXWRITE) {
2317                 if ((buflen -= 8) < 0)
2318                         goto out_resource;
2319                 WRITE64((u64) svc_max_payload(rqstp));
2320         }
2321         if (bmval1 & FATTR4_WORD1_MODE) {
2322                 if ((buflen -= 4) < 0)
2323                         goto out_resource;
2324                 WRITE32(stat.mode & S_IALLUGO);
2325         }
2326         if (bmval1 & FATTR4_WORD1_NO_TRUNC) {
2327                 if ((buflen -= 4) < 0)
2328                         goto out_resource;
2329                 WRITE32(1);
2330         }
2331         if (bmval1 & FATTR4_WORD1_NUMLINKS) {
2332                 if ((buflen -= 4) < 0)
2333                         goto out_resource;
2334                 WRITE32(stat.nlink);
2335         }
2336         if (bmval1 & FATTR4_WORD1_OWNER) {
2337                 status = nfsd4_encode_user(rqstp, stat.uid, &p, &buflen);
2338                 if (status == nfserr_resource)
2339                         goto out_resource;
2340                 if (status)
2341                         goto out;
2342         }
2343         if (bmval1 & FATTR4_WORD1_OWNER_GROUP) {
2344                 status = nfsd4_encode_group(rqstp, stat.gid, &p, &buflen);
2345                 if (status == nfserr_resource)
2346                         goto out_resource;
2347                 if (status)
2348                         goto out;
2349         }
2350         if (bmval1 & FATTR4_WORD1_RAWDEV) {
2351                 if ((buflen -= 8) < 0)
2352                         goto out_resource;
2353                 WRITE32((u32) MAJOR(stat.rdev));
2354                 WRITE32((u32) MINOR(stat.rdev));
2355         }
2356         if (bmval1 & FATTR4_WORD1_SPACE_AVAIL) {
2357                 if ((buflen -= 8) < 0)
2358                         goto out_resource;
2359                 dummy64 = (u64)statfs.f_bavail * (u64)statfs.f_bsize;
2360                 WRITE64(dummy64);
2361         }
2362         if (bmval1 & FATTR4_WORD1_SPACE_FREE) {
2363                 if ((buflen -= 8) < 0)
2364                         goto out_resource;
2365                 dummy64 = (u64)statfs.f_bfree * (u64)statfs.f_bsize;
2366                 WRITE64(dummy64);
2367         }
2368         if (bmval1 & FATTR4_WORD1_SPACE_TOTAL) {
2369                 if ((buflen -= 8) < 0)
2370                         goto out_resource;
2371                 dummy64 = (u64)statfs.f_blocks * (u64)statfs.f_bsize;
2372                 WRITE64(dummy64);
2373         }
2374         if (bmval1 & FATTR4_WORD1_SPACE_USED) {
2375                 if ((buflen -= 8) < 0)
2376                         goto out_resource;
2377                 dummy64 = (u64)stat.blocks << 9;
2378                 WRITE64(dummy64);
2379         }
2380         if (bmval1 & FATTR4_WORD1_TIME_ACCESS) {
2381                 if ((buflen -= 12) < 0)
2382                         goto out_resource;
2383                 WRITE64((s64)stat.atime.tv_sec);
2384                 WRITE32(stat.atime.tv_nsec);
2385         }
2386         if (bmval1 & FATTR4_WORD1_TIME_DELTA) {
2387                 if ((buflen -= 12) < 0)
2388                         goto out_resource;
2389                 WRITE32(0);
2390                 WRITE32(1);
2391                 WRITE32(0);
2392         }
2393         if (bmval1 & FATTR4_WORD1_TIME_METADATA) {
2394                 if ((buflen -= 12) < 0)
2395                         goto out_resource;
2396                 WRITE64((s64)stat.ctime.tv_sec);
2397                 WRITE32(stat.ctime.tv_nsec);
2398         }
2399         if (bmval1 & FATTR4_WORD1_TIME_MODIFY) {
2400                 if ((buflen -= 12) < 0)
2401                         goto out_resource;
2402                 WRITE64((s64)stat.mtime.tv_sec);
2403                 WRITE32(stat.mtime.tv_nsec);
2404         }
2405         if (bmval1 & FATTR4_WORD1_MOUNTED_ON_FILEID) {
2406                 if ((buflen -= 8) < 0)
2407                         goto out_resource;
2408                 /*
2409                  * Get parent's attributes if not ignoring crossmount
2410                  * and this is the root of a cross-mounted filesystem.
2411                  */
2412                 if (ignore_crossmnt == 0 &&
2413                     dentry == exp->ex_path.mnt->mnt_root)
2414                         get_parent_attributes(exp, &stat);
2415                 WRITE64(stat.ino);
2416         }
2417         if (bmval2 & FATTR4_WORD2_SUPPATTR_EXCLCREAT) {
2418                 if ((buflen -= 16) < 0)
2419                         goto out_resource;
2420                 WRITE32(3);
2421                 WRITE32(NFSD_SUPPATTR_EXCLCREAT_WORD0);
2422                 WRITE32(NFSD_SUPPATTR_EXCLCREAT_WORD1);
2423                 WRITE32(NFSD_SUPPATTR_EXCLCREAT_WORD2);
2424         }
2425
2426         *attrlenp = htonl((char *)p - (char *)attrlenp - 4);
2427         *buffer = p;
2428         status = nfs_ok;
2429
2430 out:
2431         kfree(acl);
2432         if (fhp == &tempfh)
2433                 fh_put(&tempfh);
2434         return status;
2435 out_nfserr:
2436         status = nfserrno(err);
2437         goto out;
2438 out_resource:
2439         status = nfserr_resource;
2440         goto out;
2441 out_serverfault:
2442         status = nfserr_serverfault;
2443         goto out;
2444 }
2445
2446 static inline int attributes_need_mount(u32 *bmval)
2447 {
2448         if (bmval[0] & ~(FATTR4_WORD0_RDATTR_ERROR | FATTR4_WORD0_LEASE_TIME))
2449                 return 1;
2450         if (bmval[1] & ~FATTR4_WORD1_MOUNTED_ON_FILEID)
2451                 return 1;
2452         return 0;
2453 }
2454
2455 static __be32
2456 nfsd4_encode_dirent_fattr(struct nfsd4_readdir *cd,
2457                 const char *name, int namlen, __be32 **p, int buflen)
2458 {
2459         struct svc_export *exp = cd->rd_fhp->fh_export;
2460         struct dentry *dentry;
2461         __be32 nfserr;
2462         int ignore_crossmnt = 0;
2463
2464         dentry = lookup_one_len(name, cd->rd_fhp->fh_dentry, namlen);
2465         if (IS_ERR(dentry))
2466                 return nfserrno(PTR_ERR(dentry));
2467         if (!dentry->d_inode) {
2468                 /*
2469                  * nfsd_buffered_readdir drops the i_mutex between
2470                  * readdir and calling this callback, leaving a window
2471                  * where this directory entry could have gone away.
2472                  */
2473                 dput(dentry);
2474                 return nfserr_noent;
2475         }
2476
2477         exp_get(exp);
2478         /*
2479          * In the case of a mountpoint, the client may be asking for
2480          * attributes that are only properties of the underlying filesystem
2481          * as opposed to the cross-mounted file system. In such a case,
2482          * we will not follow the cross mount and will fill the attribtutes
2483          * directly from the mountpoint dentry.
2484          */
2485         if (nfsd_mountpoint(dentry, exp)) {
2486                 int err;
2487
2488                 if (!(exp->ex_flags & NFSEXP_V4ROOT)
2489                                 && !attributes_need_mount(cd->rd_bmval)) {
2490                         ignore_crossmnt = 1;
2491                         goto out_encode;
2492                 }
2493                 /*
2494                  * Why the heck aren't we just using nfsd_lookup??
2495                  * Different "."/".." handling?  Something else?
2496                  * At least, add a comment here to explain....
2497                  */
2498                 err = nfsd_cross_mnt(cd->rd_rqstp, &dentry, &exp);
2499                 if (err) {
2500                         nfserr = nfserrno(err);
2501                         goto out_put;
2502                 }
2503                 nfserr = check_nfsd_access(exp, cd->rd_rqstp);
2504                 if (nfserr)
2505                         goto out_put;
2506
2507         }
2508 out_encode:
2509         nfserr = nfsd4_encode_fattr(NULL, exp, dentry, p, buflen, cd->rd_bmval,
2510                                         cd->rd_rqstp, ignore_crossmnt);
2511 out_put:
2512         dput(dentry);
2513         exp_put(exp);
2514         return nfserr;
2515 }
2516
2517 static __be32 *
2518 nfsd4_encode_rdattr_error(__be32 *p, int buflen, __be32 nfserr)
2519 {
2520         __be32 *attrlenp;
2521
2522         if (buflen < 6)
2523                 return NULL;
2524         *p++ = htonl(2);
2525         *p++ = htonl(FATTR4_WORD0_RDATTR_ERROR); /* bmval0 */
2526         *p++ = htonl(0);                         /* bmval1 */
2527
2528         attrlenp = p++;
2529         *p++ = nfserr;       /* no htonl */
2530         *attrlenp = htonl((char *)p - (char *)attrlenp - 4);
2531         return p;
2532 }
2533
2534 static int
2535 nfsd4_encode_dirent(void *ccdv, const char *name, int namlen,
2536                     loff_t offset, u64 ino, unsigned int d_type)
2537 {
2538         struct readdir_cd *ccd = ccdv;
2539         struct nfsd4_readdir *cd = container_of(ccd, struct nfsd4_readdir, common);
2540         int buflen;
2541         __be32 *p = cd->buffer;
2542         __be32 *cookiep;
2543         __be32 nfserr = nfserr_toosmall;
2544
2545         /* In nfsv4, "." and ".." never make it onto the wire.. */
2546         if (name && isdotent(name, namlen)) {
2547                 cd->common.err = nfs_ok;
2548                 return 0;
2549         }
2550
2551         if (cd->offset)
2552                 xdr_encode_hyper(cd->offset, (u64) offset);
2553
2554         buflen = cd->buflen - 4 - XDR_QUADLEN(namlen);
2555         if (buflen < 0)
2556                 goto fail;
2557
2558         *p++ = xdr_one;                             /* mark entry present */
2559         cookiep = p;
2560         p = xdr_encode_hyper(p, NFS_OFFSET_MAX);    /* offset of next entry */
2561         p = xdr_encode_array(p, name, namlen);      /* name length & name */
2562
2563         nfserr = nfsd4_encode_dirent_fattr(cd, name, namlen, &p, buflen);
2564         switch (nfserr) {
2565         case nfs_ok:
2566                 break;
2567         case nfserr_resource:
2568                 nfserr = nfserr_toosmall;
2569                 goto fail;
2570         case nfserr_noent:
2571                 goto skip_entry;
2572         default:
2573                 /*
2574                  * If the client requested the RDATTR_ERROR attribute,
2575                  * we stuff the error code into this attribute
2576                  * and continue.  If this attribute was not requested,
2577                  * then in accordance with the spec, we fail the
2578                  * entire READDIR operation(!)
2579                  */
2580                 if (!(cd->rd_bmval[0] & FATTR4_WORD0_RDATTR_ERROR))
2581                         goto fail;
2582                 p = nfsd4_encode_rdattr_error(p, buflen, nfserr);
2583                 if (p == NULL) {
2584                         nfserr = nfserr_toosmall;
2585                         goto fail;
2586                 }
2587         }
2588         cd->buflen -= (p - cd->buffer);
2589         cd->buffer = p;
2590         cd->offset = cookiep;
2591 skip_entry:
2592         cd->common.err = nfs_ok;
2593         return 0;
2594 fail:
2595         cd->common.err = nfserr;
2596         return -EINVAL;
2597 }
2598
2599 static void
2600 nfsd4_encode_stateid(struct nfsd4_compoundres *resp, stateid_t *sid)
2601 {
2602         __be32 *p;
2603
2604         RESERVE_SPACE(sizeof(stateid_t));
2605         WRITE32(sid->si_generation);
2606         WRITEMEM(&sid->si_opaque, sizeof(stateid_opaque_t));
2607         ADJUST_ARGS();
2608 }
2609
2610 static __be32
2611 nfsd4_encode_access(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_access *access)
2612 {
2613         __be32 *p;
2614
2615         if (!nfserr) {
2616                 RESERVE_SPACE(8);
2617                 WRITE32(access->ac_supported);
2618                 WRITE32(access->ac_resp_access);
2619                 ADJUST_ARGS();
2620         }
2621         return nfserr;
2622 }
2623
2624 static __be32 nfsd4_encode_bind_conn_to_session(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_bind_conn_to_session *bcts)
2625 {
2626         __be32 *p;
2627
2628         if (!nfserr) {
2629                 RESERVE_SPACE(NFS4_MAX_SESSIONID_LEN + 8);
2630                 WRITEMEM(bcts->sessionid.data, NFS4_MAX_SESSIONID_LEN);
2631                 WRITE32(bcts->dir);
2632                 /* Sorry, we do not yet support RDMA over 4.1: */
2633                 WRITE32(0);
2634                 ADJUST_ARGS();
2635         }
2636         return nfserr;
2637 }
2638
2639 static __be32
2640 nfsd4_encode_close(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_close *close)
2641 {
2642         if (!nfserr)
2643                 nfsd4_encode_stateid(resp, &close->cl_stateid);
2644
2645         return nfserr;
2646 }
2647
2648
2649 static __be32
2650 nfsd4_encode_commit(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_commit *commit)
2651 {
2652         __be32 *p;
2653
2654         if (!nfserr) {
2655                 RESERVE_SPACE(NFS4_VERIFIER_SIZE);
2656                 WRITEMEM(commit->co_verf.data, NFS4_VERIFIER_SIZE);
2657                 ADJUST_ARGS();
2658         }
2659         return nfserr;
2660 }
2661
2662 static __be32
2663 nfsd4_encode_create(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_create *create)
2664 {
2665         __be32 *p;
2666
2667         if (!nfserr) {
2668                 RESERVE_SPACE(32);
2669                 write_cinfo(&p, &create->cr_cinfo);
2670                 WRITE32(2);
2671                 WRITE32(create->cr_bmval[0]);
2672                 WRITE32(create->cr_bmval[1]);
2673                 ADJUST_ARGS();
2674         }
2675         return nfserr;
2676 }
2677
2678 static __be32
2679 nfsd4_encode_getattr(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_getattr *getattr)
2680 {
2681         struct svc_fh *fhp = getattr->ga_fhp;
2682         int buflen;
2683
2684         if (nfserr)
2685                 return nfserr;
2686
2687         buflen = resp->end - resp->p - (COMPOUND_ERR_SLACK_SPACE >> 2);
2688         nfserr = nfsd4_encode_fattr(fhp, fhp->fh_export, fhp->fh_dentry,
2689                                     &resp->p, buflen, getattr->ga_bmval,
2690                                     resp->rqstp, 0);
2691         return nfserr;
2692 }
2693
2694 static __be32
2695 nfsd4_encode_getfh(struct nfsd4_compoundres *resp, __be32 nfserr, struct svc_fh **fhpp)
2696 {
2697         struct svc_fh *fhp = *fhpp;
2698         unsigned int len;
2699         __be32 *p;
2700
2701         if (!nfserr) {
2702                 len = fhp->fh_handle.fh_size;
2703                 RESERVE_SPACE(len + 4);
2704                 WRITE32(len);
2705                 WRITEMEM(&fhp->fh_handle.fh_base, len);
2706                 ADJUST_ARGS();
2707         }
2708         return nfserr;
2709 }
2710
2711 /*
2712 * Including all fields other than the name, a LOCK4denied structure requires
2713 *   8(clientid) + 4(namelen) + 8(offset) + 8(length) + 4(type) = 32 bytes.
2714 */
2715 static void
2716 nfsd4_encode_lock_denied(struct nfsd4_compoundres *resp, struct nfsd4_lock_denied *ld)
2717 {
2718         struct xdr_netobj *conf = &ld->ld_owner;
2719         __be32 *p;
2720
2721         RESERVE_SPACE(32 + XDR_LEN(conf->len));
2722         WRITE64(ld->ld_start);
2723         WRITE64(ld->ld_length);
2724         WRITE32(ld->ld_type);
2725         if (conf->len) {
2726                 WRITEMEM(&ld->ld_clientid, 8);
2727                 WRITE32(conf->len);
2728                 WRITEMEM(conf->data, conf->len);
2729                 kfree(conf->data);
2730         }  else {  /* non - nfsv4 lock in conflict, no clientid nor owner */
2731                 WRITE64((u64)0); /* clientid */
2732                 WRITE32(0); /* length of owner name */
2733         }
2734         ADJUST_ARGS();
2735 }
2736
2737 static __be32
2738 nfsd4_encode_lock(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_lock *lock)
2739 {
2740         if (!nfserr)
2741                 nfsd4_encode_stateid(resp, &lock->lk_resp_stateid);
2742         else if (nfserr == nfserr_denied)
2743                 nfsd4_encode_lock_denied(resp, &lock->lk_denied);
2744
2745         return nfserr;
2746 }
2747
2748 static __be32
2749 nfsd4_encode_lockt(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_lockt *lockt)
2750 {
2751         if (nfserr == nfserr_denied)
2752                 nfsd4_encode_lock_denied(resp, &lockt->lt_denied);
2753         return nfserr;
2754 }
2755
2756 static __be32
2757 nfsd4_encode_locku(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_locku *locku)
2758 {
2759         if (!nfserr)
2760                 nfsd4_encode_stateid(resp, &locku->lu_stateid);
2761
2762         return nfserr;
2763 }
2764
2765
2766 static __be32
2767 nfsd4_encode_link(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_link *link)
2768 {
2769         __be32 *p;
2770
2771         if (!nfserr) {
2772                 RESERVE_SPACE(20);
2773                 write_cinfo(&p, &link->li_cinfo);
2774                 ADJUST_ARGS();
2775         }
2776         return nfserr;
2777 }
2778
2779
2780 static __be32
2781 nfsd4_encode_open(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open *open)
2782 {
2783         __be32 *p;
2784
2785         if (nfserr)
2786                 goto out;
2787
2788         nfsd4_encode_stateid(resp, &open->op_stateid);
2789         RESERVE_SPACE(40);
2790         write_cinfo(&p, &open->op_cinfo);
2791         WRITE32(open->op_rflags);
2792         WRITE32(2);
2793         WRITE32(open->op_bmval[0]);
2794         WRITE32(open->op_bmval[1]);
2795         WRITE32(open->op_delegate_type);
2796         ADJUST_ARGS();
2797
2798         switch (open->op_delegate_type) {
2799         case NFS4_OPEN_DELEGATE_NONE:
2800                 break;
2801         case NFS4_OPEN_DELEGATE_READ:
2802                 nfsd4_encode_stateid(resp, &open->op_delegate_stateid);
2803                 RESERVE_SPACE(20);
2804                 WRITE32(open->op_recall);
2805
2806                 /*
2807                  * TODO: ACE's in delegations
2808                  */
2809                 WRITE32(NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE);
2810                 WRITE32(0);
2811                 WRITE32(0);
2812                 WRITE32(0);   /* XXX: is NULL principal ok? */
2813                 ADJUST_ARGS();
2814                 break;
2815         case NFS4_OPEN_DELEGATE_WRITE:
2816                 nfsd4_encode_stateid(resp, &open->op_delegate_stateid);
2817                 RESERVE_SPACE(32);
2818                 WRITE32(0);
2819
2820                 /*
2821                  * TODO: space_limit's in delegations
2822                  */
2823                 WRITE32(NFS4_LIMIT_SIZE);
2824                 WRITE32(~(u32)0);
2825                 WRITE32(~(u32)0);
2826
2827                 /*
2828                  * TODO: ACE's in delegations
2829                  */
2830                 WRITE32(NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE);
2831                 WRITE32(0);
2832                 WRITE32(0);
2833                 WRITE32(0);   /* XXX: is NULL principal ok? */
2834                 ADJUST_ARGS();
2835                 break;
2836         case NFS4_OPEN_DELEGATE_NONE_EXT: /* 4.1 */
2837                 switch (open->op_why_no_deleg) {
2838                 case WND4_CONTENTION:
2839                 case WND4_RESOURCE:
2840                         RESERVE_SPACE(8);
2841                         WRITE32(open->op_why_no_deleg);
2842                         WRITE32(0);     /* deleg signaling not supported yet */
2843                         break;
2844                 default:
2845                         RESERVE_SPACE(4);
2846                         WRITE32(open->op_why_no_deleg);
2847                 }
2848                 ADJUST_ARGS();
2849                 break;
2850         default:
2851                 BUG();
2852         }
2853         /* XXX save filehandle here */
2854 out:
2855         return nfserr;
2856 }
2857
2858 static __be32
2859 nfsd4_encode_open_confirm(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open_confirm *oc)
2860 {
2861         if (!nfserr)
2862                 nfsd4_encode_stateid(resp, &oc->oc_resp_stateid);
2863
2864         return nfserr;
2865 }
2866
2867 static __be32
2868 nfsd4_encode_open_downgrade(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open_downgrade *od)
2869 {
2870         if (!nfserr)
2871                 nfsd4_encode_stateid(resp, &od->od_stateid);
2872
2873         return nfserr;
2874 }
2875
2876 static __be32
2877 nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr,
2878                   struct nfsd4_read *read)
2879 {
2880         u32 eof;
2881         int v;
2882         struct page *page;
2883         unsigned long maxcount; 
2884         long len;
2885         __be32 *p;
2886
2887         if (nfserr)
2888                 return nfserr;
2889         if (resp->xbuf->page_len)
2890                 return nfserr_resource;
2891
2892         RESERVE_SPACE(8); /* eof flag and byte count */
2893
2894         maxcount = svc_max_payload(resp->rqstp);
2895         if (maxcount > read->rd_length)
2896                 maxcount = read->rd_length;
2897
2898         len = maxcount;
2899         v = 0;
2900         while (len > 0) {
2901                 page = *(resp->rqstp->rq_next_page);
2902                 if (!page) { /* ran out of pages */
2903                         maxcount -= len;
2904                         break;
2905                 }
2906                 resp->rqstp->rq_vec[v].iov_base = page_address(page);
2907                 resp->rqstp->rq_vec[v].iov_len =
2908                         len < PAGE_SIZE ? len : PAGE_SIZE;
2909                 resp->rqstp->rq_next_page++;
2910                 v++;
2911                 len -= PAGE_SIZE;
2912         }
2913         read->rd_vlen = v;
2914
2915         nfserr = nfsd_read_file(read->rd_rqstp, read->rd_fhp, read->rd_filp,
2916                         read->rd_offset, resp->rqstp->rq_vec, read->rd_vlen,
2917                         &maxcount);
2918
2919         if (nfserr)
2920                 return nfserr;
2921         eof = (read->rd_offset + maxcount >=
2922                read->rd_fhp->fh_dentry->d_inode->i_size);
2923
2924         WRITE32(eof);
2925         WRITE32(maxcount);
2926         ADJUST_ARGS();
2927         resp->xbuf->head[0].iov_len = (char*)p
2928                                         - (char*)resp->xbuf->head[0].iov_base;
2929         resp->xbuf->page_len = maxcount;
2930
2931         /* Use rest of head for padding and remaining ops: */
2932         resp->xbuf->tail[0].iov_base = p;
2933         resp->xbuf->tail[0].iov_len = 0;
2934         if (maxcount&3) {
2935                 RESERVE_SPACE(4);
2936                 WRITE32(0);
2937                 resp->xbuf->tail[0].iov_base += maxcount&3;
2938                 resp->xbuf->tail[0].iov_len = 4 - (maxcount&3);
2939                 ADJUST_ARGS();
2940         }
2941         return 0;
2942 }
2943
2944 static __be32
2945 nfsd4_encode_readlink(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_readlink *readlink)
2946 {
2947         int maxcount;
2948         char *page;
2949         __be32 *p;
2950
2951         if (nfserr)
2952                 return nfserr;
2953         if (resp->xbuf->page_len)
2954                 return nfserr_resource;
2955         if (!*resp->rqstp->rq_next_page)
2956                 return nfserr_resource;
2957
2958         page = page_address(*(resp->rqstp->rq_next_page++));
2959
2960         maxcount = PAGE_SIZE;
2961         RESERVE_SPACE(4);
2962
2963         /*
2964          * XXX: By default, the ->readlink() VFS op will truncate symlinks
2965          * if they would overflow the buffer.  Is this kosher in NFSv4?  If
2966          * not, one easy fix is: if ->readlink() precisely fills the buffer,
2967          * assume that truncation occurred, and return NFS4ERR_RESOURCE.
2968          */
2969         nfserr = nfsd_readlink(readlink->rl_rqstp, readlink->rl_fhp, page, &maxcount);
2970         if (nfserr == nfserr_isdir)
2971                 return nfserr_inval;
2972         if (nfserr)
2973                 return nfserr;
2974
2975         WRITE32(maxcount);
2976         ADJUST_ARGS();
2977         resp->xbuf->head[0].iov_len = (char*)p
2978                                 - (char*)resp->xbuf->head[0].iov_base;
2979         resp->xbuf->page_len = maxcount;
2980
2981         /* Use rest of head for padding and remaining ops: */
2982         resp->xbuf->tail[0].iov_base = p;
2983         resp->xbuf->tail[0].iov_len = 0;
2984         if (maxcount&3) {
2985                 RESERVE_SPACE(4);
2986                 WRITE32(0);
2987                 resp->xbuf->tail[0].iov_base += maxcount&3;
2988                 resp->xbuf->tail[0].iov_len = 4 - (maxcount&3);
2989                 ADJUST_ARGS();
2990         }
2991         return 0;
2992 }
2993
2994 static __be32
2995 nfsd4_encode_readdir(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_readdir *readdir)
2996 {
2997         int maxcount;
2998         loff_t offset;
2999         __be32 *page, *savep, *tailbase;
3000         __be32 *p;
3001
3002         if (nfserr)
3003                 return nfserr;
3004         if (resp->xbuf->page_len)
3005                 return nfserr_resource;
3006         if (!*resp->rqstp->rq_next_page)
3007                 return nfserr_resource;
3008
3009         RESERVE_SPACE(NFS4_VERIFIER_SIZE);
3010         savep = p;
3011
3012         /* XXX: Following NFSv3, we ignore the READDIR verifier for now. */
3013         WRITE32(0);
3014         WRITE32(0);
3015         ADJUST_ARGS();
3016         resp->xbuf->head[0].iov_len = ((char*)resp->p) - (char*)resp->xbuf->head[0].iov_base;
3017         tailbase = p;
3018
3019         maxcount = PAGE_SIZE;
3020         if (maxcount > readdir->rd_maxcount)
3021                 maxcount = readdir->rd_maxcount;
3022
3023         /*
3024          * Convert from bytes to words, account for the two words already
3025          * written, make sure to leave two words at the end for the next
3026          * pointer and eof field.
3027          */
3028         maxcount = (maxcount >> 2) - 4;
3029         if (maxcount < 0) {
3030                 nfserr =  nfserr_toosmall;
3031                 goto err_no_verf;
3032         }
3033
3034         page = page_address(*(resp->rqstp->rq_next_page++));
3035         readdir->common.err = 0;
3036         readdir->buflen = maxcount;
3037         readdir->buffer = page;
3038         readdir->offset = NULL;
3039
3040         offset = readdir->rd_cookie;
3041         nfserr = nfsd_readdir(readdir->rd_rqstp, readdir->rd_fhp,
3042                               &offset,
3043                               &readdir->common, nfsd4_encode_dirent);
3044         if (nfserr == nfs_ok &&
3045             readdir->common.err == nfserr_toosmall &&
3046             readdir->buffer == page) 
3047                 nfserr = nfserr_toosmall;
3048         if (nfserr)
3049                 goto err_no_verf;
3050
3051         if (readdir->offset)
3052                 xdr_encode_hyper(readdir->offset, offset);
3053
3054         p = readdir->buffer;
3055         *p++ = 0;       /* no more entries */
3056         *p++ = htonl(readdir->common.err == nfserr_eof);
3057         resp->xbuf->page_len = ((char*)p) -
3058                 (char*)page_address(*(resp->rqstp->rq_next_page-1));
3059
3060         /* Use rest of head for padding and remaining ops: */
3061         resp->xbuf->tail[0].iov_base = tailbase;
3062         resp->xbuf->tail[0].iov_len = 0;
3063         resp->p = resp->xbuf->tail[0].iov_base;
3064         resp->end = resp->p + (PAGE_SIZE - resp->xbuf->head[0].iov_len)/4;
3065
3066         return 0;
3067 err_no_verf:
3068         p = savep;
3069         ADJUST_ARGS();
3070         return nfserr;
3071 }
3072
3073 static __be32
3074 nfsd4_encode_remove(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_remove *remove)
3075 {
3076         __be32 *p;
3077
3078         if (!nfserr) {
3079                 RESERVE_SPACE(20);
3080                 write_cinfo(&p, &remove->rm_cinfo);
3081                 ADJUST_ARGS();
3082         }
3083         return nfserr;
3084 }
3085
3086 static __be32
3087 nfsd4_encode_rename(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_rename *rename)
3088 {
3089         __be32 *p;
3090
3091         if (!nfserr) {
3092                 RESERVE_SPACE(40);
3093                 write_cinfo(&p, &rename->rn_sinfo);
3094                 write_cinfo(&p, &rename->rn_tinfo);
3095                 ADJUST_ARGS();
3096         }
3097         return nfserr;
3098 }
3099
3100 static __be32
3101 nfsd4_do_encode_secinfo(struct nfsd4_compoundres *resp,
3102                          __be32 nfserr, struct svc_export *exp)
3103 {
3104         u32 i, nflavs, supported;
3105         struct exp_flavor_info *flavs;
3106         struct exp_flavor_info def_flavs[2];
3107         __be32 *p, *flavorsp;
3108         static bool report = true;
3109
3110         if (nfserr)
3111                 goto out;
3112         if (exp->ex_nflavors) {
3113                 flavs = exp->ex_flavors;
3114                 nflavs = exp->ex_nflavors;
3115         } else { /* Handling of some defaults in absence of real secinfo: */
3116                 flavs = def_flavs;
3117                 if (exp->ex_client->flavour->flavour == RPC_AUTH_UNIX) {
3118                         nflavs = 2;
3119                         flavs[0].pseudoflavor = RPC_AUTH_UNIX;
3120                         flavs[1].pseudoflavor = RPC_AUTH_NULL;
3121                 } else if (exp->ex_client->flavour->flavour == RPC_AUTH_GSS) {
3122                         nflavs = 1;
3123                         flavs[0].pseudoflavor
3124                                         = svcauth_gss_flavor(exp->ex_client);
3125                 } else {
3126                         nflavs = 1;
3127                         flavs[0].pseudoflavor
3128                                         = exp->ex_client->flavour->flavour;
3129                 }
3130         }
3131
3132         supported = 0;
3133         RESERVE_SPACE(4);
3134         flavorsp = p++;         /* to be backfilled later */
3135         ADJUST_ARGS();
3136
3137         for (i = 0; i < nflavs; i++) {
3138                 rpc_authflavor_t pf = flavs[i].pseudoflavor;
3139                 struct rpcsec_gss_info info;
3140
3141                 if (rpcauth_get_gssinfo(pf, &info) == 0) {
3142                         supported++;
3143                         RESERVE_SPACE(4 + 4 + info.oid.len + 4 + 4);
3144                         WRITE32(RPC_AUTH_GSS);
3145                         WRITE32(info.oid.len);
3146                         WRITEMEM(info.oid.data, info.oid.len);
3147                         WRITE32(info.qop);
3148                         WRITE32(info.service);
3149                         ADJUST_ARGS();
3150                 } else if (pf < RPC_AUTH_MAXFLAVOR) {
3151                         supported++;
3152                         RESERVE_SPACE(4);
3153                         WRITE32(pf);
3154                         ADJUST_ARGS();
3155                 } else {
3156                         if (report)
3157                                 pr_warn("NFS: SECINFO: security flavor %u "
3158                                         "is not supported\n", pf);
3159                 }
3160         }
3161
3162         if (nflavs != supported)
3163                 report = false;
3164         *flavorsp = htonl(supported);
3165
3166 out:
3167         if (exp)
3168                 exp_put(exp);
3169         return nfserr;
3170 }
3171
3172 static __be32
3173 nfsd4_encode_secinfo(struct nfsd4_compoundres *resp, __be32 nfserr,
3174                      struct nfsd4_secinfo *secinfo)
3175 {
3176         return nfsd4_do_encode_secinfo(resp, nfserr, secinfo->si_exp);
3177 }
3178
3179 static __be32
3180 nfsd4_encode_secinfo_no_name(struct nfsd4_compoundres *resp, __be32 nfserr,
3181                      struct nfsd4_secinfo_no_name *secinfo)
3182 {
3183         return nfsd4_do_encode_secinfo(resp, nfserr, secinfo->sin_exp);
3184 }
3185
3186 /*
3187  * The SETATTR encode routine is special -- it always encodes a bitmap,
3188  * regardless of the error status.
3189  */
3190 static __be32
3191 nfsd4_encode_setattr(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_setattr *setattr)
3192 {
3193         __be32 *p;
3194
3195         RESERVE_SPACE(12);
3196         if (nfserr) {
3197                 WRITE32(2);
3198                 WRITE32(0);
3199                 WRITE32(0);
3200         }
3201         else {
3202                 WRITE32(2);
3203                 WRITE32(setattr->sa_bmval[0]);
3204                 WRITE32(setattr->sa_bmval[1]);
3205         }
3206         ADJUST_ARGS();
3207         return nfserr;
3208 }
3209
3210 static __be32
3211 nfsd4_encode_setclientid(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_setclientid *scd)
3212 {
3213         __be32 *p;
3214
3215         if (!nfserr) {
3216                 RESERVE_SPACE(8 + NFS4_VERIFIER_SIZE);
3217                 WRITEMEM(&scd->se_clientid, 8);
3218                 WRITEMEM(&scd->se_confirm, NFS4_VERIFIER_SIZE);
3219                 ADJUST_ARGS();
3220         }
3221         else if (nfserr == nfserr_clid_inuse) {
3222                 RESERVE_SPACE(8);
3223                 WRITE32(0);
3224                 WRITE32(0);
3225                 ADJUST_ARGS();
3226         }
3227         return nfserr;
3228 }
3229
3230 static __be32
3231 nfsd4_encode_write(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_write *write)
3232 {
3233         __be32 *p;
3234
3235         if (!nfserr) {
3236                 RESERVE_SPACE(16);
3237                 WRITE32(write->wr_bytes_written);
3238                 WRITE32(write->wr_how_written);
3239                 WRITEMEM(write->wr_verifier.data, NFS4_VERIFIER_SIZE);
3240                 ADJUST_ARGS();
3241         }
3242         return nfserr;
3243 }
3244
3245 static __be32
3246 nfsd4_encode_exchange_id(struct nfsd4_compoundres *resp, __be32 nfserr,
3247                          struct nfsd4_exchange_id *exid)
3248 {
3249         __be32 *p;
3250         char *major_id;
3251         char *server_scope;
3252         int major_id_sz;
3253         int server_scope_sz;
3254         uint64_t minor_id = 0;
3255
3256         if (nfserr)
3257                 return nfserr;
3258
3259         major_id = utsname()->nodename;
3260         major_id_sz = strlen(major_id);
3261         server_scope = utsname()->nodename;
3262         server_scope_sz = strlen(server_scope);
3263
3264         RESERVE_SPACE(
3265                 8 /* eir_clientid */ +
3266                 4 /* eir_sequenceid */ +
3267                 4 /* eir_flags */ +
3268                 4 /* spr_how (SP4_NONE) */ +
3269                 8 /* so_minor_id */ +
3270                 4 /* so_major_id.len */ +
3271                 (XDR_QUADLEN(major_id_sz) * 4) +
3272                 4 /* eir_server_scope.len */ +
3273                 (XDR_QUADLEN(server_scope_sz) * 4) +
3274                 4 /* eir_server_impl_id.count (0) */);
3275
3276         WRITEMEM(&exid->clientid, 8);
3277         WRITE32(exid->seqid);
3278         WRITE32(exid->flags);
3279
3280         /* state_protect4_r. Currently only support SP4_NONE */
3281         BUG_ON(exid->spa_how != SP4_NONE);
3282         WRITE32(exid->spa_how);
3283
3284         /* The server_owner struct */
3285         WRITE64(minor_id);      /* Minor id */
3286         /* major id */
3287         WRITE32(major_id_sz);
3288         WRITEMEM(major_id, major_id_sz);
3289
3290         /* Server scope */
3291         WRITE32(server_scope_sz);
3292         WRITEMEM(server_scope, server_scope_sz);
3293
3294         /* Implementation id */
3295         WRITE32(0);     /* zero length nfs_impl_id4 array */
3296         ADJUST_ARGS();
3297         return 0;
3298 }
3299
3300 static __be32
3301 nfsd4_encode_create_session(struct nfsd4_compoundres *resp, __be32 nfserr,
3302                             struct nfsd4_create_session *sess)
3303 {
3304         __be32 *p;
3305
3306         if (nfserr)
3307                 return nfserr;
3308
3309         RESERVE_SPACE(24);
3310         WRITEMEM(sess->sessionid.data, NFS4_MAX_SESSIONID_LEN);
3311         WRITE32(sess->seqid);
3312         WRITE32(sess->flags);
3313         ADJUST_ARGS();
3314
3315         RESERVE_SPACE(28);
3316         WRITE32(0); /* headerpadsz */
3317         WRITE32(sess->fore_channel.maxreq_sz);
3318         WRITE32(sess->fore_channel.maxresp_sz);
3319         WRITE32(sess->fore_channel.maxresp_cached);
3320         WRITE32(sess->fore_channel.maxops);
3321         WRITE32(sess->fore_channel.maxreqs);
3322         WRITE32(sess->fore_channel.nr_rdma_attrs);
3323         ADJUST_ARGS();
3324
3325         if (sess->fore_channel.nr_rdma_attrs) {
3326                 RESERVE_SPACE(4);
3327                 WRITE32(sess->fore_channel.rdma_attrs);
3328                 ADJUST_ARGS();
3329         }
3330
3331         RESERVE_SPACE(28);
3332         WRITE32(0); /* headerpadsz */
3333         WRITE32(sess->back_channel.maxreq_sz);
3334         WRITE32(sess->back_channel.maxresp_sz);
3335         WRITE32(sess->back_channel.maxresp_cached);
3336         WRITE32(sess->back_channel.maxops);
3337         WRITE32(sess->back_channel.maxreqs);
3338         WRITE32(sess->back_channel.nr_rdma_attrs);
3339         ADJUST_ARGS();
3340
3341         if (sess->back_channel.nr_rdma_attrs) {
3342                 RESERVE_SPACE(4);
3343                 WRITE32(sess->back_channel.rdma_attrs);
3344                 ADJUST_ARGS();
3345         }
3346         return 0;
3347 }
3348
3349 static __be32
3350 nfsd4_encode_destroy_session(struct nfsd4_compoundres *resp, __be32 nfserr,
3351                              struct nfsd4_destroy_session *destroy_session)
3352 {
3353         return nfserr;
3354 }
3355
3356 static __be32
3357 nfsd4_encode_free_stateid(struct nfsd4_compoundres *resp, __be32 nfserr,
3358                           struct nfsd4_free_stateid *free_stateid)
3359 {
3360         __be32 *p;
3361
3362         if (nfserr)
3363                 return nfserr;
3364
3365         RESERVE_SPACE(4);
3366         *p++ = nfserr;
3367         ADJUST_ARGS();
3368         return nfserr;
3369 }
3370
3371 static __be32
3372 nfsd4_encode_sequence(struct nfsd4_compoundres *resp, __be32 nfserr,
3373                       struct nfsd4_sequence *seq)
3374 {
3375         __be32 *p;
3376
3377         if (nfserr)
3378                 return nfserr;
3379
3380         RESERVE_SPACE(NFS4_MAX_SESSIONID_LEN + 20);
3381         WRITEMEM(seq->sessionid.data, NFS4_MAX_SESSIONID_LEN);
3382         WRITE32(seq->seqid);
3383         WRITE32(seq->slotid);
3384         /* Note slotid's are numbered from zero: */
3385         WRITE32(seq->maxslots - 1); /* sr_highest_slotid */
3386         WRITE32(seq->maxslots - 1); /* sr_target_highest_slotid */
3387         WRITE32(seq->status_flags);
3388
3389         ADJUST_ARGS();
3390         resp->cstate.datap = p; /* DRC cache data pointer */
3391         return 0;
3392 }
3393
3394 static __be32
3395 nfsd4_encode_test_stateid(struct nfsd4_compoundres *resp, __be32 nfserr,
3396                           struct nfsd4_test_stateid *test_stateid)
3397 {
3398         struct nfsd4_test_stateid_id *stateid, *next;
3399         __be32 *p;
3400
3401         if (nfserr)
3402                 return nfserr;
3403
3404         RESERVE_SPACE(4 + (4 * test_stateid->ts_num_ids));
3405         *p++ = htonl(test_stateid->ts_num_ids);
3406
3407         list_for_each_entry_safe(stateid, next, &test_stateid->ts_stateid_list, ts_id_list) {
3408                 *p++ = stateid->ts_id_status;
3409         }
3410
3411         ADJUST_ARGS();
3412         return nfserr;
3413 }
3414
3415 static __be32
3416 nfsd4_encode_noop(struct nfsd4_compoundres *resp, __be32 nfserr, void *p)
3417 {
3418         return nfserr;
3419 }
3420
3421 typedef __be32(* nfsd4_enc)(struct nfsd4_compoundres *, __be32, void *);
3422
3423 /*
3424  * Note: nfsd4_enc_ops vector is shared for v4.0 and v4.1
3425  * since we don't need to filter out obsolete ops as this is
3426  * done in the decoding phase.
3427  */
3428 static nfsd4_enc nfsd4_enc_ops[] = {
3429         [OP_ACCESS]             = (nfsd4_enc)nfsd4_encode_access,
3430         [OP_CLOSE]              = (nfsd4_enc)nfsd4_encode_close,
3431         [OP_COMMIT]             = (nfsd4_enc)nfsd4_encode_commit,
3432         [OP_CREATE]             = (nfsd4_enc)nfsd4_encode_create,
3433         [OP_DELEGPURGE]         = (nfsd4_enc)nfsd4_encode_noop,
3434         [OP_DELEGRETURN]        = (nfsd4_enc)nfsd4_encode_noop,
3435         [OP_GETATTR]            = (nfsd4_enc)nfsd4_encode_getattr,
3436         [OP_GETFH]              = (nfsd4_enc)nfsd4_encode_getfh,
3437         [OP_LINK]               = (nfsd4_enc)nfsd4_encode_link,
3438         [OP_LOCK]               = (nfsd4_enc)nfsd4_encode_lock,
3439         [OP_LOCKT]              = (nfsd4_enc)nfsd4_encode_lockt,
3440         [OP_LOCKU]              = (nfsd4_enc)nfsd4_encode_locku,
3441         [OP_LOOKUP]             = (nfsd4_enc)nfsd4_encode_noop,
3442         [OP_LOOKUPP]            = (nfsd4_enc)nfsd4_encode_noop,
3443         [OP_NVERIFY]            = (nfsd4_enc)nfsd4_encode_noop,
3444         [OP_OPEN]               = (nfsd4_enc)nfsd4_encode_open,
3445         [OP_OPENATTR]           = (nfsd4_enc)nfsd4_encode_noop,
3446         [OP_OPEN_CONFIRM]       = (nfsd4_enc)nfsd4_encode_open_confirm,
3447         [OP_OPEN_DOWNGRADE]     = (nfsd4_enc)nfsd4_encode_open_downgrade,
3448         [OP_PUTFH]              = (nfsd4_enc)nfsd4_encode_noop,
3449         [OP_PUTPUBFH]           = (nfsd4_enc)nfsd4_encode_noop,
3450         [OP_PUTROOTFH]          = (nfsd4_enc)nfsd4_encode_noop,
3451         [OP_READ]               = (nfsd4_enc)nfsd4_encode_read,
3452         [OP_READDIR]            = (nfsd4_enc)nfsd4_encode_readdir,
3453         [OP_READLINK]           = (nfsd4_enc)nfsd4_encode_readlink,
3454         [OP_REMOVE]             = (nfsd4_enc)nfsd4_encode_remove,
3455         [OP_RENAME]             = (nfsd4_enc)nfsd4_encode_rename,
3456         [OP_RENEW]              = (nfsd4_enc)nfsd4_encode_noop,
3457         [OP_RESTOREFH]          = (nfsd4_enc)nfsd4_encode_noop,
3458         [OP_SAVEFH]             = (nfsd4_enc)nfsd4_encode_noop,
3459         [OP_SECINFO]            = (nfsd4_enc)nfsd4_encode_secinfo,
3460         [OP_SETATTR]            = (nfsd4_enc)nfsd4_encode_setattr,
3461         [OP_SETCLIENTID]        = (nfsd4_enc)nfsd4_encode_setclientid,
3462         [OP_SETCLIENTID_CONFIRM] = (nfsd4_enc)nfsd4_encode_noop,
3463         [OP_VERIFY]             = (nfsd4_enc)nfsd4_encode_noop,
3464         [OP_WRITE]              = (nfsd4_enc)nfsd4_encode_write,
3465         [OP_RELEASE_LOCKOWNER]  = (nfsd4_enc)nfsd4_encode_noop,
3466
3467         /* NFSv4.1 operations */
3468         [OP_BACKCHANNEL_CTL]    = (nfsd4_enc)nfsd4_encode_noop,
3469         [OP_BIND_CONN_TO_SESSION] = (nfsd4_enc)nfsd4_encode_bind_conn_to_session,
3470         [OP_EXCHANGE_ID]        = (nfsd4_enc)nfsd4_encode_exchange_id,
3471         [OP_CREATE_SESSION]     = (nfsd4_enc)nfsd4_encode_create_session,
3472         [OP_DESTROY_SESSION]    = (nfsd4_enc)nfsd4_encode_destroy_session,
3473         [OP_FREE_STATEID]       = (nfsd4_enc)nfsd4_encode_free_stateid,
3474         [OP_GET_DIR_DELEGATION] = (nfsd4_enc)nfsd4_encode_noop,
3475         [OP_GETDEVICEINFO]      = (nfsd4_enc)nfsd4_encode_noop,
3476         [OP_GETDEVICELIST]      = (nfsd4_enc)nfsd4_encode_noop,
3477         [OP_LAYOUTCOMMIT]       = (nfsd4_enc)nfsd4_encode_noop,
3478         [OP_LAYOUTGET]          = (nfsd4_enc)nfsd4_encode_noop,
3479         [OP_LAYOUTRETURN]       = (nfsd4_enc)nfsd4_encode_noop,
3480         [OP_SECINFO_NO_NAME]    = (nfsd4_enc)nfsd4_encode_secinfo_no_name,
3481         [OP_SEQUENCE]           = (nfsd4_enc)nfsd4_encode_sequence,
3482         [OP_SET_SSV]            = (nfsd4_enc)nfsd4_encode_noop,
3483         [OP_TEST_STATEID]       = (nfsd4_enc)nfsd4_encode_test_stateid,
3484         [OP_WANT_DELEGATION]    = (nfsd4_enc)nfsd4_encode_noop,
3485         [OP_DESTROY_CLIENTID]   = (nfsd4_enc)nfsd4_encode_noop,
3486         [OP_RECLAIM_COMPLETE]   = (nfsd4_enc)nfsd4_encode_noop,
3487 };
3488
3489 /*
3490  * Calculate the total amount of memory that the compound response has taken
3491  * after encoding the current operation with pad.
3492  *
3493  * pad: if operation is non-idempotent, pad was calculate by op_rsize_bop()
3494  *      which was specified at nfsd4_operation, else pad is zero.
3495  *
3496  * Compare this length to the session se_fmaxresp_sz and se_fmaxresp_cached.
3497  *
3498  * Our se_fmaxresp_cached will always be a multiple of PAGE_SIZE, and so
3499  * will be at least a page and will therefore hold the xdr_buf head.
3500  */
3501 __be32 nfsd4_check_resp_size(struct nfsd4_compoundres *resp, u32 pad)
3502 {
3503         struct xdr_buf *xb = &resp->rqstp->rq_res;
3504         struct nfsd4_session *session = NULL;
3505         struct nfsd4_slot *slot = resp->cstate.slot;
3506         u32 length, tlen = 0;
3507
3508         if (!nfsd4_has_session(&resp->cstate))
3509                 return 0;
3510
3511         session = resp->cstate.session;
3512         if (session == NULL)
3513                 return 0;
3514
3515         if (xb->page_len == 0) {
3516                 length = (char *)resp->p - (char *)xb->head[0].iov_base + pad;
3517         } else {
3518                 if (xb->tail[0].iov_base && xb->tail[0].iov_len > 0)
3519                         tlen = (char *)resp->p - (char *)xb->tail[0].iov_base;
3520
3521                 length = xb->head[0].iov_len + xb->page_len + tlen + pad;
3522         }
3523         dprintk("%s length %u, xb->page_len %u tlen %u pad %u\n", __func__,
3524                 length, xb->page_len, tlen, pad);
3525
3526         if (length > session->se_fchannel.maxresp_sz)
3527                 return nfserr_rep_too_big;
3528
3529         if ((slot->sl_flags & NFSD4_SLOT_CACHETHIS) &&
3530             length > session->se_fchannel.maxresp_cached)
3531                 return nfserr_rep_too_big_to_cache;
3532
3533         return 0;
3534 }
3535
3536 void
3537 nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op)
3538 {
3539         struct nfs4_stateowner *so = resp->cstate.replay_owner;
3540         __be32 *statp;
3541         __be32 *p;
3542
3543         RESERVE_SPACE(8);
3544         WRITE32(op->opnum);
3545         statp = p++;    /* to be backfilled at the end */
3546         ADJUST_ARGS();
3547
3548         if (op->opnum == OP_ILLEGAL)
3549                 goto status;
3550         BUG_ON(op->opnum < 0 || op->opnum >= ARRAY_SIZE(nfsd4_enc_ops) ||
3551                !nfsd4_enc_ops[op->opnum]);
3552         op->status = nfsd4_enc_ops[op->opnum](resp, op->status, &op->u);
3553         /* nfsd4_check_drc_limit guarantees enough room for error status */
3554         if (!op->status)
3555                 op->status = nfsd4_check_resp_size(resp, 0);
3556         if (so) {
3557                 so->so_replay.rp_status = op->status;
3558                 so->so_replay.rp_buflen = (char *)resp->p - (char *)(statp+1);
3559                 memcpy(so->so_replay.rp_buf, statp+1, so->so_replay.rp_buflen);
3560         }
3561 status:
3562         /*
3563          * Note: We write the status directly, instead of using WRITE32(),
3564          * since it is already in network byte order.
3565          */
3566         *statp = op->status;
3567 }
3568
3569 /* 
3570  * Encode the reply stored in the stateowner reply cache 
3571  * 
3572  * XDR note: do not encode rp->rp_buflen: the buffer contains the
3573  * previously sent already encoded operation.
3574  *
3575  * called with nfs4_lock_state() held
3576  */
3577 void
3578 nfsd4_encode_replay(struct nfsd4_compoundres *resp, struct nfsd4_op *op)
3579 {
3580         __be32 *p;
3581         struct nfs4_replay *rp = op->replay;
3582
3583         BUG_ON(!rp);
3584
3585         RESERVE_SPACE(8);
3586         WRITE32(op->opnum);
3587         *p++ = rp->rp_status;  /* already xdr'ed */
3588         ADJUST_ARGS();
3589
3590         RESERVE_SPACE(rp->rp_buflen);
3591         WRITEMEM(rp->rp_buf, rp->rp_buflen);
3592         ADJUST_ARGS();
3593 }
3594
3595 int
3596 nfs4svc_encode_voidres(struct svc_rqst *rqstp, __be32 *p, void *dummy)
3597 {
3598         return xdr_ressize_check(rqstp, p);
3599 }
3600
3601 int nfsd4_release_compoundargs(void *rq, __be32 *p, void *resp)
3602 {
3603         struct svc_rqst *rqstp = rq;
3604         struct nfsd4_compoundargs *args = rqstp->rq_argp;
3605
3606         if (args->ops != args->iops) {
3607                 kfree(args->ops);
3608                 args->ops = args->iops;
3609         }
3610         kfree(args->tmpp);
3611         args->tmpp = NULL;
3612         while (args->to_free) {
3613                 struct tmpbuf *tb = args->to_free;
3614                 args->to_free = tb->next;
3615                 tb->release(tb->buf);
3616                 kfree(tb);
3617         }
3618         return 1;
3619 }
3620
3621 int
3622 nfs4svc_decode_compoundargs(struct svc_rqst *rqstp, __be32 *p, struct nfsd4_compoundargs *args)
3623 {
3624         args->p = p;
3625         args->end = rqstp->rq_arg.head[0].iov_base + rqstp->rq_arg.head[0].iov_len;
3626         args->pagelist = rqstp->rq_arg.pages;
3627         args->pagelen = rqstp->rq_arg.page_len;
3628         args->tmpp = NULL;
3629         args->to_free = NULL;
3630         args->ops = args->iops;
3631         args->rqstp = rqstp;
3632
3633         return !nfsd4_decode_compound(args);
3634 }
3635
3636 int
3637 nfs4svc_encode_compoundres(struct svc_rqst *rqstp, __be32 *p, struct nfsd4_compoundres *resp)
3638 {
3639         /*
3640          * All that remains is to write the tag and operation count...
3641          */
3642         struct nfsd4_compound_state *cs = &resp->cstate;
3643         struct kvec *iov;
3644         p = resp->tagp;
3645         *p++ = htonl(resp->taglen);
3646         memcpy(p, resp->tag, resp->taglen);
3647         p += XDR_QUADLEN(resp->taglen);
3648         *p++ = htonl(resp->opcnt);
3649
3650         if (rqstp->rq_res.page_len) 
3651                 iov = &rqstp->rq_res.tail[0];
3652         else
3653                 iov = &rqstp->rq_res.head[0];
3654         iov->iov_len = ((char*)resp->p) - (char*)iov->iov_base;
3655         BUG_ON(iov->iov_len > PAGE_SIZE);
3656         if (nfsd4_has_session(cs)) {
3657                 if (cs->status != nfserr_replay_cache) {
3658                         nfsd4_store_cache_entry(resp);
3659                         cs->slot->sl_flags &= ~NFSD4_SLOT_INUSE;
3660                 }
3661                 /* Renew the clientid on success and on replay */
3662                 put_client_renew(cs->session->se_client);
3663                 nfsd4_put_session(cs->session);
3664         }
3665         return 1;
3666 }
3667
3668 /*
3669  * Local variables:
3670  *  c-basic-offset: 8
3671  * End:
3672  */