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