fb458b6ea7be167bb5720d54e255d24aa3548946
[linux-2.6.git] / fs / nfsd / nfs4xdr.c
1 /*
2  *  fs/nfs/nfs4xdr.c
3  *
4  *  Server-side XDR for NFSv4
5  *
6  *  Copyright (c) 2002 The Regents of the University of Michigan.
7  *  All rights reserved.
8  *
9  *  Kendrick Smith <kmsmith@umich.edu>
10  *  Andy Adamson   <andros@umich.edu>
11  *
12  *  Redistribution and use in source and binary forms, with or without
13  *  modification, are permitted provided that the following conditions
14  *  are met:
15  *
16  *  1. Redistributions of source code must retain the above copyright
17  *     notice, this list of conditions and the following disclaimer.
18  *  2. Redistributions in binary form must reproduce the above copyright
19  *     notice, this list of conditions and the following disclaimer in the
20  *     documentation and/or other materials provided with the distribution.
21  *  3. Neither the name of the University nor the names of its
22  *     contributors may be used to endorse or promote products derived
23  *     from this software without specific prior written permission.
24  *
25  *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
26  *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
27  *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
28  *  DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29  *  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
32  *  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33  *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34  *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35  *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36  *
37  * TODO: Neil Brown made the following observation:  We currently
38  * initially reserve NFSD_BUFSIZE space on the transmit queue and
39  * never release any of that until the request is complete.
40  * It would be good to calculate a new maximum response size while
41  * decoding the COMPOUND, and call svc_reserve with this number
42  * at the end of nfs4svc_decode_compoundargs.
43  */
44
45 #include <linux/param.h>
46 #include <linux/smp.h>
47 #include <linux/smp_lock.h>
48 #include <linux/fs.h>
49 #include <linux/namei.h>
50 #include <linux/vfs.h>
51 #include <linux/sunrpc/xdr.h>
52 #include <linux/sunrpc/svc.h>
53 #include <linux/sunrpc/clnt.h>
54 #include <linux/nfsd/nfsd.h>
55 #include <linux/nfsd/state.h>
56 #include <linux/nfsd/xdr4.h>
57 #include <linux/nfsd_idmap.h>
58
59 #define NFSDDBG_FACILITY                NFSDDBG_XDR
60
61 static const char utf8_byte_len[256] = {
62         1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
63         1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
64         1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
65         1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
66         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
67         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
68         0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
69         3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, 4,4,4,4,4,4,4,4,5,5,5,5,6,6,0,0
70 };
71
72 static inline int
73 is_legal_utf8_sequence(unsigned char *source, int length)
74 {
75         unsigned char *ptr;
76         unsigned char c;
77
78         if (length==1) return 1;
79
80         /* Check for overlong sequence, and check second byte */
81         c = *(source + 1);
82         switch (*source) {
83         case 0xE0: /* 3 bytes */
84                 if ( c < 0xA0 ) return 0;
85                 break;
86         case 0xF0: /* 4 bytes */
87                 if ( c < 0x90 ) return 0;
88                 break;
89         case 0xF8: /* 5 bytes */
90                 if ( c < 0xC8 ) return 0;
91                 break;
92         case 0xFC: /* 6 bytes */
93                 if ( c < 0x84 ) return 0;
94                 break;
95         default:
96                 if ( (c & 0xC0) != 0x80) return 0;
97         }
98
99         /* Check that trailing bytes look like 10xxxxxx */
100         for (ptr = source++ + length - 1; ptr>source; ptr--)
101                 if ( ((*ptr) & 0xC0) != 0x80 ) return 0;
102         return 1;
103 }
104
105 /* This does some screening on disallowed unicode characters.  It is NOT
106  * comprehensive.
107  */
108 static int
109 is_allowed_utf8_char(unsigned char *source, int length)
110 {
111         /* We assume length and source point to a valid utf8 sequence */
112         unsigned char c;
113
114         /* Disallow F0000 and up (in utf8, F3B08080) */
115         if (*source > 0xF3 ) return 0;
116         c = *(source + 1);
117         switch (*source) {
118         case 0xF3:
119                 if (c >= 0xB0) return 0;
120                 break;
121         /* Disallow D800-F8FF (in utf8, EDA080-EFA3BF */
122         case 0xED:
123                 if (c >= 0xA0) return 0;
124                 break;
125         case 0xEE:
126                 return 0;
127                 break;
128         case 0xEF:
129                 if (c <= 0xA3) return 0;
130         /* Disallow FFF9-FFFF (EFBFB9-EFBFBF) */
131                 if (c==0xBF)
132                         /* Don't need to check <=0xBF, since valid utf8 */
133                         if ( *(source+2) >= 0xB9) return 0;
134                 break;
135         }
136         return 1;
137 }
138
139 /* This routine should really check to see that the proper stringprep
140  * mappings have been applied.  Instead, we do a simple screen of some
141  * of the more obvious illegal values by calling is_allowed_utf8_char.
142  * This will allow many illegal strings through, but if a client behaves,
143  * it will get full functionality.  The other option (apart from full
144  * stringprep checking) is to limit everything to an easily handled subset,
145  * such as 7-bit ascii.
146  *
147  * Note - currently calling routines ignore return value except as boolean.
148  */
149 static int
150 check_utf8(char *str, int len)
151 {
152         unsigned char *chunk, *sourceend;
153         int chunklen;
154
155         chunk = str;
156         sourceend = str + len;
157
158         while (chunk < sourceend) {
159                 chunklen = utf8_byte_len[*chunk];
160                 if (!chunklen)
161                         return nfserr_inval;
162                 if (chunk + chunklen > sourceend)
163                         return nfserr_inval;
164                 if (!is_legal_utf8_sequence(chunk, chunklen))
165                         return nfserr_inval;
166                 if (!is_allowed_utf8_char(chunk, chunklen))
167                         return nfserr_inval;
168                 if ( (chunklen==1) && (!*chunk) )
169                         return nfserr_inval; /* Disallow embedded nulls */
170                 chunk += chunklen;
171         }
172
173         return 0;
174 }
175
176 static int
177 check_filename(char *str, int len, int err)
178 {
179         int i;
180
181         if (len == 0)
182                 return nfserr_inval;
183         if (isdotent(str, len))
184                 return err;
185         for (i = 0; i < len; i++)
186                 if (str[i] == '/')
187                         return err;
188         return check_utf8(str, len);
189 }
190
191 /*
192  * START OF "GENERIC" DECODE ROUTINES.
193  *   These may look a little ugly since they are imported from a "generic"
194  * set of XDR encode/decode routines which are intended to be shared by
195  * all of our NFSv4 implementations (OpenBSD, MacOS X...).
196  *
197  * If the pain of reading these is too great, it should be a straightforward
198  * task to translate them into Linux-specific versions which are more
199  * consistent with the style used in NFSv2/v3...
200  */
201 #define DECODE_HEAD                             \
202         u32 *p;                                 \
203         int status
204 #define DECODE_TAIL                             \
205         status = 0;                             \
206 out:                                            \
207         return status;                          \
208 xdr_error:                                      \
209         printk(KERN_NOTICE "xdr error! (%s:%d)\n", __FILE__, __LINE__); \
210         status = nfserr_bad_xdr;                \
211         goto out
212
213 #define READ32(x)         (x) = ntohl(*p++)
214 #define READ64(x)         do {                  \
215         (x) = (u64)ntohl(*p++) << 32;           \
216         (x) |= ntohl(*p++);                     \
217 } while (0)
218 #define READTIME(x)       do {                  \
219         p++;                                    \
220         (x) = ntohl(*p++);                      \
221         p++;                                    \
222 } while (0)
223 #define READMEM(x,nbytes) do {                  \
224         x = (char *)p;                          \
225         p += XDR_QUADLEN(nbytes);               \
226 } while (0)
227 #define SAVEMEM(x,nbytes) do {                  \
228         if (!(x = (p==argp->tmp || p == argp->tmpp) ? \
229                 savemem(argp, p, nbytes) :      \
230                 (char *)p)) {                   \
231                 printk(KERN_NOTICE "xdr error! (%s:%d)\n", __FILE__, __LINE__); \
232                 goto xdr_error;                 \
233                 }                               \
234         p += XDR_QUADLEN(nbytes);               \
235 } while (0)
236 #define COPYMEM(x,nbytes) do {                  \
237         memcpy((x), p, nbytes);                 \
238         p += XDR_QUADLEN(nbytes);               \
239 } while (0)
240
241 /* READ_BUF, read_buf(): nbytes must be <= PAGE_SIZE */
242 #define READ_BUF(nbytes)  do {                  \
243         if (nbytes <= (u32)((char *)argp->end - (char *)argp->p)) {     \
244                 p = argp->p;                    \
245                 argp->p += XDR_QUADLEN(nbytes); \
246         } else if (!(p = read_buf(argp, nbytes))) { \
247                 printk(KERN_NOTICE "xdr error! (%s:%d)\n", __FILE__, __LINE__); \
248                 goto xdr_error;                 \
249         }                                       \
250 } while (0)
251
252 u32 *read_buf(struct nfsd4_compoundargs *argp, int nbytes)
253 {
254         /* We want more bytes than seem to be available.
255          * Maybe we need a new page, maybe we have just run out
256          */
257         int avail = (char*)argp->end - (char*)argp->p;
258         u32 *p;
259         if (avail + argp->pagelen < nbytes)
260                 return NULL;
261         if (avail + PAGE_SIZE < nbytes) /* need more than a page !! */
262                 return NULL;
263         /* ok, we can do it with the current plus the next page */
264         if (nbytes <= sizeof(argp->tmp))
265                 p = argp->tmp;
266         else {
267                 if (argp->tmpp)
268                         kfree(argp->tmpp);
269                 p = argp->tmpp = kmalloc(nbytes, GFP_KERNEL);
270                 if (!p)
271                         return NULL;
272                 
273         }
274         memcpy(p, argp->p, avail);
275         /* step to next page */
276         argp->p = page_address(argp->pagelist[0]);
277         argp->pagelist++;
278         if (argp->pagelen < PAGE_SIZE) {
279                 argp->end = p + (argp->pagelen>>2);
280                 argp->pagelen = 0;
281         } else {
282                 argp->end = p + (PAGE_SIZE>>2);
283                 argp->pagelen -= PAGE_SIZE;
284         }
285         memcpy(((char*)p)+avail, argp->p, (nbytes - avail));
286         argp->p += XDR_QUADLEN(nbytes - avail);
287         return p;
288 }
289
290 static int
291 defer_free(struct nfsd4_compoundargs *argp,
292                 void (*release)(const void *), void *p)
293 {
294         struct tmpbuf *tb;
295
296         tb = kmalloc(sizeof(*tb), GFP_KERNEL);
297         if (!tb)
298                 return -ENOMEM;
299         tb->buf = p;
300         tb->release = release;
301         tb->next = argp->to_free;
302         argp->to_free = tb;
303         return 0;
304 }
305
306 char *savemem(struct nfsd4_compoundargs *argp, u32 *p, int nbytes)
307 {
308         void *new = NULL;
309         if (p == argp->tmp) {
310                 new = kmalloc(nbytes, GFP_KERNEL);
311                 if (!new) return NULL;
312                 p = new;
313                 memcpy(p, argp->tmp, nbytes);
314         } else {
315                 if (p != argp->tmpp)
316                         BUG();
317                 argp->tmpp = NULL;
318         }
319         if (defer_free(argp, kfree, p)) {
320                 kfree(new);
321                 return NULL;
322         } else
323                 return (char *)p;
324 }
325
326
327 static int
328 nfsd4_decode_bitmap(struct nfsd4_compoundargs *argp, u32 *bmval)
329 {
330         u32 bmlen;
331         DECODE_HEAD;
332
333         bmval[0] = 0;
334         bmval[1] = 0;
335
336         READ_BUF(4);
337         READ32(bmlen);
338         if (bmlen > 1000)
339                 goto xdr_error;
340
341         READ_BUF(bmlen << 2);
342         if (bmlen > 0)
343                 READ32(bmval[0]);
344         if (bmlen > 1)
345                 READ32(bmval[1]);
346
347         DECODE_TAIL;
348 }
349
350 static int
351 nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, struct iattr *iattr)
352 {
353         int expected_len, len = 0;
354         u32 dummy32;
355         char *buf;
356
357         DECODE_HEAD;
358         iattr->ia_valid = 0;
359         if ((status = nfsd4_decode_bitmap(argp, bmval)))
360                 return status;
361
362         /*
363          * According to spec, unsupported attributes return ERR_NOTSUPP;
364          * read-only attributes return ERR_INVAL.
365          */
366         if ((bmval[0] & ~NFSD_SUPPORTED_ATTRS_WORD0) || (bmval[1] & ~NFSD_SUPPORTED_ATTRS_WORD1))
367                 return nfserr_attrnotsupp;
368         if ((bmval[0] & ~NFSD_WRITEABLE_ATTRS_WORD0) || (bmval[1] & ~NFSD_WRITEABLE_ATTRS_WORD1))
369                 return nfserr_inval;
370
371         READ_BUF(4);
372         READ32(expected_len);
373
374         if (bmval[0] & FATTR4_WORD0_SIZE) {
375                 READ_BUF(8);
376                 len += 8;
377                 READ64(iattr->ia_size);
378                 iattr->ia_valid |= ATTR_SIZE;
379         }
380         if (bmval[1] & FATTR4_WORD1_MODE) {
381                 READ_BUF(4);
382                 len += 4;
383                 READ32(iattr->ia_mode);
384                 iattr->ia_mode &= (S_IFMT | S_IALLUGO);
385                 iattr->ia_valid |= ATTR_MODE;
386         }
387         if (bmval[1] & FATTR4_WORD1_OWNER) {
388                 READ_BUF(4);
389                 len += 4;
390                 READ32(dummy32);
391                 READ_BUF(dummy32);
392                 len += (XDR_QUADLEN(dummy32) << 2);
393                 READMEM(buf, dummy32);
394                 if (check_utf8(buf, dummy32))
395                         return nfserr_inval;
396                 if ((status = nfsd_map_name_to_uid(argp->rqstp, buf, dummy32, &iattr->ia_uid)))
397                         goto out_nfserr;
398                 iattr->ia_valid |= ATTR_UID;
399         }
400         if (bmval[1] & FATTR4_WORD1_OWNER_GROUP) {
401                 READ_BUF(4);
402                 len += 4;
403                 READ32(dummy32);
404                 READ_BUF(dummy32);
405                 len += (XDR_QUADLEN(dummy32) << 2);
406                 READMEM(buf, dummy32);
407                 if (check_utf8(buf, dummy32))
408                         return nfserr_inval;
409                 if ((status = nfsd_map_name_to_gid(argp->rqstp, buf, dummy32, &iattr->ia_gid)))
410                         goto out_nfserr;
411                 iattr->ia_valid |= ATTR_GID;
412         }
413         if (bmval[1] & FATTR4_WORD1_TIME_ACCESS_SET) {
414                 READ_BUF(4);
415                 len += 4;
416                 READ32(dummy32);
417                 switch (dummy32) {
418                 case NFS4_SET_TO_CLIENT_TIME:
419                         /* We require the high 32 bits of 'seconds' to be 0, and we ignore
420                            all 32 bits of 'nseconds'. */
421                         READ_BUF(12);
422                         len += 12;
423                         READ32(dummy32);
424                         if (dummy32)
425                                 return nfserr_inval;
426                         READ32(iattr->ia_atime.tv_sec);
427                         READ32(iattr->ia_atime.tv_nsec);
428                         if (iattr->ia_atime.tv_nsec >= (u32)1000000000)
429                                 return nfserr_inval;
430                         iattr->ia_valid |= (ATTR_ATIME | ATTR_ATIME_SET);
431                         break;
432                 case NFS4_SET_TO_SERVER_TIME:
433                         iattr->ia_valid |= ATTR_ATIME;
434                         break;
435                 default:
436                         goto xdr_error;
437                 }
438         }
439         if (bmval[1] & FATTR4_WORD1_TIME_METADATA) {
440                 /* We require the high 32 bits of 'seconds' to be 0, and we ignore
441                    all 32 bits of 'nseconds'. */
442                 READ_BUF(12);
443                 len += 12;
444                 READ32(dummy32);
445                 if (dummy32)
446                         return nfserr_inval;
447                 READ32(iattr->ia_ctime.tv_sec);
448                 READ32(iattr->ia_ctime.tv_nsec);
449                 if (iattr->ia_ctime.tv_nsec >= (u32)1000000000)
450                         return nfserr_inval;
451                 iattr->ia_valid |= ATTR_CTIME;
452         }
453         if (bmval[1] & FATTR4_WORD1_TIME_MODIFY_SET) {
454                 READ_BUF(4);
455                 len += 4;
456                 READ32(dummy32);
457                 switch (dummy32) {
458                 case NFS4_SET_TO_CLIENT_TIME:
459                         /* We require the high 32 bits of 'seconds' to be 0, and we ignore
460                            all 32 bits of 'nseconds'. */
461                         READ_BUF(12);
462                         len += 12;
463                         READ32(dummy32);
464                         if (dummy32)
465                                 return nfserr_inval;
466                         READ32(iattr->ia_mtime.tv_sec);
467                         READ32(iattr->ia_mtime.tv_nsec);
468                         if (iattr->ia_mtime.tv_nsec >= (u32)1000000000)
469                                 return nfserr_inval;
470                         iattr->ia_valid |= (ATTR_MTIME | ATTR_MTIME_SET);
471                         break;
472                 case NFS4_SET_TO_SERVER_TIME:
473                         iattr->ia_valid |= ATTR_MTIME;
474                         break;
475                 default:
476                         goto xdr_error;
477                 }
478         }
479         if (len != expected_len)
480                 goto xdr_error;
481
482         DECODE_TAIL;
483
484 out_nfserr:
485         status = nfserrno(status);
486         goto out;
487 }
488
489 static int
490 nfsd4_decode_access(struct nfsd4_compoundargs *argp, struct nfsd4_access *access)
491 {
492         DECODE_HEAD;
493
494         READ_BUF(4);
495         READ32(access->ac_req_access);
496
497         DECODE_TAIL;
498 }
499
500 #define NFS4_STATE_NOT_LOCKED   ((void *)-1)
501
502 static int
503 nfsd4_decode_close(struct nfsd4_compoundargs *argp, struct nfsd4_close *close)
504 {
505         DECODE_HEAD;
506
507         close->cl_stateowner = NFS4_STATE_NOT_LOCKED;
508         READ_BUF(4 + sizeof(stateid_t));
509         READ32(close->cl_seqid);
510         READ32(close->cl_stateid.si_generation);
511         COPYMEM(&close->cl_stateid.si_opaque, sizeof(stateid_opaque_t));
512
513         DECODE_TAIL;
514 }
515
516
517 static int
518 nfsd4_decode_commit(struct nfsd4_compoundargs *argp, struct nfsd4_commit *commit)
519 {
520         DECODE_HEAD;
521
522         READ_BUF(12);
523         READ64(commit->co_offset);
524         READ32(commit->co_count);
525
526         DECODE_TAIL;
527 }
528
529 static int
530 nfsd4_decode_create(struct nfsd4_compoundargs *argp, struct nfsd4_create *create)
531 {
532         DECODE_HEAD;
533
534         READ_BUF(4);
535         READ32(create->cr_type);
536         switch (create->cr_type) {
537         case NF4LNK:
538                 READ_BUF(4);
539                 READ32(create->cr_linklen);
540                 READ_BUF(create->cr_linklen);
541                 SAVEMEM(create->cr_linkname, create->cr_linklen);
542                 if (check_utf8(create->cr_linkname, create->cr_linklen))
543                         return nfserr_inval;
544                 break;
545         case NF4BLK:
546         case NF4CHR:
547                 READ_BUF(8);
548                 READ32(create->cr_specdata1);
549                 READ32(create->cr_specdata2);
550                 break;
551         case NF4SOCK:
552         case NF4FIFO:
553         case NF4DIR:
554         default:
555                 break;
556         }
557
558         READ_BUF(4);
559         READ32(create->cr_namelen);
560         READ_BUF(create->cr_namelen);
561         SAVEMEM(create->cr_name, create->cr_namelen);
562         if ((status = check_filename(create->cr_name, create->cr_namelen, nfserr_inval)))
563                 return status;
564
565         if ((status = nfsd4_decode_fattr(argp, create->cr_bmval, &create->cr_iattr)))
566                 goto out;
567
568         DECODE_TAIL;
569 }
570
571 static inline int
572 nfsd4_decode_getattr(struct nfsd4_compoundargs *argp, struct nfsd4_getattr *getattr)
573 {
574         return nfsd4_decode_bitmap(argp, getattr->ga_bmval);
575 }
576
577 static int
578 nfsd4_decode_link(struct nfsd4_compoundargs *argp, struct nfsd4_link *link)
579 {
580         DECODE_HEAD;
581
582         READ_BUF(4);
583         READ32(link->li_namelen);
584         READ_BUF(link->li_namelen);
585         SAVEMEM(link->li_name, link->li_namelen);
586         if ((status = check_filename(link->li_name, link->li_namelen, nfserr_inval)))
587                 return status;
588
589         DECODE_TAIL;
590 }
591
592 static int
593 nfsd4_decode_lock(struct nfsd4_compoundargs *argp, struct nfsd4_lock *lock)
594 {
595         DECODE_HEAD;
596
597         lock->lk_stateowner = NFS4_STATE_NOT_LOCKED;
598         /*
599         * type, reclaim(boolean), offset, length, new_lock_owner(boolean)
600         */
601         READ_BUF(28);
602         READ32(lock->lk_type);
603         if ((lock->lk_type < NFS4_READ_LT) || (lock->lk_type > NFS4_WRITEW_LT))
604                 goto xdr_error;
605         READ32(lock->lk_reclaim);
606         READ64(lock->lk_offset);
607         READ64(lock->lk_length);
608         READ32(lock->lk_is_new);
609
610         if (lock->lk_is_new) {
611                 READ_BUF(36);
612                 READ32(lock->lk_new_open_seqid);
613                 READ32(lock->lk_new_open_stateid.si_generation);
614
615                 COPYMEM(&lock->lk_new_open_stateid.si_opaque, sizeof(stateid_opaque_t));
616                 READ32(lock->lk_new_lock_seqid);
617                 COPYMEM(&lock->lk_new_clientid, sizeof(clientid_t));
618                 READ32(lock->lk_new_owner.len);
619                 READ_BUF(lock->lk_new_owner.len);
620                 READMEM(lock->lk_new_owner.data, lock->lk_new_owner.len);
621         } else {
622                 READ_BUF(20);
623                 READ32(lock->lk_old_lock_stateid.si_generation);
624                 COPYMEM(&lock->lk_old_lock_stateid.si_opaque, sizeof(stateid_opaque_t));
625                 READ32(lock->lk_old_lock_seqid);
626         }
627
628         DECODE_TAIL;
629 }
630
631 static int
632 nfsd4_decode_lockt(struct nfsd4_compoundargs *argp, struct nfsd4_lockt *lockt)
633 {
634         DECODE_HEAD;
635                         
636         READ_BUF(32);
637         READ32(lockt->lt_type);
638         if((lockt->lt_type < NFS4_READ_LT) || (lockt->lt_type > NFS4_WRITEW_LT))
639                 goto xdr_error;
640         READ64(lockt->lt_offset);
641         READ64(lockt->lt_length);
642         COPYMEM(&lockt->lt_clientid, 8);
643         READ32(lockt->lt_owner.len);
644         READ_BUF(lockt->lt_owner.len);
645         READMEM(lockt->lt_owner.data, lockt->lt_owner.len);
646
647         DECODE_TAIL;
648 }
649
650 static int
651 nfsd4_decode_locku(struct nfsd4_compoundargs *argp, struct nfsd4_locku *locku)
652 {
653         DECODE_HEAD;
654
655         locku->lu_stateowner = NFS4_STATE_NOT_LOCKED;
656         READ_BUF(24 + sizeof(stateid_t));
657         READ32(locku->lu_type);
658         if ((locku->lu_type < NFS4_READ_LT) || (locku->lu_type > NFS4_WRITEW_LT))
659                 goto xdr_error;
660         READ32(locku->lu_seqid);
661         READ32(locku->lu_stateid.si_generation);
662         COPYMEM(&locku->lu_stateid.si_opaque, sizeof(stateid_opaque_t));
663         READ64(locku->lu_offset);
664         READ64(locku->lu_length);
665
666         DECODE_TAIL;
667 }
668
669 static int
670 nfsd4_decode_lookup(struct nfsd4_compoundargs *argp, struct nfsd4_lookup *lookup)
671 {
672         DECODE_HEAD;
673
674         READ_BUF(4);
675         READ32(lookup->lo_len);
676         READ_BUF(lookup->lo_len);
677         SAVEMEM(lookup->lo_name, lookup->lo_len);
678         if ((status = check_filename(lookup->lo_name, lookup->lo_len, nfserr_noent)))
679                 return status;
680
681         DECODE_TAIL;
682 }
683
684 static int
685 nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
686 {
687         DECODE_HEAD;
688
689         memset(open->op_bmval, 0, sizeof(open->op_bmval));
690         open->op_iattr.ia_valid = 0;
691         open->op_stateowner = NFS4_STATE_NOT_LOCKED;
692
693         /* seqid, share_access, share_deny, clientid, ownerlen */
694         READ_BUF(16 + sizeof(clientid_t));
695         READ32(open->op_seqid);
696         READ32(open->op_share_access);
697         READ32(open->op_share_deny);
698         COPYMEM(&open->op_clientid, sizeof(clientid_t));
699         READ32(open->op_owner.len);
700
701         /* owner, open_flag */
702         READ_BUF(open->op_owner.len + 4);
703         SAVEMEM(open->op_owner.data, open->op_owner.len);
704         READ32(open->op_create);
705         switch (open->op_create) {
706         case NFS4_OPEN_NOCREATE:
707                 break;
708         case NFS4_OPEN_CREATE:
709                 READ_BUF(4);
710                 READ32(open->op_createmode);
711                 switch (open->op_createmode) {
712                 case NFS4_CREATE_UNCHECKED:
713                 case NFS4_CREATE_GUARDED:
714                         if ((status = nfsd4_decode_fattr(argp, open->op_bmval, &open->op_iattr)))
715                                 goto out;
716                         break;
717                 case NFS4_CREATE_EXCLUSIVE:
718                         READ_BUF(8);
719                         COPYMEM(open->op_verf.data, 8);
720                         break;
721                 default:
722                         goto xdr_error;
723                 }
724                 break;
725         default:
726                 goto xdr_error;
727         }
728
729         /* open_claim */
730         READ_BUF(4);
731         READ32(open->op_claim_type);
732         switch (open->op_claim_type) {
733         case NFS4_OPEN_CLAIM_NULL:
734         case NFS4_OPEN_CLAIM_DELEGATE_PREV:
735                 READ_BUF(4);
736                 READ32(open->op_fname.len);
737                 READ_BUF(open->op_fname.len);
738                 SAVEMEM(open->op_fname.data, open->op_fname.len);
739                 if ((status = check_filename(open->op_fname.data, open->op_fname.len, nfserr_inval)))
740                         return status;
741                 break;
742         case NFS4_OPEN_CLAIM_PREVIOUS:
743                 READ_BUF(4);
744                 READ32(open->op_delegate_type);
745                 break;
746         case NFS4_OPEN_CLAIM_DELEGATE_CUR:
747                 READ_BUF(sizeof(delegation_stateid_t) + 4);
748                 COPYMEM(&open->op_delegate_stateid, sizeof(delegation_stateid_t));
749                 READ32(open->op_fname.len);
750                 READ_BUF(open->op_fname.len);
751                 SAVEMEM(open->op_fname.data, open->op_fname.len);
752                 if ((status = check_filename(open->op_fname.data, open->op_fname.len, nfserr_inval)))
753                         return status;
754                 break;
755         default:
756                 goto xdr_error;
757         }
758
759         DECODE_TAIL;
760 }
761
762 static int
763 nfsd4_decode_open_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_open_confirm *open_conf)
764 {
765         DECODE_HEAD;
766                     
767         open_conf->oc_stateowner = NFS4_STATE_NOT_LOCKED;
768         READ_BUF(4 + sizeof(stateid_t));
769         READ32(open_conf->oc_req_stateid.si_generation);
770         COPYMEM(&open_conf->oc_req_stateid.si_opaque, sizeof(stateid_opaque_t));
771         READ32(open_conf->oc_seqid);
772                                                         
773         DECODE_TAIL;
774 }
775
776 static int
777 nfsd4_decode_open_downgrade(struct nfsd4_compoundargs *argp, struct nfsd4_open_downgrade *open_down)
778 {
779         DECODE_HEAD;
780                     
781         open_down->od_stateowner = NFS4_STATE_NOT_LOCKED;
782         READ_BUF(4 + sizeof(stateid_t));
783         READ32(open_down->od_stateid.si_generation);
784         COPYMEM(&open_down->od_stateid.si_opaque, sizeof(stateid_opaque_t));
785         READ32(open_down->od_seqid);
786         READ32(open_down->od_share_access);
787         READ32(open_down->od_share_deny);
788                                                         
789         DECODE_TAIL;
790 }
791
792 static int
793 nfsd4_decode_putfh(struct nfsd4_compoundargs *argp, struct nfsd4_putfh *putfh)
794 {
795         DECODE_HEAD;
796
797         READ_BUF(4);
798         READ32(putfh->pf_fhlen);
799         if (putfh->pf_fhlen > NFS4_FHSIZE)
800                 goto xdr_error;
801         READ_BUF(putfh->pf_fhlen);
802         SAVEMEM(putfh->pf_fhval, putfh->pf_fhlen);
803
804         DECODE_TAIL;
805 }
806
807 static int
808 nfsd4_decode_read(struct nfsd4_compoundargs *argp, struct nfsd4_read *read)
809 {
810         DECODE_HEAD;
811
812         READ_BUF(sizeof(stateid_t) + 12);
813         READ32(read->rd_stateid.si_generation);
814         COPYMEM(&read->rd_stateid.si_opaque, sizeof(stateid_opaque_t));
815         READ64(read->rd_offset);
816         READ32(read->rd_length);
817
818         DECODE_TAIL;
819 }
820
821 static int
822 nfsd4_decode_readdir(struct nfsd4_compoundargs *argp, struct nfsd4_readdir *readdir)
823 {
824         DECODE_HEAD;
825
826         READ_BUF(24);
827         READ64(readdir->rd_cookie);
828         COPYMEM(readdir->rd_verf.data, sizeof(readdir->rd_verf.data));
829         READ32(readdir->rd_dircount);    /* just in case you needed a useless field... */
830         READ32(readdir->rd_maxcount);
831         if ((status = nfsd4_decode_bitmap(argp, readdir->rd_bmval)))
832                 goto out;
833
834         DECODE_TAIL;
835 }
836
837 static int
838 nfsd4_decode_remove(struct nfsd4_compoundargs *argp, struct nfsd4_remove *remove)
839 {
840         DECODE_HEAD;
841
842         READ_BUF(4);
843         READ32(remove->rm_namelen);
844         READ_BUF(remove->rm_namelen);
845         SAVEMEM(remove->rm_name, remove->rm_namelen);
846         if ((status = check_filename(remove->rm_name, remove->rm_namelen, nfserr_noent)))
847                 return status;
848
849         DECODE_TAIL;
850 }
851
852 static int
853 nfsd4_decode_rename(struct nfsd4_compoundargs *argp, struct nfsd4_rename *rename)
854 {
855         DECODE_HEAD;
856
857         READ_BUF(4);
858         READ32(rename->rn_snamelen);
859         READ_BUF(rename->rn_snamelen + 4);
860         SAVEMEM(rename->rn_sname, rename->rn_snamelen);
861         READ32(rename->rn_tnamelen);
862         READ_BUF(rename->rn_tnamelen);
863         SAVEMEM(rename->rn_tname, rename->rn_tnamelen);
864         if ((status = check_filename(rename->rn_sname, rename->rn_snamelen, nfserr_noent)))
865                 return status;
866         if ((status = check_filename(rename->rn_tname, rename->rn_tnamelen, nfserr_inval)))
867                 return status;
868
869         DECODE_TAIL;
870 }
871
872 static int
873 nfsd4_decode_renew(struct nfsd4_compoundargs *argp, clientid_t *clientid)
874 {
875         DECODE_HEAD;
876
877         READ_BUF(sizeof(clientid_t));
878         COPYMEM(clientid, sizeof(clientid_t));
879
880         DECODE_TAIL;
881 }
882
883 static int
884 nfsd4_decode_setattr(struct nfsd4_compoundargs *argp, struct nfsd4_setattr *setattr)
885 {
886         DECODE_HEAD;
887
888         READ_BUF(sizeof(stateid_t));
889         READ32(setattr->sa_stateid.si_generation);
890         COPYMEM(&setattr->sa_stateid.si_opaque, sizeof(stateid_opaque_t));
891         if ((status = nfsd4_decode_fattr(argp, setattr->sa_bmval, &setattr->sa_iattr)))
892                 goto out;
893
894         DECODE_TAIL;
895 }
896
897 static int
898 nfsd4_decode_setclientid(struct nfsd4_compoundargs *argp, struct nfsd4_setclientid *setclientid)
899 {
900         DECODE_HEAD;
901
902         READ_BUF(12);
903         COPYMEM(setclientid->se_verf.data, 8);
904         READ32(setclientid->se_namelen);
905
906         READ_BUF(setclientid->se_namelen + 8);
907         SAVEMEM(setclientid->se_name, setclientid->se_namelen);
908         READ32(setclientid->se_callback_prog);
909         READ32(setclientid->se_callback_netid_len);
910
911         READ_BUF(setclientid->se_callback_netid_len + 4);
912         SAVEMEM(setclientid->se_callback_netid_val, setclientid->se_callback_netid_len);
913         READ32(setclientid->se_callback_addr_len);
914
915         READ_BUF(setclientid->se_callback_addr_len + 4);
916         SAVEMEM(setclientid->se_callback_addr_val, setclientid->se_callback_addr_len);
917         READ32(setclientid->se_callback_ident);
918
919         DECODE_TAIL;
920 }
921
922 static int
923 nfsd4_decode_setclientid_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_setclientid_confirm *scd_c)
924 {
925         DECODE_HEAD;
926
927         READ_BUF(8 + sizeof(nfs4_verifier));
928         COPYMEM(&scd_c->sc_clientid, 8);
929         COPYMEM(&scd_c->sc_confirm, sizeof(nfs4_verifier));
930
931         DECODE_TAIL;
932 }
933
934 /* Also used for NVERIFY */
935 static int
936 nfsd4_decode_verify(struct nfsd4_compoundargs *argp, struct nfsd4_verify *verify)
937 {
938 #if 0
939         struct nfsd4_compoundargs save = {
940                 .p = argp->p,
941                 .end = argp->end,
942                 .rqstp = argp->rqstp,
943         };
944         u32             ve_bmval[2];
945         struct iattr    ve_iattr;           /* request */
946         struct nfs4_acl *ve_acl;            /* request */
947 #endif
948         DECODE_HEAD;
949
950         if ((status = nfsd4_decode_bitmap(argp, verify->ve_bmval)))
951                 goto out;
952
953         /* For convenience's sake, we compare raw xdr'd attributes in
954          * nfsd4_proc_verify; however we still decode here just to return
955          * correct error in case of bad xdr. */
956 #if 0
957         status = nfsd4_decode_fattr(ve_bmval, &ve_iattr, &ve_acl);
958         if (status == nfserr_inval) {
959                 status = nfserrno(status);
960                 goto out;
961         }
962 #endif
963         READ_BUF(4);
964         READ32(verify->ve_attrlen);
965         READ_BUF(verify->ve_attrlen);
966         SAVEMEM(verify->ve_attrval, verify->ve_attrlen);
967
968         DECODE_TAIL;
969 }
970
971 static int
972 nfsd4_decode_write(struct nfsd4_compoundargs *argp, struct nfsd4_write *write)
973 {
974         int avail;
975         int v;
976         int len;
977         DECODE_HEAD;
978
979         READ_BUF(sizeof(stateid_opaque_t) + 20);
980         READ32(write->wr_stateid.si_generation);
981         COPYMEM(&write->wr_stateid.si_opaque, sizeof(stateid_opaque_t));
982         READ64(write->wr_offset);
983         READ32(write->wr_stable_how);
984         if (write->wr_stable_how > 2)
985                 goto xdr_error;
986         READ32(write->wr_buflen);
987
988         /* Sorry .. no magic macros for this.. *
989          * READ_BUF(write->wr_buflen);
990          * SAVEMEM(write->wr_buf, write->wr_buflen);
991          */
992         avail = (char*)argp->end - (char*)argp->p;
993         if (avail + argp->pagelen < write->wr_buflen) {
994                 printk(KERN_NOTICE "xdr error! (%s:%d)\n", __FILE__, __LINE__); 
995                 goto xdr_error;
996         }
997         write->wr_vec[0].iov_base = p;
998         write->wr_vec[0].iov_len = avail;
999         v = 0;
1000         len = write->wr_buflen;
1001         while (len > write->wr_vec[v].iov_len) {
1002                 len -= write->wr_vec[v].iov_len;
1003                 v++;
1004                 write->wr_vec[v].iov_base = page_address(argp->pagelist[0]);
1005                 argp->pagelist++;
1006                 if (argp->pagelen >= PAGE_SIZE) {
1007                         write->wr_vec[v].iov_len = PAGE_SIZE;
1008                         argp->pagelen -= PAGE_SIZE;
1009                 } else {
1010                         write->wr_vec[v].iov_len = argp->pagelen;
1011                         argp->pagelen -= len;
1012                 }
1013         }
1014         argp->end = (u32*) (write->wr_vec[v].iov_base + write->wr_vec[v].iov_len);
1015         argp->p = (u32*)  (write->wr_vec[v].iov_base + (XDR_QUADLEN(len) << 2));
1016         write->wr_vec[v].iov_len = len;
1017         write->wr_vlen = v+1;
1018
1019         DECODE_TAIL;
1020 }
1021
1022 static int
1023 nfsd4_decode_release_lockowner(struct nfsd4_compoundargs *argp, struct nfsd4_release_lockowner *rlockowner)
1024 {
1025         DECODE_HEAD;
1026
1027         READ_BUF(12);
1028         COPYMEM(&rlockowner->rl_clientid, sizeof(clientid_t));
1029         READ32(rlockowner->rl_owner.len);
1030         READ_BUF(rlockowner->rl_owner.len);
1031         READMEM(rlockowner->rl_owner.data, rlockowner->rl_owner.len);
1032
1033         DECODE_TAIL;
1034 }
1035
1036 static int
1037 nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
1038 {
1039         DECODE_HEAD;
1040         struct nfsd4_op *op;
1041         int i;
1042
1043         /*
1044          * XXX: According to spec, we should check the tag
1045          * for UTF-8 compliance.  I'm postponing this for
1046          * now because it seems that some clients do use
1047          * binary tags.
1048          */
1049         READ_BUF(4);
1050         READ32(argp->taglen);
1051         READ_BUF(argp->taglen + 8);
1052         SAVEMEM(argp->tag, argp->taglen);
1053         READ32(argp->minorversion);
1054         READ32(argp->opcnt);
1055
1056         if (argp->taglen > NFSD4_MAX_TAGLEN)
1057                 goto xdr_error;
1058         if (argp->opcnt > 100)
1059                 goto xdr_error;
1060
1061         if (argp->opcnt > sizeof(argp->iops)/sizeof(argp->iops[0])) {
1062                 argp->ops = kmalloc(argp->opcnt * sizeof(*argp->ops), GFP_KERNEL);
1063                 if (!argp->ops) {
1064                         argp->ops = argp->iops;
1065                         printk(KERN_INFO "nfsd: couldn't allocate room for COMPOUND\n");
1066                         goto xdr_error;
1067                 }
1068         }
1069
1070         for (i = 0; i < argp->opcnt; i++) {
1071                 op = &argp->ops[i];
1072                 op->replay = NULL;
1073
1074                 /*
1075                  * We can't use READ_BUF() here because we need to handle
1076                  * a missing opcode as an OP_WRITE + 1. So we need to check
1077                  * to see if we're truly at the end of our buffer or if there
1078                  * is another page we need to flip to.
1079                  */
1080
1081                 if (argp->p == argp->end) {
1082                         if (argp->pagelen < 4) {
1083                                 /* There isn't an opcode still on the wire */
1084                                 op->opnum = OP_WRITE + 1;
1085                                 op->status = nfserr_bad_xdr;
1086                                 argp->opcnt = i+1;
1087                                 break;
1088                         }
1089
1090                         /*
1091                          * False alarm. We just hit a page boundary, but there
1092                          * is still data available.  Move pointer across page
1093                          * boundary.  *snip from READ_BUF*
1094                          */
1095                         argp->p = page_address(argp->pagelist[0]);
1096                         argp->pagelist++;
1097                         if (argp->pagelen < PAGE_SIZE) {
1098                                 argp->end = p + (argp->pagelen>>2);
1099                                 argp->pagelen = 0;
1100                         } else {
1101                                 argp->end = p + (PAGE_SIZE>>2);
1102                                 argp->pagelen -= PAGE_SIZE;
1103                         }
1104                 }
1105                 op->opnum = ntohl(*argp->p++);
1106
1107                 switch (op->opnum) {
1108                 case 2: /* Reserved operation */
1109                         op->opnum = OP_ILLEGAL;
1110                         if (argp->minorversion == 0)
1111                                 op->status = nfserr_op_illegal;
1112                         else
1113                                 op->status = nfserr_minor_vers_mismatch;
1114                         break;
1115                 case OP_ACCESS:
1116                         op->status = nfsd4_decode_access(argp, &op->u.access);
1117                         break;
1118                 case OP_CLOSE:
1119                         op->status = nfsd4_decode_close(argp, &op->u.close);
1120                         break;
1121                 case OP_COMMIT:
1122                         op->status = nfsd4_decode_commit(argp, &op->u.commit);
1123                         break;
1124                 case OP_CREATE:
1125                         op->status = nfsd4_decode_create(argp, &op->u.create);
1126                         break;
1127                 case OP_GETATTR:
1128                         op->status = nfsd4_decode_getattr(argp, &op->u.getattr);
1129                         break;
1130                 case OP_GETFH:
1131                         op->status = nfs_ok;
1132                         break;
1133                 case OP_LINK:
1134                         op->status = nfsd4_decode_link(argp, &op->u.link);
1135                         break;
1136                 case OP_LOCK:
1137                         op->status = nfsd4_decode_lock(argp, &op->u.lock);
1138                         break;
1139                 case OP_LOCKT:
1140                         op->status = nfsd4_decode_lockt(argp, &op->u.lockt);
1141                         break;
1142                 case OP_LOCKU:
1143                         op->status = nfsd4_decode_locku(argp, &op->u.locku);
1144                         break;
1145                 case OP_LOOKUP:
1146                         op->status = nfsd4_decode_lookup(argp, &op->u.lookup);
1147                         break;
1148                 case OP_LOOKUPP:
1149                         op->status = nfs_ok;
1150                         break;
1151                 case OP_NVERIFY:
1152                         op->status = nfsd4_decode_verify(argp, &op->u.nverify);
1153                         break;
1154                 case OP_OPEN:
1155                         op->status = nfsd4_decode_open(argp, &op->u.open);
1156                         break;
1157                 case OP_OPEN_CONFIRM:
1158                         op->status = nfsd4_decode_open_confirm(argp, &op->u.open_confirm);
1159                         break;
1160                 case OP_OPEN_DOWNGRADE:
1161                         op->status = nfsd4_decode_open_downgrade(argp, &op->u.open_downgrade);
1162                         break;
1163                 case OP_PUTFH:
1164                         op->status = nfsd4_decode_putfh(argp, &op->u.putfh);
1165                         break;
1166                 case OP_PUTROOTFH:
1167                         op->status = nfs_ok;
1168                         break;
1169                 case OP_READ:
1170                         op->status = nfsd4_decode_read(argp, &op->u.read);
1171                         break;
1172                 case OP_READDIR:
1173                         op->status = nfsd4_decode_readdir(argp, &op->u.readdir);
1174                         break;
1175                 case OP_READLINK:
1176                         op->status = nfs_ok;
1177                         break;
1178                 case OP_REMOVE:
1179                         op->status = nfsd4_decode_remove(argp, &op->u.remove);
1180                         break;
1181                 case OP_RENAME:
1182                         op->status = nfsd4_decode_rename(argp, &op->u.rename);
1183                         break;
1184                 case OP_RESTOREFH:
1185                         op->status = nfs_ok;
1186                         break;
1187                 case OP_RENEW:
1188                         op->status = nfsd4_decode_renew(argp, &op->u.renew);
1189                         break;
1190                 case OP_SAVEFH:
1191                         op->status = nfs_ok;
1192                         break;
1193                 case OP_SETATTR:
1194                         op->status = nfsd4_decode_setattr(argp, &op->u.setattr);
1195                         break;
1196                 case OP_SETCLIENTID:
1197                         op->status = nfsd4_decode_setclientid(argp, &op->u.setclientid);
1198                         break;
1199                 case OP_SETCLIENTID_CONFIRM:
1200                         op->status = nfsd4_decode_setclientid_confirm(argp, &op->u.setclientid_confirm);
1201                         break;
1202                 case OP_VERIFY:
1203                         op->status = nfsd4_decode_verify(argp, &op->u.verify);
1204                         break;
1205                 case OP_WRITE:
1206                         op->status = nfsd4_decode_write(argp, &op->u.write);
1207                         break;
1208                 case OP_RELEASE_LOCKOWNER:
1209                         op->status = nfsd4_decode_release_lockowner(argp, &op->u.release_lockowner);
1210                         break;
1211                 default:
1212                         op->opnum = OP_ILLEGAL;
1213                         op->status = nfserr_op_illegal;
1214                         break;
1215                 }
1216
1217                 if (op->status) {
1218                         argp->opcnt = i+1;
1219                         break;
1220                 }
1221         }
1222
1223         DECODE_TAIL;
1224 }
1225 /*
1226  * END OF "GENERIC" DECODE ROUTINES.
1227  */
1228
1229 /*
1230  * START OF "GENERIC" ENCODE ROUTINES.
1231  *   These may look a little ugly since they are imported from a "generic"
1232  * set of XDR encode/decode routines which are intended to be shared by
1233  * all of our NFSv4 implementations (OpenBSD, MacOS X...).
1234  *
1235  * If the pain of reading these is too great, it should be a straightforward
1236  * task to translate them into Linux-specific versions which are more
1237  * consistent with the style used in NFSv2/v3...
1238  */
1239 #define ENCODE_HEAD              u32 *p
1240
1241 #define WRITE32(n)               *p++ = htonl(n)
1242 #define WRITE64(n)               do {                           \
1243         *p++ = htonl((u32)((n) >> 32));                         \
1244         *p++ = htonl((u32)(n));                                 \
1245 } while (0)
1246 #define WRITEMEM(ptr,nbytes)     do {                           \
1247         *(p + XDR_QUADLEN(nbytes) -1) = 0;                      \
1248         memcpy(p, ptr, nbytes);                                 \
1249         p += XDR_QUADLEN(nbytes);                               \
1250 } while (0)
1251 #define WRITECINFO(c)           do {                            \
1252         *p++ = htonl(c.atomic);                                 \
1253         *p++ = htonl(c.before_ctime_sec);                               \
1254         *p++ = htonl(c.before_ctime_nsec);                              \
1255         *p++ = htonl(c.after_ctime_sec);                                \
1256         *p++ = htonl(c.after_ctime_nsec);                               \
1257 } while (0)
1258
1259 #define RESERVE_SPACE(nbytes)   do {                            \
1260         p = resp->p;                                            \
1261         BUG_ON(p + XDR_QUADLEN(nbytes) > resp->end);            \
1262 } while (0)
1263 #define ADJUST_ARGS()           resp->p = p
1264
1265 /*
1266  * Header routine to setup seqid operation replay cache
1267  */
1268 #define ENCODE_SEQID_OP_HEAD                                    \
1269         u32 *p;                                                 \
1270         u32 *save;                                              \
1271                                                                 \
1272         save = resp->p;
1273
1274 /*
1275  * Routine for encoding the result of a
1276  * "seqid-mutating" NFSv4 operation.  This is
1277  * where seqids are incremented, and the
1278  * replay cache is filled.
1279  */
1280
1281 #define ENCODE_SEQID_OP_TAIL(stateowner) do {                   \
1282         if (seqid_mutating_err(nfserr) && stateowner            \
1283             && (stateowner != NFS4_STATE_NOT_LOCKED)) {         \
1284                 if (stateowner->so_confirmed)                   \
1285                         stateowner->so_seqid++;                 \
1286                 stateowner->so_replay.rp_status = nfserr;       \
1287                 stateowner->so_replay.rp_buflen =               \
1288                           (((char *)(resp)->p - (char *)save)); \
1289                 memcpy(stateowner->so_replay.rp_buf, save,      \
1290                         stateowner->so_replay.rp_buflen);       \
1291         }                                                       \
1292         if (stateowner != NFS4_STATE_NOT_LOCKED)                \
1293                 nfs4_unlock_state();                            \
1294         } while (0);
1295
1296
1297 static u32 nfs4_ftypes[16] = {
1298         NF4BAD,  NF4FIFO, NF4CHR, NF4BAD,
1299         NF4DIR,  NF4BAD,  NF4BLK, NF4BAD,
1300         NF4REG,  NF4BAD,  NF4LNK, NF4BAD,
1301         NF4SOCK, NF4BAD,  NF4LNK, NF4BAD,
1302 };
1303
1304 static int
1305 nfsd4_encode_name(struct svc_rqst *rqstp, int group, uid_t id,
1306                         u32 **p, int *buflen)
1307 {
1308         int status;
1309
1310         if (*buflen < (XDR_QUADLEN(IDMAP_NAMESZ) << 2) + 4)
1311                 return nfserr_resource;
1312         if (group)
1313                 status = nfsd_map_gid_to_name(rqstp, id, (u8 *)(*p + 1));
1314         else
1315                 status = nfsd_map_uid_to_name(rqstp, id, (u8 *)(*p + 1));
1316         if (status < 0)
1317                 return nfserrno(status);
1318         *p = xdr_encode_opaque(*p, NULL, status);
1319         *buflen -= (XDR_QUADLEN(status) << 2) + 4;
1320         BUG_ON(*buflen < 0);
1321         return 0;
1322 }
1323
1324 static inline int
1325 nfsd4_encode_user(struct svc_rqst *rqstp, uid_t uid, u32 **p, int *buflen)
1326 {
1327         return nfsd4_encode_name(rqstp, uid, 0, p, buflen);
1328 }
1329
1330 static inline int
1331 nfsd4_encode_group(struct svc_rqst *rqstp, uid_t gid, u32 **p, int *buflen)
1332 {
1333         return nfsd4_encode_name(rqstp, gid, 1, p, buflen);
1334 }
1335
1336
1337 /*
1338  * Note: @fhp can be NULL; in this case, we might have to compose the filehandle
1339  * ourselves.
1340  *
1341  * @countp is the buffer size in _words_; upon successful return this becomes
1342  * replaced with the number of words written.
1343  */
1344 int
1345 nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
1346                 struct dentry *dentry, u32 *buffer, int *countp, u32 *bmval,
1347                 struct svc_rqst *rqstp)
1348 {
1349         u32 bmval0 = bmval[0];
1350         u32 bmval1 = bmval[1];
1351         struct kstat stat;
1352         struct svc_fh tempfh;
1353         struct kstatfs statfs;
1354         int buflen = *countp << 2;
1355         u32 *attrlenp;
1356         u32 dummy;
1357         u64 dummy64;
1358         u32 *p = buffer;
1359         int status;
1360
1361         BUG_ON(bmval1 & NFSD_WRITEONLY_ATTRS_WORD1);
1362         BUG_ON(bmval0 & ~NFSD_SUPPORTED_ATTRS_WORD0);
1363         BUG_ON(bmval1 & ~NFSD_SUPPORTED_ATTRS_WORD1);
1364
1365         status = vfs_getattr(exp->ex_mnt, dentry, &stat);
1366         if (status)
1367                 goto out_nfserr;
1368         if ((bmval0 & (FATTR4_WORD0_FILES_FREE | FATTR4_WORD0_FILES_TOTAL)) ||
1369             (bmval1 & (FATTR4_WORD1_SPACE_AVAIL | FATTR4_WORD1_SPACE_FREE |
1370                        FATTR4_WORD1_SPACE_TOTAL))) {
1371                 status = vfs_statfs(dentry->d_inode->i_sb, &statfs);
1372                 if (status)
1373                         goto out_nfserr;
1374         }
1375         if ((bmval0 & FATTR4_WORD0_FILEHANDLE) && !fhp) {
1376                 fh_init(&tempfh, NFS4_FHSIZE);
1377                 status = fh_compose(&tempfh, exp, dentry, NULL);
1378                 if (status)
1379                         goto out;
1380                 fhp = &tempfh;
1381         }
1382         if ((buflen -= 16) < 0)
1383                 goto out_resource;
1384
1385         WRITE32(2);
1386         WRITE32(bmval0);
1387         WRITE32(bmval1);
1388         attrlenp = p++;                /* to be backfilled later */
1389
1390         if (bmval0 & FATTR4_WORD0_SUPPORTED_ATTRS) {
1391                 if ((buflen -= 12) < 0)
1392                         goto out_resource;
1393                 WRITE32(2);
1394                 WRITE32(NFSD_SUPPORTED_ATTRS_WORD0);
1395                 WRITE32(NFSD_SUPPORTED_ATTRS_WORD1);
1396         }
1397         if (bmval0 & FATTR4_WORD0_TYPE) {
1398                 if ((buflen -= 4) < 0)
1399                         goto out_resource;
1400                 dummy = nfs4_ftypes[(stat.mode & S_IFMT) >> 12];
1401                 if (dummy == NF4BAD)
1402                         goto out_serverfault;
1403                 WRITE32(dummy);
1404         }
1405         if (bmval0 & FATTR4_WORD0_FH_EXPIRE_TYPE) {
1406                 if ((buflen -= 4) < 0)
1407                         goto out_resource;
1408                 WRITE32( NFS4_FH_NOEXPIRE_WITH_OPEN | NFS4_FH_VOL_RENAME );
1409         }
1410         if (bmval0 & FATTR4_WORD0_CHANGE) {
1411                 /*
1412                  * Note: This _must_ be consistent with the scheme for writing
1413                  * change_info, so any changes made here must be reflected there
1414                  * as well.  (See xdr4.h:set_change_info() and the WRITECINFO()
1415                  * macro above.)
1416                  */
1417                 if ((buflen -= 8) < 0)
1418                         goto out_resource;
1419                 WRITE32(stat.ctime.tv_sec);
1420                 WRITE32(stat.ctime.tv_nsec);
1421         }
1422         if (bmval0 & FATTR4_WORD0_SIZE) {
1423                 if ((buflen -= 8) < 0)
1424                         goto out_resource;
1425                 WRITE64(stat.size);
1426         }
1427         if (bmval0 & FATTR4_WORD0_LINK_SUPPORT) {
1428                 if ((buflen -= 4) < 0)
1429                         goto out_resource;
1430                 WRITE32(1);
1431         }
1432         if (bmval0 & FATTR4_WORD0_SYMLINK_SUPPORT) {
1433                 if ((buflen -= 4) < 0)
1434                         goto out_resource;
1435                 WRITE32(1);
1436         }
1437         if (bmval0 & FATTR4_WORD0_NAMED_ATTR) {
1438                 if ((buflen -= 4) < 0)
1439                         goto out_resource;
1440                 WRITE32(0);
1441         }
1442         if (bmval0 & FATTR4_WORD0_FSID) {
1443                 if ((buflen -= 16) < 0)
1444                         goto out_resource;
1445                 WRITE32(0);
1446                 WRITE32(MAJOR(stat.dev));
1447                 WRITE32(0);
1448                 WRITE32(MINOR(stat.dev));
1449         }
1450         if (bmval0 & FATTR4_WORD0_UNIQUE_HANDLES) {
1451                 if ((buflen -= 4) < 0)
1452                         goto out_resource;
1453                 WRITE32(0);
1454         }
1455         if (bmval0 & FATTR4_WORD0_LEASE_TIME) {
1456                 if ((buflen -= 4) < 0)
1457                         goto out_resource;
1458                 WRITE32(NFSD_LEASE_TIME);
1459         }
1460         if (bmval0 & FATTR4_WORD0_RDATTR_ERROR) {
1461                 if ((buflen -= 4) < 0)
1462                         goto out_resource;
1463                 WRITE32(0);
1464         }
1465         if (bmval0 & FATTR4_WORD0_ACLSUPPORT) {
1466                 if ((buflen -= 4) < 0)
1467                         goto out_resource;
1468                 WRITE32(0);
1469         }
1470         if (bmval0 & FATTR4_WORD0_CANSETTIME) {
1471                 if ((buflen -= 4) < 0)
1472                         goto out_resource;
1473                 WRITE32(1);
1474         }
1475         if (bmval0 & FATTR4_WORD0_CASE_INSENSITIVE) {
1476                 if ((buflen -= 4) < 0)
1477                         goto out_resource;
1478                 WRITE32(1);
1479         }
1480         if (bmval0 & FATTR4_WORD0_CASE_PRESERVING) {
1481                 if ((buflen -= 4) < 0)
1482                         goto out_resource;
1483                 WRITE32(1);
1484         }
1485         if (bmval0 & FATTR4_WORD0_CHOWN_RESTRICTED) {
1486                 if ((buflen -= 4) < 0)
1487                         goto out_resource;
1488                 WRITE32(1);
1489         }
1490         if (bmval0 & FATTR4_WORD0_FILEHANDLE) {
1491                 buflen -= (XDR_QUADLEN(fhp->fh_handle.fh_size) << 2) + 4;
1492                 if (buflen < 0)
1493                         goto out_resource;
1494                 WRITE32(fhp->fh_handle.fh_size);
1495                 WRITEMEM(&fhp->fh_handle.fh_base, fhp->fh_handle.fh_size);
1496         }
1497         if (bmval0 & FATTR4_WORD0_FILEID) {
1498                 if ((buflen -= 8) < 0)
1499                         goto out_resource;
1500                 WRITE64((u64) stat.ino);
1501         }
1502         if (bmval0 & FATTR4_WORD0_FILES_AVAIL) {
1503                 if ((buflen -= 8) < 0)
1504                         goto out_resource;
1505                 WRITE64((u64) statfs.f_ffree);
1506         }
1507         if (bmval0 & FATTR4_WORD0_FILES_FREE) {
1508                 if ((buflen -= 8) < 0)
1509                         goto out_resource;
1510                 WRITE64((u64) statfs.f_ffree);
1511         }
1512         if (bmval0 & FATTR4_WORD0_FILES_TOTAL) {
1513                 if ((buflen -= 8) < 0)
1514                         goto out_resource;
1515                 WRITE64((u64) statfs.f_files);
1516         }
1517         if (bmval0 & FATTR4_WORD0_HOMOGENEOUS) {
1518                 if ((buflen -= 4) < 0)
1519                         goto out_resource;
1520                 WRITE32(1);
1521         }
1522         if (bmval0 & FATTR4_WORD0_MAXFILESIZE) {
1523                 if ((buflen -= 8) < 0)
1524                         goto out_resource;
1525                 WRITE64(~(u64)0);
1526         }
1527         if (bmval0 & FATTR4_WORD0_MAXLINK) {
1528                 if ((buflen -= 4) < 0)
1529                         goto out_resource;
1530                 WRITE32(255);
1531         }
1532         if (bmval0 & FATTR4_WORD0_MAXNAME) {
1533                 if ((buflen -= 4) < 0)
1534                         goto out_resource;
1535                 WRITE32(~(u32) 0);
1536         }
1537         if (bmval0 & FATTR4_WORD0_MAXREAD) {
1538                 if ((buflen -= 8) < 0)
1539                         goto out_resource;
1540                 WRITE64((u64) NFSSVC_MAXBLKSIZE);
1541         }
1542         if (bmval0 & FATTR4_WORD0_MAXWRITE) {
1543                 if ((buflen -= 8) < 0)
1544                         goto out_resource;
1545                 WRITE64((u64) NFSSVC_MAXBLKSIZE);
1546         }
1547         if (bmval1 & FATTR4_WORD1_MODE) {
1548                 if ((buflen -= 4) < 0)
1549                         goto out_resource;
1550                 WRITE32(stat.mode & S_IALLUGO);
1551         }
1552         if (bmval1 & FATTR4_WORD1_NO_TRUNC) {
1553                 if ((buflen -= 4) < 0)
1554                         goto out_resource;
1555                 WRITE32(1);
1556         }
1557         if (bmval1 & FATTR4_WORD1_NUMLINKS) {
1558                 if ((buflen -= 4) < 0)
1559                         goto out_resource;
1560                 WRITE32(stat.nlink);
1561         }
1562         if (bmval1 & FATTR4_WORD1_OWNER) {
1563                 status = nfsd4_encode_user(rqstp, stat.uid, &p, &buflen);
1564                 if (status == nfserr_resource)
1565                         goto out_resource;
1566                 if (status)
1567                         goto out;
1568         }
1569         if (bmval1 & FATTR4_WORD1_OWNER_GROUP) {
1570                 status = nfsd4_encode_group(rqstp, stat.gid, &p, &buflen);
1571                 if (status == nfserr_resource)
1572                         goto out_resource;
1573                 if (status)
1574                         goto out;
1575         }
1576         if (bmval1 & FATTR4_WORD1_RAWDEV) {
1577                 if ((buflen -= 8) < 0)
1578                         goto out_resource;
1579                 WRITE32((u32) MAJOR(stat.rdev));
1580                 WRITE32((u32) MINOR(stat.rdev));
1581         }
1582         if (bmval1 & FATTR4_WORD1_SPACE_AVAIL) {
1583                 if ((buflen -= 8) < 0)
1584                         goto out_resource;
1585                 dummy64 = (u64)statfs.f_bavail * (u64)statfs.f_bsize;
1586                 WRITE64(dummy64);
1587         }
1588         if (bmval1 & FATTR4_WORD1_SPACE_FREE) {
1589                 if ((buflen -= 8) < 0)
1590                         goto out_resource;
1591                 dummy64 = (u64)statfs.f_bfree * (u64)statfs.f_bsize;
1592                 WRITE64(dummy64);
1593         }
1594         if (bmval1 & FATTR4_WORD1_SPACE_TOTAL) {
1595                 if ((buflen -= 8) < 0)
1596                         goto out_resource;
1597                 dummy64 = (u64)statfs.f_blocks * (u64)statfs.f_bsize;
1598                 WRITE64(dummy64);
1599         }
1600         if (bmval1 & FATTR4_WORD1_SPACE_USED) {
1601                 if ((buflen -= 8) < 0)
1602                         goto out_resource;
1603                 dummy64 = (u64)stat.blocks << 9;
1604                 WRITE64(dummy64);
1605         }
1606         if (bmval1 & FATTR4_WORD1_TIME_ACCESS) {
1607                 if ((buflen -= 12) < 0)
1608                         goto out_resource;
1609                 WRITE32(0);
1610                 WRITE32(stat.atime.tv_sec);
1611                 WRITE32(stat.atime.tv_nsec);
1612         }
1613         if (bmval1 & FATTR4_WORD1_TIME_DELTA) {
1614                 if ((buflen -= 12) < 0)
1615                         goto out_resource;
1616                 WRITE32(0);
1617                 WRITE32(1);
1618                 WRITE32(0);
1619         }
1620         if (bmval1 & FATTR4_WORD1_TIME_METADATA) {
1621                 if ((buflen -= 12) < 0)
1622                         goto out_resource;
1623                 WRITE32(0);
1624                 WRITE32(stat.ctime.tv_sec);
1625                 WRITE32(stat.ctime.tv_nsec);
1626         }
1627         if (bmval1 & FATTR4_WORD1_TIME_MODIFY) {
1628                 if ((buflen -= 12) < 0)
1629                         goto out_resource;
1630                 WRITE32(0);
1631                 WRITE32(stat.mtime.tv_sec);
1632                 WRITE32(stat.mtime.tv_nsec);
1633         }
1634         if (bmval1 & FATTR4_WORD1_MOUNTED_ON_FILEID) {
1635                 struct dentry *mnt_pnt, *mnt_root;
1636
1637                 if ((buflen -= 8) < 0)
1638                         goto out_resource;
1639                 mnt_root = exp->ex_mnt->mnt_root;
1640                 if (mnt_root->d_inode == dentry->d_inode) {
1641                         mnt_pnt = exp->ex_mnt->mnt_mountpoint;
1642                         WRITE64((u64) mnt_pnt->d_inode->i_ino);
1643                 } else
1644                         WRITE64((u64) stat.ino);
1645         }
1646         *attrlenp = htonl((char *)p - (char *)attrlenp - 4);
1647         *countp = p - buffer;
1648         status = nfs_ok;
1649
1650 out:
1651         if (fhp == &tempfh)
1652                 fh_put(&tempfh);
1653         return status;
1654 out_nfserr:
1655         status = nfserrno(status);
1656         goto out;
1657 out_resource:
1658         *countp = 0;
1659         status = nfserr_resource;
1660         goto out;
1661 out_serverfault:
1662         status = nfserr_serverfault;
1663         goto out;
1664 }
1665
1666 static int
1667 nfsd4_encode_dirent(struct readdir_cd *ccd, const char *name, int namlen,
1668                     loff_t offset, ino_t ino, unsigned int d_type)
1669 {
1670         struct nfsd4_readdir *cd = container_of(ccd, struct nfsd4_readdir, common);
1671         int buflen;
1672         u32 *p = cd->buffer;
1673         u32 *attrlenp;
1674         struct dentry *dentry;
1675         struct svc_export *exp = cd->rd_fhp->fh_export;
1676         u32 bmval0, bmval1;
1677         int nfserr = 0;
1678
1679         /* In nfsv4, "." and ".." never make it onto the wire.. */
1680         if (name && isdotent(name, namlen)) {
1681                 cd->common.err = nfs_ok;
1682                 return 0;
1683         }
1684
1685         if (cd->offset)
1686                 xdr_encode_hyper(cd->offset, (u64) offset);
1687
1688         buflen = cd->buflen - 4 - XDR_QUADLEN(namlen);
1689         if (buflen < 0)
1690                 goto nospc;
1691
1692         *p++ = xdr_one;                             /* mark entry present */
1693         cd->offset = p;                             /* remember pointer */
1694         p = xdr_encode_hyper(p, NFS_OFFSET_MAX);    /* offset of next entry */
1695         p = xdr_encode_array(p, name, namlen);      /* name length & name */
1696
1697         /*
1698          * Now we come to the ugly part: writing the fattr for this entry.
1699          */
1700         bmval0 = cd->rd_bmval[0];
1701         bmval1 = cd->rd_bmval[1];
1702         if ((bmval0 & ~(FATTR4_WORD0_RDATTR_ERROR | FATTR4_WORD0_FILEID)) || bmval1)  {
1703                 /*
1704                  * "Heavyweight" case: we have no choice except to
1705                  * call nfsd4_encode_fattr(). 
1706                  */
1707                 dentry = lookup_one_len(name, cd->rd_fhp->fh_dentry, namlen);
1708                 if (IS_ERR(dentry)) {
1709                         nfserr = nfserrno(PTR_ERR(dentry));
1710                         goto error;
1711                 }
1712
1713                 exp_get(exp);
1714                 if (d_mountpoint(dentry)) {
1715                         if ((nfserr = nfsd_cross_mnt(cd->rd_rqstp, &dentry, 
1716                                          &exp))) {      
1717                         /* 
1718                          * -EAGAIN is the only error returned from 
1719                          * nfsd_cross_mnt() and it indicates that an 
1720                          * up-call has  been initiated to fill in the export 
1721                          * options on exp.  When the answer comes back,
1722                          * this call will be retried.
1723                          */
1724                                 dput(dentry);
1725                                 exp_put(exp);
1726                                 nfserr = nfserr_dropit;
1727                                 goto error;
1728                         }
1729
1730                 }
1731
1732                 nfserr = nfsd4_encode_fattr(NULL, exp,
1733                                 dentry, p, &buflen, cd->rd_bmval,
1734                                 cd->rd_rqstp);
1735                 dput(dentry);
1736                 exp_put(exp);
1737                 if (!nfserr) {
1738                         p += buflen;
1739                         goto out;
1740                 }
1741                 if (nfserr == nfserr_resource)
1742                         goto nospc;
1743
1744 error:
1745                 /*
1746                  * If we get here, we experienced a miscellaneous
1747                  * failure while writing the attributes.  If the
1748                  * client requested the RDATTR_ERROR attribute,
1749                  * we stuff the error code into this attribute
1750                  * and continue.  If this attribute was not requested,
1751                  * then in accordance with the spec, we fail the
1752                  * entire READDIR operation(!)
1753                  */
1754                 if (!(bmval0 & FATTR4_WORD0_RDATTR_ERROR)) {
1755                         cd->common.err = nfserr;
1756                         return -EINVAL;
1757                 }
1758
1759                 bmval0 = FATTR4_WORD0_RDATTR_ERROR;
1760                 bmval1 = 0;
1761                 /* falling through here will do the right thing... */
1762         }
1763
1764         /*
1765          * In the common "lightweight" case, we avoid
1766          * the overhead of nfsd4_encode_fattr() by assembling
1767          * a small fattr by hand.
1768          */
1769         if (buflen < 6)
1770                 goto nospc;
1771         *p++ = htonl(2);
1772         *p++ = htonl(bmval0);
1773         *p++ = htonl(bmval1);
1774
1775         attrlenp = p++;
1776         if (bmval0 & FATTR4_WORD0_RDATTR_ERROR)
1777                 *p++ = nfserr;       /* no htonl */
1778         if (bmval0 & FATTR4_WORD0_FILEID)
1779                 p = xdr_encode_hyper(p, (u64)ino);
1780         *attrlenp = htonl((char *)p - (char *)attrlenp - 4);
1781
1782 out:
1783         cd->buflen -= (p - cd->buffer);
1784         cd->buffer = p;
1785         cd->common.err = nfs_ok;
1786         return 0;
1787
1788 nospc:
1789         cd->common.err = nfserr_toosmall;
1790         return -EINVAL;
1791 }
1792
1793 static void
1794 nfsd4_encode_access(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_access *access)
1795 {
1796         ENCODE_HEAD;
1797
1798         if (!nfserr) {
1799                 RESERVE_SPACE(8);
1800                 WRITE32(access->ac_supported);
1801                 WRITE32(access->ac_resp_access);
1802                 ADJUST_ARGS();
1803         }
1804 }
1805
1806 static void
1807 nfsd4_encode_close(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_close *close)
1808 {
1809         ENCODE_SEQID_OP_HEAD;
1810
1811         if (!nfserr) {
1812                 RESERVE_SPACE(sizeof(stateid_t));
1813                 WRITE32(close->cl_stateid.si_generation);
1814                 WRITEMEM(&close->cl_stateid.si_opaque, sizeof(stateid_opaque_t));
1815                 ADJUST_ARGS();
1816         }
1817         ENCODE_SEQID_OP_TAIL(close->cl_stateowner);
1818 }
1819
1820
1821 static void
1822 nfsd4_encode_commit(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_commit *commit)
1823 {
1824         ENCODE_HEAD;
1825
1826         if (!nfserr) {
1827                 RESERVE_SPACE(8);
1828                 WRITEMEM(commit->co_verf.data, 8);
1829                 ADJUST_ARGS();
1830         }
1831 }
1832
1833 static void
1834 nfsd4_encode_create(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_create *create)
1835 {
1836         ENCODE_HEAD;
1837
1838         if (!nfserr) {
1839                 RESERVE_SPACE(32);
1840                 WRITECINFO(create->cr_cinfo);
1841                 WRITE32(2);
1842                 WRITE32(create->cr_bmval[0]);
1843                 WRITE32(create->cr_bmval[1]);
1844                 ADJUST_ARGS();
1845         }
1846 }
1847
1848 static int
1849 nfsd4_encode_getattr(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_getattr *getattr)
1850 {
1851         struct svc_fh *fhp = getattr->ga_fhp;
1852         int buflen;
1853
1854         if (nfserr)
1855                 return nfserr;
1856
1857         buflen = resp->end - resp->p - (COMPOUND_ERR_SLACK_SPACE >> 2);
1858         nfserr = nfsd4_encode_fattr(fhp, fhp->fh_export, fhp->fh_dentry,
1859                                     resp->p, &buflen, getattr->ga_bmval,
1860                                     resp->rqstp);
1861
1862         if (!nfserr)
1863                 resp->p += buflen;
1864         return nfserr;
1865 }
1866
1867 static void
1868 nfsd4_encode_getfh(struct nfsd4_compoundres *resp, int nfserr, struct svc_fh *fhp)
1869 {
1870         unsigned int len;
1871         ENCODE_HEAD;
1872
1873         if (!nfserr) {
1874                 len = fhp->fh_handle.fh_size;
1875                 RESERVE_SPACE(len + 4);
1876                 WRITE32(len);
1877                 WRITEMEM(&fhp->fh_handle.fh_base, len);
1878                 ADJUST_ARGS();
1879         }
1880 }
1881
1882 /*
1883 * Including all fields other than the name, a LOCK4denied structure requires
1884 *   8(clientid) + 4(namelen) + 8(offset) + 8(length) + 4(type) = 32 bytes.
1885 */
1886 static void
1887 nfsd4_encode_lock_denied(struct nfsd4_compoundres *resp, struct nfsd4_lock_denied *ld)
1888 {
1889         ENCODE_HEAD;
1890
1891         RESERVE_SPACE(32 + XDR_LEN(ld->ld_sop->so_owner.len));
1892         WRITE64(ld->ld_start);
1893         WRITE64(ld->ld_length);
1894         WRITE32(ld->ld_type);
1895         WRITEMEM(&ld->ld_sop->so_client->cl_clientid, 8);
1896         WRITE32(ld->ld_sop->so_owner.len);
1897         WRITEMEM(ld->ld_sop->so_owner.data, ld->ld_sop->so_owner.len);
1898         ADJUST_ARGS();
1899 }
1900
1901 static void
1902 nfsd4_encode_lock(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_lock *lock)
1903 {
1904
1905         ENCODE_SEQID_OP_HEAD;
1906
1907         if (!nfserr) {
1908                 RESERVE_SPACE(4 + sizeof(stateid_t));
1909                 WRITE32(lock->lk_resp_stateid.si_generation);
1910                 WRITEMEM(&lock->lk_resp_stateid.si_opaque, sizeof(stateid_opaque_t));
1911                 ADJUST_ARGS();
1912         } else if (nfserr == nfserr_denied)
1913                 nfsd4_encode_lock_denied(resp, &lock->lk_denied);
1914
1915         ENCODE_SEQID_OP_TAIL(lock->lk_stateowner);
1916 }
1917
1918 static void
1919 nfsd4_encode_lockt(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_lockt *lockt)
1920 {
1921         if (nfserr == nfserr_denied)
1922                 nfsd4_encode_lock_denied(resp, &lockt->lt_denied);
1923 }
1924
1925 static void
1926 nfsd4_encode_locku(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_locku *locku)
1927 {
1928         ENCODE_SEQID_OP_HEAD;
1929
1930         if (!nfserr) {
1931                 RESERVE_SPACE(sizeof(stateid_t));
1932                 WRITE32(locku->lu_stateid.si_generation);
1933                 WRITEMEM(&locku->lu_stateid.si_opaque, sizeof(stateid_opaque_t));
1934                 ADJUST_ARGS();
1935         }
1936                                         
1937         ENCODE_SEQID_OP_TAIL(locku->lu_stateowner);
1938 }
1939
1940
1941 static void
1942 nfsd4_encode_link(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_link *link)
1943 {
1944         ENCODE_HEAD;
1945
1946         if (!nfserr) {
1947                 RESERVE_SPACE(20);
1948                 WRITECINFO(link->li_cinfo);
1949                 ADJUST_ARGS();
1950         }
1951 }
1952
1953
1954 static void
1955 nfsd4_encode_open(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_open *open)
1956 {
1957         ENCODE_SEQID_OP_HEAD;
1958
1959         if (nfserr)
1960                 goto out;
1961
1962         RESERVE_SPACE(36 + sizeof(stateid_t));
1963         WRITE32(open->op_stateid.si_generation);
1964         WRITEMEM(&open->op_stateid.si_opaque, sizeof(stateid_opaque_t));
1965         WRITECINFO(open->op_cinfo);
1966         WRITE32(open->op_rflags);
1967         WRITE32(2);
1968         WRITE32(open->op_bmval[0]);
1969         WRITE32(open->op_bmval[1]);
1970         WRITE32(open->op_delegate_type);
1971         ADJUST_ARGS();
1972
1973         switch (open->op_delegate_type) {
1974         case NFS4_OPEN_DELEGATE_NONE:
1975                 break;
1976         case NFS4_OPEN_DELEGATE_READ:
1977                 RESERVE_SPACE(20 + sizeof(delegation_stateid_t));
1978                 WRITEMEM(&open->op_delegate_stateid, sizeof(delegation_stateid_t));
1979                 WRITE32(0);
1980
1981                 /*
1982                  * TODO: ACE's in delegations
1983                  */
1984                 WRITE32(NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE);
1985                 WRITE32(0);
1986                 WRITE32(0);
1987                 WRITE32(0);   /* XXX: is NULL principal ok? */
1988                 ADJUST_ARGS();
1989                 break;
1990         case NFS4_OPEN_DELEGATE_WRITE:
1991                 RESERVE_SPACE(32 + sizeof(delegation_stateid_t));
1992                 WRITEMEM(&open->op_delegate_stateid, sizeof(delegation_stateid_t));
1993                 WRITE32(0);
1994
1995                 /*
1996                  * TODO: space_limit's in delegations
1997                  */
1998                 WRITE32(NFS4_LIMIT_SIZE);
1999                 WRITE32(~(u32)0);
2000                 WRITE32(~(u32)0);
2001
2002                 /*
2003                  * TODO: ACE's in delegations
2004                  */
2005                 WRITE32(NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE);
2006                 WRITE32(0);
2007                 WRITE32(0);
2008                 WRITE32(0);   /* XXX: is NULL principal ok? */
2009                 ADJUST_ARGS();
2010                 break;
2011         default:
2012                 BUG();
2013         }
2014         /* XXX save filehandle here */
2015 out:
2016         ENCODE_SEQID_OP_TAIL(open->op_stateowner);
2017 }
2018
2019 static void
2020 nfsd4_encode_open_confirm(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_open_confirm *oc)
2021 {
2022         ENCODE_SEQID_OP_HEAD;
2023                                         
2024         if (!nfserr) {
2025                 RESERVE_SPACE(sizeof(stateid_t));
2026                 WRITE32(oc->oc_resp_stateid.si_generation);
2027                 WRITEMEM(&oc->oc_resp_stateid.si_opaque, sizeof(stateid_opaque_t));
2028                 ADJUST_ARGS();
2029         }
2030
2031         ENCODE_SEQID_OP_TAIL(oc->oc_stateowner);
2032 }
2033
2034 static void
2035 nfsd4_encode_open_downgrade(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_open_downgrade *od)
2036 {
2037         ENCODE_SEQID_OP_HEAD;
2038                                         
2039         if (!nfserr) {
2040                 RESERVE_SPACE(sizeof(stateid_t));
2041                 WRITE32(od->od_stateid.si_generation);
2042                 WRITEMEM(&od->od_stateid.si_opaque, sizeof(stateid_opaque_t));
2043                 ADJUST_ARGS();
2044         }
2045
2046         ENCODE_SEQID_OP_TAIL(od->od_stateowner);
2047 }
2048
2049 static int
2050 nfsd4_encode_read(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_read *read)
2051 {
2052         u32 eof;
2053         int v, pn;
2054         unsigned long maxcount; 
2055         long len;
2056         ENCODE_HEAD;
2057
2058         if (nfserr)
2059                 return nfserr;
2060         if (resp->xbuf->page_len)
2061                 return nfserr_resource;
2062
2063         RESERVE_SPACE(8); /* eof flag and byte count */
2064
2065         maxcount = NFSSVC_MAXBLKSIZE;
2066         if (maxcount > read->rd_length)
2067                 maxcount = read->rd_length;
2068
2069         len = maxcount;
2070         v = 0;
2071         while (len > 0) {
2072                 pn = resp->rqstp->rq_resused;
2073                 svc_take_page(resp->rqstp);
2074                 read->rd_iov[v].iov_base = page_address(resp->rqstp->rq_respages[pn]);
2075                 read->rd_iov[v].iov_len = len < PAGE_SIZE ? len : PAGE_SIZE;
2076                 v++;
2077                 len -= PAGE_SIZE;
2078         }
2079         read->rd_vlen = v;
2080
2081         nfserr = nfsd_read(read->rd_rqstp, read->rd_fhp,
2082                            read->rd_offset,
2083                            read->rd_iov, read->rd_vlen,
2084                            &maxcount);
2085         if (nfserr == nfserr_symlink)
2086                 nfserr = nfserr_inval;
2087         if (nfserr)
2088                 return nfserr;
2089         eof = (read->rd_offset + maxcount >= read->rd_fhp->fh_dentry->d_inode->i_size);
2090
2091         WRITE32(eof);
2092         WRITE32(maxcount);
2093         ADJUST_ARGS();
2094         resp->xbuf->head[0].iov_len = ((char*)resp->p) - (char*)resp->xbuf->head[0].iov_base;
2095
2096         resp->xbuf->page_len = maxcount;
2097
2098         /* read zero bytes -> don't set up tail */
2099         if(!maxcount)
2100                 return 0;        
2101
2102         /* set up page for remaining responses */
2103         svc_take_page(resp->rqstp);
2104         resp->xbuf->tail[0].iov_base = 
2105                 page_address(resp->rqstp->rq_respages[resp->rqstp->rq_resused-1]);
2106         resp->rqstp->rq_restailpage = resp->rqstp->rq_resused-1;
2107         resp->xbuf->tail[0].iov_len = 0;
2108         resp->p = resp->xbuf->tail[0].iov_base;
2109         resp->end = resp->p + PAGE_SIZE/4;
2110
2111         if (maxcount&3) {
2112                 *(resp->p)++ = 0;
2113                 resp->xbuf->tail[0].iov_base += maxcount&3;
2114                 resp->xbuf->tail[0].iov_len = 4 - (maxcount&3);
2115         }
2116         return 0;
2117 }
2118
2119 static int
2120 nfsd4_encode_readlink(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_readlink *readlink)
2121 {
2122         int maxcount;
2123         char *page;
2124         ENCODE_HEAD;
2125
2126         if (nfserr)
2127                 return nfserr;
2128         if (resp->xbuf->page_len)
2129                 return nfserr_resource;
2130
2131         svc_take_page(resp->rqstp);
2132         page = page_address(resp->rqstp->rq_respages[resp->rqstp->rq_resused-1]);
2133
2134         maxcount = PAGE_SIZE;
2135         RESERVE_SPACE(4);
2136
2137         /*
2138          * XXX: By default, the ->readlink() VFS op will truncate symlinks
2139          * if they would overflow the buffer.  Is this kosher in NFSv4?  If
2140          * not, one easy fix is: if ->readlink() precisely fills the buffer,
2141          * assume that truncation occurred, and return NFS4ERR_RESOURCE.
2142          */
2143         nfserr = nfsd_readlink(readlink->rl_rqstp, readlink->rl_fhp, page, &maxcount);
2144         if (nfserr == nfserr_isdir)
2145                 return nfserr_inval;
2146         if (nfserr)
2147                 return nfserr;
2148
2149         WRITE32(maxcount);
2150         ADJUST_ARGS();
2151         resp->xbuf->head[0].iov_len = ((char*)resp->p) - (char*)resp->xbuf->head[0].iov_base;
2152
2153         svc_take_page(resp->rqstp);
2154         resp->xbuf->tail[0].iov_base = 
2155                 page_address(resp->rqstp->rq_respages[resp->rqstp->rq_resused-1]);
2156         resp->rqstp->rq_restailpage = resp->rqstp->rq_resused-1;
2157         resp->xbuf->tail[0].iov_len = 0;
2158         resp->p = resp->xbuf->tail[0].iov_base;
2159         resp->end = resp->p + PAGE_SIZE/4;
2160
2161         resp->xbuf->page_len = maxcount;
2162         if (maxcount&3) {
2163                 *(resp->p)++ = 0;
2164                 resp->xbuf->tail[0].iov_base += maxcount&3;
2165                 resp->xbuf->tail[0].iov_len = 4 - (maxcount&3);
2166         }
2167         return 0;
2168 }
2169
2170 static int
2171 nfsd4_encode_readdir(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_readdir *readdir)
2172 {
2173         int maxcount;
2174         loff_t offset;
2175         u32 *page, *savep;
2176         ENCODE_HEAD;
2177
2178         if (nfserr)
2179                 return nfserr;
2180         if (resp->xbuf->page_len)
2181                 return nfserr_resource;
2182
2183         RESERVE_SPACE(8);  /* verifier */
2184         savep = p;
2185
2186         /* XXX: Following NFSv3, we ignore the READDIR verifier for now. */
2187         WRITE32(0);
2188         WRITE32(0);
2189         ADJUST_ARGS();
2190         resp->xbuf->head[0].iov_len = ((char*)resp->p) - (char*)resp->xbuf->head[0].iov_base;
2191
2192         maxcount = PAGE_SIZE;
2193         if (maxcount > readdir->rd_maxcount)
2194                 maxcount = readdir->rd_maxcount;
2195
2196         /*
2197          * Convert from bytes to words, account for the two words already
2198          * written, make sure to leave two words at the end for the next
2199          * pointer and eof field.
2200          */
2201         maxcount = (maxcount >> 2) - 4;
2202         if (maxcount < 0) {
2203                 nfserr =  nfserr_toosmall;
2204                 goto err_no_verf;
2205         }
2206
2207         svc_take_page(resp->rqstp);
2208         page = page_address(resp->rqstp->rq_respages[resp->rqstp->rq_resused-1]);
2209         readdir->common.err = 0;
2210         readdir->buflen = maxcount;
2211         readdir->buffer = page;
2212         readdir->offset = NULL;
2213
2214         offset = readdir->rd_cookie;
2215         nfserr = nfsd_readdir(readdir->rd_rqstp, readdir->rd_fhp,
2216                               &offset,
2217                               &readdir->common, nfsd4_encode_dirent);
2218         if (nfserr == nfs_ok &&
2219             readdir->common.err == nfserr_toosmall &&
2220             readdir->buffer == page) 
2221                 nfserr = nfserr_toosmall;
2222         if (nfserr == nfserr_symlink)
2223                 nfserr = nfserr_notdir;
2224         if (nfserr)
2225                 goto err_no_verf;
2226
2227         if (readdir->offset)
2228                 xdr_encode_hyper(readdir->offset, offset);
2229
2230         p = readdir->buffer;
2231         *p++ = 0;       /* no more entries */
2232         *p++ = htonl(readdir->common.err == nfserr_eof);
2233         resp->xbuf->page_len = ((char*)p) - (char*)page_address(resp->rqstp->rq_respages[resp->rqstp->rq_resused-1]);
2234
2235         /* allocate a page for the tail */
2236         svc_take_page(resp->rqstp);
2237         resp->xbuf->tail[0].iov_base = 
2238                 page_address(resp->rqstp->rq_respages[resp->rqstp->rq_resused-1]);
2239         resp->rqstp->rq_restailpage = resp->rqstp->rq_resused-1;
2240         resp->xbuf->tail[0].iov_len = 0;
2241         resp->p = resp->xbuf->tail[0].iov_base;
2242         resp->end = resp->p + PAGE_SIZE/4;
2243
2244         return 0;
2245 err_no_verf:
2246         p = savep;
2247         ADJUST_ARGS();
2248         return nfserr;
2249 }
2250
2251 static void
2252 nfsd4_encode_remove(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_remove *remove)
2253 {
2254         ENCODE_HEAD;
2255
2256         if (!nfserr) {
2257                 RESERVE_SPACE(20);
2258                 WRITECINFO(remove->rm_cinfo);
2259                 ADJUST_ARGS();
2260         }
2261 }
2262
2263 static void
2264 nfsd4_encode_rename(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_rename *rename)
2265 {
2266         ENCODE_HEAD;
2267
2268         if (!nfserr) {
2269                 RESERVE_SPACE(40);
2270                 WRITECINFO(rename->rn_sinfo);
2271                 WRITECINFO(rename->rn_tinfo);
2272                 ADJUST_ARGS();
2273         }
2274 }
2275
2276 /*
2277  * The SETATTR encode routine is special -- it always encodes a bitmap,
2278  * regardless of the error status.
2279  */
2280 static void
2281 nfsd4_encode_setattr(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_setattr *setattr)
2282 {
2283         ENCODE_HEAD;
2284
2285         RESERVE_SPACE(12);
2286         if (nfserr) {
2287                 WRITE32(2);
2288                 WRITE32(0);
2289                 WRITE32(0);
2290         }
2291         else {
2292                 WRITE32(2);
2293                 WRITE32(setattr->sa_bmval[0]);
2294                 WRITE32(setattr->sa_bmval[1]);
2295         }
2296         ADJUST_ARGS();
2297 }
2298
2299 static void
2300 nfsd4_encode_setclientid(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_setclientid *scd)
2301 {
2302         ENCODE_HEAD;
2303
2304         if (!nfserr) {
2305                 RESERVE_SPACE(8 + sizeof(nfs4_verifier));
2306                 WRITEMEM(&scd->se_clientid, 8);
2307                 WRITEMEM(&scd->se_confirm, sizeof(nfs4_verifier));
2308                 ADJUST_ARGS();
2309         }
2310         else if (nfserr == nfserr_clid_inuse) {
2311                 RESERVE_SPACE(8);
2312                 WRITE32(0);
2313                 WRITE32(0);
2314                 ADJUST_ARGS();
2315         }
2316 }
2317
2318 static void
2319 nfsd4_encode_write(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_write *write)
2320 {
2321         ENCODE_HEAD;
2322
2323         if (!nfserr) {
2324                 RESERVE_SPACE(16);
2325                 WRITE32(write->wr_bytes_written);
2326                 WRITE32(write->wr_how_written);
2327                 WRITEMEM(write->wr_verifier.data, 8);
2328                 ADJUST_ARGS();
2329         }
2330 }
2331
2332 void
2333 nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op)
2334 {
2335         u32 *statp;
2336         ENCODE_HEAD;
2337
2338         RESERVE_SPACE(8);
2339         WRITE32(op->opnum);
2340         statp = p++;    /* to be backfilled at the end */
2341         ADJUST_ARGS();
2342
2343         switch (op->opnum) {
2344         case OP_ACCESS:
2345                 nfsd4_encode_access(resp, op->status, &op->u.access);
2346                 break;
2347         case OP_CLOSE:
2348                 nfsd4_encode_close(resp, op->status, &op->u.close);
2349                 break;
2350         case OP_COMMIT:
2351                 nfsd4_encode_commit(resp, op->status, &op->u.commit);
2352                 break;
2353         case OP_CREATE:
2354                 nfsd4_encode_create(resp, op->status, &op->u.create);
2355                 break;
2356         case OP_GETATTR:
2357                 op->status = nfsd4_encode_getattr(resp, op->status, &op->u.getattr);
2358                 break;
2359         case OP_GETFH:
2360                 nfsd4_encode_getfh(resp, op->status, op->u.getfh);
2361                 break;
2362         case OP_LINK:
2363                 nfsd4_encode_link(resp, op->status, &op->u.link);
2364                 break;
2365         case OP_LOCK:
2366                 nfsd4_encode_lock(resp, op->status, &op->u.lock);
2367                 break;
2368         case OP_LOCKT:
2369                 nfsd4_encode_lockt(resp, op->status, &op->u.lockt);
2370                 break;
2371         case OP_LOCKU:
2372                 nfsd4_encode_locku(resp, op->status, &op->u.locku);
2373                 break;
2374         case OP_LOOKUP:
2375                 break;
2376         case OP_LOOKUPP:
2377                 break;
2378         case OP_NVERIFY:
2379                 break;
2380         case OP_OPEN:
2381                 nfsd4_encode_open(resp, op->status, &op->u.open);
2382                 break;
2383         case OP_OPEN_CONFIRM:
2384                 nfsd4_encode_open_confirm(resp, op->status, &op->u.open_confirm);
2385                 break;
2386         case OP_OPEN_DOWNGRADE:
2387                 nfsd4_encode_open_downgrade(resp, op->status, &op->u.open_downgrade);
2388                 break;
2389         case OP_PUTFH:
2390                 break;
2391         case OP_PUTROOTFH:
2392                 break;
2393         case OP_READ:
2394                 op->status = nfsd4_encode_read(resp, op->status, &op->u.read);
2395                 break;
2396         case OP_READDIR:
2397                 op->status = nfsd4_encode_readdir(resp, op->status, &op->u.readdir);
2398                 break;
2399         case OP_READLINK:
2400                 op->status = nfsd4_encode_readlink(resp, op->status, &op->u.readlink);
2401                 break;
2402         case OP_REMOVE:
2403                 nfsd4_encode_remove(resp, op->status, &op->u.remove);
2404                 break;
2405         case OP_RENAME:
2406                 nfsd4_encode_rename(resp, op->status, &op->u.rename);
2407                 break;
2408         case OP_RENEW:
2409                 break;
2410         case OP_RESTOREFH:
2411                 break;
2412         case OP_SAVEFH:
2413                 break;
2414         case OP_SETATTR:
2415                 nfsd4_encode_setattr(resp, op->status, &op->u.setattr);
2416                 break;
2417         case OP_SETCLIENTID:
2418                 nfsd4_encode_setclientid(resp, op->status, &op->u.setclientid);
2419                 break;
2420         case OP_SETCLIENTID_CONFIRM:
2421                 break;
2422         case OP_VERIFY:
2423                 break;
2424         case OP_WRITE:
2425                 nfsd4_encode_write(resp, op->status, &op->u.write);
2426                 break;
2427         case OP_RELEASE_LOCKOWNER:
2428                 break;
2429         default:
2430                 break;
2431         }
2432
2433         /*
2434          * Note: We write the status directly, instead of using WRITE32(),
2435          * since it is already in network byte order.
2436          */
2437         *statp = op->status;
2438 }
2439
2440 /* 
2441  * Encode the reply stored in the stateowner reply cache 
2442  * 
2443  * XDR note: do not encode rp->rp_buflen: the buffer contains the
2444  * previously sent already encoded operation.
2445  *
2446  * called with nfs4_lock_state() held
2447  */
2448 void
2449 nfsd4_encode_replay(struct nfsd4_compoundres *resp, struct nfsd4_op *op)
2450 {
2451         ENCODE_HEAD;
2452         struct nfs4_replay *rp = op->replay;
2453
2454         BUG_ON(!rp);
2455
2456         RESERVE_SPACE(8);
2457         WRITE32(op->opnum);
2458         *p++ = rp->rp_status;  /* already xdr'ed */
2459         ADJUST_ARGS();
2460
2461         RESERVE_SPACE(rp->rp_buflen);
2462         WRITEMEM(rp->rp_buf, rp->rp_buflen);
2463         ADJUST_ARGS();
2464         nfs4_unlock_state();
2465 }
2466
2467 /*
2468  * END OF "GENERIC" ENCODE ROUTINES.
2469  */
2470
2471 int
2472 nfs4svc_encode_voidres(struct svc_rqst *rqstp, u32 *p, void *dummy)
2473 {
2474         return xdr_ressize_check(rqstp, p);
2475 }
2476
2477 void nfsd4_release_compoundargs(struct nfsd4_compoundargs *args)
2478 {
2479         if (args->ops != args->iops) {
2480                 kfree(args->ops);
2481                 args->ops = args->iops;
2482         }
2483         if (args->tmpp) {
2484                 kfree(args->tmpp);
2485                 args->tmpp = NULL;
2486         }
2487         while (args->to_free) {
2488                 struct tmpbuf *tb = args->to_free;
2489                 args->to_free = tb->next;
2490                 tb->release(tb->buf);
2491                 kfree(tb);
2492         }
2493 }
2494
2495 int
2496 nfs4svc_decode_compoundargs(struct svc_rqst *rqstp, u32 *p, struct nfsd4_compoundargs *args)
2497 {
2498         int status;
2499
2500         args->p = p;
2501         args->end = rqstp->rq_arg.head[0].iov_base + rqstp->rq_arg.head[0].iov_len;
2502         args->pagelist = rqstp->rq_arg.pages;
2503         args->pagelen = rqstp->rq_arg.page_len;
2504         args->tmpp = NULL;
2505         args->to_free = NULL;
2506         args->ops = args->iops;
2507         args->rqstp = rqstp;
2508
2509         status = nfsd4_decode_compound(args);
2510         if (status) {
2511                 nfsd4_release_compoundargs(args);
2512         }
2513         return !status;
2514 }
2515
2516 int
2517 nfs4svc_encode_compoundres(struct svc_rqst *rqstp, u32 *p, struct nfsd4_compoundres *resp)
2518 {
2519         /*
2520          * All that remains is to write the tag and operation count...
2521          */
2522         struct kvec *iov;
2523         p = resp->tagp;
2524         *p++ = htonl(resp->taglen);
2525         memcpy(p, resp->tag, resp->taglen);
2526         p += XDR_QUADLEN(resp->taglen);
2527         *p++ = htonl(resp->opcnt);
2528
2529         if (rqstp->rq_res.page_len) 
2530                 iov = &rqstp->rq_res.tail[0];
2531         else
2532                 iov = &rqstp->rq_res.head[0];
2533         iov->iov_len = ((char*)resp->p) - (char*)iov->iov_base;
2534         BUG_ON(iov->iov_len > PAGE_SIZE);
2535         return 1;
2536 }
2537
2538 /*
2539  * Local variables:
2540  *  c-basic-offset: 8
2541  * End:
2542  */