xref: /openbmc/linux/fs/nfsd/nfs4xdr.c (revision b04b4f78)
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 
2218 	exp_get(exp);
2219 	/*
2220 	 * In the case of a mountpoint, the client may be asking for
2221 	 * attributes that are only properties of the underlying filesystem
2222 	 * as opposed to the cross-mounted file system. In such a case,
2223 	 * we will not follow the cross mount and will fill the attribtutes
2224 	 * directly from the mountpoint dentry.
2225 	 */
2226 	if (d_mountpoint(dentry) && !attributes_need_mount(cd->rd_bmval))
2227 		ignore_crossmnt = 1;
2228 	else if (d_mountpoint(dentry)) {
2229 		int err;
2230 
2231 		/*
2232 		 * Why the heck aren't we just using nfsd_lookup??
2233 		 * Different "."/".." handling?  Something else?
2234 		 * At least, add a comment here to explain....
2235 		 */
2236 		err = nfsd_cross_mnt(cd->rd_rqstp, &dentry, &exp);
2237 		if (err) {
2238 			nfserr = nfserrno(err);
2239 			goto out_put;
2240 		}
2241 		nfserr = check_nfsd_access(exp, cd->rd_rqstp);
2242 		if (nfserr)
2243 			goto out_put;
2244 
2245 	}
2246 	nfserr = nfsd4_encode_fattr(NULL, exp, dentry, p, buflen, cd->rd_bmval,
2247 					cd->rd_rqstp, ignore_crossmnt);
2248 out_put:
2249 	dput(dentry);
2250 	exp_put(exp);
2251 	return nfserr;
2252 }
2253 
2254 static __be32 *
2255 nfsd4_encode_rdattr_error(__be32 *p, int buflen, __be32 nfserr)
2256 {
2257 	__be32 *attrlenp;
2258 
2259 	if (buflen < 6)
2260 		return NULL;
2261 	*p++ = htonl(2);
2262 	*p++ = htonl(FATTR4_WORD0_RDATTR_ERROR); /* bmval0 */
2263 	*p++ = htonl(0);			 /* bmval1 */
2264 
2265 	attrlenp = p++;
2266 	*p++ = nfserr;       /* no htonl */
2267 	*attrlenp = htonl((char *)p - (char *)attrlenp - 4);
2268 	return p;
2269 }
2270 
2271 static int
2272 nfsd4_encode_dirent(void *ccdv, const char *name, int namlen,
2273 		    loff_t offset, u64 ino, unsigned int d_type)
2274 {
2275 	struct readdir_cd *ccd = ccdv;
2276 	struct nfsd4_readdir *cd = container_of(ccd, struct nfsd4_readdir, common);
2277 	int buflen;
2278 	__be32 *p = cd->buffer;
2279 	__be32 nfserr = nfserr_toosmall;
2280 
2281 	/* In nfsv4, "." and ".." never make it onto the wire.. */
2282 	if (name && isdotent(name, namlen)) {
2283 		cd->common.err = nfs_ok;
2284 		return 0;
2285 	}
2286 
2287 	if (cd->offset)
2288 		xdr_encode_hyper(cd->offset, (u64) offset);
2289 
2290 	buflen = cd->buflen - 4 - XDR_QUADLEN(namlen);
2291 	if (buflen < 0)
2292 		goto fail;
2293 
2294 	*p++ = xdr_one;                             /* mark entry present */
2295 	cd->offset = p;                             /* remember pointer */
2296 	p = xdr_encode_hyper(p, NFS_OFFSET_MAX);    /* offset of next entry */
2297 	p = xdr_encode_array(p, name, namlen);      /* name length & name */
2298 
2299 	nfserr = nfsd4_encode_dirent_fattr(cd, name, namlen, p, &buflen);
2300 	switch (nfserr) {
2301 	case nfs_ok:
2302 		p += buflen;
2303 		break;
2304 	case nfserr_resource:
2305 		nfserr = nfserr_toosmall;
2306 		goto fail;
2307 	case nfserr_dropit:
2308 		goto fail;
2309 	default:
2310 		/*
2311 		 * If the client requested the RDATTR_ERROR attribute,
2312 		 * we stuff the error code into this attribute
2313 		 * and continue.  If this attribute was not requested,
2314 		 * then in accordance with the spec, we fail the
2315 		 * entire READDIR operation(!)
2316 		 */
2317 		if (!(cd->rd_bmval[0] & FATTR4_WORD0_RDATTR_ERROR))
2318 			goto fail;
2319 		p = nfsd4_encode_rdattr_error(p, buflen, nfserr);
2320 		if (p == NULL) {
2321 			nfserr = nfserr_toosmall;
2322 			goto fail;
2323 		}
2324 	}
2325 	cd->buflen -= (p - cd->buffer);
2326 	cd->buffer = p;
2327 	cd->common.err = nfs_ok;
2328 	return 0;
2329 fail:
2330 	cd->common.err = nfserr;
2331 	return -EINVAL;
2332 }
2333 
2334 static void
2335 nfsd4_encode_stateid(struct nfsd4_compoundres *resp, stateid_t *sid)
2336 {
2337 	ENCODE_HEAD;
2338 
2339 	RESERVE_SPACE(sizeof(stateid_t));
2340 	WRITE32(sid->si_generation);
2341 	WRITEMEM(&sid->si_opaque, sizeof(stateid_opaque_t));
2342 	ADJUST_ARGS();
2343 }
2344 
2345 static __be32
2346 nfsd4_encode_access(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_access *access)
2347 {
2348 	ENCODE_HEAD;
2349 
2350 	if (!nfserr) {
2351 		RESERVE_SPACE(8);
2352 		WRITE32(access->ac_supported);
2353 		WRITE32(access->ac_resp_access);
2354 		ADJUST_ARGS();
2355 	}
2356 	return nfserr;
2357 }
2358 
2359 static __be32
2360 nfsd4_encode_close(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_close *close)
2361 {
2362 	ENCODE_SEQID_OP_HEAD;
2363 
2364 	if (!nfserr)
2365 		nfsd4_encode_stateid(resp, &close->cl_stateid);
2366 
2367 	ENCODE_SEQID_OP_TAIL(close->cl_stateowner);
2368 	return nfserr;
2369 }
2370 
2371 
2372 static __be32
2373 nfsd4_encode_commit(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_commit *commit)
2374 {
2375 	ENCODE_HEAD;
2376 
2377 	if (!nfserr) {
2378 		RESERVE_SPACE(8);
2379 		WRITEMEM(commit->co_verf.data, 8);
2380 		ADJUST_ARGS();
2381 	}
2382 	return nfserr;
2383 }
2384 
2385 static __be32
2386 nfsd4_encode_create(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_create *create)
2387 {
2388 	ENCODE_HEAD;
2389 
2390 	if (!nfserr) {
2391 		RESERVE_SPACE(32);
2392 		WRITECINFO(create->cr_cinfo);
2393 		WRITE32(2);
2394 		WRITE32(create->cr_bmval[0]);
2395 		WRITE32(create->cr_bmval[1]);
2396 		ADJUST_ARGS();
2397 	}
2398 	return nfserr;
2399 }
2400 
2401 static __be32
2402 nfsd4_encode_getattr(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_getattr *getattr)
2403 {
2404 	struct svc_fh *fhp = getattr->ga_fhp;
2405 	int buflen;
2406 
2407 	if (nfserr)
2408 		return nfserr;
2409 
2410 	buflen = resp->end - resp->p - (COMPOUND_ERR_SLACK_SPACE >> 2);
2411 	nfserr = nfsd4_encode_fattr(fhp, fhp->fh_export, fhp->fh_dentry,
2412 				    resp->p, &buflen, getattr->ga_bmval,
2413 				    resp->rqstp, 0);
2414 	if (!nfserr)
2415 		resp->p += buflen;
2416 	return nfserr;
2417 }
2418 
2419 static __be32
2420 nfsd4_encode_getfh(struct nfsd4_compoundres *resp, __be32 nfserr, struct svc_fh **fhpp)
2421 {
2422 	struct svc_fh *fhp = *fhpp;
2423 	unsigned int len;
2424 	ENCODE_HEAD;
2425 
2426 	if (!nfserr) {
2427 		len = fhp->fh_handle.fh_size;
2428 		RESERVE_SPACE(len + 4);
2429 		WRITE32(len);
2430 		WRITEMEM(&fhp->fh_handle.fh_base, len);
2431 		ADJUST_ARGS();
2432 	}
2433 	return nfserr;
2434 }
2435 
2436 /*
2437 * Including all fields other than the name, a LOCK4denied structure requires
2438 *   8(clientid) + 4(namelen) + 8(offset) + 8(length) + 4(type) = 32 bytes.
2439 */
2440 static void
2441 nfsd4_encode_lock_denied(struct nfsd4_compoundres *resp, struct nfsd4_lock_denied *ld)
2442 {
2443 	ENCODE_HEAD;
2444 
2445 	RESERVE_SPACE(32 + XDR_LEN(ld->ld_sop ? ld->ld_sop->so_owner.len : 0));
2446 	WRITE64(ld->ld_start);
2447 	WRITE64(ld->ld_length);
2448 	WRITE32(ld->ld_type);
2449 	if (ld->ld_sop) {
2450 		WRITEMEM(&ld->ld_clientid, 8);
2451 		WRITE32(ld->ld_sop->so_owner.len);
2452 		WRITEMEM(ld->ld_sop->so_owner.data, ld->ld_sop->so_owner.len);
2453 		kref_put(&ld->ld_sop->so_ref, nfs4_free_stateowner);
2454 	}  else {  /* non - nfsv4 lock in conflict, no clientid nor owner */
2455 		WRITE64((u64)0); /* clientid */
2456 		WRITE32(0); /* length of owner name */
2457 	}
2458 	ADJUST_ARGS();
2459 }
2460 
2461 static __be32
2462 nfsd4_encode_lock(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_lock *lock)
2463 {
2464 	ENCODE_SEQID_OP_HEAD;
2465 
2466 	if (!nfserr)
2467 		nfsd4_encode_stateid(resp, &lock->lk_resp_stateid);
2468 	else if (nfserr == nfserr_denied)
2469 		nfsd4_encode_lock_denied(resp, &lock->lk_denied);
2470 
2471 	ENCODE_SEQID_OP_TAIL(lock->lk_replay_owner);
2472 	return nfserr;
2473 }
2474 
2475 static __be32
2476 nfsd4_encode_lockt(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_lockt *lockt)
2477 {
2478 	if (nfserr == nfserr_denied)
2479 		nfsd4_encode_lock_denied(resp, &lockt->lt_denied);
2480 	return nfserr;
2481 }
2482 
2483 static __be32
2484 nfsd4_encode_locku(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_locku *locku)
2485 {
2486 	ENCODE_SEQID_OP_HEAD;
2487 
2488 	if (!nfserr)
2489 		nfsd4_encode_stateid(resp, &locku->lu_stateid);
2490 
2491 	ENCODE_SEQID_OP_TAIL(locku->lu_stateowner);
2492 	return nfserr;
2493 }
2494 
2495 
2496 static __be32
2497 nfsd4_encode_link(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_link *link)
2498 {
2499 	ENCODE_HEAD;
2500 
2501 	if (!nfserr) {
2502 		RESERVE_SPACE(20);
2503 		WRITECINFO(link->li_cinfo);
2504 		ADJUST_ARGS();
2505 	}
2506 	return nfserr;
2507 }
2508 
2509 
2510 static __be32
2511 nfsd4_encode_open(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open *open)
2512 {
2513 	ENCODE_HEAD;
2514 	ENCODE_SEQID_OP_HEAD;
2515 
2516 	if (nfserr)
2517 		goto out;
2518 
2519 	nfsd4_encode_stateid(resp, &open->op_stateid);
2520 	RESERVE_SPACE(40);
2521 	WRITECINFO(open->op_cinfo);
2522 	WRITE32(open->op_rflags);
2523 	WRITE32(2);
2524 	WRITE32(open->op_bmval[0]);
2525 	WRITE32(open->op_bmval[1]);
2526 	WRITE32(open->op_delegate_type);
2527 	ADJUST_ARGS();
2528 
2529 	switch (open->op_delegate_type) {
2530 	case NFS4_OPEN_DELEGATE_NONE:
2531 		break;
2532 	case NFS4_OPEN_DELEGATE_READ:
2533 		nfsd4_encode_stateid(resp, &open->op_delegate_stateid);
2534 		RESERVE_SPACE(20);
2535 		WRITE32(open->op_recall);
2536 
2537 		/*
2538 		 * TODO: ACE's in delegations
2539 		 */
2540 		WRITE32(NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE);
2541 		WRITE32(0);
2542 		WRITE32(0);
2543 		WRITE32(0);   /* XXX: is NULL principal ok? */
2544 		ADJUST_ARGS();
2545 		break;
2546 	case NFS4_OPEN_DELEGATE_WRITE:
2547 		nfsd4_encode_stateid(resp, &open->op_delegate_stateid);
2548 		RESERVE_SPACE(32);
2549 		WRITE32(0);
2550 
2551 		/*
2552 		 * TODO: space_limit's in delegations
2553 		 */
2554 		WRITE32(NFS4_LIMIT_SIZE);
2555 		WRITE32(~(u32)0);
2556 		WRITE32(~(u32)0);
2557 
2558 		/*
2559 		 * TODO: ACE's in delegations
2560 		 */
2561 		WRITE32(NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE);
2562 		WRITE32(0);
2563 		WRITE32(0);
2564 		WRITE32(0);   /* XXX: is NULL principal ok? */
2565 		ADJUST_ARGS();
2566 		break;
2567 	default:
2568 		BUG();
2569 	}
2570 	/* XXX save filehandle here */
2571 out:
2572 	ENCODE_SEQID_OP_TAIL(open->op_stateowner);
2573 	return nfserr;
2574 }
2575 
2576 static __be32
2577 nfsd4_encode_open_confirm(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open_confirm *oc)
2578 {
2579 	ENCODE_SEQID_OP_HEAD;
2580 
2581 	if (!nfserr)
2582 		nfsd4_encode_stateid(resp, &oc->oc_resp_stateid);
2583 
2584 	ENCODE_SEQID_OP_TAIL(oc->oc_stateowner);
2585 	return nfserr;
2586 }
2587 
2588 static __be32
2589 nfsd4_encode_open_downgrade(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open_downgrade *od)
2590 {
2591 	ENCODE_SEQID_OP_HEAD;
2592 
2593 	if (!nfserr)
2594 		nfsd4_encode_stateid(resp, &od->od_stateid);
2595 
2596 	ENCODE_SEQID_OP_TAIL(od->od_stateowner);
2597 	return nfserr;
2598 }
2599 
2600 static __be32
2601 nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr,
2602 		  struct nfsd4_read *read)
2603 {
2604 	u32 eof;
2605 	int v, pn;
2606 	unsigned long maxcount;
2607 	long len;
2608 	ENCODE_HEAD;
2609 
2610 	if (nfserr)
2611 		return nfserr;
2612 	if (resp->xbuf->page_len)
2613 		return nfserr_resource;
2614 
2615 	RESERVE_SPACE(8); /* eof flag and byte count */
2616 
2617 	maxcount = svc_max_payload(resp->rqstp);
2618 	if (maxcount > read->rd_length)
2619 		maxcount = read->rd_length;
2620 
2621 	len = maxcount;
2622 	v = 0;
2623 	while (len > 0) {
2624 		pn = resp->rqstp->rq_resused++;
2625 		resp->rqstp->rq_vec[v].iov_base =
2626 			page_address(resp->rqstp->rq_respages[pn]);
2627 		resp->rqstp->rq_vec[v].iov_len =
2628 			len < PAGE_SIZE ? len : PAGE_SIZE;
2629 		v++;
2630 		len -= PAGE_SIZE;
2631 	}
2632 	read->rd_vlen = v;
2633 
2634 	nfserr = nfsd_read(read->rd_rqstp, read->rd_fhp, read->rd_filp,
2635 			read->rd_offset, resp->rqstp->rq_vec, read->rd_vlen,
2636 			&maxcount);
2637 
2638 	if (nfserr == nfserr_symlink)
2639 		nfserr = nfserr_inval;
2640 	if (nfserr)
2641 		return nfserr;
2642 	eof = (read->rd_offset + maxcount >=
2643 	       read->rd_fhp->fh_dentry->d_inode->i_size);
2644 
2645 	WRITE32(eof);
2646 	WRITE32(maxcount);
2647 	ADJUST_ARGS();
2648 	resp->xbuf->head[0].iov_len = (char*)p
2649 					- (char*)resp->xbuf->head[0].iov_base;
2650 	resp->xbuf->page_len = maxcount;
2651 
2652 	/* Use rest of head for padding and remaining ops: */
2653 	resp->xbuf->tail[0].iov_base = p;
2654 	resp->xbuf->tail[0].iov_len = 0;
2655 	if (maxcount&3) {
2656 		RESERVE_SPACE(4);
2657 		WRITE32(0);
2658 		resp->xbuf->tail[0].iov_base += maxcount&3;
2659 		resp->xbuf->tail[0].iov_len = 4 - (maxcount&3);
2660 		ADJUST_ARGS();
2661 	}
2662 	return 0;
2663 }
2664 
2665 static __be32
2666 nfsd4_encode_readlink(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_readlink *readlink)
2667 {
2668 	int maxcount;
2669 	char *page;
2670 	ENCODE_HEAD;
2671 
2672 	if (nfserr)
2673 		return nfserr;
2674 	if (resp->xbuf->page_len)
2675 		return nfserr_resource;
2676 
2677 	page = page_address(resp->rqstp->rq_respages[resp->rqstp->rq_resused++]);
2678 
2679 	maxcount = PAGE_SIZE;
2680 	RESERVE_SPACE(4);
2681 
2682 	/*
2683 	 * XXX: By default, the ->readlink() VFS op will truncate symlinks
2684 	 * if they would overflow the buffer.  Is this kosher in NFSv4?  If
2685 	 * not, one easy fix is: if ->readlink() precisely fills the buffer,
2686 	 * assume that truncation occurred, and return NFS4ERR_RESOURCE.
2687 	 */
2688 	nfserr = nfsd_readlink(readlink->rl_rqstp, readlink->rl_fhp, page, &maxcount);
2689 	if (nfserr == nfserr_isdir)
2690 		return nfserr_inval;
2691 	if (nfserr)
2692 		return nfserr;
2693 
2694 	WRITE32(maxcount);
2695 	ADJUST_ARGS();
2696 	resp->xbuf->head[0].iov_len = (char*)p
2697 				- (char*)resp->xbuf->head[0].iov_base;
2698 	resp->xbuf->page_len = maxcount;
2699 
2700 	/* Use rest of head for padding and remaining ops: */
2701 	resp->xbuf->tail[0].iov_base = p;
2702 	resp->xbuf->tail[0].iov_len = 0;
2703 	if (maxcount&3) {
2704 		RESERVE_SPACE(4);
2705 		WRITE32(0);
2706 		resp->xbuf->tail[0].iov_base += maxcount&3;
2707 		resp->xbuf->tail[0].iov_len = 4 - (maxcount&3);
2708 		ADJUST_ARGS();
2709 	}
2710 	return 0;
2711 }
2712 
2713 static __be32
2714 nfsd4_encode_readdir(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_readdir *readdir)
2715 {
2716 	int maxcount;
2717 	loff_t offset;
2718 	__be32 *page, *savep, *tailbase;
2719 	ENCODE_HEAD;
2720 
2721 	if (nfserr)
2722 		return nfserr;
2723 	if (resp->xbuf->page_len)
2724 		return nfserr_resource;
2725 
2726 	RESERVE_SPACE(8);  /* verifier */
2727 	savep = p;
2728 
2729 	/* XXX: Following NFSv3, we ignore the READDIR verifier for now. */
2730 	WRITE32(0);
2731 	WRITE32(0);
2732 	ADJUST_ARGS();
2733 	resp->xbuf->head[0].iov_len = ((char*)resp->p) - (char*)resp->xbuf->head[0].iov_base;
2734 	tailbase = p;
2735 
2736 	maxcount = PAGE_SIZE;
2737 	if (maxcount > readdir->rd_maxcount)
2738 		maxcount = readdir->rd_maxcount;
2739 
2740 	/*
2741 	 * Convert from bytes to words, account for the two words already
2742 	 * written, make sure to leave two words at the end for the next
2743 	 * pointer and eof field.
2744 	 */
2745 	maxcount = (maxcount >> 2) - 4;
2746 	if (maxcount < 0) {
2747 		nfserr =  nfserr_toosmall;
2748 		goto err_no_verf;
2749 	}
2750 
2751 	page = page_address(resp->rqstp->rq_respages[resp->rqstp->rq_resused++]);
2752 	readdir->common.err = 0;
2753 	readdir->buflen = maxcount;
2754 	readdir->buffer = page;
2755 	readdir->offset = NULL;
2756 
2757 	offset = readdir->rd_cookie;
2758 	nfserr = nfsd_readdir(readdir->rd_rqstp, readdir->rd_fhp,
2759 			      &offset,
2760 			      &readdir->common, nfsd4_encode_dirent);
2761 	if (nfserr == nfs_ok &&
2762 	    readdir->common.err == nfserr_toosmall &&
2763 	    readdir->buffer == page)
2764 		nfserr = nfserr_toosmall;
2765 	if (nfserr == nfserr_symlink)
2766 		nfserr = nfserr_notdir;
2767 	if (nfserr)
2768 		goto err_no_verf;
2769 
2770 	if (readdir->offset)
2771 		xdr_encode_hyper(readdir->offset, offset);
2772 
2773 	p = readdir->buffer;
2774 	*p++ = 0;	/* no more entries */
2775 	*p++ = htonl(readdir->common.err == nfserr_eof);
2776 	resp->xbuf->page_len = ((char*)p) - (char*)page_address(
2777 		resp->rqstp->rq_respages[resp->rqstp->rq_resused-1]);
2778 
2779 	/* Use rest of head for padding and remaining ops: */
2780 	resp->xbuf->tail[0].iov_base = tailbase;
2781 	resp->xbuf->tail[0].iov_len = 0;
2782 	resp->p = resp->xbuf->tail[0].iov_base;
2783 	resp->end = resp->p + (PAGE_SIZE - resp->xbuf->head[0].iov_len)/4;
2784 
2785 	return 0;
2786 err_no_verf:
2787 	p = savep;
2788 	ADJUST_ARGS();
2789 	return nfserr;
2790 }
2791 
2792 static __be32
2793 nfsd4_encode_remove(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_remove *remove)
2794 {
2795 	ENCODE_HEAD;
2796 
2797 	if (!nfserr) {
2798 		RESERVE_SPACE(20);
2799 		WRITECINFO(remove->rm_cinfo);
2800 		ADJUST_ARGS();
2801 	}
2802 	return nfserr;
2803 }
2804 
2805 static __be32
2806 nfsd4_encode_rename(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_rename *rename)
2807 {
2808 	ENCODE_HEAD;
2809 
2810 	if (!nfserr) {
2811 		RESERVE_SPACE(40);
2812 		WRITECINFO(rename->rn_sinfo);
2813 		WRITECINFO(rename->rn_tinfo);
2814 		ADJUST_ARGS();
2815 	}
2816 	return nfserr;
2817 }
2818 
2819 static __be32
2820 nfsd4_encode_secinfo(struct nfsd4_compoundres *resp, __be32 nfserr,
2821 		     struct nfsd4_secinfo *secinfo)
2822 {
2823 	int i = 0;
2824 	struct svc_export *exp = secinfo->si_exp;
2825 	u32 nflavs;
2826 	struct exp_flavor_info *flavs;
2827 	struct exp_flavor_info def_flavs[2];
2828 	ENCODE_HEAD;
2829 
2830 	if (nfserr)
2831 		goto out;
2832 	if (exp->ex_nflavors) {
2833 		flavs = exp->ex_flavors;
2834 		nflavs = exp->ex_nflavors;
2835 	} else { /* Handling of some defaults in absence of real secinfo: */
2836 		flavs = def_flavs;
2837 		if (exp->ex_client->flavour->flavour == RPC_AUTH_UNIX) {
2838 			nflavs = 2;
2839 			flavs[0].pseudoflavor = RPC_AUTH_UNIX;
2840 			flavs[1].pseudoflavor = RPC_AUTH_NULL;
2841 		} else if (exp->ex_client->flavour->flavour == RPC_AUTH_GSS) {
2842 			nflavs = 1;
2843 			flavs[0].pseudoflavor
2844 					= svcauth_gss_flavor(exp->ex_client);
2845 		} else {
2846 			nflavs = 1;
2847 			flavs[0].pseudoflavor
2848 					= exp->ex_client->flavour->flavour;
2849 		}
2850 	}
2851 
2852 	RESERVE_SPACE(4);
2853 	WRITE32(nflavs);
2854 	ADJUST_ARGS();
2855 	for (i = 0; i < nflavs; i++) {
2856 		u32 flav = flavs[i].pseudoflavor;
2857 		struct gss_api_mech *gm = gss_mech_get_by_pseudoflavor(flav);
2858 
2859 		if (gm) {
2860 			RESERVE_SPACE(4);
2861 			WRITE32(RPC_AUTH_GSS);
2862 			ADJUST_ARGS();
2863 			RESERVE_SPACE(4 + gm->gm_oid.len);
2864 			WRITE32(gm->gm_oid.len);
2865 			WRITEMEM(gm->gm_oid.data, gm->gm_oid.len);
2866 			ADJUST_ARGS();
2867 			RESERVE_SPACE(4);
2868 			WRITE32(0); /* qop */
2869 			ADJUST_ARGS();
2870 			RESERVE_SPACE(4);
2871 			WRITE32(gss_pseudoflavor_to_service(gm, flav));
2872 			ADJUST_ARGS();
2873 			gss_mech_put(gm);
2874 		} else {
2875 			RESERVE_SPACE(4);
2876 			WRITE32(flav);
2877 			ADJUST_ARGS();
2878 		}
2879 	}
2880 out:
2881 	if (exp)
2882 		exp_put(exp);
2883 	return nfserr;
2884 }
2885 
2886 /*
2887  * The SETATTR encode routine is special -- it always encodes a bitmap,
2888  * regardless of the error status.
2889  */
2890 static __be32
2891 nfsd4_encode_setattr(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_setattr *setattr)
2892 {
2893 	ENCODE_HEAD;
2894 
2895 	RESERVE_SPACE(12);
2896 	if (nfserr) {
2897 		WRITE32(2);
2898 		WRITE32(0);
2899 		WRITE32(0);
2900 	}
2901 	else {
2902 		WRITE32(2);
2903 		WRITE32(setattr->sa_bmval[0]);
2904 		WRITE32(setattr->sa_bmval[1]);
2905 	}
2906 	ADJUST_ARGS();
2907 	return nfserr;
2908 }
2909 
2910 static __be32
2911 nfsd4_encode_setclientid(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_setclientid *scd)
2912 {
2913 	ENCODE_HEAD;
2914 
2915 	if (!nfserr) {
2916 		RESERVE_SPACE(8 + sizeof(nfs4_verifier));
2917 		WRITEMEM(&scd->se_clientid, 8);
2918 		WRITEMEM(&scd->se_confirm, sizeof(nfs4_verifier));
2919 		ADJUST_ARGS();
2920 	}
2921 	else if (nfserr == nfserr_clid_inuse) {
2922 		RESERVE_SPACE(8);
2923 		WRITE32(0);
2924 		WRITE32(0);
2925 		ADJUST_ARGS();
2926 	}
2927 	return nfserr;
2928 }
2929 
2930 static __be32
2931 nfsd4_encode_write(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_write *write)
2932 {
2933 	ENCODE_HEAD;
2934 
2935 	if (!nfserr) {
2936 		RESERVE_SPACE(16);
2937 		WRITE32(write->wr_bytes_written);
2938 		WRITE32(write->wr_how_written);
2939 		WRITEMEM(write->wr_verifier.data, 8);
2940 		ADJUST_ARGS();
2941 	}
2942 	return nfserr;
2943 }
2944 
2945 static __be32
2946 nfsd4_encode_exchange_id(struct nfsd4_compoundres *resp, int nfserr,
2947 			 struct nfsd4_exchange_id *exid)
2948 {
2949 	ENCODE_HEAD;
2950 	char *major_id;
2951 	char *server_scope;
2952 	int major_id_sz;
2953 	int server_scope_sz;
2954 	uint64_t minor_id = 0;
2955 
2956 	if (nfserr)
2957 		return nfserr;
2958 
2959 	major_id = utsname()->nodename;
2960 	major_id_sz = strlen(major_id);
2961 	server_scope = utsname()->nodename;
2962 	server_scope_sz = strlen(server_scope);
2963 
2964 	RESERVE_SPACE(
2965 		8 /* eir_clientid */ +
2966 		4 /* eir_sequenceid */ +
2967 		4 /* eir_flags */ +
2968 		4 /* spr_how (SP4_NONE) */ +
2969 		8 /* so_minor_id */ +
2970 		4 /* so_major_id.len */ +
2971 		(XDR_QUADLEN(major_id_sz) * 4) +
2972 		4 /* eir_server_scope.len */ +
2973 		(XDR_QUADLEN(server_scope_sz) * 4) +
2974 		4 /* eir_server_impl_id.count (0) */);
2975 
2976 	WRITEMEM(&exid->clientid, 8);
2977 	WRITE32(exid->seqid);
2978 	WRITE32(exid->flags);
2979 
2980 	/* state_protect4_r. Currently only support SP4_NONE */
2981 	BUG_ON(exid->spa_how != SP4_NONE);
2982 	WRITE32(exid->spa_how);
2983 
2984 	/* The server_owner struct */
2985 	WRITE64(minor_id);      /* Minor id */
2986 	/* major id */
2987 	WRITE32(major_id_sz);
2988 	WRITEMEM(major_id, major_id_sz);
2989 
2990 	/* Server scope */
2991 	WRITE32(server_scope_sz);
2992 	WRITEMEM(server_scope, server_scope_sz);
2993 
2994 	/* Implementation id */
2995 	WRITE32(0);	/* zero length nfs_impl_id4 array */
2996 	ADJUST_ARGS();
2997 	return 0;
2998 }
2999 
3000 static __be32
3001 nfsd4_encode_create_session(struct nfsd4_compoundres *resp, int nfserr,
3002 			    struct nfsd4_create_session *sess)
3003 {
3004 	ENCODE_HEAD;
3005 
3006 	if (nfserr)
3007 		return nfserr;
3008 
3009 	RESERVE_SPACE(24);
3010 	WRITEMEM(sess->sessionid.data, NFS4_MAX_SESSIONID_LEN);
3011 	WRITE32(sess->seqid);
3012 	WRITE32(sess->flags);
3013 	ADJUST_ARGS();
3014 
3015 	RESERVE_SPACE(28);
3016 	WRITE32(0); /* headerpadsz */
3017 	WRITE32(sess->fore_channel.maxreq_sz);
3018 	WRITE32(sess->fore_channel.maxresp_sz);
3019 	WRITE32(sess->fore_channel.maxresp_cached);
3020 	WRITE32(sess->fore_channel.maxops);
3021 	WRITE32(sess->fore_channel.maxreqs);
3022 	WRITE32(sess->fore_channel.nr_rdma_attrs);
3023 	ADJUST_ARGS();
3024 
3025 	if (sess->fore_channel.nr_rdma_attrs) {
3026 		RESERVE_SPACE(4);
3027 		WRITE32(sess->fore_channel.rdma_attrs);
3028 		ADJUST_ARGS();
3029 	}
3030 
3031 	RESERVE_SPACE(28);
3032 	WRITE32(0); /* headerpadsz */
3033 	WRITE32(sess->back_channel.maxreq_sz);
3034 	WRITE32(sess->back_channel.maxresp_sz);
3035 	WRITE32(sess->back_channel.maxresp_cached);
3036 	WRITE32(sess->back_channel.maxops);
3037 	WRITE32(sess->back_channel.maxreqs);
3038 	WRITE32(sess->back_channel.nr_rdma_attrs);
3039 	ADJUST_ARGS();
3040 
3041 	if (sess->back_channel.nr_rdma_attrs) {
3042 		RESERVE_SPACE(4);
3043 		WRITE32(sess->back_channel.rdma_attrs);
3044 		ADJUST_ARGS();
3045 	}
3046 	return 0;
3047 }
3048 
3049 static __be32
3050 nfsd4_encode_destroy_session(struct nfsd4_compoundres *resp, int nfserr,
3051 			     struct nfsd4_destroy_session *destroy_session)
3052 {
3053 	return nfserr;
3054 }
3055 
3056 __be32
3057 nfsd4_encode_sequence(struct nfsd4_compoundres *resp, int nfserr,
3058 		      struct nfsd4_sequence *seq)
3059 {
3060 	ENCODE_HEAD;
3061 
3062 	if (nfserr)
3063 		return nfserr;
3064 
3065 	RESERVE_SPACE(NFS4_MAX_SESSIONID_LEN + 20);
3066 	WRITEMEM(seq->sessionid.data, NFS4_MAX_SESSIONID_LEN);
3067 	WRITE32(seq->seqid);
3068 	WRITE32(seq->slotid);
3069 	WRITE32(seq->maxslots);
3070 	/*
3071 	 * FIXME: for now:
3072 	 *   target_maxslots = maxslots
3073 	 *   status_flags = 0
3074 	 */
3075 	WRITE32(seq->maxslots);
3076 	WRITE32(0);
3077 
3078 	ADJUST_ARGS();
3079 	return 0;
3080 }
3081 
3082 static __be32
3083 nfsd4_encode_noop(struct nfsd4_compoundres *resp, __be32 nfserr, void *p)
3084 {
3085 	return nfserr;
3086 }
3087 
3088 typedef __be32(* nfsd4_enc)(struct nfsd4_compoundres *, __be32, void *);
3089 
3090 /*
3091  * Note: nfsd4_enc_ops vector is shared for v4.0 and v4.1
3092  * since we don't need to filter out obsolete ops as this is
3093  * done in the decoding phase.
3094  */
3095 static nfsd4_enc nfsd4_enc_ops[] = {
3096 	[OP_ACCESS]		= (nfsd4_enc)nfsd4_encode_access,
3097 	[OP_CLOSE]		= (nfsd4_enc)nfsd4_encode_close,
3098 	[OP_COMMIT]		= (nfsd4_enc)nfsd4_encode_commit,
3099 	[OP_CREATE]		= (nfsd4_enc)nfsd4_encode_create,
3100 	[OP_DELEGPURGE]		= (nfsd4_enc)nfsd4_encode_noop,
3101 	[OP_DELEGRETURN]	= (nfsd4_enc)nfsd4_encode_noop,
3102 	[OP_GETATTR]		= (nfsd4_enc)nfsd4_encode_getattr,
3103 	[OP_GETFH]		= (nfsd4_enc)nfsd4_encode_getfh,
3104 	[OP_LINK]		= (nfsd4_enc)nfsd4_encode_link,
3105 	[OP_LOCK]		= (nfsd4_enc)nfsd4_encode_lock,
3106 	[OP_LOCKT]		= (nfsd4_enc)nfsd4_encode_lockt,
3107 	[OP_LOCKU]		= (nfsd4_enc)nfsd4_encode_locku,
3108 	[OP_LOOKUP]		= (nfsd4_enc)nfsd4_encode_noop,
3109 	[OP_LOOKUPP]		= (nfsd4_enc)nfsd4_encode_noop,
3110 	[OP_NVERIFY]		= (nfsd4_enc)nfsd4_encode_noop,
3111 	[OP_OPEN]		= (nfsd4_enc)nfsd4_encode_open,
3112 	[OP_OPENATTR]		= (nfsd4_enc)nfsd4_encode_noop,
3113 	[OP_OPEN_CONFIRM]	= (nfsd4_enc)nfsd4_encode_open_confirm,
3114 	[OP_OPEN_DOWNGRADE]	= (nfsd4_enc)nfsd4_encode_open_downgrade,
3115 	[OP_PUTFH]		= (nfsd4_enc)nfsd4_encode_noop,
3116 	[OP_PUTPUBFH]		= (nfsd4_enc)nfsd4_encode_noop,
3117 	[OP_PUTROOTFH]		= (nfsd4_enc)nfsd4_encode_noop,
3118 	[OP_READ]		= (nfsd4_enc)nfsd4_encode_read,
3119 	[OP_READDIR]		= (nfsd4_enc)nfsd4_encode_readdir,
3120 	[OP_READLINK]		= (nfsd4_enc)nfsd4_encode_readlink,
3121 	[OP_REMOVE]		= (nfsd4_enc)nfsd4_encode_remove,
3122 	[OP_RENAME]		= (nfsd4_enc)nfsd4_encode_rename,
3123 	[OP_RENEW]		= (nfsd4_enc)nfsd4_encode_noop,
3124 	[OP_RESTOREFH]		= (nfsd4_enc)nfsd4_encode_noop,
3125 	[OP_SAVEFH]		= (nfsd4_enc)nfsd4_encode_noop,
3126 	[OP_SECINFO]		= (nfsd4_enc)nfsd4_encode_secinfo,
3127 	[OP_SETATTR]		= (nfsd4_enc)nfsd4_encode_setattr,
3128 	[OP_SETCLIENTID]	= (nfsd4_enc)nfsd4_encode_setclientid,
3129 	[OP_SETCLIENTID_CONFIRM] = (nfsd4_enc)nfsd4_encode_noop,
3130 	[OP_VERIFY]		= (nfsd4_enc)nfsd4_encode_noop,
3131 	[OP_WRITE]		= (nfsd4_enc)nfsd4_encode_write,
3132 	[OP_RELEASE_LOCKOWNER]	= (nfsd4_enc)nfsd4_encode_noop,
3133 
3134 	/* NFSv4.1 operations */
3135 	[OP_BACKCHANNEL_CTL]	= (nfsd4_enc)nfsd4_encode_noop,
3136 	[OP_BIND_CONN_TO_SESSION] = (nfsd4_enc)nfsd4_encode_noop,
3137 	[OP_EXCHANGE_ID]	= (nfsd4_enc)nfsd4_encode_exchange_id,
3138 	[OP_CREATE_SESSION]	= (nfsd4_enc)nfsd4_encode_create_session,
3139 	[OP_DESTROY_SESSION]	= (nfsd4_enc)nfsd4_encode_destroy_session,
3140 	[OP_FREE_STATEID]	= (nfsd4_enc)nfsd4_encode_noop,
3141 	[OP_GET_DIR_DELEGATION]	= (nfsd4_enc)nfsd4_encode_noop,
3142 	[OP_GETDEVICEINFO]	= (nfsd4_enc)nfsd4_encode_noop,
3143 	[OP_GETDEVICELIST]	= (nfsd4_enc)nfsd4_encode_noop,
3144 	[OP_LAYOUTCOMMIT]	= (nfsd4_enc)nfsd4_encode_noop,
3145 	[OP_LAYOUTGET]		= (nfsd4_enc)nfsd4_encode_noop,
3146 	[OP_LAYOUTRETURN]	= (nfsd4_enc)nfsd4_encode_noop,
3147 	[OP_SECINFO_NO_NAME]	= (nfsd4_enc)nfsd4_encode_noop,
3148 	[OP_SEQUENCE]		= (nfsd4_enc)nfsd4_encode_sequence,
3149 	[OP_SET_SSV]		= (nfsd4_enc)nfsd4_encode_noop,
3150 	[OP_TEST_STATEID]	= (nfsd4_enc)nfsd4_encode_noop,
3151 	[OP_WANT_DELEGATION]	= (nfsd4_enc)nfsd4_encode_noop,
3152 	[OP_DESTROY_CLIENTID]	= (nfsd4_enc)nfsd4_encode_noop,
3153 	[OP_RECLAIM_COMPLETE]	= (nfsd4_enc)nfsd4_encode_noop,
3154 };
3155 
3156 /*
3157  * Calculate the total amount of memory that the compound response has taken
3158  * after encoding the current operation.
3159  *
3160  * pad: add on 8 bytes for the next operation's op_code and status so that
3161  * there is room to cache a failure on the next operation.
3162  *
3163  * Compare this length to the session se_fmaxresp_cached.
3164  *
3165  * Our se_fmaxresp_cached will always be a multiple of PAGE_SIZE, and so
3166  * will be at least a page and will therefore hold the xdr_buf head.
3167  */
3168 static int nfsd4_check_drc_limit(struct nfsd4_compoundres *resp)
3169 {
3170 	int status = 0;
3171 	struct xdr_buf *xb = &resp->rqstp->rq_res;
3172 	struct nfsd4_compoundargs *args = resp->rqstp->rq_argp;
3173 	struct nfsd4_session *session = NULL;
3174 	struct nfsd4_slot *slot = resp->cstate.slot;
3175 	u32 length, tlen = 0, pad = 8;
3176 
3177 	if (!nfsd4_has_session(&resp->cstate))
3178 		return status;
3179 
3180 	session = resp->cstate.session;
3181 	if (session == NULL || slot->sl_cache_entry.ce_cachethis == 0)
3182 		return status;
3183 
3184 	if (resp->opcnt >= args->opcnt)
3185 		pad = 0; /* this is the last operation */
3186 
3187 	if (xb->page_len == 0) {
3188 		length = (char *)resp->p - (char *)xb->head[0].iov_base + pad;
3189 	} else {
3190 		if (xb->tail[0].iov_base && xb->tail[0].iov_len > 0)
3191 			tlen = (char *)resp->p - (char *)xb->tail[0].iov_base;
3192 
3193 		length = xb->head[0].iov_len + xb->page_len + tlen + pad;
3194 	}
3195 	dprintk("%s length %u, xb->page_len %u tlen %u pad %u\n", __func__,
3196 		length, xb->page_len, tlen, pad);
3197 
3198 	if (length <= session->se_fmaxresp_cached)
3199 		return status;
3200 	else
3201 		return nfserr_rep_too_big_to_cache;
3202 }
3203 
3204 void
3205 nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op)
3206 {
3207 	__be32 *statp;
3208 	ENCODE_HEAD;
3209 
3210 	RESERVE_SPACE(8);
3211 	WRITE32(op->opnum);
3212 	statp = p++;	/* to be backfilled at the end */
3213 	ADJUST_ARGS();
3214 
3215 	if (op->opnum == OP_ILLEGAL)
3216 		goto status;
3217 	BUG_ON(op->opnum < 0 || op->opnum >= ARRAY_SIZE(nfsd4_enc_ops) ||
3218 	       !nfsd4_enc_ops[op->opnum]);
3219 	op->status = nfsd4_enc_ops[op->opnum](resp, op->status, &op->u);
3220 	/* nfsd4_check_drc_limit guarantees enough room for error status */
3221 	if (!op->status && nfsd4_check_drc_limit(resp))
3222 		op->status = nfserr_rep_too_big_to_cache;
3223 status:
3224 	/*
3225 	 * Note: We write the status directly, instead of using WRITE32(),
3226 	 * since it is already in network byte order.
3227 	 */
3228 	*statp = op->status;
3229 }
3230 
3231 /*
3232  * Encode the reply stored in the stateowner reply cache
3233  *
3234  * XDR note: do not encode rp->rp_buflen: the buffer contains the
3235  * previously sent already encoded operation.
3236  *
3237  * called with nfs4_lock_state() held
3238  */
3239 void
3240 nfsd4_encode_replay(struct nfsd4_compoundres *resp, struct nfsd4_op *op)
3241 {
3242 	ENCODE_HEAD;
3243 	struct nfs4_replay *rp = op->replay;
3244 
3245 	BUG_ON(!rp);
3246 
3247 	RESERVE_SPACE(8);
3248 	WRITE32(op->opnum);
3249 	*p++ = rp->rp_status;  /* already xdr'ed */
3250 	ADJUST_ARGS();
3251 
3252 	RESERVE_SPACE(rp->rp_buflen);
3253 	WRITEMEM(rp->rp_buf, rp->rp_buflen);
3254 	ADJUST_ARGS();
3255 }
3256 
3257 /*
3258  * END OF "GENERIC" ENCODE ROUTINES.
3259  */
3260 
3261 int
3262 nfs4svc_encode_voidres(struct svc_rqst *rqstp, __be32 *p, void *dummy)
3263 {
3264         return xdr_ressize_check(rqstp, p);
3265 }
3266 
3267 void nfsd4_release_compoundargs(struct nfsd4_compoundargs *args)
3268 {
3269 	if (args->ops != args->iops) {
3270 		kfree(args->ops);
3271 		args->ops = args->iops;
3272 	}
3273 	kfree(args->tmpp);
3274 	args->tmpp = NULL;
3275 	while (args->to_free) {
3276 		struct tmpbuf *tb = args->to_free;
3277 		args->to_free = tb->next;
3278 		tb->release(tb->buf);
3279 		kfree(tb);
3280 	}
3281 }
3282 
3283 int
3284 nfs4svc_decode_compoundargs(struct svc_rqst *rqstp, __be32 *p, struct nfsd4_compoundargs *args)
3285 {
3286 	__be32 status;
3287 
3288 	args->p = p;
3289 	args->end = rqstp->rq_arg.head[0].iov_base + rqstp->rq_arg.head[0].iov_len;
3290 	args->pagelist = rqstp->rq_arg.pages;
3291 	args->pagelen = rqstp->rq_arg.page_len;
3292 	args->tmpp = NULL;
3293 	args->to_free = NULL;
3294 	args->ops = args->iops;
3295 	args->rqstp = rqstp;
3296 
3297 	status = nfsd4_decode_compound(args);
3298 	if (status) {
3299 		nfsd4_release_compoundargs(args);
3300 	}
3301 	return !status;
3302 }
3303 
3304 int
3305 nfs4svc_encode_compoundres(struct svc_rqst *rqstp, __be32 *p, struct nfsd4_compoundres *resp)
3306 {
3307 	/*
3308 	 * All that remains is to write the tag and operation count...
3309 	 */
3310 	struct kvec *iov;
3311 	p = resp->tagp;
3312 	*p++ = htonl(resp->taglen);
3313 	memcpy(p, resp->tag, resp->taglen);
3314 	p += XDR_QUADLEN(resp->taglen);
3315 	*p++ = htonl(resp->opcnt);
3316 
3317 	if (rqstp->rq_res.page_len)
3318 		iov = &rqstp->rq_res.tail[0];
3319 	else
3320 		iov = &rqstp->rq_res.head[0];
3321 	iov->iov_len = ((char*)resp->p) - (char*)iov->iov_base;
3322 	BUG_ON(iov->iov_len > PAGE_SIZE);
3323 	if (nfsd4_has_session(&resp->cstate)) {
3324 		if (resp->cstate.status == nfserr_replay_cache &&
3325 				!nfsd4_not_cached(resp)) {
3326 			iov->iov_len = resp->cstate.iovlen;
3327 		} else {
3328 			nfsd4_store_cache_entry(resp);
3329 			dprintk("%s: SET SLOT STATE TO AVAILABLE\n", __func__);
3330 			resp->cstate.slot->sl_inuse = 0;
3331 		}
3332 		if (resp->cstate.session)
3333 			nfsd4_put_session(resp->cstate.session);
3334 	}
3335 	return 1;
3336 }
3337 
3338 /*
3339  * Local variables:
3340  *  c-basic-offset: 8
3341  * End:
3342  */
3343