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