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