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
36#include <linux/slab.h>
37#include <linux/namei.h>
38#include <linux/statfs.h>
39#include <linux/utsname.h>
40#include <linux/pagemap.h>
41#include <linux/sunrpc/svcauth_gss.h>
42
43#include "idmap.h"
44#include "acl.h"
45#include "xdr4.h"
46#include "vfs.h"
47#include "state.h"
48#include "cache.h"
49#include "netns.h"
50#include "pnfs.h"
51
52#ifdef CONFIG_NFSD_V4_SECURITY_LABEL
53#include <linux/security.h>
54#endif
55
56
57#define NFSDDBG_FACILITY		NFSDDBG_XDR
58
59/*
60 * As per referral draft, the fsid for a referral MUST be different from the fsid of the containing
61 * directory in order to indicate to the client that a filesystem boundary is present
62 * We use a fixed fsid for a referral
63 */
64#define NFS4_REFERRAL_FSID_MAJOR	0x8000000ULL
65#define NFS4_REFERRAL_FSID_MINOR	0x8000000ULL
66
67static __be32
68check_filename(char *str, int len)
69{
70	int i;
71
72	if (len == 0)
73		return nfserr_inval;
74	if (isdotent(str, len))
75		return nfserr_badname;
76	for (i = 0; i < len; i++)
77		if (str[i] == '/')
78			return nfserr_badname;
79	return 0;
80}
81
82#define DECODE_HEAD				\
83	__be32 *p;				\
84	__be32 status
85#define DECODE_TAIL				\
86	status = 0;				\
87out:						\
88	return status;				\
89xdr_error:					\
90	dprintk("NFSD: xdr error (%s:%d)\n",	\
91			__FILE__, __LINE__);	\
92	status = nfserr_bad_xdr;		\
93	goto out
94
95#define READMEM(x,nbytes) do {			\
96	x = (char *)p;				\
97	p += XDR_QUADLEN(nbytes);		\
98} while (0)
99#define SAVEMEM(x,nbytes) do {			\
100	if (!(x = (p==argp->tmp || p == argp->tmpp) ? \
101 		savemem(argp, p, nbytes) :	\
102 		(char *)p)) {			\
103		dprintk("NFSD: xdr error (%s:%d)\n", \
104				__FILE__, __LINE__); \
105		goto xdr_error;			\
106		}				\
107	p += XDR_QUADLEN(nbytes);		\
108} while (0)
109#define COPYMEM(x,nbytes) do {			\
110	memcpy((x), p, nbytes);			\
111	p += XDR_QUADLEN(nbytes);		\
112} while (0)
113
114/* READ_BUF, read_buf(): nbytes must be <= PAGE_SIZE */
115#define READ_BUF(nbytes)  do {			\
116	if (nbytes <= (u32)((char *)argp->end - (char *)argp->p)) {	\
117		p = argp->p;			\
118		argp->p += XDR_QUADLEN(nbytes);	\
119	} else if (!(p = read_buf(argp, nbytes))) { \
120		dprintk("NFSD: xdr error (%s:%d)\n", \
121				__FILE__, __LINE__); \
122		goto xdr_error;			\
123	}					\
124} while (0)
125
126static void next_decode_page(struct nfsd4_compoundargs *argp)
127{
128	argp->p = page_address(argp->pagelist[0]);
129	argp->pagelist++;
130	if (argp->pagelen < PAGE_SIZE) {
131		argp->end = argp->p + (argp->pagelen>>2);
132		argp->pagelen = 0;
133	} else {
134		argp->end = argp->p + (PAGE_SIZE>>2);
135		argp->pagelen -= PAGE_SIZE;
136	}
137}
138
139static __be32 *read_buf(struct nfsd4_compoundargs *argp, u32 nbytes)
140{
141	/* We want more bytes than seem to be available.
142	 * Maybe we need a new page, maybe we have just run out
143	 */
144	unsigned int avail = (char *)argp->end - (char *)argp->p;
145	__be32 *p;
146	if (avail + argp->pagelen < nbytes)
147		return NULL;
148	if (avail + PAGE_SIZE < nbytes) /* need more than a page !! */
149		return NULL;
150	/* ok, we can do it with the current plus the next page */
151	if (nbytes <= sizeof(argp->tmp))
152		p = argp->tmp;
153	else {
154		kfree(argp->tmpp);
155		p = argp->tmpp = kmalloc(nbytes, GFP_KERNEL);
156		if (!p)
157			return NULL;
158
159	}
160	/*
161	 * The following memcpy is safe because read_buf is always
162	 * called with nbytes > avail, and the two cases above both
163	 * guarantee p points to at least nbytes bytes.
164	 */
165	memcpy(p, argp->p, avail);
166	next_decode_page(argp);
167	memcpy(((char*)p)+avail, argp->p, (nbytes - avail));
168	argp->p += XDR_QUADLEN(nbytes - avail);
169	return p;
170}
171
172static int zero_clientid(clientid_t *clid)
173{
174	return (clid->cl_boot == 0) && (clid->cl_id == 0);
175}
176
177/**
178 * svcxdr_tmpalloc - allocate memory to be freed after compound processing
179 * @argp: NFSv4 compound argument structure
180 * @p: pointer to be freed (with kfree())
181 *
182 * Marks @p to be freed when processing the compound operation
183 * described in @argp finishes.
184 */
185static void *
186svcxdr_tmpalloc(struct nfsd4_compoundargs *argp, u32 len)
187{
188	struct svcxdr_tmpbuf *tb;
189
190	tb = kmalloc(sizeof(*tb) + len, GFP_KERNEL);
191	if (!tb)
192		return NULL;
193	tb->next = argp->to_free;
194	argp->to_free = tb;
195	return tb->buf;
196}
197
198/*
199 * For xdr strings that need to be passed to other kernel api's
200 * as null-terminated strings.
201 *
202 * Note null-terminating in place usually isn't safe since the
203 * buffer might end on a page boundary.
204 */
205static char *
206svcxdr_dupstr(struct nfsd4_compoundargs *argp, void *buf, u32 len)
207{
208	char *p = svcxdr_tmpalloc(argp, len + 1);
209
210	if (!p)
211		return NULL;
212	memcpy(p, buf, len);
213	p[len] = '\0';
214	return p;
215}
216
217/**
218 * savemem - duplicate a chunk of memory for later processing
219 * @argp: NFSv4 compound argument structure to be freed with
220 * @p: pointer to be duplicated
221 * @nbytes: length to be duplicated
222 *
223 * Returns a pointer to a copy of @nbytes bytes of memory at @p
224 * that are preserved until processing of the NFSv4 compound
225 * operation described by @argp finishes.
226 */
227static char *savemem(struct nfsd4_compoundargs *argp, __be32 *p, int nbytes)
228{
229	void *ret;
230
231	ret = svcxdr_tmpalloc(argp, nbytes);
232	if (!ret)
233		return NULL;
234	memcpy(ret, p, nbytes);
235	return ret;
236}
237
238/*
239 * We require the high 32 bits of 'seconds' to be 0, and
240 * we ignore all 32 bits of 'nseconds'.
241 */
242static __be32
243nfsd4_decode_time(struct nfsd4_compoundargs *argp, struct timespec *tv)
244{
245	DECODE_HEAD;
246	u64 sec;
247
248	READ_BUF(12);
249	p = xdr_decode_hyper(p, &sec);
250	tv->tv_sec = sec;
251	tv->tv_nsec = be32_to_cpup(p++);
252	if (tv->tv_nsec >= (u32)1000000000)
253		return nfserr_inval;
254
255	DECODE_TAIL;
256}
257
258static __be32
259nfsd4_decode_bitmap(struct nfsd4_compoundargs *argp, u32 *bmval)
260{
261	u32 bmlen;
262	DECODE_HEAD;
263
264	bmval[0] = 0;
265	bmval[1] = 0;
266	bmval[2] = 0;
267
268	READ_BUF(4);
269	bmlen = be32_to_cpup(p++);
270	if (bmlen > 1000)
271		goto xdr_error;
272
273	READ_BUF(bmlen << 2);
274	if (bmlen > 0)
275		bmval[0] = be32_to_cpup(p++);
276	if (bmlen > 1)
277		bmval[1] = be32_to_cpup(p++);
278	if (bmlen > 2)
279		bmval[2] = be32_to_cpup(p++);
280
281	DECODE_TAIL;
282}
283
284static __be32
285nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
286		   struct iattr *iattr, struct nfs4_acl **acl,
287		   struct xdr_netobj *label)
288{
289	int expected_len, len = 0;
290	u32 dummy32;
291	char *buf;
292
293	DECODE_HEAD;
294	iattr->ia_valid = 0;
295	if ((status = nfsd4_decode_bitmap(argp, bmval)))
296		return status;
297
298	READ_BUF(4);
299	expected_len = be32_to_cpup(p++);
300
301	if (bmval[0] & FATTR4_WORD0_SIZE) {
302		READ_BUF(8);
303		len += 8;
304		p = xdr_decode_hyper(p, &iattr->ia_size);
305		iattr->ia_valid |= ATTR_SIZE;
306	}
307	if (bmval[0] & FATTR4_WORD0_ACL) {
308		u32 nace;
309		struct nfs4_ace *ace;
310
311		READ_BUF(4); len += 4;
312		nace = be32_to_cpup(p++);
313
314		if (nace > NFS4_ACL_MAX)
315			return nfserr_fbig;
316
317		*acl = svcxdr_tmpalloc(argp, nfs4_acl_bytes(nace));
318		if (*acl == NULL)
319			return nfserr_jukebox;
320
321		(*acl)->naces = nace;
322		for (ace = (*acl)->aces; ace < (*acl)->aces + nace; ace++) {
323			READ_BUF(16); len += 16;
324			ace->type = be32_to_cpup(p++);
325			ace->flag = be32_to_cpup(p++);
326			ace->access_mask = be32_to_cpup(p++);
327			dummy32 = be32_to_cpup(p++);
328			READ_BUF(dummy32);
329			len += XDR_QUADLEN(dummy32) << 2;
330			READMEM(buf, dummy32);
331			ace->whotype = nfs4_acl_get_whotype(buf, dummy32);
332			status = nfs_ok;
333			if (ace->whotype != NFS4_ACL_WHO_NAMED)
334				;
335			else if (ace->flag & NFS4_ACE_IDENTIFIER_GROUP)
336				status = nfsd_map_name_to_gid(argp->rqstp,
337						buf, dummy32, &ace->who_gid);
338			else
339				status = nfsd_map_name_to_uid(argp->rqstp,
340						buf, dummy32, &ace->who_uid);
341			if (status)
342				return status;
343		}
344	} else
345		*acl = NULL;
346	if (bmval[1] & FATTR4_WORD1_MODE) {
347		READ_BUF(4);
348		len += 4;
349		iattr->ia_mode = be32_to_cpup(p++);
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		dummy32 = be32_to_cpup(p++);
357		READ_BUF(dummy32);
358		len += (XDR_QUADLEN(dummy32) << 2);
359		READMEM(buf, dummy32);
360		if ((status = nfsd_map_name_to_uid(argp->rqstp, buf, dummy32, &iattr->ia_uid)))
361			return status;
362		iattr->ia_valid |= ATTR_UID;
363	}
364	if (bmval[1] & FATTR4_WORD1_OWNER_GROUP) {
365		READ_BUF(4);
366		len += 4;
367		dummy32 = be32_to_cpup(p++);
368		READ_BUF(dummy32);
369		len += (XDR_QUADLEN(dummy32) << 2);
370		READMEM(buf, dummy32);
371		if ((status = nfsd_map_name_to_gid(argp->rqstp, buf, dummy32, &iattr->ia_gid)))
372			return status;
373		iattr->ia_valid |= ATTR_GID;
374	}
375	if (bmval[1] & FATTR4_WORD1_TIME_ACCESS_SET) {
376		READ_BUF(4);
377		len += 4;
378		dummy32 = be32_to_cpup(p++);
379		switch (dummy32) {
380		case NFS4_SET_TO_CLIENT_TIME:
381			len += 12;
382			status = nfsd4_decode_time(argp, &iattr->ia_atime);
383			if (status)
384				return status;
385			iattr->ia_valid |= (ATTR_ATIME | ATTR_ATIME_SET);
386			break;
387		case NFS4_SET_TO_SERVER_TIME:
388			iattr->ia_valid |= ATTR_ATIME;
389			break;
390		default:
391			goto xdr_error;
392		}
393	}
394	if (bmval[1] & FATTR4_WORD1_TIME_MODIFY_SET) {
395		READ_BUF(4);
396		len += 4;
397		dummy32 = be32_to_cpup(p++);
398		switch (dummy32) {
399		case NFS4_SET_TO_CLIENT_TIME:
400			len += 12;
401			status = nfsd4_decode_time(argp, &iattr->ia_mtime);
402			if (status)
403				return status;
404			iattr->ia_valid |= (ATTR_MTIME | ATTR_MTIME_SET);
405			break;
406		case NFS4_SET_TO_SERVER_TIME:
407			iattr->ia_valid |= ATTR_MTIME;
408			break;
409		default:
410			goto xdr_error;
411		}
412	}
413
414	label->len = 0;
415#ifdef CONFIG_NFSD_V4_SECURITY_LABEL
416	if (bmval[2] & FATTR4_WORD2_SECURITY_LABEL) {
417		READ_BUF(4);
418		len += 4;
419		dummy32 = be32_to_cpup(p++); /* lfs: we don't use it */
420		READ_BUF(4);
421		len += 4;
422		dummy32 = be32_to_cpup(p++); /* pi: we don't use it either */
423		READ_BUF(4);
424		len += 4;
425		dummy32 = be32_to_cpup(p++);
426		READ_BUF(dummy32);
427		if (dummy32 > NFS4_MAXLABELLEN)
428			return nfserr_badlabel;
429		len += (XDR_QUADLEN(dummy32) << 2);
430		READMEM(buf, dummy32);
431		label->len = dummy32;
432		label->data = svcxdr_dupstr(argp, buf, dummy32);
433		if (!label->data)
434			return nfserr_jukebox;
435	}
436#endif
437
438	if (bmval[0] & ~NFSD_WRITEABLE_ATTRS_WORD0
439	    || bmval[1] & ~NFSD_WRITEABLE_ATTRS_WORD1
440	    || bmval[2] & ~NFSD_WRITEABLE_ATTRS_WORD2)
441		READ_BUF(expected_len - len);
442	else if (len != expected_len)
443		goto xdr_error;
444
445	DECODE_TAIL;
446}
447
448static __be32
449nfsd4_decode_stateid(struct nfsd4_compoundargs *argp, stateid_t *sid)
450{
451	DECODE_HEAD;
452
453	READ_BUF(sizeof(stateid_t));
454	sid->si_generation = be32_to_cpup(p++);
455	COPYMEM(&sid->si_opaque, sizeof(stateid_opaque_t));
456
457	DECODE_TAIL;
458}
459
460static __be32
461nfsd4_decode_access(struct nfsd4_compoundargs *argp, struct nfsd4_access *access)
462{
463	DECODE_HEAD;
464
465	READ_BUF(4);
466	access->ac_req_access = be32_to_cpup(p++);
467
468	DECODE_TAIL;
469}
470
471static __be32 nfsd4_decode_cb_sec(struct nfsd4_compoundargs *argp, struct nfsd4_cb_sec *cbs)
472{
473	DECODE_HEAD;
474	u32 dummy, uid, gid;
475	char *machine_name;
476	int i;
477	int nr_secflavs;
478
479	/* callback_sec_params4 */
480	READ_BUF(4);
481	nr_secflavs = be32_to_cpup(p++);
482	if (nr_secflavs)
483		cbs->flavor = (u32)(-1);
484	else
485		/* Is this legal? Be generous, take it to mean AUTH_NONE: */
486		cbs->flavor = 0;
487	for (i = 0; i < nr_secflavs; ++i) {
488		READ_BUF(4);
489		dummy = be32_to_cpup(p++);
490		switch (dummy) {
491		case RPC_AUTH_NULL:
492			/* Nothing to read */
493			if (cbs->flavor == (u32)(-1))
494				cbs->flavor = RPC_AUTH_NULL;
495			break;
496		case RPC_AUTH_UNIX:
497			READ_BUF(8);
498			/* stamp */
499			dummy = be32_to_cpup(p++);
500
501			/* machine name */
502			dummy = be32_to_cpup(p++);
503			READ_BUF(dummy);
504			SAVEMEM(machine_name, dummy);
505
506			/* uid, gid */
507			READ_BUF(8);
508			uid = be32_to_cpup(p++);
509			gid = be32_to_cpup(p++);
510
511			/* more gids */
512			READ_BUF(4);
513			dummy = be32_to_cpup(p++);
514			READ_BUF(dummy * 4);
515			if (cbs->flavor == (u32)(-1)) {
516				kuid_t kuid = make_kuid(&init_user_ns, uid);
517				kgid_t kgid = make_kgid(&init_user_ns, gid);
518				if (uid_valid(kuid) && gid_valid(kgid)) {
519					cbs->uid = kuid;
520					cbs->gid = kgid;
521					cbs->flavor = RPC_AUTH_UNIX;
522				} else {
523					dprintk("RPC_AUTH_UNIX with invalid"
524						"uid or gid ignoring!\n");
525				}
526			}
527			break;
528		case RPC_AUTH_GSS:
529			dprintk("RPC_AUTH_GSS callback secflavor "
530				"not supported!\n");
531			READ_BUF(8);
532			/* gcbp_service */
533			dummy = be32_to_cpup(p++);
534			/* gcbp_handle_from_server */
535			dummy = be32_to_cpup(p++);
536			READ_BUF(dummy);
537			p += XDR_QUADLEN(dummy);
538			/* gcbp_handle_from_client */
539			READ_BUF(4);
540			dummy = be32_to_cpup(p++);
541			READ_BUF(dummy);
542			break;
543		default:
544			dprintk("Illegal callback secflavor\n");
545			return nfserr_inval;
546		}
547	}
548	DECODE_TAIL;
549}
550
551static __be32 nfsd4_decode_backchannel_ctl(struct nfsd4_compoundargs *argp, struct nfsd4_backchannel_ctl *bc)
552{
553	DECODE_HEAD;
554
555	READ_BUF(4);
556	bc->bc_cb_program = be32_to_cpup(p++);
557	nfsd4_decode_cb_sec(argp, &bc->bc_cb_sec);
558
559	DECODE_TAIL;
560}
561
562static __be32 nfsd4_decode_bind_conn_to_session(struct nfsd4_compoundargs *argp, struct nfsd4_bind_conn_to_session *bcts)
563{
564	DECODE_HEAD;
565
566	READ_BUF(NFS4_MAX_SESSIONID_LEN + 8);
567	COPYMEM(bcts->sessionid.data, NFS4_MAX_SESSIONID_LEN);
568	bcts->dir = be32_to_cpup(p++);
569	/* XXX: skipping ctsa_use_conn_in_rdma_mode.  Perhaps Tom Tucker
570	 * could help us figure out we should be using it. */
571	DECODE_TAIL;
572}
573
574static __be32
575nfsd4_decode_close(struct nfsd4_compoundargs *argp, struct nfsd4_close *close)
576{
577	DECODE_HEAD;
578
579	READ_BUF(4);
580	close->cl_seqid = be32_to_cpup(p++);
581	return nfsd4_decode_stateid(argp, &close->cl_stateid);
582
583	DECODE_TAIL;
584}
585
586
587static __be32
588nfsd4_decode_commit(struct nfsd4_compoundargs *argp, struct nfsd4_commit *commit)
589{
590	DECODE_HEAD;
591
592	READ_BUF(12);
593	p = xdr_decode_hyper(p, &commit->co_offset);
594	commit->co_count = be32_to_cpup(p++);
595
596	DECODE_TAIL;
597}
598
599static __be32
600nfsd4_decode_create(struct nfsd4_compoundargs *argp, struct nfsd4_create *create)
601{
602	DECODE_HEAD;
603
604	READ_BUF(4);
605	create->cr_type = be32_to_cpup(p++);
606	switch (create->cr_type) {
607	case NF4LNK:
608		READ_BUF(4);
609		create->cr_datalen = be32_to_cpup(p++);
610		READ_BUF(create->cr_datalen);
611		create->cr_data = svcxdr_dupstr(argp, p, create->cr_datalen);
612		if (!create->cr_data)
613			return nfserr_jukebox;
614		break;
615	case NF4BLK:
616	case NF4CHR:
617		READ_BUF(8);
618		create->cr_specdata1 = be32_to_cpup(p++);
619		create->cr_specdata2 = be32_to_cpup(p++);
620		break;
621	case NF4SOCK:
622	case NF4FIFO:
623	case NF4DIR:
624	default:
625		break;
626	}
627
628	READ_BUF(4);
629	create->cr_namelen = be32_to_cpup(p++);
630	READ_BUF(create->cr_namelen);
631	SAVEMEM(create->cr_name, create->cr_namelen);
632	if ((status = check_filename(create->cr_name, create->cr_namelen)))
633		return status;
634
635	status = nfsd4_decode_fattr(argp, create->cr_bmval, &create->cr_iattr,
636				    &create->cr_acl, &create->cr_label);
637	if (status)
638		goto out;
639
640	DECODE_TAIL;
641}
642
643static inline __be32
644nfsd4_decode_delegreturn(struct nfsd4_compoundargs *argp, struct nfsd4_delegreturn *dr)
645{
646	return nfsd4_decode_stateid(argp, &dr->dr_stateid);
647}
648
649static inline __be32
650nfsd4_decode_getattr(struct nfsd4_compoundargs *argp, struct nfsd4_getattr *getattr)
651{
652	return nfsd4_decode_bitmap(argp, getattr->ga_bmval);
653}
654
655static __be32
656nfsd4_decode_link(struct nfsd4_compoundargs *argp, struct nfsd4_link *link)
657{
658	DECODE_HEAD;
659
660	READ_BUF(4);
661	link->li_namelen = be32_to_cpup(p++);
662	READ_BUF(link->li_namelen);
663	SAVEMEM(link->li_name, link->li_namelen);
664	if ((status = check_filename(link->li_name, link->li_namelen)))
665		return status;
666
667	DECODE_TAIL;
668}
669
670static __be32
671nfsd4_decode_lock(struct nfsd4_compoundargs *argp, struct nfsd4_lock *lock)
672{
673	DECODE_HEAD;
674
675	/*
676	* type, reclaim(boolean), offset, length, new_lock_owner(boolean)
677	*/
678	READ_BUF(28);
679	lock->lk_type = be32_to_cpup(p++);
680	if ((lock->lk_type < NFS4_READ_LT) || (lock->lk_type > NFS4_WRITEW_LT))
681		goto xdr_error;
682	lock->lk_reclaim = be32_to_cpup(p++);
683	p = xdr_decode_hyper(p, &lock->lk_offset);
684	p = xdr_decode_hyper(p, &lock->lk_length);
685	lock->lk_is_new = be32_to_cpup(p++);
686
687	if (lock->lk_is_new) {
688		READ_BUF(4);
689		lock->lk_new_open_seqid = be32_to_cpup(p++);
690		status = nfsd4_decode_stateid(argp, &lock->lk_new_open_stateid);
691		if (status)
692			return status;
693		READ_BUF(8 + sizeof(clientid_t));
694		lock->lk_new_lock_seqid = be32_to_cpup(p++);
695		COPYMEM(&lock->lk_new_clientid, sizeof(clientid_t));
696		lock->lk_new_owner.len = be32_to_cpup(p++);
697		READ_BUF(lock->lk_new_owner.len);
698		READMEM(lock->lk_new_owner.data, lock->lk_new_owner.len);
699	} else {
700		status = nfsd4_decode_stateid(argp, &lock->lk_old_lock_stateid);
701		if (status)
702			return status;
703		READ_BUF(4);
704		lock->lk_old_lock_seqid = be32_to_cpup(p++);
705	}
706
707	DECODE_TAIL;
708}
709
710static __be32
711nfsd4_decode_lockt(struct nfsd4_compoundargs *argp, struct nfsd4_lockt *lockt)
712{
713	DECODE_HEAD;
714
715	READ_BUF(32);
716	lockt->lt_type = be32_to_cpup(p++);
717	if((lockt->lt_type < NFS4_READ_LT) || (lockt->lt_type > NFS4_WRITEW_LT))
718		goto xdr_error;
719	p = xdr_decode_hyper(p, &lockt->lt_offset);
720	p = xdr_decode_hyper(p, &lockt->lt_length);
721	COPYMEM(&lockt->lt_clientid, 8);
722	lockt->lt_owner.len = be32_to_cpup(p++);
723	READ_BUF(lockt->lt_owner.len);
724	READMEM(lockt->lt_owner.data, lockt->lt_owner.len);
725
726	DECODE_TAIL;
727}
728
729static __be32
730nfsd4_decode_locku(struct nfsd4_compoundargs *argp, struct nfsd4_locku *locku)
731{
732	DECODE_HEAD;
733
734	READ_BUF(8);
735	locku->lu_type = be32_to_cpup(p++);
736	if ((locku->lu_type < NFS4_READ_LT) || (locku->lu_type > NFS4_WRITEW_LT))
737		goto xdr_error;
738	locku->lu_seqid = be32_to_cpup(p++);
739	status = nfsd4_decode_stateid(argp, &locku->lu_stateid);
740	if (status)
741		return status;
742	READ_BUF(16);
743	p = xdr_decode_hyper(p, &locku->lu_offset);
744	p = xdr_decode_hyper(p, &locku->lu_length);
745
746	DECODE_TAIL;
747}
748
749static __be32
750nfsd4_decode_lookup(struct nfsd4_compoundargs *argp, struct nfsd4_lookup *lookup)
751{
752	DECODE_HEAD;
753
754	READ_BUF(4);
755	lookup->lo_len = be32_to_cpup(p++);
756	READ_BUF(lookup->lo_len);
757	SAVEMEM(lookup->lo_name, lookup->lo_len);
758	if ((status = check_filename(lookup->lo_name, lookup->lo_len)))
759		return status;
760
761	DECODE_TAIL;
762}
763
764static __be32 nfsd4_decode_share_access(struct nfsd4_compoundargs *argp, u32 *share_access, u32 *deleg_want, u32 *deleg_when)
765{
766	__be32 *p;
767	u32 w;
768
769	READ_BUF(4);
770	w = be32_to_cpup(p++);
771	*share_access = w & NFS4_SHARE_ACCESS_MASK;
772	*deleg_want = w & NFS4_SHARE_WANT_MASK;
773	if (deleg_when)
774		*deleg_when = w & NFS4_SHARE_WHEN_MASK;
775
776	switch (w & NFS4_SHARE_ACCESS_MASK) {
777	case NFS4_SHARE_ACCESS_READ:
778	case NFS4_SHARE_ACCESS_WRITE:
779	case NFS4_SHARE_ACCESS_BOTH:
780		break;
781	default:
782		return nfserr_bad_xdr;
783	}
784	w &= ~NFS4_SHARE_ACCESS_MASK;
785	if (!w)
786		return nfs_ok;
787	if (!argp->minorversion)
788		return nfserr_bad_xdr;
789	switch (w & NFS4_SHARE_WANT_MASK) {
790	case NFS4_SHARE_WANT_NO_PREFERENCE:
791	case NFS4_SHARE_WANT_READ_DELEG:
792	case NFS4_SHARE_WANT_WRITE_DELEG:
793	case NFS4_SHARE_WANT_ANY_DELEG:
794	case NFS4_SHARE_WANT_NO_DELEG:
795	case NFS4_SHARE_WANT_CANCEL:
796		break;
797	default:
798		return nfserr_bad_xdr;
799	}
800	w &= ~NFS4_SHARE_WANT_MASK;
801	if (!w)
802		return nfs_ok;
803
804	if (!deleg_when)	/* open_downgrade */
805		return nfserr_inval;
806	switch (w) {
807	case NFS4_SHARE_SIGNAL_DELEG_WHEN_RESRC_AVAIL:
808	case NFS4_SHARE_PUSH_DELEG_WHEN_UNCONTENDED:
809	case (NFS4_SHARE_SIGNAL_DELEG_WHEN_RESRC_AVAIL |
810	      NFS4_SHARE_PUSH_DELEG_WHEN_UNCONTENDED):
811		return nfs_ok;
812	}
813xdr_error:
814	return nfserr_bad_xdr;
815}
816
817static __be32 nfsd4_decode_share_deny(struct nfsd4_compoundargs *argp, u32 *x)
818{
819	__be32 *p;
820
821	READ_BUF(4);
822	*x = be32_to_cpup(p++);
823	/* Note: unlinke access bits, deny bits may be zero. */
824	if (*x & ~NFS4_SHARE_DENY_BOTH)
825		return nfserr_bad_xdr;
826	return nfs_ok;
827xdr_error:
828	return nfserr_bad_xdr;
829}
830
831static __be32 nfsd4_decode_opaque(struct nfsd4_compoundargs *argp, struct xdr_netobj *o)
832{
833	__be32 *p;
834
835	READ_BUF(4);
836	o->len = be32_to_cpup(p++);
837
838	if (o->len == 0 || o->len > NFS4_OPAQUE_LIMIT)
839		return nfserr_bad_xdr;
840
841	READ_BUF(o->len);
842	SAVEMEM(o->data, o->len);
843	return nfs_ok;
844xdr_error:
845	return nfserr_bad_xdr;
846}
847
848static __be32
849nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
850{
851	DECODE_HEAD;
852	u32 dummy;
853
854	memset(open->op_bmval, 0, sizeof(open->op_bmval));
855	open->op_iattr.ia_valid = 0;
856	open->op_openowner = NULL;
857
858	open->op_xdr_error = 0;
859	/* seqid, share_access, share_deny, clientid, ownerlen */
860	READ_BUF(4);
861	open->op_seqid = be32_to_cpup(p++);
862	/* decode, yet ignore deleg_when until supported */
863	status = nfsd4_decode_share_access(argp, &open->op_share_access,
864					   &open->op_deleg_want, &dummy);
865	if (status)
866		goto xdr_error;
867	status = nfsd4_decode_share_deny(argp, &open->op_share_deny);
868	if (status)
869		goto xdr_error;
870	READ_BUF(sizeof(clientid_t));
871	COPYMEM(&open->op_clientid, sizeof(clientid_t));
872	status = nfsd4_decode_opaque(argp, &open->op_owner);
873	if (status)
874		goto xdr_error;
875	READ_BUF(4);
876	open->op_create = be32_to_cpup(p++);
877	switch (open->op_create) {
878	case NFS4_OPEN_NOCREATE:
879		break;
880	case NFS4_OPEN_CREATE:
881		READ_BUF(4);
882		open->op_createmode = be32_to_cpup(p++);
883		switch (open->op_createmode) {
884		case NFS4_CREATE_UNCHECKED:
885		case NFS4_CREATE_GUARDED:
886			status = nfsd4_decode_fattr(argp, open->op_bmval,
887				&open->op_iattr, &open->op_acl, &open->op_label);
888			if (status)
889				goto out;
890			break;
891		case NFS4_CREATE_EXCLUSIVE:
892			READ_BUF(NFS4_VERIFIER_SIZE);
893			COPYMEM(open->op_verf.data, NFS4_VERIFIER_SIZE);
894			break;
895		case NFS4_CREATE_EXCLUSIVE4_1:
896			if (argp->minorversion < 1)
897				goto xdr_error;
898			READ_BUF(NFS4_VERIFIER_SIZE);
899			COPYMEM(open->op_verf.data, NFS4_VERIFIER_SIZE);
900			status = nfsd4_decode_fattr(argp, open->op_bmval,
901				&open->op_iattr, &open->op_acl, &open->op_label);
902			if (status)
903				goto out;
904			break;
905		default:
906			goto xdr_error;
907		}
908		break;
909	default:
910		goto xdr_error;
911	}
912
913	/* open_claim */
914	READ_BUF(4);
915	open->op_claim_type = be32_to_cpup(p++);
916	switch (open->op_claim_type) {
917	case NFS4_OPEN_CLAIM_NULL:
918	case NFS4_OPEN_CLAIM_DELEGATE_PREV:
919		READ_BUF(4);
920		open->op_fname.len = be32_to_cpup(p++);
921		READ_BUF(open->op_fname.len);
922		SAVEMEM(open->op_fname.data, open->op_fname.len);
923		if ((status = check_filename(open->op_fname.data, open->op_fname.len)))
924			return status;
925		break;
926	case NFS4_OPEN_CLAIM_PREVIOUS:
927		READ_BUF(4);
928		open->op_delegate_type = be32_to_cpup(p++);
929		break;
930	case NFS4_OPEN_CLAIM_DELEGATE_CUR:
931		status = nfsd4_decode_stateid(argp, &open->op_delegate_stateid);
932		if (status)
933			return status;
934		READ_BUF(4);
935		open->op_fname.len = be32_to_cpup(p++);
936		READ_BUF(open->op_fname.len);
937		SAVEMEM(open->op_fname.data, open->op_fname.len);
938		if ((status = check_filename(open->op_fname.data, open->op_fname.len)))
939			return status;
940		break;
941	case NFS4_OPEN_CLAIM_FH:
942	case NFS4_OPEN_CLAIM_DELEG_PREV_FH:
943		if (argp->minorversion < 1)
944			goto xdr_error;
945		/* void */
946		break;
947	case NFS4_OPEN_CLAIM_DELEG_CUR_FH:
948		if (argp->minorversion < 1)
949			goto xdr_error;
950		status = nfsd4_decode_stateid(argp, &open->op_delegate_stateid);
951		if (status)
952			return status;
953		break;
954	default:
955		goto xdr_error;
956	}
957
958	DECODE_TAIL;
959}
960
961static __be32
962nfsd4_decode_open_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_open_confirm *open_conf)
963{
964	DECODE_HEAD;
965
966	if (argp->minorversion >= 1)
967		return nfserr_notsupp;
968
969	status = nfsd4_decode_stateid(argp, &open_conf->oc_req_stateid);
970	if (status)
971		return status;
972	READ_BUF(4);
973	open_conf->oc_seqid = be32_to_cpup(p++);
974
975	DECODE_TAIL;
976}
977
978static __be32
979nfsd4_decode_open_downgrade(struct nfsd4_compoundargs *argp, struct nfsd4_open_downgrade *open_down)
980{
981	DECODE_HEAD;
982
983	status = nfsd4_decode_stateid(argp, &open_down->od_stateid);
984	if (status)
985		return status;
986	READ_BUF(4);
987	open_down->od_seqid = be32_to_cpup(p++);
988	status = nfsd4_decode_share_access(argp, &open_down->od_share_access,
989					   &open_down->od_deleg_want, NULL);
990	if (status)
991		return status;
992	status = nfsd4_decode_share_deny(argp, &open_down->od_share_deny);
993	if (status)
994		return status;
995	DECODE_TAIL;
996}
997
998static __be32
999nfsd4_decode_putfh(struct nfsd4_compoundargs *argp, struct nfsd4_putfh *putfh)
1000{
1001	DECODE_HEAD;
1002
1003	READ_BUF(4);
1004	putfh->pf_fhlen = be32_to_cpup(p++);
1005	if (putfh->pf_fhlen > NFS4_FHSIZE)
1006		goto xdr_error;
1007	READ_BUF(putfh->pf_fhlen);
1008	SAVEMEM(putfh->pf_fhval, putfh->pf_fhlen);
1009
1010	DECODE_TAIL;
1011}
1012
1013static __be32
1014nfsd4_decode_putpubfh(struct nfsd4_compoundargs *argp, void *p)
1015{
1016	if (argp->minorversion == 0)
1017		return nfs_ok;
1018	return nfserr_notsupp;
1019}
1020
1021static __be32
1022nfsd4_decode_read(struct nfsd4_compoundargs *argp, struct nfsd4_read *read)
1023{
1024	DECODE_HEAD;
1025
1026	status = nfsd4_decode_stateid(argp, &read->rd_stateid);
1027	if (status)
1028		return status;
1029	READ_BUF(12);
1030	p = xdr_decode_hyper(p, &read->rd_offset);
1031	read->rd_length = be32_to_cpup(p++);
1032
1033	DECODE_TAIL;
1034}
1035
1036static __be32
1037nfsd4_decode_readdir(struct nfsd4_compoundargs *argp, struct nfsd4_readdir *readdir)
1038{
1039	DECODE_HEAD;
1040
1041	READ_BUF(24);
1042	p = xdr_decode_hyper(p, &readdir->rd_cookie);
1043	COPYMEM(readdir->rd_verf.data, sizeof(readdir->rd_verf.data));
1044	readdir->rd_dircount = be32_to_cpup(p++);
1045	readdir->rd_maxcount = be32_to_cpup(p++);
1046	if ((status = nfsd4_decode_bitmap(argp, readdir->rd_bmval)))
1047		goto out;
1048
1049	DECODE_TAIL;
1050}
1051
1052static __be32
1053nfsd4_decode_remove(struct nfsd4_compoundargs *argp, struct nfsd4_remove *remove)
1054{
1055	DECODE_HEAD;
1056
1057	READ_BUF(4);
1058	remove->rm_namelen = be32_to_cpup(p++);
1059	READ_BUF(remove->rm_namelen);
1060	SAVEMEM(remove->rm_name, remove->rm_namelen);
1061	if ((status = check_filename(remove->rm_name, remove->rm_namelen)))
1062		return status;
1063
1064	DECODE_TAIL;
1065}
1066
1067static __be32
1068nfsd4_decode_rename(struct nfsd4_compoundargs *argp, struct nfsd4_rename *rename)
1069{
1070	DECODE_HEAD;
1071
1072	READ_BUF(4);
1073	rename->rn_snamelen = be32_to_cpup(p++);
1074	READ_BUF(rename->rn_snamelen);
1075	SAVEMEM(rename->rn_sname, rename->rn_snamelen);
1076	READ_BUF(4);
1077	rename->rn_tnamelen = be32_to_cpup(p++);
1078	READ_BUF(rename->rn_tnamelen);
1079	SAVEMEM(rename->rn_tname, rename->rn_tnamelen);
1080	if ((status = check_filename(rename->rn_sname, rename->rn_snamelen)))
1081		return status;
1082	if ((status = check_filename(rename->rn_tname, rename->rn_tnamelen)))
1083		return status;
1084
1085	DECODE_TAIL;
1086}
1087
1088static __be32
1089nfsd4_decode_renew(struct nfsd4_compoundargs *argp, clientid_t *clientid)
1090{
1091	DECODE_HEAD;
1092
1093	if (argp->minorversion >= 1)
1094		return nfserr_notsupp;
1095
1096	READ_BUF(sizeof(clientid_t));
1097	COPYMEM(clientid, sizeof(clientid_t));
1098
1099	DECODE_TAIL;
1100}
1101
1102static __be32
1103nfsd4_decode_secinfo(struct nfsd4_compoundargs *argp,
1104		     struct nfsd4_secinfo *secinfo)
1105{
1106	DECODE_HEAD;
1107
1108	READ_BUF(4);
1109	secinfo->si_namelen = be32_to_cpup(p++);
1110	READ_BUF(secinfo->si_namelen);
1111	SAVEMEM(secinfo->si_name, secinfo->si_namelen);
1112	status = check_filename(secinfo->si_name, secinfo->si_namelen);
1113	if (status)
1114		return status;
1115	DECODE_TAIL;
1116}
1117
1118static __be32
1119nfsd4_decode_secinfo_no_name(struct nfsd4_compoundargs *argp,
1120		     struct nfsd4_secinfo_no_name *sin)
1121{
1122	DECODE_HEAD;
1123
1124	READ_BUF(4);
1125	sin->sin_style = be32_to_cpup(p++);
1126	DECODE_TAIL;
1127}
1128
1129static __be32
1130nfsd4_decode_setattr(struct nfsd4_compoundargs *argp, struct nfsd4_setattr *setattr)
1131{
1132	__be32 status;
1133
1134	status = nfsd4_decode_stateid(argp, &setattr->sa_stateid);
1135	if (status)
1136		return status;
1137	return nfsd4_decode_fattr(argp, setattr->sa_bmval, &setattr->sa_iattr,
1138				  &setattr->sa_acl, &setattr->sa_label);
1139}
1140
1141static __be32
1142nfsd4_decode_setclientid(struct nfsd4_compoundargs *argp, struct nfsd4_setclientid *setclientid)
1143{
1144	DECODE_HEAD;
1145
1146	if (argp->minorversion >= 1)
1147		return nfserr_notsupp;
1148
1149	READ_BUF(NFS4_VERIFIER_SIZE);
1150	COPYMEM(setclientid->se_verf.data, NFS4_VERIFIER_SIZE);
1151
1152	status = nfsd4_decode_opaque(argp, &setclientid->se_name);
1153	if (status)
1154		return nfserr_bad_xdr;
1155	READ_BUF(8);
1156	setclientid->se_callback_prog = be32_to_cpup(p++);
1157	setclientid->se_callback_netid_len = be32_to_cpup(p++);
1158	READ_BUF(setclientid->se_callback_netid_len);
1159	SAVEMEM(setclientid->se_callback_netid_val, setclientid->se_callback_netid_len);
1160	READ_BUF(4);
1161	setclientid->se_callback_addr_len = be32_to_cpup(p++);
1162
1163	READ_BUF(setclientid->se_callback_addr_len);
1164	SAVEMEM(setclientid->se_callback_addr_val, setclientid->se_callback_addr_len);
1165	READ_BUF(4);
1166	setclientid->se_callback_ident = be32_to_cpup(p++);
1167
1168	DECODE_TAIL;
1169}
1170
1171static __be32
1172nfsd4_decode_setclientid_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_setclientid_confirm *scd_c)
1173{
1174	DECODE_HEAD;
1175
1176	if (argp->minorversion >= 1)
1177		return nfserr_notsupp;
1178
1179	READ_BUF(8 + NFS4_VERIFIER_SIZE);
1180	COPYMEM(&scd_c->sc_clientid, 8);
1181	COPYMEM(&scd_c->sc_confirm, NFS4_VERIFIER_SIZE);
1182
1183	DECODE_TAIL;
1184}
1185
1186/* Also used for NVERIFY */
1187static __be32
1188nfsd4_decode_verify(struct nfsd4_compoundargs *argp, struct nfsd4_verify *verify)
1189{
1190	DECODE_HEAD;
1191
1192	if ((status = nfsd4_decode_bitmap(argp, verify->ve_bmval)))
1193		goto out;
1194
1195	/* For convenience's sake, we compare raw xdr'd attributes in
1196	 * nfsd4_proc_verify */
1197
1198	READ_BUF(4);
1199	verify->ve_attrlen = be32_to_cpup(p++);
1200	READ_BUF(verify->ve_attrlen);
1201	SAVEMEM(verify->ve_attrval, verify->ve_attrlen);
1202
1203	DECODE_TAIL;
1204}
1205
1206static __be32
1207nfsd4_decode_write(struct nfsd4_compoundargs *argp, struct nfsd4_write *write)
1208{
1209	int avail;
1210	int len;
1211	DECODE_HEAD;
1212
1213	status = nfsd4_decode_stateid(argp, &write->wr_stateid);
1214	if (status)
1215		return status;
1216	READ_BUF(16);
1217	p = xdr_decode_hyper(p, &write->wr_offset);
1218	write->wr_stable_how = be32_to_cpup(p++);
1219	if (write->wr_stable_how > 2)
1220		goto xdr_error;
1221	write->wr_buflen = be32_to_cpup(p++);
1222
1223	/* Sorry .. no magic macros for this.. *
1224	 * READ_BUF(write->wr_buflen);
1225	 * SAVEMEM(write->wr_buf, write->wr_buflen);
1226	 */
1227	avail = (char*)argp->end - (char*)argp->p;
1228	if (avail + argp->pagelen < write->wr_buflen) {
1229		dprintk("NFSD: xdr error (%s:%d)\n",
1230				__FILE__, __LINE__);
1231		goto xdr_error;
1232	}
1233	write->wr_head.iov_base = p;
1234	write->wr_head.iov_len = avail;
1235	write->wr_pagelist = argp->pagelist;
1236
1237	len = XDR_QUADLEN(write->wr_buflen) << 2;
1238	if (len >= avail) {
1239		int pages;
1240
1241		len -= avail;
1242
1243		pages = len >> PAGE_SHIFT;
1244		argp->pagelist += pages;
1245		argp->pagelen -= pages * PAGE_SIZE;
1246		len -= pages * PAGE_SIZE;
1247
1248		argp->p = (__be32 *)page_address(argp->pagelist[0]);
1249		argp->pagelist++;
1250		argp->end = argp->p + XDR_QUADLEN(PAGE_SIZE);
1251	}
1252	argp->p += XDR_QUADLEN(len);
1253
1254	DECODE_TAIL;
1255}
1256
1257static __be32
1258nfsd4_decode_release_lockowner(struct nfsd4_compoundargs *argp, struct nfsd4_release_lockowner *rlockowner)
1259{
1260	DECODE_HEAD;
1261
1262	if (argp->minorversion >= 1)
1263		return nfserr_notsupp;
1264
1265	READ_BUF(12);
1266	COPYMEM(&rlockowner->rl_clientid, sizeof(clientid_t));
1267	rlockowner->rl_owner.len = be32_to_cpup(p++);
1268	READ_BUF(rlockowner->rl_owner.len);
1269	READMEM(rlockowner->rl_owner.data, rlockowner->rl_owner.len);
1270
1271	if (argp->minorversion && !zero_clientid(&rlockowner->rl_clientid))
1272		return nfserr_inval;
1273	DECODE_TAIL;
1274}
1275
1276static __be32
1277nfsd4_decode_exchange_id(struct nfsd4_compoundargs *argp,
1278			 struct nfsd4_exchange_id *exid)
1279{
1280	int dummy, tmp;
1281	DECODE_HEAD;
1282
1283	READ_BUF(NFS4_VERIFIER_SIZE);
1284	COPYMEM(exid->verifier.data, NFS4_VERIFIER_SIZE);
1285
1286	status = nfsd4_decode_opaque(argp, &exid->clname);
1287	if (status)
1288		return nfserr_bad_xdr;
1289
1290	READ_BUF(4);
1291	exid->flags = be32_to_cpup(p++);
1292
1293	/* Ignore state_protect4_a */
1294	READ_BUF(4);
1295	exid->spa_how = be32_to_cpup(p++);
1296	switch (exid->spa_how) {
1297	case SP4_NONE:
1298		break;
1299	case SP4_MACH_CRED:
1300		/* spo_must_enforce */
1301		READ_BUF(4);
1302		dummy = be32_to_cpup(p++);
1303		READ_BUF(dummy * 4);
1304		p += dummy;
1305
1306		/* spo_must_allow */
1307		READ_BUF(4);
1308		dummy = be32_to_cpup(p++);
1309		READ_BUF(dummy * 4);
1310		p += dummy;
1311		break;
1312	case SP4_SSV:
1313		/* ssp_ops */
1314		READ_BUF(4);
1315		dummy = be32_to_cpup(p++);
1316		READ_BUF(dummy * 4);
1317		p += dummy;
1318
1319		READ_BUF(4);
1320		dummy = be32_to_cpup(p++);
1321		READ_BUF(dummy * 4);
1322		p += dummy;
1323
1324		/* ssp_hash_algs<> */
1325		READ_BUF(4);
1326		tmp = be32_to_cpup(p++);
1327		while (tmp--) {
1328			READ_BUF(4);
1329			dummy = be32_to_cpup(p++);
1330			READ_BUF(dummy);
1331			p += XDR_QUADLEN(dummy);
1332		}
1333
1334		/* ssp_encr_algs<> */
1335		READ_BUF(4);
1336		tmp = be32_to_cpup(p++);
1337		while (tmp--) {
1338			READ_BUF(4);
1339			dummy = be32_to_cpup(p++);
1340			READ_BUF(dummy);
1341			p += XDR_QUADLEN(dummy);
1342		}
1343
1344		/* ssp_window and ssp_num_gss_handles */
1345		READ_BUF(8);
1346		dummy = be32_to_cpup(p++);
1347		dummy = be32_to_cpup(p++);
1348		break;
1349	default:
1350		goto xdr_error;
1351	}
1352
1353	/* Ignore Implementation ID */
1354	READ_BUF(4);    /* nfs_impl_id4 array length */
1355	dummy = be32_to_cpup(p++);
1356
1357	if (dummy > 1)
1358		goto xdr_error;
1359
1360	if (dummy == 1) {
1361		/* nii_domain */
1362		READ_BUF(4);
1363		dummy = be32_to_cpup(p++);
1364		READ_BUF(dummy);
1365		p += XDR_QUADLEN(dummy);
1366
1367		/* nii_name */
1368		READ_BUF(4);
1369		dummy = be32_to_cpup(p++);
1370		READ_BUF(dummy);
1371		p += XDR_QUADLEN(dummy);
1372
1373		/* nii_date */
1374		READ_BUF(12);
1375		p += 3;
1376	}
1377	DECODE_TAIL;
1378}
1379
1380static __be32
1381nfsd4_decode_create_session(struct nfsd4_compoundargs *argp,
1382			    struct nfsd4_create_session *sess)
1383{
1384	DECODE_HEAD;
1385	u32 dummy;
1386
1387	READ_BUF(16);
1388	COPYMEM(&sess->clientid, 8);
1389	sess->seqid = be32_to_cpup(p++);
1390	sess->flags = be32_to_cpup(p++);
1391
1392	/* Fore channel attrs */
1393	READ_BUF(28);
1394	dummy = be32_to_cpup(p++); /* headerpadsz is always 0 */
1395	sess->fore_channel.maxreq_sz = be32_to_cpup(p++);
1396	sess->fore_channel.maxresp_sz = be32_to_cpup(p++);
1397	sess->fore_channel.maxresp_cached = be32_to_cpup(p++);
1398	sess->fore_channel.maxops = be32_to_cpup(p++);
1399	sess->fore_channel.maxreqs = be32_to_cpup(p++);
1400	sess->fore_channel.nr_rdma_attrs = be32_to_cpup(p++);
1401	if (sess->fore_channel.nr_rdma_attrs == 1) {
1402		READ_BUF(4);
1403		sess->fore_channel.rdma_attrs = be32_to_cpup(p++);
1404	} else if (sess->fore_channel.nr_rdma_attrs > 1) {
1405		dprintk("Too many fore channel attr bitmaps!\n");
1406		goto xdr_error;
1407	}
1408
1409	/* Back channel attrs */
1410	READ_BUF(28);
1411	dummy = be32_to_cpup(p++); /* headerpadsz is always 0 */
1412	sess->back_channel.maxreq_sz = be32_to_cpup(p++);
1413	sess->back_channel.maxresp_sz = be32_to_cpup(p++);
1414	sess->back_channel.maxresp_cached = be32_to_cpup(p++);
1415	sess->back_channel.maxops = be32_to_cpup(p++);
1416	sess->back_channel.maxreqs = be32_to_cpup(p++);
1417	sess->back_channel.nr_rdma_attrs = be32_to_cpup(p++);
1418	if (sess->back_channel.nr_rdma_attrs == 1) {
1419		READ_BUF(4);
1420		sess->back_channel.rdma_attrs = be32_to_cpup(p++);
1421	} else if (sess->back_channel.nr_rdma_attrs > 1) {
1422		dprintk("Too many back channel attr bitmaps!\n");
1423		goto xdr_error;
1424	}
1425
1426	READ_BUF(4);
1427	sess->callback_prog = be32_to_cpup(p++);
1428	nfsd4_decode_cb_sec(argp, &sess->cb_sec);
1429	DECODE_TAIL;
1430}
1431
1432static __be32
1433nfsd4_decode_destroy_session(struct nfsd4_compoundargs *argp,
1434			     struct nfsd4_destroy_session *destroy_session)
1435{
1436	DECODE_HEAD;
1437	READ_BUF(NFS4_MAX_SESSIONID_LEN);
1438	COPYMEM(destroy_session->sessionid.data, NFS4_MAX_SESSIONID_LEN);
1439
1440	DECODE_TAIL;
1441}
1442
1443static __be32
1444nfsd4_decode_free_stateid(struct nfsd4_compoundargs *argp,
1445			  struct nfsd4_free_stateid *free_stateid)
1446{
1447	DECODE_HEAD;
1448
1449	READ_BUF(sizeof(stateid_t));
1450	free_stateid->fr_stateid.si_generation = be32_to_cpup(p++);
1451	COPYMEM(&free_stateid->fr_stateid.si_opaque, sizeof(stateid_opaque_t));
1452
1453	DECODE_TAIL;
1454}
1455
1456static __be32
1457nfsd4_decode_sequence(struct nfsd4_compoundargs *argp,
1458		      struct nfsd4_sequence *seq)
1459{
1460	DECODE_HEAD;
1461
1462	READ_BUF(NFS4_MAX_SESSIONID_LEN + 16);
1463	COPYMEM(seq->sessionid.data, NFS4_MAX_SESSIONID_LEN);
1464	seq->seqid = be32_to_cpup(p++);
1465	seq->slotid = be32_to_cpup(p++);
1466	seq->maxslots = be32_to_cpup(p++);
1467	seq->cachethis = be32_to_cpup(p++);
1468
1469	DECODE_TAIL;
1470}
1471
1472static __be32
1473nfsd4_decode_test_stateid(struct nfsd4_compoundargs *argp, struct nfsd4_test_stateid *test_stateid)
1474{
1475	int i;
1476	__be32 *p, status;
1477	struct nfsd4_test_stateid_id *stateid;
1478
1479	READ_BUF(4);
1480	test_stateid->ts_num_ids = ntohl(*p++);
1481
1482	INIT_LIST_HEAD(&test_stateid->ts_stateid_list);
1483
1484	for (i = 0; i < test_stateid->ts_num_ids; i++) {
1485		stateid = svcxdr_tmpalloc(argp, sizeof(*stateid));
1486		if (!stateid) {
1487			status = nfserrno(-ENOMEM);
1488			goto out;
1489		}
1490
1491		INIT_LIST_HEAD(&stateid->ts_id_list);
1492		list_add_tail(&stateid->ts_id_list, &test_stateid->ts_stateid_list);
1493
1494		status = nfsd4_decode_stateid(argp, &stateid->ts_id_stateid);
1495		if (status)
1496			goto out;
1497	}
1498
1499	status = 0;
1500out:
1501	return status;
1502xdr_error:
1503	dprintk("NFSD: xdr error (%s:%d)\n", __FILE__, __LINE__);
1504	status = nfserr_bad_xdr;
1505	goto out;
1506}
1507
1508static __be32 nfsd4_decode_destroy_clientid(struct nfsd4_compoundargs *argp, struct nfsd4_destroy_clientid *dc)
1509{
1510	DECODE_HEAD;
1511
1512	READ_BUF(8);
1513	COPYMEM(&dc->clientid, 8);
1514
1515	DECODE_TAIL;
1516}
1517
1518static __be32 nfsd4_decode_reclaim_complete(struct nfsd4_compoundargs *argp, struct nfsd4_reclaim_complete *rc)
1519{
1520	DECODE_HEAD;
1521
1522	READ_BUF(4);
1523	rc->rca_one_fs = be32_to_cpup(p++);
1524
1525	DECODE_TAIL;
1526}
1527
1528#ifdef CONFIG_NFSD_PNFS
1529static __be32
1530nfsd4_decode_getdeviceinfo(struct nfsd4_compoundargs *argp,
1531		struct nfsd4_getdeviceinfo *gdev)
1532{
1533	DECODE_HEAD;
1534	u32 num, i;
1535
1536	READ_BUF(sizeof(struct nfsd4_deviceid) + 3 * 4);
1537	COPYMEM(&gdev->gd_devid, sizeof(struct nfsd4_deviceid));
1538	gdev->gd_layout_type = be32_to_cpup(p++);
1539	gdev->gd_maxcount = be32_to_cpup(p++);
1540	num = be32_to_cpup(p++);
1541	if (num) {
1542		READ_BUF(4 * num);
1543		gdev->gd_notify_types = be32_to_cpup(p++);
1544		for (i = 1; i < num; i++) {
1545			if (be32_to_cpup(p++)) {
1546				status = nfserr_inval;
1547				goto out;
1548			}
1549		}
1550	}
1551	DECODE_TAIL;
1552}
1553
1554static __be32
1555nfsd4_decode_layoutget(struct nfsd4_compoundargs *argp,
1556		struct nfsd4_layoutget *lgp)
1557{
1558	DECODE_HEAD;
1559
1560	READ_BUF(36);
1561	lgp->lg_signal = be32_to_cpup(p++);
1562	lgp->lg_layout_type = be32_to_cpup(p++);
1563	lgp->lg_seg.iomode = be32_to_cpup(p++);
1564	p = xdr_decode_hyper(p, &lgp->lg_seg.offset);
1565	p = xdr_decode_hyper(p, &lgp->lg_seg.length);
1566	p = xdr_decode_hyper(p, &lgp->lg_minlength);
1567
1568	status = nfsd4_decode_stateid(argp, &lgp->lg_sid);
1569	if (status)
1570		return status;
1571
1572	READ_BUF(4);
1573	lgp->lg_maxcount = be32_to_cpup(p++);
1574
1575	DECODE_TAIL;
1576}
1577
1578static __be32
1579nfsd4_decode_layoutcommit(struct nfsd4_compoundargs *argp,
1580		struct nfsd4_layoutcommit *lcp)
1581{
1582	DECODE_HEAD;
1583	u32 timechange;
1584
1585	READ_BUF(20);
1586	p = xdr_decode_hyper(p, &lcp->lc_seg.offset);
1587	p = xdr_decode_hyper(p, &lcp->lc_seg.length);
1588	lcp->lc_reclaim = be32_to_cpup(p++);
1589
1590	status = nfsd4_decode_stateid(argp, &lcp->lc_sid);
1591	if (status)
1592		return status;
1593
1594	READ_BUF(4);
1595	lcp->lc_newoffset = be32_to_cpup(p++);
1596	if (lcp->lc_newoffset) {
1597		READ_BUF(8);
1598		p = xdr_decode_hyper(p, &lcp->lc_last_wr);
1599	} else
1600		lcp->lc_last_wr = 0;
1601	READ_BUF(4);
1602	timechange = be32_to_cpup(p++);
1603	if (timechange) {
1604		status = nfsd4_decode_time(argp, &lcp->lc_mtime);
1605		if (status)
1606			return status;
1607	} else {
1608		lcp->lc_mtime.tv_nsec = UTIME_NOW;
1609	}
1610	READ_BUF(8);
1611	lcp->lc_layout_type = be32_to_cpup(p++);
1612
1613	/*
1614	 * Save the layout update in XDR format and let the layout driver deal
1615	 * with it later.
1616	 */
1617	lcp->lc_up_len = be32_to_cpup(p++);
1618	if (lcp->lc_up_len > 0) {
1619		READ_BUF(lcp->lc_up_len);
1620		READMEM(lcp->lc_up_layout, lcp->lc_up_len);
1621	}
1622
1623	DECODE_TAIL;
1624}
1625
1626static __be32
1627nfsd4_decode_layoutreturn(struct nfsd4_compoundargs *argp,
1628		struct nfsd4_layoutreturn *lrp)
1629{
1630	DECODE_HEAD;
1631
1632	READ_BUF(16);
1633	lrp->lr_reclaim = be32_to_cpup(p++);
1634	lrp->lr_layout_type = be32_to_cpup(p++);
1635	lrp->lr_seg.iomode = be32_to_cpup(p++);
1636	lrp->lr_return_type = be32_to_cpup(p++);
1637	if (lrp->lr_return_type == RETURN_FILE) {
1638		READ_BUF(16);
1639		p = xdr_decode_hyper(p, &lrp->lr_seg.offset);
1640		p = xdr_decode_hyper(p, &lrp->lr_seg.length);
1641
1642		status = nfsd4_decode_stateid(argp, &lrp->lr_sid);
1643		if (status)
1644			return status;
1645
1646		READ_BUF(4);
1647		lrp->lrf_body_len = be32_to_cpup(p++);
1648		if (lrp->lrf_body_len > 0) {
1649			READ_BUF(lrp->lrf_body_len);
1650			READMEM(lrp->lrf_body, lrp->lrf_body_len);
1651		}
1652	} else {
1653		lrp->lr_seg.offset = 0;
1654		lrp->lr_seg.length = NFS4_MAX_UINT64;
1655	}
1656
1657	DECODE_TAIL;
1658}
1659#endif /* CONFIG_NFSD_PNFS */
1660
1661static __be32
1662nfsd4_decode_fallocate(struct nfsd4_compoundargs *argp,
1663		       struct nfsd4_fallocate *fallocate)
1664{
1665	DECODE_HEAD;
1666
1667	status = nfsd4_decode_stateid(argp, &fallocate->falloc_stateid);
1668	if (status)
1669		return status;
1670
1671	READ_BUF(16);
1672	p = xdr_decode_hyper(p, &fallocate->falloc_offset);
1673	xdr_decode_hyper(p, &fallocate->falloc_length);
1674
1675	DECODE_TAIL;
1676}
1677
1678static __be32
1679nfsd4_decode_seek(struct nfsd4_compoundargs *argp, struct nfsd4_seek *seek)
1680{
1681	DECODE_HEAD;
1682
1683	status = nfsd4_decode_stateid(argp, &seek->seek_stateid);
1684	if (status)
1685		return status;
1686
1687	READ_BUF(8 + 4);
1688	p = xdr_decode_hyper(p, &seek->seek_offset);
1689	seek->seek_whence = be32_to_cpup(p);
1690
1691	DECODE_TAIL;
1692}
1693
1694static __be32
1695nfsd4_decode_noop(struct nfsd4_compoundargs *argp, void *p)
1696{
1697	return nfs_ok;
1698}
1699
1700static __be32
1701nfsd4_decode_notsupp(struct nfsd4_compoundargs *argp, void *p)
1702{
1703	return nfserr_notsupp;
1704}
1705
1706typedef __be32(*nfsd4_dec)(struct nfsd4_compoundargs *argp, void *);
1707
1708static nfsd4_dec nfsd4_dec_ops[] = {
1709	[OP_ACCESS]		= (nfsd4_dec)nfsd4_decode_access,
1710	[OP_CLOSE]		= (nfsd4_dec)nfsd4_decode_close,
1711	[OP_COMMIT]		= (nfsd4_dec)nfsd4_decode_commit,
1712	[OP_CREATE]		= (nfsd4_dec)nfsd4_decode_create,
1713	[OP_DELEGPURGE]		= (nfsd4_dec)nfsd4_decode_notsupp,
1714	[OP_DELEGRETURN]	= (nfsd4_dec)nfsd4_decode_delegreturn,
1715	[OP_GETATTR]		= (nfsd4_dec)nfsd4_decode_getattr,
1716	[OP_GETFH]		= (nfsd4_dec)nfsd4_decode_noop,
1717	[OP_LINK]		= (nfsd4_dec)nfsd4_decode_link,
1718	[OP_LOCK]		= (nfsd4_dec)nfsd4_decode_lock,
1719	[OP_LOCKT]		= (nfsd4_dec)nfsd4_decode_lockt,
1720	[OP_LOCKU]		= (nfsd4_dec)nfsd4_decode_locku,
1721	[OP_LOOKUP]		= (nfsd4_dec)nfsd4_decode_lookup,
1722	[OP_LOOKUPP]		= (nfsd4_dec)nfsd4_decode_noop,
1723	[OP_NVERIFY]		= (nfsd4_dec)nfsd4_decode_verify,
1724	[OP_OPEN]		= (nfsd4_dec)nfsd4_decode_open,
1725	[OP_OPENATTR]		= (nfsd4_dec)nfsd4_decode_notsupp,
1726	[OP_OPEN_CONFIRM]	= (nfsd4_dec)nfsd4_decode_open_confirm,
1727	[OP_OPEN_DOWNGRADE]	= (nfsd4_dec)nfsd4_decode_open_downgrade,
1728	[OP_PUTFH]		= (nfsd4_dec)nfsd4_decode_putfh,
1729	[OP_PUTPUBFH]		= (nfsd4_dec)nfsd4_decode_putpubfh,
1730	[OP_PUTROOTFH]		= (nfsd4_dec)nfsd4_decode_noop,
1731	[OP_READ]		= (nfsd4_dec)nfsd4_decode_read,
1732	[OP_READDIR]		= (nfsd4_dec)nfsd4_decode_readdir,
1733	[OP_READLINK]		= (nfsd4_dec)nfsd4_decode_noop,
1734	[OP_REMOVE]		= (nfsd4_dec)nfsd4_decode_remove,
1735	[OP_RENAME]		= (nfsd4_dec)nfsd4_decode_rename,
1736	[OP_RENEW]		= (nfsd4_dec)nfsd4_decode_renew,
1737	[OP_RESTOREFH]		= (nfsd4_dec)nfsd4_decode_noop,
1738	[OP_SAVEFH]		= (nfsd4_dec)nfsd4_decode_noop,
1739	[OP_SECINFO]		= (nfsd4_dec)nfsd4_decode_secinfo,
1740	[OP_SETATTR]		= (nfsd4_dec)nfsd4_decode_setattr,
1741	[OP_SETCLIENTID]	= (nfsd4_dec)nfsd4_decode_setclientid,
1742	[OP_SETCLIENTID_CONFIRM] = (nfsd4_dec)nfsd4_decode_setclientid_confirm,
1743	[OP_VERIFY]		= (nfsd4_dec)nfsd4_decode_verify,
1744	[OP_WRITE]		= (nfsd4_dec)nfsd4_decode_write,
1745	[OP_RELEASE_LOCKOWNER]	= (nfsd4_dec)nfsd4_decode_release_lockowner,
1746
1747	/* new operations for NFSv4.1 */
1748	[OP_BACKCHANNEL_CTL]	= (nfsd4_dec)nfsd4_decode_backchannel_ctl,
1749	[OP_BIND_CONN_TO_SESSION]= (nfsd4_dec)nfsd4_decode_bind_conn_to_session,
1750	[OP_EXCHANGE_ID]	= (nfsd4_dec)nfsd4_decode_exchange_id,
1751	[OP_CREATE_SESSION]	= (nfsd4_dec)nfsd4_decode_create_session,
1752	[OP_DESTROY_SESSION]	= (nfsd4_dec)nfsd4_decode_destroy_session,
1753	[OP_FREE_STATEID]	= (nfsd4_dec)nfsd4_decode_free_stateid,
1754	[OP_GET_DIR_DELEGATION]	= (nfsd4_dec)nfsd4_decode_notsupp,
1755#ifdef CONFIG_NFSD_PNFS
1756	[OP_GETDEVICEINFO]	= (nfsd4_dec)nfsd4_decode_getdeviceinfo,
1757	[OP_GETDEVICELIST]	= (nfsd4_dec)nfsd4_decode_notsupp,
1758	[OP_LAYOUTCOMMIT]	= (nfsd4_dec)nfsd4_decode_layoutcommit,
1759	[OP_LAYOUTGET]		= (nfsd4_dec)nfsd4_decode_layoutget,
1760	[OP_LAYOUTRETURN]	= (nfsd4_dec)nfsd4_decode_layoutreturn,
1761#else
1762	[OP_GETDEVICEINFO]	= (nfsd4_dec)nfsd4_decode_notsupp,
1763	[OP_GETDEVICELIST]	= (nfsd4_dec)nfsd4_decode_notsupp,
1764	[OP_LAYOUTCOMMIT]	= (nfsd4_dec)nfsd4_decode_notsupp,
1765	[OP_LAYOUTGET]		= (nfsd4_dec)nfsd4_decode_notsupp,
1766	[OP_LAYOUTRETURN]	= (nfsd4_dec)nfsd4_decode_notsupp,
1767#endif
1768	[OP_SECINFO_NO_NAME]	= (nfsd4_dec)nfsd4_decode_secinfo_no_name,
1769	[OP_SEQUENCE]		= (nfsd4_dec)nfsd4_decode_sequence,
1770	[OP_SET_SSV]		= (nfsd4_dec)nfsd4_decode_notsupp,
1771	[OP_TEST_STATEID]	= (nfsd4_dec)nfsd4_decode_test_stateid,
1772	[OP_WANT_DELEGATION]	= (nfsd4_dec)nfsd4_decode_notsupp,
1773	[OP_DESTROY_CLIENTID]	= (nfsd4_dec)nfsd4_decode_destroy_clientid,
1774	[OP_RECLAIM_COMPLETE]	= (nfsd4_dec)nfsd4_decode_reclaim_complete,
1775
1776	/* new operations for NFSv4.2 */
1777	[OP_ALLOCATE]		= (nfsd4_dec)nfsd4_decode_fallocate,
1778	[OP_COPY]		= (nfsd4_dec)nfsd4_decode_notsupp,
1779	[OP_COPY_NOTIFY]	= (nfsd4_dec)nfsd4_decode_notsupp,
1780	[OP_DEALLOCATE]		= (nfsd4_dec)nfsd4_decode_fallocate,
1781	[OP_IO_ADVISE]		= (nfsd4_dec)nfsd4_decode_notsupp,
1782	[OP_LAYOUTERROR]	= (nfsd4_dec)nfsd4_decode_notsupp,
1783	[OP_LAYOUTSTATS]	= (nfsd4_dec)nfsd4_decode_notsupp,
1784	[OP_OFFLOAD_CANCEL]	= (nfsd4_dec)nfsd4_decode_notsupp,
1785	[OP_OFFLOAD_STATUS]	= (nfsd4_dec)nfsd4_decode_notsupp,
1786	[OP_READ_PLUS]		= (nfsd4_dec)nfsd4_decode_notsupp,
1787	[OP_SEEK]		= (nfsd4_dec)nfsd4_decode_seek,
1788	[OP_WRITE_SAME]		= (nfsd4_dec)nfsd4_decode_notsupp,
1789};
1790
1791static inline bool
1792nfsd4_opnum_in_range(struct nfsd4_compoundargs *argp, struct nfsd4_op *op)
1793{
1794	if (op->opnum < FIRST_NFS4_OP)
1795		return false;
1796	else if (argp->minorversion == 0 && op->opnum > LAST_NFS40_OP)
1797		return false;
1798	else if (argp->minorversion == 1 && op->opnum > LAST_NFS41_OP)
1799		return false;
1800	else if (argp->minorversion == 2 && op->opnum > LAST_NFS42_OP)
1801		return false;
1802	return true;
1803}
1804
1805static __be32
1806nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
1807{
1808	DECODE_HEAD;
1809	struct nfsd4_op *op;
1810	bool cachethis = false;
1811	int auth_slack= argp->rqstp->rq_auth_slack;
1812	int max_reply = auth_slack + 8; /* opcnt, status */
1813	int readcount = 0;
1814	int readbytes = 0;
1815	int i;
1816
1817	READ_BUF(4);
1818	argp->taglen = be32_to_cpup(p++);
1819	READ_BUF(argp->taglen);
1820	SAVEMEM(argp->tag, argp->taglen);
1821	READ_BUF(8);
1822	argp->minorversion = be32_to_cpup(p++);
1823	argp->opcnt = be32_to_cpup(p++);
1824	max_reply += 4 + (XDR_QUADLEN(argp->taglen) << 2);
1825
1826	if (argp->taglen > NFSD4_MAX_TAGLEN)
1827		goto xdr_error;
1828	if (argp->opcnt > 100)
1829		goto xdr_error;
1830
1831	if (argp->opcnt > ARRAY_SIZE(argp->iops)) {
1832		argp->ops = kzalloc(argp->opcnt * sizeof(*argp->ops), GFP_KERNEL);
1833		if (!argp->ops) {
1834			argp->ops = argp->iops;
1835			dprintk("nfsd: couldn't allocate room for COMPOUND\n");
1836			goto xdr_error;
1837		}
1838	}
1839
1840	if (argp->minorversion > NFSD_SUPPORTED_MINOR_VERSION)
1841		argp->opcnt = 0;
1842
1843	for (i = 0; i < argp->opcnt; i++) {
1844		op = &argp->ops[i];
1845		op->replay = NULL;
1846
1847		READ_BUF(4);
1848		op->opnum = be32_to_cpup(p++);
1849
1850		if (nfsd4_opnum_in_range(argp, op))
1851			op->status = nfsd4_dec_ops[op->opnum](argp, &op->u);
1852		else {
1853			op->opnum = OP_ILLEGAL;
1854			op->status = nfserr_op_illegal;
1855		}
1856		/*
1857		 * We'll try to cache the result in the DRC if any one
1858		 * op in the compound wants to be cached:
1859		 */
1860		cachethis |= nfsd4_cache_this_op(op);
1861
1862		if (op->opnum == OP_READ) {
1863			readcount++;
1864			readbytes += nfsd4_max_reply(argp->rqstp, op);
1865		} else
1866			max_reply += nfsd4_max_reply(argp->rqstp, op);
1867		/*
1868		 * OP_LOCK may return a conflicting lock.  (Special case
1869		 * because it will just skip encoding this if it runs
1870		 * out of xdr buffer space, and it is the only operation
1871		 * that behaves this way.)
1872		 */
1873		if (op->opnum == OP_LOCK)
1874			max_reply += NFS4_OPAQUE_LIMIT;
1875
1876		if (op->status) {
1877			argp->opcnt = i+1;
1878			break;
1879		}
1880	}
1881	/* Sessions make the DRC unnecessary: */
1882	if (argp->minorversion)
1883		cachethis = false;
1884	svc_reserve(argp->rqstp, max_reply + readbytes);
1885	argp->rqstp->rq_cachetype = cachethis ? RC_REPLBUFF : RC_NOCACHE;
1886
1887	if (readcount > 1 || max_reply > PAGE_SIZE - auth_slack)
1888		clear_bit(RQ_SPLICE_OK, &argp->rqstp->rq_flags);
1889
1890	DECODE_TAIL;
1891}
1892
1893static __be32 *encode_change(__be32 *p, struct kstat *stat, struct inode *inode)
1894{
1895	if (IS_I_VERSION(inode)) {
1896		p = xdr_encode_hyper(p, inode->i_version);
1897	} else {
1898		*p++ = cpu_to_be32(stat->ctime.tv_sec);
1899		*p++ = cpu_to_be32(stat->ctime.tv_nsec);
1900	}
1901	return p;
1902}
1903
1904static __be32 *encode_cinfo(__be32 *p, struct nfsd4_change_info *c)
1905{
1906	*p++ = cpu_to_be32(c->atomic);
1907	if (c->change_supported) {
1908		p = xdr_encode_hyper(p, c->before_change);
1909		p = xdr_encode_hyper(p, c->after_change);
1910	} else {
1911		*p++ = cpu_to_be32(c->before_ctime_sec);
1912		*p++ = cpu_to_be32(c->before_ctime_nsec);
1913		*p++ = cpu_to_be32(c->after_ctime_sec);
1914		*p++ = cpu_to_be32(c->after_ctime_nsec);
1915	}
1916	return p;
1917}
1918
1919/* Encode as an array of strings the string given with components
1920 * separated @sep, escaped with esc_enter and esc_exit.
1921 */
1922static __be32 nfsd4_encode_components_esc(struct xdr_stream *xdr, char sep,
1923					  char *components, char esc_enter,
1924					  char esc_exit)
1925{
1926	__be32 *p;
1927	__be32 pathlen;
1928	int pathlen_offset;
1929	int strlen, count=0;
1930	char *str, *end, *next;
1931
1932	dprintk("nfsd4_encode_components(%s)\n", components);
1933
1934	pathlen_offset = xdr->buf->len;
1935	p = xdr_reserve_space(xdr, 4);
1936	if (!p)
1937		return nfserr_resource;
1938	p++; /* We will fill this in with @count later */
1939
1940	end = str = components;
1941	while (*end) {
1942		bool found_esc = false;
1943
1944		/* try to parse as esc_start, ..., esc_end, sep */
1945		if (*str == esc_enter) {
1946			for (; *end && (*end != esc_exit); end++)
1947				/* find esc_exit or end of string */;
1948			next = end + 1;
1949			if (*end && (!*next || *next == sep)) {
1950				str++;
1951				found_esc = true;
1952			}
1953		}
1954
1955		if (!found_esc)
1956			for (; *end && (*end != sep); end++)
1957				/* find sep or end of string */;
1958
1959		strlen = end - str;
1960		if (strlen) {
1961			p = xdr_reserve_space(xdr, strlen + 4);
1962			if (!p)
1963				return nfserr_resource;
1964			p = xdr_encode_opaque(p, str, strlen);
1965			count++;
1966		}
1967		else
1968			end++;
1969		if (found_esc)
1970			end = next;
1971
1972		str = end;
1973	}
1974	pathlen = htonl(count);
1975	write_bytes_to_xdr_buf(xdr->buf, pathlen_offset, &pathlen, 4);
1976	return 0;
1977}
1978
1979/* Encode as an array of strings the string given with components
1980 * separated @sep.
1981 */
1982static __be32 nfsd4_encode_components(struct xdr_stream *xdr, char sep,
1983				      char *components)
1984{
1985	return nfsd4_encode_components_esc(xdr, sep, components, 0, 0);
1986}
1987
1988/*
1989 * encode a location element of a fs_locations structure
1990 */
1991static __be32 nfsd4_encode_fs_location4(struct xdr_stream *xdr,
1992					struct nfsd4_fs_location *location)
1993{
1994	__be32 status;
1995
1996	status = nfsd4_encode_components_esc(xdr, ':', location->hosts,
1997						'[', ']');
1998	if (status)
1999		return status;
2000	status = nfsd4_encode_components(xdr, '/', location->path);
2001	if (status)
2002		return status;
2003	return 0;
2004}
2005
2006/*
2007 * Encode a path in RFC3530 'pathname4' format
2008 */
2009static __be32 nfsd4_encode_path(struct xdr_stream *xdr,
2010				const struct path *root,
2011				const struct path *path)
2012{
2013	struct path cur = *path;
2014	__be32 *p;
2015	struct dentry **components = NULL;
2016	unsigned int ncomponents = 0;
2017	__be32 err = nfserr_jukebox;
2018
2019	dprintk("nfsd4_encode_components(");
2020
2021	path_get(&cur);
2022	/* First walk the path up to the nfsd root, and store the
2023	 * dentries/path components in an array.
2024	 */
2025	for (;;) {
2026		if (path_equal(&cur, root))
2027			break;
2028		if (cur.dentry == cur.mnt->mnt_root) {
2029			if (follow_up(&cur))
2030				continue;
2031			goto out_free;
2032		}
2033		if ((ncomponents & 15) == 0) {
2034			struct dentry **new;
2035			new = krealloc(components,
2036					sizeof(*new) * (ncomponents + 16),
2037					GFP_KERNEL);
2038			if (!new)
2039				goto out_free;
2040			components = new;
2041		}
2042		components[ncomponents++] = cur.dentry;
2043		cur.dentry = dget_parent(cur.dentry);
2044	}
2045	err = nfserr_resource;
2046	p = xdr_reserve_space(xdr, 4);
2047	if (!p)
2048		goto out_free;
2049	*p++ = cpu_to_be32(ncomponents);
2050
2051	while (ncomponents) {
2052		struct dentry *dentry = components[ncomponents - 1];
2053		unsigned int len;
2054
2055		spin_lock(&dentry->d_lock);
2056		len = dentry->d_name.len;
2057		p = xdr_reserve_space(xdr, len + 4);
2058		if (!p) {
2059			spin_unlock(&dentry->d_lock);
2060			goto out_free;
2061		}
2062		p = xdr_encode_opaque(p, dentry->d_name.name, len);
2063		dprintk("/%pd", dentry);
2064		spin_unlock(&dentry->d_lock);
2065		dput(dentry);
2066		ncomponents--;
2067	}
2068
2069	err = 0;
2070out_free:
2071	dprintk(")\n");
2072	while (ncomponents)
2073		dput(components[--ncomponents]);
2074	kfree(components);
2075	path_put(&cur);
2076	return err;
2077}
2078
2079static __be32 nfsd4_encode_fsloc_fsroot(struct xdr_stream *xdr,
2080			struct svc_rqst *rqstp, const struct path *path)
2081{
2082	struct svc_export *exp_ps;
2083	__be32 res;
2084
2085	exp_ps = rqst_find_fsidzero_export(rqstp);
2086	if (IS_ERR(exp_ps))
2087		return nfserrno(PTR_ERR(exp_ps));
2088	res = nfsd4_encode_path(xdr, &exp_ps->ex_path, path);
2089	exp_put(exp_ps);
2090	return res;
2091}
2092
2093/*
2094 *  encode a fs_locations structure
2095 */
2096static __be32 nfsd4_encode_fs_locations(struct xdr_stream *xdr,
2097			struct svc_rqst *rqstp, struct svc_export *exp)
2098{
2099	__be32 status;
2100	int i;
2101	__be32 *p;
2102	struct nfsd4_fs_locations *fslocs = &exp->ex_fslocs;
2103
2104	status = nfsd4_encode_fsloc_fsroot(xdr, rqstp, &exp->ex_path);
2105	if (status)
2106		return status;
2107	p = xdr_reserve_space(xdr, 4);
2108	if (!p)
2109		return nfserr_resource;
2110	*p++ = cpu_to_be32(fslocs->locations_count);
2111	for (i=0; i<fslocs->locations_count; i++) {
2112		status = nfsd4_encode_fs_location4(xdr, &fslocs->locations[i]);
2113		if (status)
2114			return status;
2115	}
2116	return 0;
2117}
2118
2119static u32 nfs4_file_type(umode_t mode)
2120{
2121	switch (mode & S_IFMT) {
2122	case S_IFIFO:	return NF4FIFO;
2123	case S_IFCHR:	return NF4CHR;
2124	case S_IFDIR:	return NF4DIR;
2125	case S_IFBLK:	return NF4BLK;
2126	case S_IFLNK:	return NF4LNK;
2127	case S_IFREG:	return NF4REG;
2128	case S_IFSOCK:	return NF4SOCK;
2129	default:	return NF4BAD;
2130	};
2131}
2132
2133static inline __be32
2134nfsd4_encode_aclname(struct xdr_stream *xdr, struct svc_rqst *rqstp,
2135		     struct nfs4_ace *ace)
2136{
2137	if (ace->whotype != NFS4_ACL_WHO_NAMED)
2138		return nfs4_acl_write_who(xdr, ace->whotype);
2139	else if (ace->flag & NFS4_ACE_IDENTIFIER_GROUP)
2140		return nfsd4_encode_group(xdr, rqstp, ace->who_gid);
2141	else
2142		return nfsd4_encode_user(xdr, rqstp, ace->who_uid);
2143}
2144
2145static inline __be32
2146nfsd4_encode_layout_type(struct xdr_stream *xdr, enum pnfs_layouttype layout_type)
2147{
2148	__be32 *p;
2149
2150	if (layout_type) {
2151		p = xdr_reserve_space(xdr, 8);
2152		if (!p)
2153			return nfserr_resource;
2154		*p++ = cpu_to_be32(1);
2155		*p++ = cpu_to_be32(layout_type);
2156	} else {
2157		p = xdr_reserve_space(xdr, 4);
2158		if (!p)
2159			return nfserr_resource;
2160		*p++ = cpu_to_be32(0);
2161	}
2162
2163	return 0;
2164}
2165
2166#define WORD0_ABSENT_FS_ATTRS (FATTR4_WORD0_FS_LOCATIONS | FATTR4_WORD0_FSID | \
2167			      FATTR4_WORD0_RDATTR_ERROR)
2168#define WORD1_ABSENT_FS_ATTRS FATTR4_WORD1_MOUNTED_ON_FILEID
2169#define WORD2_ABSENT_FS_ATTRS 0
2170
2171#ifdef CONFIG_NFSD_V4_SECURITY_LABEL
2172static inline __be32
2173nfsd4_encode_security_label(struct xdr_stream *xdr, struct svc_rqst *rqstp,
2174			    void *context, int len)
2175{
2176	__be32 *p;
2177
2178	p = xdr_reserve_space(xdr, len + 4 + 4 + 4);
2179	if (!p)
2180		return nfserr_resource;
2181
2182	/*
2183	 * For now we use a 0 here to indicate the null translation; in
2184	 * the future we may place a call to translation code here.
2185	 */
2186	*p++ = cpu_to_be32(0); /* lfs */
2187	*p++ = cpu_to_be32(0); /* pi */
2188	p = xdr_encode_opaque(p, context, len);
2189	return 0;
2190}
2191#else
2192static inline __be32
2193nfsd4_encode_security_label(struct xdr_stream *xdr, struct svc_rqst *rqstp,
2194			    void *context, int len)
2195{ return 0; }
2196#endif
2197
2198static __be32 fattr_handle_absent_fs(u32 *bmval0, u32 *bmval1, u32 *bmval2, u32 *rdattr_err)
2199{
2200	/* As per referral draft:  */
2201	if (*bmval0 & ~WORD0_ABSENT_FS_ATTRS ||
2202	    *bmval1 & ~WORD1_ABSENT_FS_ATTRS) {
2203		if (*bmval0 & FATTR4_WORD0_RDATTR_ERROR ||
2204	            *bmval0 & FATTR4_WORD0_FS_LOCATIONS)
2205			*rdattr_err = NFSERR_MOVED;
2206		else
2207			return nfserr_moved;
2208	}
2209	*bmval0 &= WORD0_ABSENT_FS_ATTRS;
2210	*bmval1 &= WORD1_ABSENT_FS_ATTRS;
2211	*bmval2 &= WORD2_ABSENT_FS_ATTRS;
2212	return 0;
2213}
2214
2215
2216static int get_parent_attributes(struct svc_export *exp, struct kstat *stat)
2217{
2218	struct path path = exp->ex_path;
2219	int err;
2220
2221	path_get(&path);
2222	while (follow_up(&path)) {
2223		if (path.dentry != path.mnt->mnt_root)
2224			break;
2225	}
2226	err = vfs_getattr(&path, stat);
2227	path_put(&path);
2228	return err;
2229}
2230
2231/*
2232 * Note: @fhp can be NULL; in this case, we might have to compose the filehandle
2233 * ourselves.
2234 */
2235static __be32
2236nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp,
2237		struct svc_export *exp,
2238		struct dentry *dentry, u32 *bmval,
2239		struct svc_rqst *rqstp, int ignore_crossmnt)
2240{
2241	u32 bmval0 = bmval[0];
2242	u32 bmval1 = bmval[1];
2243	u32 bmval2 = bmval[2];
2244	struct kstat stat;
2245	struct svc_fh *tempfh = NULL;
2246	struct kstatfs statfs;
2247	__be32 *p;
2248	int starting_len = xdr->buf->len;
2249	int attrlen_offset;
2250	__be32 attrlen;
2251	u32 dummy;
2252	u64 dummy64;
2253	u32 rdattr_err = 0;
2254	__be32 status;
2255	int err;
2256	int aclsupport = 0;
2257	struct nfs4_acl *acl = NULL;
2258	void *context = NULL;
2259	int contextlen;
2260	bool contextsupport = false;
2261	struct nfsd4_compoundres *resp = rqstp->rq_resp;
2262	u32 minorversion = resp->cstate.minorversion;
2263	struct path path = {
2264		.mnt	= exp->ex_path.mnt,
2265		.dentry	= dentry,
2266	};
2267	struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
2268
2269	BUG_ON(bmval1 & NFSD_WRITEONLY_ATTRS_WORD1);
2270	BUG_ON(bmval0 & ~nfsd_suppattrs0(minorversion));
2271	BUG_ON(bmval1 & ~nfsd_suppattrs1(minorversion));
2272	BUG_ON(bmval2 & ~nfsd_suppattrs2(minorversion));
2273
2274	if (exp->ex_fslocs.migrated) {
2275		status = fattr_handle_absent_fs(&bmval0, &bmval1, &bmval2, &rdattr_err);
2276		if (status)
2277			goto out;
2278	}
2279
2280	err = vfs_getattr(&path, &stat);
2281	if (err)
2282		goto out_nfserr;
2283	if ((bmval0 & (FATTR4_WORD0_FILES_AVAIL | FATTR4_WORD0_FILES_FREE |
2284			FATTR4_WORD0_FILES_TOTAL | FATTR4_WORD0_MAXNAME)) ||
2285	    (bmval1 & (FATTR4_WORD1_SPACE_AVAIL | FATTR4_WORD1_SPACE_FREE |
2286		       FATTR4_WORD1_SPACE_TOTAL))) {
2287		err = vfs_statfs(&path, &statfs);
2288		if (err)
2289			goto out_nfserr;
2290	}
2291	if ((bmval0 & (FATTR4_WORD0_FILEHANDLE | FATTR4_WORD0_FSID)) && !fhp) {
2292		tempfh = kmalloc(sizeof(struct svc_fh), GFP_KERNEL);
2293		status = nfserr_jukebox;
2294		if (!tempfh)
2295			goto out;
2296		fh_init(tempfh, NFS4_FHSIZE);
2297		status = fh_compose(tempfh, exp, dentry, NULL);
2298		if (status)
2299			goto out;
2300		fhp = tempfh;
2301	}
2302	if (bmval0 & (FATTR4_WORD0_ACL | FATTR4_WORD0_ACLSUPPORT
2303			| FATTR4_WORD0_SUPPORTED_ATTRS)) {
2304		err = nfsd4_get_nfs4_acl(rqstp, dentry, &acl);
2305		aclsupport = (err == 0);
2306		if (bmval0 & FATTR4_WORD0_ACL) {
2307			if (err == -EOPNOTSUPP)
2308				bmval0 &= ~FATTR4_WORD0_ACL;
2309			else if (err == -EINVAL) {
2310				status = nfserr_attrnotsupp;
2311				goto out;
2312			} else if (err != 0)
2313				goto out_nfserr;
2314		}
2315	}
2316
2317#ifdef CONFIG_NFSD_V4_SECURITY_LABEL
2318	if ((bmval2 & FATTR4_WORD2_SECURITY_LABEL) ||
2319	     bmval0 & FATTR4_WORD0_SUPPORTED_ATTRS) {
2320		err = security_inode_getsecctx(d_inode(dentry),
2321						&context, &contextlen);
2322		contextsupport = (err == 0);
2323		if (bmval2 & FATTR4_WORD2_SECURITY_LABEL) {
2324			if (err == -EOPNOTSUPP)
2325				bmval2 &= ~FATTR4_WORD2_SECURITY_LABEL;
2326			else if (err)
2327				goto out_nfserr;
2328		}
2329	}
2330#endif /* CONFIG_NFSD_V4_SECURITY_LABEL */
2331
2332	if (bmval2) {
2333		p = xdr_reserve_space(xdr, 16);
2334		if (!p)
2335			goto out_resource;
2336		*p++ = cpu_to_be32(3);
2337		*p++ = cpu_to_be32(bmval0);
2338		*p++ = cpu_to_be32(bmval1);
2339		*p++ = cpu_to_be32(bmval2);
2340	} else if (bmval1) {
2341		p = xdr_reserve_space(xdr, 12);
2342		if (!p)
2343			goto out_resource;
2344		*p++ = cpu_to_be32(2);
2345		*p++ = cpu_to_be32(bmval0);
2346		*p++ = cpu_to_be32(bmval1);
2347	} else {
2348		p = xdr_reserve_space(xdr, 8);
2349		if (!p)
2350			goto out_resource;
2351		*p++ = cpu_to_be32(1);
2352		*p++ = cpu_to_be32(bmval0);
2353	}
2354
2355	attrlen_offset = xdr->buf->len;
2356	p = xdr_reserve_space(xdr, 4);
2357	if (!p)
2358		goto out_resource;
2359	p++;                /* to be backfilled later */
2360
2361	if (bmval0 & FATTR4_WORD0_SUPPORTED_ATTRS) {
2362		u32 word0 = nfsd_suppattrs0(minorversion);
2363		u32 word1 = nfsd_suppattrs1(minorversion);
2364		u32 word2 = nfsd_suppattrs2(minorversion);
2365
2366		if (!aclsupport)
2367			word0 &= ~FATTR4_WORD0_ACL;
2368		if (!contextsupport)
2369			word2 &= ~FATTR4_WORD2_SECURITY_LABEL;
2370		if (!word2) {
2371			p = xdr_reserve_space(xdr, 12);
2372			if (!p)
2373				goto out_resource;
2374			*p++ = cpu_to_be32(2);
2375			*p++ = cpu_to_be32(word0);
2376			*p++ = cpu_to_be32(word1);
2377		} else {
2378			p = xdr_reserve_space(xdr, 16);
2379			if (!p)
2380				goto out_resource;
2381			*p++ = cpu_to_be32(3);
2382			*p++ = cpu_to_be32(word0);
2383			*p++ = cpu_to_be32(word1);
2384			*p++ = cpu_to_be32(word2);
2385		}
2386	}
2387	if (bmval0 & FATTR4_WORD0_TYPE) {
2388		p = xdr_reserve_space(xdr, 4);
2389		if (!p)
2390			goto out_resource;
2391		dummy = nfs4_file_type(stat.mode);
2392		if (dummy == NF4BAD) {
2393			status = nfserr_serverfault;
2394			goto out;
2395		}
2396		*p++ = cpu_to_be32(dummy);
2397	}
2398	if (bmval0 & FATTR4_WORD0_FH_EXPIRE_TYPE) {
2399		p = xdr_reserve_space(xdr, 4);
2400		if (!p)
2401			goto out_resource;
2402		if (exp->ex_flags & NFSEXP_NOSUBTREECHECK)
2403			*p++ = cpu_to_be32(NFS4_FH_PERSISTENT);
2404		else
2405			*p++ = cpu_to_be32(NFS4_FH_PERSISTENT|
2406						NFS4_FH_VOL_RENAME);
2407	}
2408	if (bmval0 & FATTR4_WORD0_CHANGE) {
2409		p = xdr_reserve_space(xdr, 8);
2410		if (!p)
2411			goto out_resource;
2412		p = encode_change(p, &stat, d_inode(dentry));
2413	}
2414	if (bmval0 & FATTR4_WORD0_SIZE) {
2415		p = xdr_reserve_space(xdr, 8);
2416		if (!p)
2417			goto out_resource;
2418		p = xdr_encode_hyper(p, stat.size);
2419	}
2420	if (bmval0 & FATTR4_WORD0_LINK_SUPPORT) {
2421		p = xdr_reserve_space(xdr, 4);
2422		if (!p)
2423			goto out_resource;
2424		*p++ = cpu_to_be32(1);
2425	}
2426	if (bmval0 & FATTR4_WORD0_SYMLINK_SUPPORT) {
2427		p = xdr_reserve_space(xdr, 4);
2428		if (!p)
2429			goto out_resource;
2430		*p++ = cpu_to_be32(1);
2431	}
2432	if (bmval0 & FATTR4_WORD0_NAMED_ATTR) {
2433		p = xdr_reserve_space(xdr, 4);
2434		if (!p)
2435			goto out_resource;
2436		*p++ = cpu_to_be32(0);
2437	}
2438	if (bmval0 & FATTR4_WORD0_FSID) {
2439		p = xdr_reserve_space(xdr, 16);
2440		if (!p)
2441			goto out_resource;
2442		if (exp->ex_fslocs.migrated) {
2443			p = xdr_encode_hyper(p, NFS4_REFERRAL_FSID_MAJOR);
2444			p = xdr_encode_hyper(p, NFS4_REFERRAL_FSID_MINOR);
2445		} else switch(fsid_source(fhp)) {
2446		case FSIDSOURCE_FSID:
2447			p = xdr_encode_hyper(p, (u64)exp->ex_fsid);
2448			p = xdr_encode_hyper(p, (u64)0);
2449			break;
2450		case FSIDSOURCE_DEV:
2451			*p++ = cpu_to_be32(0);
2452			*p++ = cpu_to_be32(MAJOR(stat.dev));
2453			*p++ = cpu_to_be32(0);
2454			*p++ = cpu_to_be32(MINOR(stat.dev));
2455			break;
2456		case FSIDSOURCE_UUID:
2457			p = xdr_encode_opaque_fixed(p, exp->ex_uuid,
2458								EX_UUID_LEN);
2459			break;
2460		}
2461	}
2462	if (bmval0 & FATTR4_WORD0_UNIQUE_HANDLES) {
2463		p = xdr_reserve_space(xdr, 4);
2464		if (!p)
2465			goto out_resource;
2466		*p++ = cpu_to_be32(0);
2467	}
2468	if (bmval0 & FATTR4_WORD0_LEASE_TIME) {
2469		p = xdr_reserve_space(xdr, 4);
2470		if (!p)
2471			goto out_resource;
2472		*p++ = cpu_to_be32(nn->nfsd4_lease);
2473	}
2474	if (bmval0 & FATTR4_WORD0_RDATTR_ERROR) {
2475		p = xdr_reserve_space(xdr, 4);
2476		if (!p)
2477			goto out_resource;
2478		*p++ = cpu_to_be32(rdattr_err);
2479	}
2480	if (bmval0 & FATTR4_WORD0_ACL) {
2481		struct nfs4_ace *ace;
2482
2483		if (acl == NULL) {
2484			p = xdr_reserve_space(xdr, 4);
2485			if (!p)
2486				goto out_resource;
2487
2488			*p++ = cpu_to_be32(0);
2489			goto out_acl;
2490		}
2491		p = xdr_reserve_space(xdr, 4);
2492		if (!p)
2493			goto out_resource;
2494		*p++ = cpu_to_be32(acl->naces);
2495
2496		for (ace = acl->aces; ace < acl->aces + acl->naces; ace++) {
2497			p = xdr_reserve_space(xdr, 4*3);
2498			if (!p)
2499				goto out_resource;
2500			*p++ = cpu_to_be32(ace->type);
2501			*p++ = cpu_to_be32(ace->flag);
2502			*p++ = cpu_to_be32(ace->access_mask &
2503							NFS4_ACE_MASK_ALL);
2504			status = nfsd4_encode_aclname(xdr, rqstp, ace);
2505			if (status)
2506				goto out;
2507		}
2508	}
2509out_acl:
2510	if (bmval0 & FATTR4_WORD0_ACLSUPPORT) {
2511		p = xdr_reserve_space(xdr, 4);
2512		if (!p)
2513			goto out_resource;
2514		*p++ = cpu_to_be32(aclsupport ?
2515			ACL4_SUPPORT_ALLOW_ACL|ACL4_SUPPORT_DENY_ACL : 0);
2516	}
2517	if (bmval0 & FATTR4_WORD0_CANSETTIME) {
2518		p = xdr_reserve_space(xdr, 4);
2519		if (!p)
2520			goto out_resource;
2521		*p++ = cpu_to_be32(1);
2522	}
2523	if (bmval0 & FATTR4_WORD0_CASE_INSENSITIVE) {
2524		p = xdr_reserve_space(xdr, 4);
2525		if (!p)
2526			goto out_resource;
2527		*p++ = cpu_to_be32(0);
2528	}
2529	if (bmval0 & FATTR4_WORD0_CASE_PRESERVING) {
2530		p = xdr_reserve_space(xdr, 4);
2531		if (!p)
2532			goto out_resource;
2533		*p++ = cpu_to_be32(1);
2534	}
2535	if (bmval0 & FATTR4_WORD0_CHOWN_RESTRICTED) {
2536		p = xdr_reserve_space(xdr, 4);
2537		if (!p)
2538			goto out_resource;
2539		*p++ = cpu_to_be32(1);
2540	}
2541	if (bmval0 & FATTR4_WORD0_FILEHANDLE) {
2542		p = xdr_reserve_space(xdr, fhp->fh_handle.fh_size + 4);
2543		if (!p)
2544			goto out_resource;
2545		p = xdr_encode_opaque(p, &fhp->fh_handle.fh_base,
2546					fhp->fh_handle.fh_size);
2547	}
2548	if (bmval0 & FATTR4_WORD0_FILEID) {
2549		p = xdr_reserve_space(xdr, 8);
2550		if (!p)
2551			goto out_resource;
2552		p = xdr_encode_hyper(p, stat.ino);
2553	}
2554	if (bmval0 & FATTR4_WORD0_FILES_AVAIL) {
2555		p = xdr_reserve_space(xdr, 8);
2556		if (!p)
2557			goto out_resource;
2558		p = xdr_encode_hyper(p, (u64) statfs.f_ffree);
2559	}
2560	if (bmval0 & FATTR4_WORD0_FILES_FREE) {
2561		p = xdr_reserve_space(xdr, 8);
2562		if (!p)
2563			goto out_resource;
2564		p = xdr_encode_hyper(p, (u64) statfs.f_ffree);
2565	}
2566	if (bmval0 & FATTR4_WORD0_FILES_TOTAL) {
2567		p = xdr_reserve_space(xdr, 8);
2568		if (!p)
2569			goto out_resource;
2570		p = xdr_encode_hyper(p, (u64) statfs.f_files);
2571	}
2572	if (bmval0 & FATTR4_WORD0_FS_LOCATIONS) {
2573		status = nfsd4_encode_fs_locations(xdr, rqstp, exp);
2574		if (status)
2575			goto out;
2576	}
2577	if (bmval0 & FATTR4_WORD0_HOMOGENEOUS) {
2578		p = xdr_reserve_space(xdr, 4);
2579		if (!p)
2580			goto out_resource;
2581		*p++ = cpu_to_be32(1);
2582	}
2583	if (bmval0 & FATTR4_WORD0_MAXFILESIZE) {
2584		p = xdr_reserve_space(xdr, 8);
2585		if (!p)
2586			goto out_resource;
2587		p = xdr_encode_hyper(p, exp->ex_path.mnt->mnt_sb->s_maxbytes);
2588	}
2589	if (bmval0 & FATTR4_WORD0_MAXLINK) {
2590		p = xdr_reserve_space(xdr, 4);
2591		if (!p)
2592			goto out_resource;
2593		*p++ = cpu_to_be32(255);
2594	}
2595	if (bmval0 & FATTR4_WORD0_MAXNAME) {
2596		p = xdr_reserve_space(xdr, 4);
2597		if (!p)
2598			goto out_resource;
2599		*p++ = cpu_to_be32(statfs.f_namelen);
2600	}
2601	if (bmval0 & FATTR4_WORD0_MAXREAD) {
2602		p = xdr_reserve_space(xdr, 8);
2603		if (!p)
2604			goto out_resource;
2605		p = xdr_encode_hyper(p, (u64) svc_max_payload(rqstp));
2606	}
2607	if (bmval0 & FATTR4_WORD0_MAXWRITE) {
2608		p = xdr_reserve_space(xdr, 8);
2609		if (!p)
2610			goto out_resource;
2611		p = xdr_encode_hyper(p, (u64) svc_max_payload(rqstp));
2612	}
2613	if (bmval1 & FATTR4_WORD1_MODE) {
2614		p = xdr_reserve_space(xdr, 4);
2615		if (!p)
2616			goto out_resource;
2617		*p++ = cpu_to_be32(stat.mode & S_IALLUGO);
2618	}
2619	if (bmval1 & FATTR4_WORD1_NO_TRUNC) {
2620		p = xdr_reserve_space(xdr, 4);
2621		if (!p)
2622			goto out_resource;
2623		*p++ = cpu_to_be32(1);
2624	}
2625	if (bmval1 & FATTR4_WORD1_NUMLINKS) {
2626		p = xdr_reserve_space(xdr, 4);
2627		if (!p)
2628			goto out_resource;
2629		*p++ = cpu_to_be32(stat.nlink);
2630	}
2631	if (bmval1 & FATTR4_WORD1_OWNER) {
2632		status = nfsd4_encode_user(xdr, rqstp, stat.uid);
2633		if (status)
2634			goto out;
2635	}
2636	if (bmval1 & FATTR4_WORD1_OWNER_GROUP) {
2637		status = nfsd4_encode_group(xdr, rqstp, stat.gid);
2638		if (status)
2639			goto out;
2640	}
2641	if (bmval1 & FATTR4_WORD1_RAWDEV) {
2642		p = xdr_reserve_space(xdr, 8);
2643		if (!p)
2644			goto out_resource;
2645		*p++ = cpu_to_be32((u32) MAJOR(stat.rdev));
2646		*p++ = cpu_to_be32((u32) MINOR(stat.rdev));
2647	}
2648	if (bmval1 & FATTR4_WORD1_SPACE_AVAIL) {
2649		p = xdr_reserve_space(xdr, 8);
2650		if (!p)
2651			goto out_resource;
2652		dummy64 = (u64)statfs.f_bavail * (u64)statfs.f_bsize;
2653		p = xdr_encode_hyper(p, dummy64);
2654	}
2655	if (bmval1 & FATTR4_WORD1_SPACE_FREE) {
2656		p = xdr_reserve_space(xdr, 8);
2657		if (!p)
2658			goto out_resource;
2659		dummy64 = (u64)statfs.f_bfree * (u64)statfs.f_bsize;
2660		p = xdr_encode_hyper(p, dummy64);
2661	}
2662	if (bmval1 & FATTR4_WORD1_SPACE_TOTAL) {
2663		p = xdr_reserve_space(xdr, 8);
2664		if (!p)
2665			goto out_resource;
2666		dummy64 = (u64)statfs.f_blocks * (u64)statfs.f_bsize;
2667		p = xdr_encode_hyper(p, dummy64);
2668	}
2669	if (bmval1 & FATTR4_WORD1_SPACE_USED) {
2670		p = xdr_reserve_space(xdr, 8);
2671		if (!p)
2672			goto out_resource;
2673		dummy64 = (u64)stat.blocks << 9;
2674		p = xdr_encode_hyper(p, dummy64);
2675	}
2676	if (bmval1 & FATTR4_WORD1_TIME_ACCESS) {
2677		p = xdr_reserve_space(xdr, 12);
2678		if (!p)
2679			goto out_resource;
2680		p = xdr_encode_hyper(p, (s64)stat.atime.tv_sec);
2681		*p++ = cpu_to_be32(stat.atime.tv_nsec);
2682	}
2683	if (bmval1 & FATTR4_WORD1_TIME_DELTA) {
2684		p = xdr_reserve_space(xdr, 12);
2685		if (!p)
2686			goto out_resource;
2687		*p++ = cpu_to_be32(0);
2688		*p++ = cpu_to_be32(1);
2689		*p++ = cpu_to_be32(0);
2690	}
2691	if (bmval1 & FATTR4_WORD1_TIME_METADATA) {
2692		p = xdr_reserve_space(xdr, 12);
2693		if (!p)
2694			goto out_resource;
2695		p = xdr_encode_hyper(p, (s64)stat.ctime.tv_sec);
2696		*p++ = cpu_to_be32(stat.ctime.tv_nsec);
2697	}
2698	if (bmval1 & FATTR4_WORD1_TIME_MODIFY) {
2699		p = xdr_reserve_space(xdr, 12);
2700		if (!p)
2701			goto out_resource;
2702		p = xdr_encode_hyper(p, (s64)stat.mtime.tv_sec);
2703		*p++ = cpu_to_be32(stat.mtime.tv_nsec);
2704	}
2705	if (bmval1 & FATTR4_WORD1_MOUNTED_ON_FILEID) {
2706		p = xdr_reserve_space(xdr, 8);
2707		if (!p)
2708                	goto out_resource;
2709		/*
2710		 * Get parent's attributes if not ignoring crossmount
2711		 * and this is the root of a cross-mounted filesystem.
2712		 */
2713		if (ignore_crossmnt == 0 &&
2714		    dentry == exp->ex_path.mnt->mnt_root)
2715			get_parent_attributes(exp, &stat);
2716		p = xdr_encode_hyper(p, stat.ino);
2717	}
2718#ifdef CONFIG_NFSD_PNFS
2719	if (bmval1 & FATTR4_WORD1_FS_LAYOUT_TYPES) {
2720		status = nfsd4_encode_layout_type(xdr, exp->ex_layout_type);
2721		if (status)
2722			goto out;
2723	}
2724
2725	if (bmval2 & FATTR4_WORD2_LAYOUT_TYPES) {
2726		status = nfsd4_encode_layout_type(xdr, exp->ex_layout_type);
2727		if (status)
2728			goto out;
2729	}
2730
2731	if (bmval2 & FATTR4_WORD2_LAYOUT_BLKSIZE) {
2732		p = xdr_reserve_space(xdr, 4);
2733		if (!p)
2734			goto out_resource;
2735		*p++ = cpu_to_be32(stat.blksize);
2736	}
2737#endif /* CONFIG_NFSD_PNFS */
2738	if (bmval2 & FATTR4_WORD2_SECURITY_LABEL) {
2739		status = nfsd4_encode_security_label(xdr, rqstp, context,
2740								contextlen);
2741		if (status)
2742			goto out;
2743	}
2744	if (bmval2 & FATTR4_WORD2_SUPPATTR_EXCLCREAT) {
2745		p = xdr_reserve_space(xdr, 16);
2746		if (!p)
2747			goto out_resource;
2748		*p++ = cpu_to_be32(3);
2749		*p++ = cpu_to_be32(NFSD_SUPPATTR_EXCLCREAT_WORD0);
2750		*p++ = cpu_to_be32(NFSD_SUPPATTR_EXCLCREAT_WORD1);
2751		*p++ = cpu_to_be32(NFSD_SUPPATTR_EXCLCREAT_WORD2);
2752	}
2753
2754	attrlen = htonl(xdr->buf->len - attrlen_offset - 4);
2755	write_bytes_to_xdr_buf(xdr->buf, attrlen_offset, &attrlen, 4);
2756	status = nfs_ok;
2757
2758out:
2759#ifdef CONFIG_NFSD_V4_SECURITY_LABEL
2760	if (context)
2761		security_release_secctx(context, contextlen);
2762#endif /* CONFIG_NFSD_V4_SECURITY_LABEL */
2763	kfree(acl);
2764	if (tempfh) {
2765		fh_put(tempfh);
2766		kfree(tempfh);
2767	}
2768	if (status)
2769		xdr_truncate_encode(xdr, starting_len);
2770	return status;
2771out_nfserr:
2772	status = nfserrno(err);
2773	goto out;
2774out_resource:
2775	status = nfserr_resource;
2776	goto out;
2777}
2778
2779static void svcxdr_init_encode_from_buffer(struct xdr_stream *xdr,
2780				struct xdr_buf *buf, __be32 *p, int bytes)
2781{
2782	xdr->scratch.iov_len = 0;
2783	memset(buf, 0, sizeof(struct xdr_buf));
2784	buf->head[0].iov_base = p;
2785	buf->head[0].iov_len = 0;
2786	buf->len = 0;
2787	xdr->buf = buf;
2788	xdr->iov = buf->head;
2789	xdr->p = p;
2790	xdr->end = (void *)p + bytes;
2791	buf->buflen = bytes;
2792}
2793
2794__be32 nfsd4_encode_fattr_to_buf(__be32 **p, int words,
2795			struct svc_fh *fhp, struct svc_export *exp,
2796			struct dentry *dentry, u32 *bmval,
2797			struct svc_rqst *rqstp, int ignore_crossmnt)
2798{
2799	struct xdr_buf dummy;
2800	struct xdr_stream xdr;
2801	__be32 ret;
2802
2803	svcxdr_init_encode_from_buffer(&xdr, &dummy, *p, words << 2);
2804	ret = nfsd4_encode_fattr(&xdr, fhp, exp, dentry, bmval, rqstp,
2805							ignore_crossmnt);
2806	*p = xdr.p;
2807	return ret;
2808}
2809
2810static inline int attributes_need_mount(u32 *bmval)
2811{
2812	if (bmval[0] & ~(FATTR4_WORD0_RDATTR_ERROR | FATTR4_WORD0_LEASE_TIME))
2813		return 1;
2814	if (bmval[1] & ~FATTR4_WORD1_MOUNTED_ON_FILEID)
2815		return 1;
2816	return 0;
2817}
2818
2819static __be32
2820nfsd4_encode_dirent_fattr(struct xdr_stream *xdr, struct nfsd4_readdir *cd,
2821			const char *name, int namlen)
2822{
2823	struct svc_export *exp = cd->rd_fhp->fh_export;
2824	struct dentry *dentry;
2825	__be32 nfserr;
2826	int ignore_crossmnt = 0;
2827
2828	dentry = lookup_one_len(name, cd->rd_fhp->fh_dentry, namlen);
2829	if (IS_ERR(dentry))
2830		return nfserrno(PTR_ERR(dentry));
2831	if (d_really_is_negative(dentry)) {
2832		/*
2833		 * nfsd_buffered_readdir drops the i_mutex between
2834		 * readdir and calling this callback, leaving a window
2835		 * where this directory entry could have gone away.
2836		 */
2837		dput(dentry);
2838		return nfserr_noent;
2839	}
2840
2841	exp_get(exp);
2842	/*
2843	 * In the case of a mountpoint, the client may be asking for
2844	 * attributes that are only properties of the underlying filesystem
2845	 * as opposed to the cross-mounted file system. In such a case,
2846	 * we will not follow the cross mount and will fill the attribtutes
2847	 * directly from the mountpoint dentry.
2848	 */
2849	if (nfsd_mountpoint(dentry, exp)) {
2850		int err;
2851
2852		if (!(exp->ex_flags & NFSEXP_V4ROOT)
2853				&& !attributes_need_mount(cd->rd_bmval)) {
2854			ignore_crossmnt = 1;
2855			goto out_encode;
2856		}
2857		/*
2858		 * Why the heck aren't we just using nfsd_lookup??
2859		 * Different "."/".." handling?  Something else?
2860		 * At least, add a comment here to explain....
2861		 */
2862		err = nfsd_cross_mnt(cd->rd_rqstp, &dentry, &exp);
2863		if (err) {
2864			nfserr = nfserrno(err);
2865			goto out_put;
2866		}
2867		nfserr = check_nfsd_access(exp, cd->rd_rqstp);
2868		if (nfserr)
2869			goto out_put;
2870
2871	}
2872out_encode:
2873	nfserr = nfsd4_encode_fattr(xdr, NULL, exp, dentry, cd->rd_bmval,
2874					cd->rd_rqstp, ignore_crossmnt);
2875out_put:
2876	dput(dentry);
2877	exp_put(exp);
2878	return nfserr;
2879}
2880
2881static __be32 *
2882nfsd4_encode_rdattr_error(struct xdr_stream *xdr, __be32 nfserr)
2883{
2884	__be32 *p;
2885
2886	p = xdr_reserve_space(xdr, 20);
2887	if (!p)
2888		return NULL;
2889	*p++ = htonl(2);
2890	*p++ = htonl(FATTR4_WORD0_RDATTR_ERROR); /* bmval0 */
2891	*p++ = htonl(0);			 /* bmval1 */
2892
2893	*p++ = htonl(4);     /* attribute length */
2894	*p++ = nfserr;       /* no htonl */
2895	return p;
2896}
2897
2898static int
2899nfsd4_encode_dirent(void *ccdv, const char *name, int namlen,
2900		    loff_t offset, u64 ino, unsigned int d_type)
2901{
2902	struct readdir_cd *ccd = ccdv;
2903	struct nfsd4_readdir *cd = container_of(ccd, struct nfsd4_readdir, common);
2904	struct xdr_stream *xdr = cd->xdr;
2905	int start_offset = xdr->buf->len;
2906	int cookie_offset;
2907	u32 name_and_cookie;
2908	int entry_bytes;
2909	__be32 nfserr = nfserr_toosmall;
2910	__be64 wire_offset;
2911	__be32 *p;
2912
2913	/* In nfsv4, "." and ".." never make it onto the wire.. */
2914	if (name && isdotent(name, namlen)) {
2915		cd->common.err = nfs_ok;
2916		return 0;
2917	}
2918
2919	if (cd->cookie_offset) {
2920		wire_offset = cpu_to_be64(offset);
2921		write_bytes_to_xdr_buf(xdr->buf, cd->cookie_offset,
2922							&wire_offset, 8);
2923	}
2924
2925	p = xdr_reserve_space(xdr, 4);
2926	if (!p)
2927		goto fail;
2928	*p++ = xdr_one;                             /* mark entry present */
2929	cookie_offset = xdr->buf->len;
2930	p = xdr_reserve_space(xdr, 3*4 + namlen);
2931	if (!p)
2932		goto fail;
2933	p = xdr_encode_hyper(p, NFS_OFFSET_MAX);    /* offset of next entry */
2934	p = xdr_encode_array(p, name, namlen);      /* name length & name */
2935
2936	nfserr = nfsd4_encode_dirent_fattr(xdr, cd, name, namlen);
2937	switch (nfserr) {
2938	case nfs_ok:
2939		break;
2940	case nfserr_resource:
2941		nfserr = nfserr_toosmall;
2942		goto fail;
2943	case nfserr_noent:
2944		xdr_truncate_encode(xdr, start_offset);
2945		goto skip_entry;
2946	default:
2947		/*
2948		 * If the client requested the RDATTR_ERROR attribute,
2949		 * we stuff the error code into this attribute
2950		 * and continue.  If this attribute was not requested,
2951		 * then in accordance with the spec, we fail the
2952		 * entire READDIR operation(!)
2953		 */
2954		if (!(cd->rd_bmval[0] & FATTR4_WORD0_RDATTR_ERROR))
2955			goto fail;
2956		p = nfsd4_encode_rdattr_error(xdr, nfserr);
2957		if (p == NULL) {
2958			nfserr = nfserr_toosmall;
2959			goto fail;
2960		}
2961	}
2962	nfserr = nfserr_toosmall;
2963	entry_bytes = xdr->buf->len - start_offset;
2964	if (entry_bytes > cd->rd_maxcount)
2965		goto fail;
2966	cd->rd_maxcount -= entry_bytes;
2967	/*
2968	 * RFC 3530 14.2.24 describes rd_dircount as only a "hint", so
2969	 * let's always let through the first entry, at least:
2970	 */
2971	if (!cd->rd_dircount)
2972		goto fail;
2973	name_and_cookie = 4 + 4 * XDR_QUADLEN(namlen) + 8;
2974	if (name_and_cookie > cd->rd_dircount && cd->cookie_offset)
2975		goto fail;
2976	cd->rd_dircount -= min(cd->rd_dircount, name_and_cookie);
2977
2978	cd->cookie_offset = cookie_offset;
2979skip_entry:
2980	cd->common.err = nfs_ok;
2981	return 0;
2982fail:
2983	xdr_truncate_encode(xdr, start_offset);
2984	cd->common.err = nfserr;
2985	return -EINVAL;
2986}
2987
2988static __be32
2989nfsd4_encode_stateid(struct xdr_stream *xdr, stateid_t *sid)
2990{
2991	__be32 *p;
2992
2993	p = xdr_reserve_space(xdr, sizeof(stateid_t));
2994	if (!p)
2995		return nfserr_resource;
2996	*p++ = cpu_to_be32(sid->si_generation);
2997	p = xdr_encode_opaque_fixed(p, &sid->si_opaque,
2998					sizeof(stateid_opaque_t));
2999	return 0;
3000}
3001
3002static __be32
3003nfsd4_encode_access(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_access *access)
3004{
3005	struct xdr_stream *xdr = &resp->xdr;
3006	__be32 *p;
3007
3008	if (!nfserr) {
3009		p = xdr_reserve_space(xdr, 8);
3010		if (!p)
3011			return nfserr_resource;
3012		*p++ = cpu_to_be32(access->ac_supported);
3013		*p++ = cpu_to_be32(access->ac_resp_access);
3014	}
3015	return nfserr;
3016}
3017
3018static __be32 nfsd4_encode_bind_conn_to_session(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_bind_conn_to_session *bcts)
3019{
3020	struct xdr_stream *xdr = &resp->xdr;
3021	__be32 *p;
3022
3023	if (!nfserr) {
3024		p = xdr_reserve_space(xdr, NFS4_MAX_SESSIONID_LEN + 8);
3025		if (!p)
3026			return nfserr_resource;
3027		p = xdr_encode_opaque_fixed(p, bcts->sessionid.data,
3028						NFS4_MAX_SESSIONID_LEN);
3029		*p++ = cpu_to_be32(bcts->dir);
3030		/* Sorry, we do not yet support RDMA over 4.1: */
3031		*p++ = cpu_to_be32(0);
3032	}
3033	return nfserr;
3034}
3035
3036static __be32
3037nfsd4_encode_close(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_close *close)
3038{
3039	struct xdr_stream *xdr = &resp->xdr;
3040
3041	if (!nfserr)
3042		nfserr = nfsd4_encode_stateid(xdr, &close->cl_stateid);
3043
3044	return nfserr;
3045}
3046
3047
3048static __be32
3049nfsd4_encode_commit(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_commit *commit)
3050{
3051	struct xdr_stream *xdr = &resp->xdr;
3052	__be32 *p;
3053
3054	if (!nfserr) {
3055		p = xdr_reserve_space(xdr, NFS4_VERIFIER_SIZE);
3056		if (!p)
3057			return nfserr_resource;
3058		p = xdr_encode_opaque_fixed(p, commit->co_verf.data,
3059						NFS4_VERIFIER_SIZE);
3060	}
3061	return nfserr;
3062}
3063
3064static __be32
3065nfsd4_encode_create(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_create *create)
3066{
3067	struct xdr_stream *xdr = &resp->xdr;
3068	__be32 *p;
3069
3070	if (!nfserr) {
3071		p = xdr_reserve_space(xdr, 32);
3072		if (!p)
3073			return nfserr_resource;
3074		p = encode_cinfo(p, &create->cr_cinfo);
3075		*p++ = cpu_to_be32(2);
3076		*p++ = cpu_to_be32(create->cr_bmval[0]);
3077		*p++ = cpu_to_be32(create->cr_bmval[1]);
3078	}
3079	return nfserr;
3080}
3081
3082static __be32
3083nfsd4_encode_getattr(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_getattr *getattr)
3084{
3085	struct svc_fh *fhp = getattr->ga_fhp;
3086	struct xdr_stream *xdr = &resp->xdr;
3087
3088	if (nfserr)
3089		return nfserr;
3090
3091	nfserr = nfsd4_encode_fattr(xdr, fhp, fhp->fh_export, fhp->fh_dentry,
3092				    getattr->ga_bmval,
3093				    resp->rqstp, 0);
3094	return nfserr;
3095}
3096
3097static __be32
3098nfsd4_encode_getfh(struct nfsd4_compoundres *resp, __be32 nfserr, struct svc_fh **fhpp)
3099{
3100	struct xdr_stream *xdr = &resp->xdr;
3101	struct svc_fh *fhp = *fhpp;
3102	unsigned int len;
3103	__be32 *p;
3104
3105	if (!nfserr) {
3106		len = fhp->fh_handle.fh_size;
3107		p = xdr_reserve_space(xdr, len + 4);
3108		if (!p)
3109			return nfserr_resource;
3110		p = xdr_encode_opaque(p, &fhp->fh_handle.fh_base, len);
3111	}
3112	return nfserr;
3113}
3114
3115/*
3116* Including all fields other than the name, a LOCK4denied structure requires
3117*   8(clientid) + 4(namelen) + 8(offset) + 8(length) + 4(type) = 32 bytes.
3118*/
3119static __be32
3120nfsd4_encode_lock_denied(struct xdr_stream *xdr, struct nfsd4_lock_denied *ld)
3121{
3122	struct xdr_netobj *conf = &ld->ld_owner;
3123	__be32 *p;
3124
3125again:
3126	p = xdr_reserve_space(xdr, 32 + XDR_LEN(conf->len));
3127	if (!p) {
3128		/*
3129		 * Don't fail to return the result just because we can't
3130		 * return the conflicting open:
3131		 */
3132		if (conf->len) {
3133			kfree(conf->data);
3134			conf->len = 0;
3135			conf->data = NULL;
3136			goto again;
3137		}
3138		return nfserr_resource;
3139	}
3140	p = xdr_encode_hyper(p, ld->ld_start);
3141	p = xdr_encode_hyper(p, ld->ld_length);
3142	*p++ = cpu_to_be32(ld->ld_type);
3143	if (conf->len) {
3144		p = xdr_encode_opaque_fixed(p, &ld->ld_clientid, 8);
3145		p = xdr_encode_opaque(p, conf->data, conf->len);
3146		kfree(conf->data);
3147	}  else {  /* non - nfsv4 lock in conflict, no clientid nor owner */
3148		p = xdr_encode_hyper(p, (u64)0); /* clientid */
3149		*p++ = cpu_to_be32(0); /* length of owner name */
3150	}
3151	return nfserr_denied;
3152}
3153
3154static __be32
3155nfsd4_encode_lock(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_lock *lock)
3156{
3157	struct xdr_stream *xdr = &resp->xdr;
3158
3159	if (!nfserr)
3160		nfserr = nfsd4_encode_stateid(xdr, &lock->lk_resp_stateid);
3161	else if (nfserr == nfserr_denied)
3162		nfserr = nfsd4_encode_lock_denied(xdr, &lock->lk_denied);
3163
3164	return nfserr;
3165}
3166
3167static __be32
3168nfsd4_encode_lockt(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_lockt *lockt)
3169{
3170	struct xdr_stream *xdr = &resp->xdr;
3171
3172	if (nfserr == nfserr_denied)
3173		nfsd4_encode_lock_denied(xdr, &lockt->lt_denied);
3174	return nfserr;
3175}
3176
3177static __be32
3178nfsd4_encode_locku(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_locku *locku)
3179{
3180	struct xdr_stream *xdr = &resp->xdr;
3181
3182	if (!nfserr)
3183		nfserr = nfsd4_encode_stateid(xdr, &locku->lu_stateid);
3184
3185	return nfserr;
3186}
3187
3188
3189static __be32
3190nfsd4_encode_link(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_link *link)
3191{
3192	struct xdr_stream *xdr = &resp->xdr;
3193	__be32 *p;
3194
3195	if (!nfserr) {
3196		p = xdr_reserve_space(xdr, 20);
3197		if (!p)
3198			return nfserr_resource;
3199		p = encode_cinfo(p, &link->li_cinfo);
3200	}
3201	return nfserr;
3202}
3203
3204
3205static __be32
3206nfsd4_encode_open(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open *open)
3207{
3208	struct xdr_stream *xdr = &resp->xdr;
3209	__be32 *p;
3210
3211	if (nfserr)
3212		goto out;
3213
3214	nfserr = nfsd4_encode_stateid(xdr, &open->op_stateid);
3215	if (nfserr)
3216		goto out;
3217	p = xdr_reserve_space(xdr, 40);
3218	if (!p)
3219		return nfserr_resource;
3220	p = encode_cinfo(p, &open->op_cinfo);
3221	*p++ = cpu_to_be32(open->op_rflags);
3222	*p++ = cpu_to_be32(2);
3223	*p++ = cpu_to_be32(open->op_bmval[0]);
3224	*p++ = cpu_to_be32(open->op_bmval[1]);
3225	*p++ = cpu_to_be32(open->op_delegate_type);
3226
3227	switch (open->op_delegate_type) {
3228	case NFS4_OPEN_DELEGATE_NONE:
3229		break;
3230	case NFS4_OPEN_DELEGATE_READ:
3231		nfserr = nfsd4_encode_stateid(xdr, &open->op_delegate_stateid);
3232		if (nfserr)
3233			return nfserr;
3234		p = xdr_reserve_space(xdr, 20);
3235		if (!p)
3236			return nfserr_resource;
3237		*p++ = cpu_to_be32(open->op_recall);
3238
3239		/*
3240		 * TODO: ACE's in delegations
3241		 */
3242		*p++ = cpu_to_be32(NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE);
3243		*p++ = cpu_to_be32(0);
3244		*p++ = cpu_to_be32(0);
3245		*p++ = cpu_to_be32(0);   /* XXX: is NULL principal ok? */
3246		break;
3247	case NFS4_OPEN_DELEGATE_WRITE:
3248		nfserr = nfsd4_encode_stateid(xdr, &open->op_delegate_stateid);
3249		if (nfserr)
3250			return nfserr;
3251		p = xdr_reserve_space(xdr, 32);
3252		if (!p)
3253			return nfserr_resource;
3254		*p++ = cpu_to_be32(0);
3255
3256		/*
3257		 * TODO: space_limit's in delegations
3258		 */
3259		*p++ = cpu_to_be32(NFS4_LIMIT_SIZE);
3260		*p++ = cpu_to_be32(~(u32)0);
3261		*p++ = cpu_to_be32(~(u32)0);
3262
3263		/*
3264		 * TODO: ACE's in delegations
3265		 */
3266		*p++ = cpu_to_be32(NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE);
3267		*p++ = cpu_to_be32(0);
3268		*p++ = cpu_to_be32(0);
3269		*p++ = cpu_to_be32(0);   /* XXX: is NULL principal ok? */
3270		break;
3271	case NFS4_OPEN_DELEGATE_NONE_EXT: /* 4.1 */
3272		switch (open->op_why_no_deleg) {
3273		case WND4_CONTENTION:
3274		case WND4_RESOURCE:
3275			p = xdr_reserve_space(xdr, 8);
3276			if (!p)
3277				return nfserr_resource;
3278			*p++ = cpu_to_be32(open->op_why_no_deleg);
3279			/* deleg signaling not supported yet: */
3280			*p++ = cpu_to_be32(0);
3281			break;
3282		default:
3283			p = xdr_reserve_space(xdr, 4);
3284			if (!p)
3285				return nfserr_resource;
3286			*p++ = cpu_to_be32(open->op_why_no_deleg);
3287		}
3288		break;
3289	default:
3290		BUG();
3291	}
3292	/* XXX save filehandle here */
3293out:
3294	return nfserr;
3295}
3296
3297static __be32
3298nfsd4_encode_open_confirm(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open_confirm *oc)
3299{
3300	struct xdr_stream *xdr = &resp->xdr;
3301
3302	if (!nfserr)
3303		nfserr = nfsd4_encode_stateid(xdr, &oc->oc_resp_stateid);
3304
3305	return nfserr;
3306}
3307
3308static __be32
3309nfsd4_encode_open_downgrade(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open_downgrade *od)
3310{
3311	struct xdr_stream *xdr = &resp->xdr;
3312
3313	if (!nfserr)
3314		nfserr = nfsd4_encode_stateid(xdr, &od->od_stateid);
3315
3316	return nfserr;
3317}
3318
3319static __be32 nfsd4_encode_splice_read(
3320				struct nfsd4_compoundres *resp,
3321				struct nfsd4_read *read,
3322				struct file *file, unsigned long maxcount)
3323{
3324	struct xdr_stream *xdr = &resp->xdr;
3325	struct xdr_buf *buf = xdr->buf;
3326	u32 eof;
3327	int space_left;
3328	__be32 nfserr;
3329	__be32 *p = xdr->p - 2;
3330
3331	/* Make sure there will be room for padding if needed */
3332	if (xdr->end - xdr->p < 1)
3333		return nfserr_resource;
3334
3335	nfserr = nfsd_splice_read(read->rd_rqstp, file,
3336				  read->rd_offset, &maxcount);
3337	if (nfserr) {
3338		/*
3339		 * nfsd_splice_actor may have already messed with the
3340		 * page length; reset it so as not to confuse
3341		 * xdr_truncate_encode:
3342		 */
3343		buf->page_len = 0;
3344		return nfserr;
3345	}
3346
3347	eof = (read->rd_offset + maxcount >=
3348	       d_inode(read->rd_fhp->fh_dentry)->i_size);
3349
3350	*(p++) = htonl(eof);
3351	*(p++) = htonl(maxcount);
3352
3353	buf->page_len = maxcount;
3354	buf->len += maxcount;
3355	xdr->page_ptr += (buf->page_base + maxcount + PAGE_SIZE - 1)
3356							/ PAGE_SIZE;
3357
3358	/* Use rest of head for padding and remaining ops: */
3359	buf->tail[0].iov_base = xdr->p;
3360	buf->tail[0].iov_len = 0;
3361	xdr->iov = buf->tail;
3362	if (maxcount&3) {
3363		int pad = 4 - (maxcount&3);
3364
3365		*(xdr->p++) = 0;
3366
3367		buf->tail[0].iov_base += maxcount&3;
3368		buf->tail[0].iov_len = pad;
3369		buf->len += pad;
3370	}
3371
3372	space_left = min_t(int, (void *)xdr->end - (void *)xdr->p,
3373				buf->buflen - buf->len);
3374	buf->buflen = buf->len + space_left;
3375	xdr->end = (__be32 *)((void *)xdr->end + space_left);
3376
3377	return 0;
3378}
3379
3380static __be32 nfsd4_encode_readv(struct nfsd4_compoundres *resp,
3381				 struct nfsd4_read *read,
3382				 struct file *file, unsigned long maxcount)
3383{
3384	struct xdr_stream *xdr = &resp->xdr;
3385	u32 eof;
3386	int v;
3387	int starting_len = xdr->buf->len - 8;
3388	long len;
3389	int thislen;
3390	__be32 nfserr;
3391	__be32 tmp;
3392	__be32 *p;
3393	u32 zzz = 0;
3394	int pad;
3395
3396	len = maxcount;
3397	v = 0;
3398
3399	thislen = min_t(long, len, ((void *)xdr->end - (void *)xdr->p));
3400	p = xdr_reserve_space(xdr, (thislen+3)&~3);
3401	WARN_ON_ONCE(!p);
3402	resp->rqstp->rq_vec[v].iov_base = p;
3403	resp->rqstp->rq_vec[v].iov_len = thislen;
3404	v++;
3405	len -= thislen;
3406
3407	while (len) {
3408		thislen = min_t(long, len, PAGE_SIZE);
3409		p = xdr_reserve_space(xdr, (thislen+3)&~3);
3410		WARN_ON_ONCE(!p);
3411		resp->rqstp->rq_vec[v].iov_base = p;
3412		resp->rqstp->rq_vec[v].iov_len = thislen;
3413		v++;
3414		len -= thislen;
3415	}
3416	read->rd_vlen = v;
3417
3418	nfserr = nfsd_readv(file, read->rd_offset, resp->rqstp->rq_vec,
3419			read->rd_vlen, &maxcount);
3420	if (nfserr)
3421		return nfserr;
3422	xdr_truncate_encode(xdr, starting_len + 8 + ((maxcount+3)&~3));
3423
3424	eof = (read->rd_offset + maxcount >=
3425	       d_inode(read->rd_fhp->fh_dentry)->i_size);
3426
3427	tmp = htonl(eof);
3428	write_bytes_to_xdr_buf(xdr->buf, starting_len    , &tmp, 4);
3429	tmp = htonl(maxcount);
3430	write_bytes_to_xdr_buf(xdr->buf, starting_len + 4, &tmp, 4);
3431
3432	pad = (maxcount&3) ? 4 - (maxcount&3) : 0;
3433	write_bytes_to_xdr_buf(xdr->buf, starting_len + 8 + maxcount,
3434								&zzz, pad);
3435	return 0;
3436
3437}
3438
3439static __be32
3440nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr,
3441		  struct nfsd4_read *read)
3442{
3443	unsigned long maxcount;
3444	struct xdr_stream *xdr = &resp->xdr;
3445	struct file *file = read->rd_filp;
3446	struct svc_fh *fhp = read->rd_fhp;
3447	int starting_len = xdr->buf->len;
3448	struct raparms *ra;
3449	__be32 *p;
3450	__be32 err;
3451
3452	if (nfserr)
3453		return nfserr;
3454
3455	p = xdr_reserve_space(xdr, 8); /* eof flag and byte count */
3456	if (!p) {
3457		WARN_ON_ONCE(test_bit(RQ_SPLICE_OK, &resp->rqstp->rq_flags));
3458		return nfserr_resource;
3459	}
3460	if (resp->xdr.buf->page_len && test_bit(RQ_SPLICE_OK, &resp->rqstp->rq_flags)) {
3461		WARN_ON_ONCE(1);
3462		return nfserr_resource;
3463	}
3464	xdr_commit_encode(xdr);
3465
3466	maxcount = svc_max_payload(resp->rqstp);
3467	maxcount = min_t(unsigned long, maxcount, (xdr->buf->buflen - xdr->buf->len));
3468	maxcount = min_t(unsigned long, maxcount, read->rd_length);
3469
3470	if (read->rd_filp)
3471		err = nfsd_permission(resp->rqstp, fhp->fh_export,
3472				fhp->fh_dentry,
3473				NFSD_MAY_READ|NFSD_MAY_OWNER_OVERRIDE);
3474	else
3475		err = nfsd_get_tmp_read_open(resp->rqstp, read->rd_fhp,
3476						&file, &ra);
3477	if (err)
3478		goto err_truncate;
3479
3480	if (file->f_op->splice_read && test_bit(RQ_SPLICE_OK, &resp->rqstp->rq_flags))
3481		err = nfsd4_encode_splice_read(resp, read, file, maxcount);
3482	else
3483		err = nfsd4_encode_readv(resp, read, file, maxcount);
3484
3485	if (!read->rd_filp)
3486		nfsd_put_tmp_read_open(file, ra);
3487
3488err_truncate:
3489	if (err)
3490		xdr_truncate_encode(xdr, starting_len);
3491	return err;
3492}
3493
3494static __be32
3495nfsd4_encode_readlink(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_readlink *readlink)
3496{
3497	int maxcount;
3498	__be32 wire_count;
3499	int zero = 0;
3500	struct xdr_stream *xdr = &resp->xdr;
3501	int length_offset = xdr->buf->len;
3502	__be32 *p;
3503
3504	if (nfserr)
3505		return nfserr;
3506
3507	p = xdr_reserve_space(xdr, 4);
3508	if (!p)
3509		return nfserr_resource;
3510	maxcount = PAGE_SIZE;
3511
3512	p = xdr_reserve_space(xdr, maxcount);
3513	if (!p)
3514		return nfserr_resource;
3515	/*
3516	 * XXX: By default, the ->readlink() VFS op will truncate symlinks
3517	 * if they would overflow the buffer.  Is this kosher in NFSv4?  If
3518	 * not, one easy fix is: if ->readlink() precisely fills the buffer,
3519	 * assume that truncation occurred, and return NFS4ERR_RESOURCE.
3520	 */
3521	nfserr = nfsd_readlink(readlink->rl_rqstp, readlink->rl_fhp,
3522						(char *)p, &maxcount);
3523	if (nfserr == nfserr_isdir)
3524		nfserr = nfserr_inval;
3525	if (nfserr) {
3526		xdr_truncate_encode(xdr, length_offset);
3527		return nfserr;
3528	}
3529
3530	wire_count = htonl(maxcount);
3531	write_bytes_to_xdr_buf(xdr->buf, length_offset, &wire_count, 4);
3532	xdr_truncate_encode(xdr, length_offset + 4 + ALIGN(maxcount, 4));
3533	if (maxcount & 3)
3534		write_bytes_to_xdr_buf(xdr->buf, length_offset + 4 + maxcount,
3535						&zero, 4 - (maxcount&3));
3536	return 0;
3537}
3538
3539static __be32
3540nfsd4_encode_readdir(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_readdir *readdir)
3541{
3542	int maxcount;
3543	int bytes_left;
3544	loff_t offset;
3545	__be64 wire_offset;
3546	struct xdr_stream *xdr = &resp->xdr;
3547	int starting_len = xdr->buf->len;
3548	__be32 *p;
3549
3550	if (nfserr)
3551		return nfserr;
3552
3553	p = xdr_reserve_space(xdr, NFS4_VERIFIER_SIZE);
3554	if (!p)
3555		return nfserr_resource;
3556
3557	/* XXX: Following NFSv3, we ignore the READDIR verifier for now. */
3558	*p++ = cpu_to_be32(0);
3559	*p++ = cpu_to_be32(0);
3560	resp->xdr.buf->head[0].iov_len = ((char *)resp->xdr.p)
3561				- (char *)resp->xdr.buf->head[0].iov_base;
3562
3563	/*
3564	 * Number of bytes left for directory entries allowing for the
3565	 * final 8 bytes of the readdir and a following failed op:
3566	 */
3567	bytes_left = xdr->buf->buflen - xdr->buf->len
3568			- COMPOUND_ERR_SLACK_SPACE - 8;
3569	if (bytes_left < 0) {
3570		nfserr = nfserr_resource;
3571		goto err_no_verf;
3572	}
3573	maxcount = min_t(u32, readdir->rd_maxcount, INT_MAX);
3574	/*
3575	 * Note the rfc defines rd_maxcount as the size of the
3576	 * READDIR4resok structure, which includes the verifier above
3577	 * and the 8 bytes encoded at the end of this function:
3578	 */
3579	if (maxcount < 16) {
3580		nfserr = nfserr_toosmall;
3581		goto err_no_verf;
3582	}
3583	maxcount = min_t(int, maxcount-16, bytes_left);
3584
3585	/* RFC 3530 14.2.24 allows us to ignore dircount when it's 0: */
3586	if (!readdir->rd_dircount)
3587		readdir->rd_dircount = INT_MAX;
3588
3589	readdir->xdr = xdr;
3590	readdir->rd_maxcount = maxcount;
3591	readdir->common.err = 0;
3592	readdir->cookie_offset = 0;
3593
3594	offset = readdir->rd_cookie;
3595	nfserr = nfsd_readdir(readdir->rd_rqstp, readdir->rd_fhp,
3596			      &offset,
3597			      &readdir->common, nfsd4_encode_dirent);
3598	if (nfserr == nfs_ok &&
3599	    readdir->common.err == nfserr_toosmall &&
3600	    xdr->buf->len == starting_len + 8) {
3601		/* nothing encoded; which limit did we hit?: */
3602		if (maxcount - 16 < bytes_left)
3603			/* It was the fault of rd_maxcount: */
3604			nfserr = nfserr_toosmall;
3605		else
3606			/* We ran out of buffer space: */
3607			nfserr = nfserr_resource;
3608	}
3609	if (nfserr)
3610		goto err_no_verf;
3611
3612	if (readdir->cookie_offset) {
3613		wire_offset = cpu_to_be64(offset);
3614		write_bytes_to_xdr_buf(xdr->buf, readdir->cookie_offset,
3615							&wire_offset, 8);
3616	}
3617
3618	p = xdr_reserve_space(xdr, 8);
3619	if (!p) {
3620		WARN_ON_ONCE(1);
3621		goto err_no_verf;
3622	}
3623	*p++ = 0;	/* no more entries */
3624	*p++ = htonl(readdir->common.err == nfserr_eof);
3625
3626	return 0;
3627err_no_verf:
3628	xdr_truncate_encode(xdr, starting_len);
3629	return nfserr;
3630}
3631
3632static __be32
3633nfsd4_encode_remove(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_remove *remove)
3634{
3635	struct xdr_stream *xdr = &resp->xdr;
3636	__be32 *p;
3637
3638	if (!nfserr) {
3639		p = xdr_reserve_space(xdr, 20);
3640		if (!p)
3641			return nfserr_resource;
3642		p = encode_cinfo(p, &remove->rm_cinfo);
3643	}
3644	return nfserr;
3645}
3646
3647static __be32
3648nfsd4_encode_rename(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_rename *rename)
3649{
3650	struct xdr_stream *xdr = &resp->xdr;
3651	__be32 *p;
3652
3653	if (!nfserr) {
3654		p = xdr_reserve_space(xdr, 40);
3655		if (!p)
3656			return nfserr_resource;
3657		p = encode_cinfo(p, &rename->rn_sinfo);
3658		p = encode_cinfo(p, &rename->rn_tinfo);
3659	}
3660	return nfserr;
3661}
3662
3663static __be32
3664nfsd4_do_encode_secinfo(struct xdr_stream *xdr,
3665			 __be32 nfserr, struct svc_export *exp)
3666{
3667	u32 i, nflavs, supported;
3668	struct exp_flavor_info *flavs;
3669	struct exp_flavor_info def_flavs[2];
3670	__be32 *p, *flavorsp;
3671	static bool report = true;
3672
3673	if (nfserr)
3674		goto out;
3675	nfserr = nfserr_resource;
3676	if (exp->ex_nflavors) {
3677		flavs = exp->ex_flavors;
3678		nflavs = exp->ex_nflavors;
3679	} else { /* Handling of some defaults in absence of real secinfo: */
3680		flavs = def_flavs;
3681		if (exp->ex_client->flavour->flavour == RPC_AUTH_UNIX) {
3682			nflavs = 2;
3683			flavs[0].pseudoflavor = RPC_AUTH_UNIX;
3684			flavs[1].pseudoflavor = RPC_AUTH_NULL;
3685		} else if (exp->ex_client->flavour->flavour == RPC_AUTH_GSS) {
3686			nflavs = 1;
3687			flavs[0].pseudoflavor
3688					= svcauth_gss_flavor(exp->ex_client);
3689		} else {
3690			nflavs = 1;
3691			flavs[0].pseudoflavor
3692					= exp->ex_client->flavour->flavour;
3693		}
3694	}
3695
3696	supported = 0;
3697	p = xdr_reserve_space(xdr, 4);
3698	if (!p)
3699		goto out;
3700	flavorsp = p++;		/* to be backfilled later */
3701
3702	for (i = 0; i < nflavs; i++) {
3703		rpc_authflavor_t pf = flavs[i].pseudoflavor;
3704		struct rpcsec_gss_info info;
3705
3706		if (rpcauth_get_gssinfo(pf, &info) == 0) {
3707			supported++;
3708			p = xdr_reserve_space(xdr, 4 + 4 +
3709					      XDR_LEN(info.oid.len) + 4 + 4);
3710			if (!p)
3711				goto out;
3712			*p++ = cpu_to_be32(RPC_AUTH_GSS);
3713			p = xdr_encode_opaque(p,  info.oid.data, info.oid.len);
3714			*p++ = cpu_to_be32(info.qop);
3715			*p++ = cpu_to_be32(info.service);
3716		} else if (pf < RPC_AUTH_MAXFLAVOR) {
3717			supported++;
3718			p = xdr_reserve_space(xdr, 4);
3719			if (!p)
3720				goto out;
3721			*p++ = cpu_to_be32(pf);
3722		} else {
3723			if (report)
3724				pr_warn("NFS: SECINFO: security flavor %u "
3725					"is not supported\n", pf);
3726		}
3727	}
3728
3729	if (nflavs != supported)
3730		report = false;
3731	*flavorsp = htonl(supported);
3732	nfserr = 0;
3733out:
3734	if (exp)
3735		exp_put(exp);
3736	return nfserr;
3737}
3738
3739static __be32
3740nfsd4_encode_secinfo(struct nfsd4_compoundres *resp, __be32 nfserr,
3741		     struct nfsd4_secinfo *secinfo)
3742{
3743	struct xdr_stream *xdr = &resp->xdr;
3744
3745	return nfsd4_do_encode_secinfo(xdr, nfserr, secinfo->si_exp);
3746}
3747
3748static __be32
3749nfsd4_encode_secinfo_no_name(struct nfsd4_compoundres *resp, __be32 nfserr,
3750		     struct nfsd4_secinfo_no_name *secinfo)
3751{
3752	struct xdr_stream *xdr = &resp->xdr;
3753
3754	return nfsd4_do_encode_secinfo(xdr, nfserr, secinfo->sin_exp);
3755}
3756
3757/*
3758 * The SETATTR encode routine is special -- it always encodes a bitmap,
3759 * regardless of the error status.
3760 */
3761static __be32
3762nfsd4_encode_setattr(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_setattr *setattr)
3763{
3764	struct xdr_stream *xdr = &resp->xdr;
3765	__be32 *p;
3766
3767	p = xdr_reserve_space(xdr, 16);
3768	if (!p)
3769		return nfserr_resource;
3770	if (nfserr) {
3771		*p++ = cpu_to_be32(3);
3772		*p++ = cpu_to_be32(0);
3773		*p++ = cpu_to_be32(0);
3774		*p++ = cpu_to_be32(0);
3775	}
3776	else {
3777		*p++ = cpu_to_be32(3);
3778		*p++ = cpu_to_be32(setattr->sa_bmval[0]);
3779		*p++ = cpu_to_be32(setattr->sa_bmval[1]);
3780		*p++ = cpu_to_be32(setattr->sa_bmval[2]);
3781	}
3782	return nfserr;
3783}
3784
3785static __be32
3786nfsd4_encode_setclientid(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_setclientid *scd)
3787{
3788	struct xdr_stream *xdr = &resp->xdr;
3789	__be32 *p;
3790
3791	if (!nfserr) {
3792		p = xdr_reserve_space(xdr, 8 + NFS4_VERIFIER_SIZE);
3793		if (!p)
3794			return nfserr_resource;
3795		p = xdr_encode_opaque_fixed(p, &scd->se_clientid, 8);
3796		p = xdr_encode_opaque_fixed(p, &scd->se_confirm,
3797						NFS4_VERIFIER_SIZE);
3798	}
3799	else if (nfserr == nfserr_clid_inuse) {
3800		p = xdr_reserve_space(xdr, 8);
3801		if (!p)
3802			return nfserr_resource;
3803		*p++ = cpu_to_be32(0);
3804		*p++ = cpu_to_be32(0);
3805	}
3806	return nfserr;
3807}
3808
3809static __be32
3810nfsd4_encode_write(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_write *write)
3811{
3812	struct xdr_stream *xdr = &resp->xdr;
3813	__be32 *p;
3814
3815	if (!nfserr) {
3816		p = xdr_reserve_space(xdr, 16);
3817		if (!p)
3818			return nfserr_resource;
3819		*p++ = cpu_to_be32(write->wr_bytes_written);
3820		*p++ = cpu_to_be32(write->wr_how_written);
3821		p = xdr_encode_opaque_fixed(p, write->wr_verifier.data,
3822							NFS4_VERIFIER_SIZE);
3823	}
3824	return nfserr;
3825}
3826
3827static const u32 nfs4_minimal_spo_must_enforce[2] = {
3828	[1] = 1 << (OP_BIND_CONN_TO_SESSION - 32) |
3829	      1 << (OP_EXCHANGE_ID - 32) |
3830	      1 << (OP_CREATE_SESSION - 32) |
3831	      1 << (OP_DESTROY_SESSION - 32) |
3832	      1 << (OP_DESTROY_CLIENTID - 32)
3833};
3834
3835static __be32
3836nfsd4_encode_exchange_id(struct nfsd4_compoundres *resp, __be32 nfserr,
3837			 struct nfsd4_exchange_id *exid)
3838{
3839	struct xdr_stream *xdr = &resp->xdr;
3840	__be32 *p;
3841	char *major_id;
3842	char *server_scope;
3843	int major_id_sz;
3844	int server_scope_sz;
3845	uint64_t minor_id = 0;
3846
3847	if (nfserr)
3848		return nfserr;
3849
3850	major_id = utsname()->nodename;
3851	major_id_sz = strlen(major_id);
3852	server_scope = utsname()->nodename;
3853	server_scope_sz = strlen(server_scope);
3854
3855	p = xdr_reserve_space(xdr,
3856		8 /* eir_clientid */ +
3857		4 /* eir_sequenceid */ +
3858		4 /* eir_flags */ +
3859		4 /* spr_how */);
3860	if (!p)
3861		return nfserr_resource;
3862
3863	p = xdr_encode_opaque_fixed(p, &exid->clientid, 8);
3864	*p++ = cpu_to_be32(exid->seqid);
3865	*p++ = cpu_to_be32(exid->flags);
3866
3867	*p++ = cpu_to_be32(exid->spa_how);
3868
3869	switch (exid->spa_how) {
3870	case SP4_NONE:
3871		break;
3872	case SP4_MACH_CRED:
3873		/* spo_must_enforce, spo_must_allow */
3874		p = xdr_reserve_space(xdr, 16);
3875		if (!p)
3876			return nfserr_resource;
3877
3878		/* spo_must_enforce bitmap: */
3879		*p++ = cpu_to_be32(2);
3880		*p++ = cpu_to_be32(nfs4_minimal_spo_must_enforce[0]);
3881		*p++ = cpu_to_be32(nfs4_minimal_spo_must_enforce[1]);
3882		/* empty spo_must_allow bitmap: */
3883		*p++ = cpu_to_be32(0);
3884
3885		break;
3886	default:
3887		WARN_ON_ONCE(1);
3888	}
3889
3890	p = xdr_reserve_space(xdr,
3891		8 /* so_minor_id */ +
3892		4 /* so_major_id.len */ +
3893		(XDR_QUADLEN(major_id_sz) * 4) +
3894		4 /* eir_server_scope.len */ +
3895		(XDR_QUADLEN(server_scope_sz) * 4) +
3896		4 /* eir_server_impl_id.count (0) */);
3897	if (!p)
3898		return nfserr_resource;
3899
3900	/* The server_owner struct */
3901	p = xdr_encode_hyper(p, minor_id);      /* Minor id */
3902	/* major id */
3903	p = xdr_encode_opaque(p, major_id, major_id_sz);
3904
3905	/* Server scope */
3906	p = xdr_encode_opaque(p, server_scope, server_scope_sz);
3907
3908	/* Implementation id */
3909	*p++ = cpu_to_be32(0);	/* zero length nfs_impl_id4 array */
3910	return 0;
3911}
3912
3913static __be32
3914nfsd4_encode_create_session(struct nfsd4_compoundres *resp, __be32 nfserr,
3915			    struct nfsd4_create_session *sess)
3916{
3917	struct xdr_stream *xdr = &resp->xdr;
3918	__be32 *p;
3919
3920	if (nfserr)
3921		return nfserr;
3922
3923	p = xdr_reserve_space(xdr, 24);
3924	if (!p)
3925		return nfserr_resource;
3926	p = xdr_encode_opaque_fixed(p, sess->sessionid.data,
3927					NFS4_MAX_SESSIONID_LEN);
3928	*p++ = cpu_to_be32(sess->seqid);
3929	*p++ = cpu_to_be32(sess->flags);
3930
3931	p = xdr_reserve_space(xdr, 28);
3932	if (!p)
3933		return nfserr_resource;
3934	*p++ = cpu_to_be32(0); /* headerpadsz */
3935	*p++ = cpu_to_be32(sess->fore_channel.maxreq_sz);
3936	*p++ = cpu_to_be32(sess->fore_channel.maxresp_sz);
3937	*p++ = cpu_to_be32(sess->fore_channel.maxresp_cached);
3938	*p++ = cpu_to_be32(sess->fore_channel.maxops);
3939	*p++ = cpu_to_be32(sess->fore_channel.maxreqs);
3940	*p++ = cpu_to_be32(sess->fore_channel.nr_rdma_attrs);
3941
3942	if (sess->fore_channel.nr_rdma_attrs) {
3943		p = xdr_reserve_space(xdr, 4);
3944		if (!p)
3945			return nfserr_resource;
3946		*p++ = cpu_to_be32(sess->fore_channel.rdma_attrs);
3947	}
3948
3949	p = xdr_reserve_space(xdr, 28);
3950	if (!p)
3951		return nfserr_resource;
3952	*p++ = cpu_to_be32(0); /* headerpadsz */
3953	*p++ = cpu_to_be32(sess->back_channel.maxreq_sz);
3954	*p++ = cpu_to_be32(sess->back_channel.maxresp_sz);
3955	*p++ = cpu_to_be32(sess->back_channel.maxresp_cached);
3956	*p++ = cpu_to_be32(sess->back_channel.maxops);
3957	*p++ = cpu_to_be32(sess->back_channel.maxreqs);
3958	*p++ = cpu_to_be32(sess->back_channel.nr_rdma_attrs);
3959
3960	if (sess->back_channel.nr_rdma_attrs) {
3961		p = xdr_reserve_space(xdr, 4);
3962		if (!p)
3963			return nfserr_resource;
3964		*p++ = cpu_to_be32(sess->back_channel.rdma_attrs);
3965	}
3966	return 0;
3967}
3968
3969static __be32
3970nfsd4_encode_sequence(struct nfsd4_compoundres *resp, __be32 nfserr,
3971		      struct nfsd4_sequence *seq)
3972{
3973	struct xdr_stream *xdr = &resp->xdr;
3974	__be32 *p;
3975
3976	if (nfserr)
3977		return nfserr;
3978
3979	p = xdr_reserve_space(xdr, NFS4_MAX_SESSIONID_LEN + 20);
3980	if (!p)
3981		return nfserr_resource;
3982	p = xdr_encode_opaque_fixed(p, seq->sessionid.data,
3983					NFS4_MAX_SESSIONID_LEN);
3984	*p++ = cpu_to_be32(seq->seqid);
3985	*p++ = cpu_to_be32(seq->slotid);
3986	/* Note slotid's are numbered from zero: */
3987	*p++ = cpu_to_be32(seq->maxslots - 1); /* sr_highest_slotid */
3988	*p++ = cpu_to_be32(seq->maxslots - 1); /* sr_target_highest_slotid */
3989	*p++ = cpu_to_be32(seq->status_flags);
3990
3991	resp->cstate.data_offset = xdr->buf->len; /* DRC cache data pointer */
3992	return 0;
3993}
3994
3995static __be32
3996nfsd4_encode_test_stateid(struct nfsd4_compoundres *resp, __be32 nfserr,
3997			  struct nfsd4_test_stateid *test_stateid)
3998{
3999	struct xdr_stream *xdr = &resp->xdr;
4000	struct nfsd4_test_stateid_id *stateid, *next;
4001	__be32 *p;
4002
4003	if (nfserr)
4004		return nfserr;
4005
4006	p = xdr_reserve_space(xdr, 4 + (4 * test_stateid->ts_num_ids));
4007	if (!p)
4008		return nfserr_resource;
4009	*p++ = htonl(test_stateid->ts_num_ids);
4010
4011	list_for_each_entry_safe(stateid, next, &test_stateid->ts_stateid_list, ts_id_list) {
4012		*p++ = stateid->ts_id_status;
4013	}
4014
4015	return nfserr;
4016}
4017
4018#ifdef CONFIG_NFSD_PNFS
4019static __be32
4020nfsd4_encode_getdeviceinfo(struct nfsd4_compoundres *resp, __be32 nfserr,
4021		struct nfsd4_getdeviceinfo *gdev)
4022{
4023	struct xdr_stream *xdr = &resp->xdr;
4024	const struct nfsd4_layout_ops *ops =
4025		nfsd4_layout_ops[gdev->gd_layout_type];
4026	u32 starting_len = xdr->buf->len, needed_len;
4027	__be32 *p;
4028
4029	dprintk("%s: err %d\n", __func__, nfserr);
4030	if (nfserr)
4031		goto out;
4032
4033	nfserr = nfserr_resource;
4034	p = xdr_reserve_space(xdr, 4);
4035	if (!p)
4036		goto out;
4037
4038	*p++ = cpu_to_be32(gdev->gd_layout_type);
4039
4040	/* If maxcount is 0 then just update notifications */
4041	if (gdev->gd_maxcount != 0) {
4042		nfserr = ops->encode_getdeviceinfo(xdr, gdev);
4043		if (nfserr) {
4044			/*
4045			 * We don't bother to burden the layout drivers with
4046			 * enforcing gd_maxcount, just tell the client to
4047			 * come back with a bigger buffer if it's not enough.
4048			 */
4049			if (xdr->buf->len + 4 > gdev->gd_maxcount)
4050				goto toosmall;
4051			goto out;
4052		}
4053	}
4054
4055	nfserr = nfserr_resource;
4056	if (gdev->gd_notify_types) {
4057		p = xdr_reserve_space(xdr, 4 + 4);
4058		if (!p)
4059			goto out;
4060		*p++ = cpu_to_be32(1);			/* bitmap length */
4061		*p++ = cpu_to_be32(gdev->gd_notify_types);
4062	} else {
4063		p = xdr_reserve_space(xdr, 4);
4064		if (!p)
4065			goto out;
4066		*p++ = 0;
4067	}
4068
4069	nfserr = 0;
4070out:
4071	kfree(gdev->gd_device);
4072	dprintk("%s: done: %d\n", __func__, be32_to_cpu(nfserr));
4073	return nfserr;
4074
4075toosmall:
4076	dprintk("%s: maxcount too small\n", __func__);
4077	needed_len = xdr->buf->len + 4 /* notifications */;
4078	xdr_truncate_encode(xdr, starting_len);
4079	p = xdr_reserve_space(xdr, 4);
4080	if (!p) {
4081		nfserr = nfserr_resource;
4082	} else {
4083		*p++ = cpu_to_be32(needed_len);
4084		nfserr = nfserr_toosmall;
4085	}
4086	goto out;
4087}
4088
4089static __be32
4090nfsd4_encode_layoutget(struct nfsd4_compoundres *resp, __be32 nfserr,
4091		struct nfsd4_layoutget *lgp)
4092{
4093	struct xdr_stream *xdr = &resp->xdr;
4094	const struct nfsd4_layout_ops *ops =
4095		nfsd4_layout_ops[lgp->lg_layout_type];
4096	__be32 *p;
4097
4098	dprintk("%s: err %d\n", __func__, nfserr);
4099	if (nfserr)
4100		goto out;
4101
4102	nfserr = nfserr_resource;
4103	p = xdr_reserve_space(xdr, 36 + sizeof(stateid_opaque_t));
4104	if (!p)
4105		goto out;
4106
4107	*p++ = cpu_to_be32(1);	/* we always set return-on-close */
4108	*p++ = cpu_to_be32(lgp->lg_sid.si_generation);
4109	p = xdr_encode_opaque_fixed(p, &lgp->lg_sid.si_opaque,
4110				    sizeof(stateid_opaque_t));
4111
4112	*p++ = cpu_to_be32(1);	/* we always return a single layout */
4113	p = xdr_encode_hyper(p, lgp->lg_seg.offset);
4114	p = xdr_encode_hyper(p, lgp->lg_seg.length);
4115	*p++ = cpu_to_be32(lgp->lg_seg.iomode);
4116	*p++ = cpu_to_be32(lgp->lg_layout_type);
4117
4118	nfserr = ops->encode_layoutget(xdr, lgp);
4119out:
4120	kfree(lgp->lg_content);
4121	return nfserr;
4122}
4123
4124static __be32
4125nfsd4_encode_layoutcommit(struct nfsd4_compoundres *resp, __be32 nfserr,
4126			  struct nfsd4_layoutcommit *lcp)
4127{
4128	struct xdr_stream *xdr = &resp->xdr;
4129	__be32 *p;
4130
4131	if (nfserr)
4132		return nfserr;
4133
4134	p = xdr_reserve_space(xdr, 4);
4135	if (!p)
4136		return nfserr_resource;
4137	*p++ = cpu_to_be32(lcp->lc_size_chg);
4138	if (lcp->lc_size_chg) {
4139		p = xdr_reserve_space(xdr, 8);
4140		if (!p)
4141			return nfserr_resource;
4142		p = xdr_encode_hyper(p, lcp->lc_newsize);
4143	}
4144
4145	return nfs_ok;
4146}
4147
4148static __be32
4149nfsd4_encode_layoutreturn(struct nfsd4_compoundres *resp, __be32 nfserr,
4150		struct nfsd4_layoutreturn *lrp)
4151{
4152	struct xdr_stream *xdr = &resp->xdr;
4153	__be32 *p;
4154
4155	if (nfserr)
4156		return nfserr;
4157
4158	p = xdr_reserve_space(xdr, 4);
4159	if (!p)
4160		return nfserr_resource;
4161	*p++ = cpu_to_be32(lrp->lrs_present);
4162	if (lrp->lrs_present)
4163		return nfsd4_encode_stateid(xdr, &lrp->lr_sid);
4164	return nfs_ok;
4165}
4166#endif /* CONFIG_NFSD_PNFS */
4167
4168static __be32
4169nfsd4_encode_seek(struct nfsd4_compoundres *resp, __be32 nfserr,
4170		  struct nfsd4_seek *seek)
4171{
4172	__be32 *p;
4173
4174	if (nfserr)
4175		return nfserr;
4176
4177	p = xdr_reserve_space(&resp->xdr, 4 + 8);
4178	*p++ = cpu_to_be32(seek->seek_eof);
4179	p = xdr_encode_hyper(p, seek->seek_pos);
4180
4181	return nfserr;
4182}
4183
4184static __be32
4185nfsd4_encode_noop(struct nfsd4_compoundres *resp, __be32 nfserr, void *p)
4186{
4187	return nfserr;
4188}
4189
4190typedef __be32(* nfsd4_enc)(struct nfsd4_compoundres *, __be32, void *);
4191
4192/*
4193 * Note: nfsd4_enc_ops vector is shared for v4.0 and v4.1
4194 * since we don't need to filter out obsolete ops as this is
4195 * done in the decoding phase.
4196 */
4197static nfsd4_enc nfsd4_enc_ops[] = {
4198	[OP_ACCESS]		= (nfsd4_enc)nfsd4_encode_access,
4199	[OP_CLOSE]		= (nfsd4_enc)nfsd4_encode_close,
4200	[OP_COMMIT]		= (nfsd4_enc)nfsd4_encode_commit,
4201	[OP_CREATE]		= (nfsd4_enc)nfsd4_encode_create,
4202	[OP_DELEGPURGE]		= (nfsd4_enc)nfsd4_encode_noop,
4203	[OP_DELEGRETURN]	= (nfsd4_enc)nfsd4_encode_noop,
4204	[OP_GETATTR]		= (nfsd4_enc)nfsd4_encode_getattr,
4205	[OP_GETFH]		= (nfsd4_enc)nfsd4_encode_getfh,
4206	[OP_LINK]		= (nfsd4_enc)nfsd4_encode_link,
4207	[OP_LOCK]		= (nfsd4_enc)nfsd4_encode_lock,
4208	[OP_LOCKT]		= (nfsd4_enc)nfsd4_encode_lockt,
4209	[OP_LOCKU]		= (nfsd4_enc)nfsd4_encode_locku,
4210	[OP_LOOKUP]		= (nfsd4_enc)nfsd4_encode_noop,
4211	[OP_LOOKUPP]		= (nfsd4_enc)nfsd4_encode_noop,
4212	[OP_NVERIFY]		= (nfsd4_enc)nfsd4_encode_noop,
4213	[OP_OPEN]		= (nfsd4_enc)nfsd4_encode_open,
4214	[OP_OPENATTR]		= (nfsd4_enc)nfsd4_encode_noop,
4215	[OP_OPEN_CONFIRM]	= (nfsd4_enc)nfsd4_encode_open_confirm,
4216	[OP_OPEN_DOWNGRADE]	= (nfsd4_enc)nfsd4_encode_open_downgrade,
4217	[OP_PUTFH]		= (nfsd4_enc)nfsd4_encode_noop,
4218	[OP_PUTPUBFH]		= (nfsd4_enc)nfsd4_encode_noop,
4219	[OP_PUTROOTFH]		= (nfsd4_enc)nfsd4_encode_noop,
4220	[OP_READ]		= (nfsd4_enc)nfsd4_encode_read,
4221	[OP_READDIR]		= (nfsd4_enc)nfsd4_encode_readdir,
4222	[OP_READLINK]		= (nfsd4_enc)nfsd4_encode_readlink,
4223	[OP_REMOVE]		= (nfsd4_enc)nfsd4_encode_remove,
4224	[OP_RENAME]		= (nfsd4_enc)nfsd4_encode_rename,
4225	[OP_RENEW]		= (nfsd4_enc)nfsd4_encode_noop,
4226	[OP_RESTOREFH]		= (nfsd4_enc)nfsd4_encode_noop,
4227	[OP_SAVEFH]		= (nfsd4_enc)nfsd4_encode_noop,
4228	[OP_SECINFO]		= (nfsd4_enc)nfsd4_encode_secinfo,
4229	[OP_SETATTR]		= (nfsd4_enc)nfsd4_encode_setattr,
4230	[OP_SETCLIENTID]	= (nfsd4_enc)nfsd4_encode_setclientid,
4231	[OP_SETCLIENTID_CONFIRM] = (nfsd4_enc)nfsd4_encode_noop,
4232	[OP_VERIFY]		= (nfsd4_enc)nfsd4_encode_noop,
4233	[OP_WRITE]		= (nfsd4_enc)nfsd4_encode_write,
4234	[OP_RELEASE_LOCKOWNER]	= (nfsd4_enc)nfsd4_encode_noop,
4235
4236	/* NFSv4.1 operations */
4237	[OP_BACKCHANNEL_CTL]	= (nfsd4_enc)nfsd4_encode_noop,
4238	[OP_BIND_CONN_TO_SESSION] = (nfsd4_enc)nfsd4_encode_bind_conn_to_session,
4239	[OP_EXCHANGE_ID]	= (nfsd4_enc)nfsd4_encode_exchange_id,
4240	[OP_CREATE_SESSION]	= (nfsd4_enc)nfsd4_encode_create_session,
4241	[OP_DESTROY_SESSION]	= (nfsd4_enc)nfsd4_encode_noop,
4242	[OP_FREE_STATEID]	= (nfsd4_enc)nfsd4_encode_noop,
4243	[OP_GET_DIR_DELEGATION]	= (nfsd4_enc)nfsd4_encode_noop,
4244#ifdef CONFIG_NFSD_PNFS
4245	[OP_GETDEVICEINFO]	= (nfsd4_enc)nfsd4_encode_getdeviceinfo,
4246	[OP_GETDEVICELIST]	= (nfsd4_enc)nfsd4_encode_noop,
4247	[OP_LAYOUTCOMMIT]	= (nfsd4_enc)nfsd4_encode_layoutcommit,
4248	[OP_LAYOUTGET]		= (nfsd4_enc)nfsd4_encode_layoutget,
4249	[OP_LAYOUTRETURN]	= (nfsd4_enc)nfsd4_encode_layoutreturn,
4250#else
4251	[OP_GETDEVICEINFO]	= (nfsd4_enc)nfsd4_encode_noop,
4252	[OP_GETDEVICELIST]	= (nfsd4_enc)nfsd4_encode_noop,
4253	[OP_LAYOUTCOMMIT]	= (nfsd4_enc)nfsd4_encode_noop,
4254	[OP_LAYOUTGET]		= (nfsd4_enc)nfsd4_encode_noop,
4255	[OP_LAYOUTRETURN]	= (nfsd4_enc)nfsd4_encode_noop,
4256#endif
4257	[OP_SECINFO_NO_NAME]	= (nfsd4_enc)nfsd4_encode_secinfo_no_name,
4258	[OP_SEQUENCE]		= (nfsd4_enc)nfsd4_encode_sequence,
4259	[OP_SET_SSV]		= (nfsd4_enc)nfsd4_encode_noop,
4260	[OP_TEST_STATEID]	= (nfsd4_enc)nfsd4_encode_test_stateid,
4261	[OP_WANT_DELEGATION]	= (nfsd4_enc)nfsd4_encode_noop,
4262	[OP_DESTROY_CLIENTID]	= (nfsd4_enc)nfsd4_encode_noop,
4263	[OP_RECLAIM_COMPLETE]	= (nfsd4_enc)nfsd4_encode_noop,
4264
4265	/* NFSv4.2 operations */
4266	[OP_ALLOCATE]		= (nfsd4_enc)nfsd4_encode_noop,
4267	[OP_COPY]		= (nfsd4_enc)nfsd4_encode_noop,
4268	[OP_COPY_NOTIFY]	= (nfsd4_enc)nfsd4_encode_noop,
4269	[OP_DEALLOCATE]		= (nfsd4_enc)nfsd4_encode_noop,
4270	[OP_IO_ADVISE]		= (nfsd4_enc)nfsd4_encode_noop,
4271	[OP_LAYOUTERROR]	= (nfsd4_enc)nfsd4_encode_noop,
4272	[OP_LAYOUTSTATS]	= (nfsd4_enc)nfsd4_encode_noop,
4273	[OP_OFFLOAD_CANCEL]	= (nfsd4_enc)nfsd4_encode_noop,
4274	[OP_OFFLOAD_STATUS]	= (nfsd4_enc)nfsd4_encode_noop,
4275	[OP_READ_PLUS]		= (nfsd4_enc)nfsd4_encode_noop,
4276	[OP_SEEK]		= (nfsd4_enc)nfsd4_encode_seek,
4277	[OP_WRITE_SAME]		= (nfsd4_enc)nfsd4_encode_noop,
4278};
4279
4280/*
4281 * Calculate whether we still have space to encode repsize bytes.
4282 * There are two considerations:
4283 *     - For NFS versions >=4.1, the size of the reply must stay within
4284 *       session limits
4285 *     - For all NFS versions, we must stay within limited preallocated
4286 *       buffer space.
4287 *
4288 * This is called before the operation is processed, so can only provide
4289 * an upper estimate.  For some nonidempotent operations (such as
4290 * getattr), it's not necessarily a problem if that estimate is wrong,
4291 * as we can fail it after processing without significant side effects.
4292 */
4293__be32 nfsd4_check_resp_size(struct nfsd4_compoundres *resp, u32 respsize)
4294{
4295	struct xdr_buf *buf = &resp->rqstp->rq_res;
4296	struct nfsd4_slot *slot = resp->cstate.slot;
4297
4298	if (buf->len + respsize <= buf->buflen)
4299		return nfs_ok;
4300	if (!nfsd4_has_session(&resp->cstate))
4301		return nfserr_resource;
4302	if (slot->sl_flags & NFSD4_SLOT_CACHETHIS) {
4303		WARN_ON_ONCE(1);
4304		return nfserr_rep_too_big_to_cache;
4305	}
4306	return nfserr_rep_too_big;
4307}
4308
4309void
4310nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op)
4311{
4312	struct xdr_stream *xdr = &resp->xdr;
4313	struct nfs4_stateowner *so = resp->cstate.replay_owner;
4314	struct svc_rqst *rqstp = resp->rqstp;
4315	int post_err_offset;
4316	nfsd4_enc encoder;
4317	__be32 *p;
4318
4319	p = xdr_reserve_space(xdr, 8);
4320	if (!p) {
4321		WARN_ON_ONCE(1);
4322		return;
4323	}
4324	*p++ = cpu_to_be32(op->opnum);
4325	post_err_offset = xdr->buf->len;
4326
4327	if (op->opnum == OP_ILLEGAL)
4328		goto status;
4329	BUG_ON(op->opnum < 0 || op->opnum >= ARRAY_SIZE(nfsd4_enc_ops) ||
4330	       !nfsd4_enc_ops[op->opnum]);
4331	encoder = nfsd4_enc_ops[op->opnum];
4332	op->status = encoder(resp, op->status, &op->u);
4333	xdr_commit_encode(xdr);
4334
4335	/* nfsd4_check_resp_size guarantees enough room for error status */
4336	if (!op->status) {
4337		int space_needed = 0;
4338		if (!nfsd4_last_compound_op(rqstp))
4339			space_needed = COMPOUND_ERR_SLACK_SPACE;
4340		op->status = nfsd4_check_resp_size(resp, space_needed);
4341	}
4342	if (op->status == nfserr_resource && nfsd4_has_session(&resp->cstate)) {
4343		struct nfsd4_slot *slot = resp->cstate.slot;
4344
4345		if (slot->sl_flags & NFSD4_SLOT_CACHETHIS)
4346			op->status = nfserr_rep_too_big_to_cache;
4347		else
4348			op->status = nfserr_rep_too_big;
4349	}
4350	if (op->status == nfserr_resource ||
4351	    op->status == nfserr_rep_too_big ||
4352	    op->status == nfserr_rep_too_big_to_cache) {
4353		/*
4354		 * The operation may have already been encoded or
4355		 * partially encoded.  No op returns anything additional
4356		 * in the case of one of these three errors, so we can
4357		 * just truncate back to after the status.  But it's a
4358		 * bug if we had to do this on a non-idempotent op:
4359		 */
4360		warn_on_nonidempotent_op(op);
4361		xdr_truncate_encode(xdr, post_err_offset);
4362	}
4363	if (so) {
4364		int len = xdr->buf->len - post_err_offset;
4365
4366		so->so_replay.rp_status = op->status;
4367		so->so_replay.rp_buflen = len;
4368		read_bytes_from_xdr_buf(xdr->buf, post_err_offset,
4369						so->so_replay.rp_buf, len);
4370	}
4371status:
4372	/* Note that op->status is already in network byte order: */
4373	write_bytes_to_xdr_buf(xdr->buf, post_err_offset - 4, &op->status, 4);
4374}
4375
4376/*
4377 * Encode the reply stored in the stateowner reply cache
4378 *
4379 * XDR note: do not encode rp->rp_buflen: the buffer contains the
4380 * previously sent already encoded operation.
4381 */
4382void
4383nfsd4_encode_replay(struct xdr_stream *xdr, struct nfsd4_op *op)
4384{
4385	__be32 *p;
4386	struct nfs4_replay *rp = op->replay;
4387
4388	BUG_ON(!rp);
4389
4390	p = xdr_reserve_space(xdr, 8 + rp->rp_buflen);
4391	if (!p) {
4392		WARN_ON_ONCE(1);
4393		return;
4394	}
4395	*p++ = cpu_to_be32(op->opnum);
4396	*p++ = rp->rp_status;  /* already xdr'ed */
4397
4398	p = xdr_encode_opaque_fixed(p, rp->rp_buf, rp->rp_buflen);
4399}
4400
4401int
4402nfs4svc_encode_voidres(struct svc_rqst *rqstp, __be32 *p, void *dummy)
4403{
4404        return xdr_ressize_check(rqstp, p);
4405}
4406
4407int nfsd4_release_compoundargs(void *rq, __be32 *p, void *resp)
4408{
4409	struct svc_rqst *rqstp = rq;
4410	struct nfsd4_compoundargs *args = rqstp->rq_argp;
4411
4412	if (args->ops != args->iops) {
4413		kfree(args->ops);
4414		args->ops = args->iops;
4415	}
4416	kfree(args->tmpp);
4417	args->tmpp = NULL;
4418	while (args->to_free) {
4419		struct svcxdr_tmpbuf *tb = args->to_free;
4420		args->to_free = tb->next;
4421		kfree(tb);
4422	}
4423	return 1;
4424}
4425
4426int
4427nfs4svc_decode_compoundargs(struct svc_rqst *rqstp, __be32 *p, struct nfsd4_compoundargs *args)
4428{
4429	if (rqstp->rq_arg.head[0].iov_len % 4) {
4430		/* client is nuts */
4431		dprintk("%s: compound not properly padded! (peeraddr=%pISc xid=0x%x)",
4432			__func__, svc_addr(rqstp), be32_to_cpu(rqstp->rq_xid));
4433		return 0;
4434	}
4435	args->p = p;
4436	args->end = rqstp->rq_arg.head[0].iov_base + rqstp->rq_arg.head[0].iov_len;
4437	args->pagelist = rqstp->rq_arg.pages;
4438	args->pagelen = rqstp->rq_arg.page_len;
4439	args->tmpp = NULL;
4440	args->to_free = NULL;
4441	args->ops = args->iops;
4442	args->rqstp = rqstp;
4443
4444	return !nfsd4_decode_compound(args);
4445}
4446
4447int
4448nfs4svc_encode_compoundres(struct svc_rqst *rqstp, __be32 *p, struct nfsd4_compoundres *resp)
4449{
4450	/*
4451	 * All that remains is to write the tag and operation count...
4452	 */
4453	struct xdr_buf *buf = resp->xdr.buf;
4454
4455	WARN_ON_ONCE(buf->len != buf->head[0].iov_len + buf->page_len +
4456				 buf->tail[0].iov_len);
4457
4458	rqstp->rq_next_page = resp->xdr.page_ptr + 1;
4459
4460	p = resp->tagp;
4461	*p++ = htonl(resp->taglen);
4462	memcpy(p, resp->tag, resp->taglen);
4463	p += XDR_QUADLEN(resp->taglen);
4464	*p++ = htonl(resp->opcnt);
4465
4466	nfsd4_sequence_done(resp);
4467	return 1;
4468}
4469
4470/*
4471 * Local variables:
4472 *  c-basic-offset: 8
4473 * End:
4474 */
4475