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