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