xref: /kernel/linux/linux-5.10/fs/nfs/nfs3xdr.c (revision 8c2ecf20)
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * linux/fs/nfs/nfs3xdr.c
4 *
5 * XDR functions to encode/decode NFSv3 RPC arguments and results.
6 *
7 * Copyright (C) 1996, 1997 Olaf Kirch
8 */
9
10#include <linux/param.h>
11#include <linux/time.h>
12#include <linux/mm.h>
13#include <linux/errno.h>
14#include <linux/string.h>
15#include <linux/in.h>
16#include <linux/pagemap.h>
17#include <linux/proc_fs.h>
18#include <linux/kdev_t.h>
19#include <linux/sunrpc/clnt.h>
20#include <linux/nfs.h>
21#include <linux/nfs3.h>
22#include <linux/nfs_fs.h>
23#include <linux/nfsacl.h>
24#include "nfstrace.h"
25#include "internal.h"
26
27#define NFSDBG_FACILITY		NFSDBG_XDR
28
29/* Mapping from NFS error code to "errno" error code. */
30#define errno_NFSERR_IO		EIO
31
32/*
33 * Declare the space requirements for NFS arguments and replies as
34 * number of 32bit-words
35 */
36#define NFS3_fhandle_sz		(1+16)
37#define NFS3_fh_sz		(NFS3_fhandle_sz)	/* shorthand */
38#define NFS3_post_op_fh_sz	(1+NFS3_fh_sz)
39#define NFS3_sattr_sz		(15)
40#define NFS3_filename_sz	(1+(NFS3_MAXNAMLEN>>2))
41#define NFS3_path_sz		(1+(NFS3_MAXPATHLEN>>2))
42#define NFS3_fattr_sz		(21)
43#define NFS3_cookieverf_sz	(NFS3_COOKIEVERFSIZE>>2)
44#define NFS3_wcc_attr_sz	(6)
45#define NFS3_pre_op_attr_sz	(1+NFS3_wcc_attr_sz)
46#define NFS3_post_op_attr_sz	(1+NFS3_fattr_sz)
47#define NFS3_wcc_data_sz	(NFS3_pre_op_attr_sz+NFS3_post_op_attr_sz)
48#define NFS3_diropargs_sz	(NFS3_fh_sz+NFS3_filename_sz)
49
50#define NFS3_getattrargs_sz	(NFS3_fh_sz)
51#define NFS3_setattrargs_sz	(NFS3_fh_sz+NFS3_sattr_sz+3)
52#define NFS3_lookupargs_sz	(NFS3_fh_sz+NFS3_filename_sz)
53#define NFS3_accessargs_sz	(NFS3_fh_sz+1)
54#define NFS3_readlinkargs_sz	(NFS3_fh_sz)
55#define NFS3_readargs_sz	(NFS3_fh_sz+3)
56#define NFS3_writeargs_sz	(NFS3_fh_sz+5)
57#define NFS3_createargs_sz	(NFS3_diropargs_sz+NFS3_sattr_sz)
58#define NFS3_mkdirargs_sz	(NFS3_diropargs_sz+NFS3_sattr_sz)
59#define NFS3_symlinkargs_sz	(NFS3_diropargs_sz+1+NFS3_sattr_sz)
60#define NFS3_mknodargs_sz	(NFS3_diropargs_sz+2+NFS3_sattr_sz)
61#define NFS3_removeargs_sz	(NFS3_fh_sz+NFS3_filename_sz)
62#define NFS3_renameargs_sz	(NFS3_diropargs_sz+NFS3_diropargs_sz)
63#define NFS3_linkargs_sz		(NFS3_fh_sz+NFS3_diropargs_sz)
64#define NFS3_readdirargs_sz	(NFS3_fh_sz+NFS3_cookieverf_sz+3)
65#define NFS3_readdirplusargs_sz	(NFS3_fh_sz+NFS3_cookieverf_sz+4)
66#define NFS3_commitargs_sz	(NFS3_fh_sz+3)
67
68#define NFS3_getattrres_sz	(1+NFS3_fattr_sz)
69#define NFS3_setattrres_sz	(1+NFS3_wcc_data_sz)
70#define NFS3_removeres_sz	(NFS3_setattrres_sz)
71#define NFS3_lookupres_sz	(1+NFS3_fh_sz+(2 * NFS3_post_op_attr_sz))
72#define NFS3_accessres_sz	(1+NFS3_post_op_attr_sz+1)
73#define NFS3_readlinkres_sz	(1+NFS3_post_op_attr_sz+1+1)
74#define NFS3_readres_sz		(1+NFS3_post_op_attr_sz+3+1)
75#define NFS3_writeres_sz	(1+NFS3_wcc_data_sz+4)
76#define NFS3_createres_sz	(1+NFS3_post_op_fh_sz+NFS3_post_op_attr_sz+NFS3_wcc_data_sz)
77#define NFS3_renameres_sz	(1+(2 * NFS3_wcc_data_sz))
78#define NFS3_linkres_sz		(1+NFS3_post_op_attr_sz+NFS3_wcc_data_sz)
79#define NFS3_readdirres_sz	(1+NFS3_post_op_attr_sz+2+1)
80#define NFS3_fsstatres_sz	(1+NFS3_post_op_attr_sz+13)
81#define NFS3_fsinfores_sz	(1+NFS3_post_op_attr_sz+12)
82#define NFS3_pathconfres_sz	(1+NFS3_post_op_attr_sz+6)
83#define NFS3_commitres_sz	(1+NFS3_wcc_data_sz+2)
84
85#define ACL3_getaclargs_sz	(NFS3_fh_sz+1)
86#define ACL3_setaclargs_sz	(NFS3_fh_sz+1+ \
87				XDR_QUADLEN(NFS_ACL_INLINE_BUFSIZE))
88#define ACL3_getaclres_sz	(1+NFS3_post_op_attr_sz+1+ \
89				XDR_QUADLEN(NFS_ACL_INLINE_BUFSIZE)+1)
90#define ACL3_setaclres_sz	(1+NFS3_post_op_attr_sz)
91
92static int nfs3_stat_to_errno(enum nfs_stat);
93
94/*
95 * Map file type to S_IFMT bits
96 */
97static const umode_t nfs_type2fmt[] = {
98	[NF3BAD] = 0,
99	[NF3REG] = S_IFREG,
100	[NF3DIR] = S_IFDIR,
101	[NF3BLK] = S_IFBLK,
102	[NF3CHR] = S_IFCHR,
103	[NF3LNK] = S_IFLNK,
104	[NF3SOCK] = S_IFSOCK,
105	[NF3FIFO] = S_IFIFO,
106};
107
108static struct user_namespace *rpc_userns(const struct rpc_clnt *clnt)
109{
110	if (clnt && clnt->cl_cred)
111		return clnt->cl_cred->user_ns;
112	return &init_user_ns;
113}
114
115static struct user_namespace *rpc_rqst_userns(const struct rpc_rqst *rqstp)
116{
117	if (rqstp->rq_task)
118		return rpc_userns(rqstp->rq_task->tk_client);
119	return &init_user_ns;
120}
121
122/*
123 * Encode/decode NFSv3 basic data types
124 *
125 * Basic NFSv3 data types are defined in section 2.5 of RFC 1813:
126 * "NFS Version 3 Protocol Specification".
127 *
128 * Not all basic data types have their own encoding and decoding
129 * functions.  For run-time efficiency, some data types are encoded
130 * or decoded inline.
131 */
132
133static void encode_uint32(struct xdr_stream *xdr, u32 value)
134{
135	__be32 *p = xdr_reserve_space(xdr, 4);
136	*p = cpu_to_be32(value);
137}
138
139static int decode_uint32(struct xdr_stream *xdr, u32 *value)
140{
141	__be32 *p;
142
143	p = xdr_inline_decode(xdr, 4);
144	if (unlikely(!p))
145		return -EIO;
146	*value = be32_to_cpup(p);
147	return 0;
148}
149
150static int decode_uint64(struct xdr_stream *xdr, u64 *value)
151{
152	__be32 *p;
153
154	p = xdr_inline_decode(xdr, 8);
155	if (unlikely(!p))
156		return -EIO;
157	xdr_decode_hyper(p, value);
158	return 0;
159}
160
161/*
162 * fileid3
163 *
164 *	typedef uint64 fileid3;
165 */
166static __be32 *xdr_decode_fileid3(__be32 *p, u64 *fileid)
167{
168	return xdr_decode_hyper(p, fileid);
169}
170
171static int decode_fileid3(struct xdr_stream *xdr, u64 *fileid)
172{
173	return decode_uint64(xdr, fileid);
174}
175
176/*
177 * filename3
178 *
179 *	typedef string filename3<>;
180 */
181static void encode_filename3(struct xdr_stream *xdr,
182			     const char *name, u32 length)
183{
184	__be32 *p;
185
186	WARN_ON_ONCE(length > NFS3_MAXNAMLEN);
187	p = xdr_reserve_space(xdr, 4 + length);
188	xdr_encode_opaque(p, name, length);
189}
190
191static int decode_inline_filename3(struct xdr_stream *xdr,
192				   const char **name, u32 *length)
193{
194	__be32 *p;
195	u32 count;
196
197	p = xdr_inline_decode(xdr, 4);
198	if (unlikely(!p))
199		return -EIO;
200	count = be32_to_cpup(p);
201	if (count > NFS3_MAXNAMLEN)
202		goto out_nametoolong;
203	p = xdr_inline_decode(xdr, count);
204	if (unlikely(!p))
205		return -EIO;
206	*name = (const char *)p;
207	*length = count;
208	return 0;
209
210out_nametoolong:
211	dprintk("NFS: returned filename too long: %u\n", count);
212	return -ENAMETOOLONG;
213}
214
215/*
216 * nfspath3
217 *
218 *	typedef string nfspath3<>;
219 */
220static void encode_nfspath3(struct xdr_stream *xdr, struct page **pages,
221			    const u32 length)
222{
223	encode_uint32(xdr, length);
224	xdr_write_pages(xdr, pages, 0, length);
225}
226
227static int decode_nfspath3(struct xdr_stream *xdr)
228{
229	u32 recvd, count;
230	__be32 *p;
231
232	p = xdr_inline_decode(xdr, 4);
233	if (unlikely(!p))
234		return -EIO;
235	count = be32_to_cpup(p);
236	if (unlikely(count >= xdr->buf->page_len || count > NFS3_MAXPATHLEN))
237		goto out_nametoolong;
238	recvd = xdr_read_pages(xdr, count);
239	if (unlikely(count > recvd))
240		goto out_cheating;
241	xdr_terminate_string(xdr->buf, count);
242	return 0;
243
244out_nametoolong:
245	dprintk("NFS: returned pathname too long: %u\n", count);
246	return -ENAMETOOLONG;
247out_cheating:
248	dprintk("NFS: server cheating in pathname result: "
249		"count %u > recvd %u\n", count, recvd);
250	return -EIO;
251}
252
253/*
254 * cookie3
255 *
256 *	typedef uint64 cookie3
257 */
258static __be32 *xdr_encode_cookie3(__be32 *p, u64 cookie)
259{
260	return xdr_encode_hyper(p, cookie);
261}
262
263static int decode_cookie3(struct xdr_stream *xdr, u64 *cookie)
264{
265	return decode_uint64(xdr, cookie);
266}
267
268/*
269 * cookieverf3
270 *
271 *	typedef opaque cookieverf3[NFS3_COOKIEVERFSIZE];
272 */
273static __be32 *xdr_encode_cookieverf3(__be32 *p, const __be32 *verifier)
274{
275	memcpy(p, verifier, NFS3_COOKIEVERFSIZE);
276	return p + XDR_QUADLEN(NFS3_COOKIEVERFSIZE);
277}
278
279static int decode_cookieverf3(struct xdr_stream *xdr, __be32 *verifier)
280{
281	__be32 *p;
282
283	p = xdr_inline_decode(xdr, NFS3_COOKIEVERFSIZE);
284	if (unlikely(!p))
285		return -EIO;
286	memcpy(verifier, p, NFS3_COOKIEVERFSIZE);
287	return 0;
288}
289
290/*
291 * createverf3
292 *
293 *	typedef opaque createverf3[NFS3_CREATEVERFSIZE];
294 */
295static void encode_createverf3(struct xdr_stream *xdr, const __be32 *verifier)
296{
297	__be32 *p;
298
299	p = xdr_reserve_space(xdr, NFS3_CREATEVERFSIZE);
300	memcpy(p, verifier, NFS3_CREATEVERFSIZE);
301}
302
303static int decode_writeverf3(struct xdr_stream *xdr, struct nfs_write_verifier *verifier)
304{
305	__be32 *p;
306
307	p = xdr_inline_decode(xdr, NFS3_WRITEVERFSIZE);
308	if (unlikely(!p))
309		return -EIO;
310	memcpy(verifier->data, p, NFS3_WRITEVERFSIZE);
311	return 0;
312}
313
314/*
315 * size3
316 *
317 *	typedef uint64 size3;
318 */
319static __be32 *xdr_decode_size3(__be32 *p, u64 *size)
320{
321	return xdr_decode_hyper(p, size);
322}
323
324/*
325 * nfsstat3
326 *
327 *	enum nfsstat3 {
328 *		NFS3_OK = 0,
329 *		...
330 *	}
331 */
332#define NFS3_OK		NFS_OK
333
334static int decode_nfsstat3(struct xdr_stream *xdr, enum nfs_stat *status)
335{
336	__be32 *p;
337
338	p = xdr_inline_decode(xdr, 4);
339	if (unlikely(!p))
340		return -EIO;
341	if (unlikely(*p != cpu_to_be32(NFS3_OK)))
342		goto out_status;
343	*status = 0;
344	return 0;
345out_status:
346	*status = be32_to_cpup(p);
347	trace_nfs_xdr_status(xdr, (int)*status);
348	return 0;
349}
350
351/*
352 * ftype3
353 *
354 *	enum ftype3 {
355 *		NF3REG	= 1,
356 *		NF3DIR	= 2,
357 *		NF3BLK	= 3,
358 *		NF3CHR	= 4,
359 *		NF3LNK	= 5,
360 *		NF3SOCK	= 6,
361 *		NF3FIFO	= 7
362 *	};
363 */
364static void encode_ftype3(struct xdr_stream *xdr, const u32 type)
365{
366	encode_uint32(xdr, type);
367}
368
369static __be32 *xdr_decode_ftype3(__be32 *p, umode_t *mode)
370{
371	u32 type;
372
373	type = be32_to_cpup(p++);
374	if (type > NF3FIFO)
375		type = NF3NON;
376	*mode = nfs_type2fmt[type];
377	return p;
378}
379
380/*
381 * specdata3
382 *
383 *     struct specdata3 {
384 *             uint32  specdata1;
385 *             uint32  specdata2;
386 *     };
387 */
388static void encode_specdata3(struct xdr_stream *xdr, const dev_t rdev)
389{
390	__be32 *p;
391
392	p = xdr_reserve_space(xdr, 8);
393	*p++ = cpu_to_be32(MAJOR(rdev));
394	*p = cpu_to_be32(MINOR(rdev));
395}
396
397static __be32 *xdr_decode_specdata3(__be32 *p, dev_t *rdev)
398{
399	unsigned int major, minor;
400
401	major = be32_to_cpup(p++);
402	minor = be32_to_cpup(p++);
403	*rdev = MKDEV(major, minor);
404	if (MAJOR(*rdev) != major || MINOR(*rdev) != minor)
405		*rdev = 0;
406	return p;
407}
408
409/*
410 * nfs_fh3
411 *
412 *	struct nfs_fh3 {
413 *		opaque       data<NFS3_FHSIZE>;
414 *	};
415 */
416static void encode_nfs_fh3(struct xdr_stream *xdr, const struct nfs_fh *fh)
417{
418	__be32 *p;
419
420	WARN_ON_ONCE(fh->size > NFS3_FHSIZE);
421	p = xdr_reserve_space(xdr, 4 + fh->size);
422	xdr_encode_opaque(p, fh->data, fh->size);
423}
424
425static int decode_nfs_fh3(struct xdr_stream *xdr, struct nfs_fh *fh)
426{
427	u32 length;
428	__be32 *p;
429
430	p = xdr_inline_decode(xdr, 4);
431	if (unlikely(!p))
432		return -EIO;
433	length = be32_to_cpup(p++);
434	if (unlikely(length > NFS3_FHSIZE))
435		goto out_toobig;
436	p = xdr_inline_decode(xdr, length);
437	if (unlikely(!p))
438		return -EIO;
439	fh->size = length;
440	memcpy(fh->data, p, length);
441	return 0;
442out_toobig:
443	dprintk("NFS: file handle size (%u) too big\n", length);
444	return -E2BIG;
445}
446
447static void zero_nfs_fh3(struct nfs_fh *fh)
448{
449	memset(fh, 0, sizeof(*fh));
450}
451
452/*
453 * nfstime3
454 *
455 *	struct nfstime3 {
456 *		uint32	seconds;
457 *		uint32	nseconds;
458 *	};
459 */
460static __be32 *xdr_encode_nfstime3(__be32 *p, const struct timespec64 *timep)
461{
462	*p++ = cpu_to_be32((u32)timep->tv_sec);
463	*p++ = cpu_to_be32(timep->tv_nsec);
464	return p;
465}
466
467static __be32 *xdr_decode_nfstime3(__be32 *p, struct timespec64 *timep)
468{
469	timep->tv_sec = be32_to_cpup(p++);
470	timep->tv_nsec = be32_to_cpup(p++);
471	return p;
472}
473
474/*
475 * sattr3
476 *
477 *	enum time_how {
478 *		DONT_CHANGE		= 0,
479 *		SET_TO_SERVER_TIME	= 1,
480 *		SET_TO_CLIENT_TIME	= 2
481 *	};
482 *
483 *	union set_mode3 switch (bool set_it) {
484 *	case TRUE:
485 *		mode3	mode;
486 *	default:
487 *		void;
488 *	};
489 *
490 *	union set_uid3 switch (bool set_it) {
491 *	case TRUE:
492 *		uid3	uid;
493 *	default:
494 *		void;
495 *	};
496 *
497 *	union set_gid3 switch (bool set_it) {
498 *	case TRUE:
499 *		gid3	gid;
500 *	default:
501 *		void;
502 *	};
503 *
504 *	union set_size3 switch (bool set_it) {
505 *	case TRUE:
506 *		size3	size;
507 *	default:
508 *		void;
509 *	};
510 *
511 *	union set_atime switch (time_how set_it) {
512 *	case SET_TO_CLIENT_TIME:
513 *		nfstime3	atime;
514 *	default:
515 *		void;
516 *	};
517 *
518 *	union set_mtime switch (time_how set_it) {
519 *	case SET_TO_CLIENT_TIME:
520 *		nfstime3  mtime;
521 *	default:
522 *		void;
523 *	};
524 *
525 *	struct sattr3 {
526 *		set_mode3	mode;
527 *		set_uid3	uid;
528 *		set_gid3	gid;
529 *		set_size3	size;
530 *		set_atime	atime;
531 *		set_mtime	mtime;
532 *	};
533 */
534static void encode_sattr3(struct xdr_stream *xdr, const struct iattr *attr,
535		struct user_namespace *userns)
536{
537	u32 nbytes;
538	__be32 *p;
539
540	/*
541	 * In order to make only a single xdr_reserve_space() call,
542	 * pre-compute the total number of bytes to be reserved.
543	 * Six boolean values, one for each set_foo field, are always
544	 * present in the encoded result, so start there.
545	 */
546	nbytes = 6 * 4;
547	if (attr->ia_valid & ATTR_MODE)
548		nbytes += 4;
549	if (attr->ia_valid & ATTR_UID)
550		nbytes += 4;
551	if (attr->ia_valid & ATTR_GID)
552		nbytes += 4;
553	if (attr->ia_valid & ATTR_SIZE)
554		nbytes += 8;
555	if (attr->ia_valid & ATTR_ATIME_SET)
556		nbytes += 8;
557	if (attr->ia_valid & ATTR_MTIME_SET)
558		nbytes += 8;
559	p = xdr_reserve_space(xdr, nbytes);
560
561	if (attr->ia_valid & ATTR_MODE) {
562		*p++ = xdr_one;
563		*p++ = cpu_to_be32(attr->ia_mode & S_IALLUGO);
564	} else
565		*p++ = xdr_zero;
566
567	if (attr->ia_valid & ATTR_UID) {
568		*p++ = xdr_one;
569		*p++ = cpu_to_be32(from_kuid_munged(userns, attr->ia_uid));
570	} else
571		*p++ = xdr_zero;
572
573	if (attr->ia_valid & ATTR_GID) {
574		*p++ = xdr_one;
575		*p++ = cpu_to_be32(from_kgid_munged(userns, attr->ia_gid));
576	} else
577		*p++ = xdr_zero;
578
579	if (attr->ia_valid & ATTR_SIZE) {
580		*p++ = xdr_one;
581		p = xdr_encode_hyper(p, (u64)attr->ia_size);
582	} else
583		*p++ = xdr_zero;
584
585	if (attr->ia_valid & ATTR_ATIME_SET) {
586		*p++ = xdr_two;
587		p = xdr_encode_nfstime3(p, &attr->ia_atime);
588	} else if (attr->ia_valid & ATTR_ATIME) {
589		*p++ = xdr_one;
590	} else
591		*p++ = xdr_zero;
592
593	if (attr->ia_valid & ATTR_MTIME_SET) {
594		*p++ = xdr_two;
595		xdr_encode_nfstime3(p, &attr->ia_mtime);
596	} else if (attr->ia_valid & ATTR_MTIME) {
597		*p = xdr_one;
598	} else
599		*p = xdr_zero;
600}
601
602/*
603 * fattr3
604 *
605 *	struct fattr3 {
606 *		ftype3		type;
607 *		mode3		mode;
608 *		uint32		nlink;
609 *		uid3		uid;
610 *		gid3		gid;
611 *		size3		size;
612 *		size3		used;
613 *		specdata3	rdev;
614 *		uint64		fsid;
615 *		fileid3		fileid;
616 *		nfstime3	atime;
617 *		nfstime3	mtime;
618 *		nfstime3	ctime;
619 *	};
620 */
621static int decode_fattr3(struct xdr_stream *xdr, struct nfs_fattr *fattr,
622		struct user_namespace *userns)
623{
624	umode_t fmode;
625	__be32 *p;
626
627	p = xdr_inline_decode(xdr, NFS3_fattr_sz << 2);
628	if (unlikely(!p))
629		return -EIO;
630
631	p = xdr_decode_ftype3(p, &fmode);
632
633	fattr->mode = (be32_to_cpup(p++) & ~S_IFMT) | fmode;
634	fattr->nlink = be32_to_cpup(p++);
635	fattr->uid = make_kuid(userns, be32_to_cpup(p++));
636	if (!uid_valid(fattr->uid))
637		goto out_uid;
638	fattr->gid = make_kgid(userns, be32_to_cpup(p++));
639	if (!gid_valid(fattr->gid))
640		goto out_gid;
641
642	p = xdr_decode_size3(p, &fattr->size);
643	p = xdr_decode_size3(p, &fattr->du.nfs3.used);
644	p = xdr_decode_specdata3(p, &fattr->rdev);
645
646	p = xdr_decode_hyper(p, &fattr->fsid.major);
647	fattr->fsid.minor = 0;
648
649	p = xdr_decode_fileid3(p, &fattr->fileid);
650	p = xdr_decode_nfstime3(p, &fattr->atime);
651	p = xdr_decode_nfstime3(p, &fattr->mtime);
652	xdr_decode_nfstime3(p, &fattr->ctime);
653	fattr->change_attr = nfs_timespec_to_change_attr(&fattr->ctime);
654
655	fattr->valid |= NFS_ATTR_FATTR_V3;
656	return 0;
657out_uid:
658	dprintk("NFS: returned invalid uid\n");
659	return -EINVAL;
660out_gid:
661	dprintk("NFS: returned invalid gid\n");
662	return -EINVAL;
663}
664
665/*
666 * post_op_attr
667 *
668 *	union post_op_attr switch (bool attributes_follow) {
669 *	case TRUE:
670 *		fattr3	attributes;
671 *	case FALSE:
672 *		void;
673 *	};
674 */
675static int decode_post_op_attr(struct xdr_stream *xdr, struct nfs_fattr *fattr,
676		struct user_namespace *userns)
677{
678	__be32 *p;
679
680	p = xdr_inline_decode(xdr, 4);
681	if (unlikely(!p))
682		return -EIO;
683	if (*p != xdr_zero)
684		return decode_fattr3(xdr, fattr, userns);
685	return 0;
686}
687
688/*
689 * wcc_attr
690 *	struct wcc_attr {
691 *		size3		size;
692 *		nfstime3	mtime;
693 *		nfstime3	ctime;
694 *	};
695 */
696static int decode_wcc_attr(struct xdr_stream *xdr, struct nfs_fattr *fattr)
697{
698	__be32 *p;
699
700	p = xdr_inline_decode(xdr, NFS3_wcc_attr_sz << 2);
701	if (unlikely(!p))
702		return -EIO;
703
704	fattr->valid |= NFS_ATTR_FATTR_PRESIZE
705		| NFS_ATTR_FATTR_PRECHANGE
706		| NFS_ATTR_FATTR_PREMTIME
707		| NFS_ATTR_FATTR_PRECTIME;
708
709	p = xdr_decode_size3(p, &fattr->pre_size);
710	p = xdr_decode_nfstime3(p, &fattr->pre_mtime);
711	xdr_decode_nfstime3(p, &fattr->pre_ctime);
712	fattr->pre_change_attr = nfs_timespec_to_change_attr(&fattr->pre_ctime);
713
714	return 0;
715}
716
717/*
718 * pre_op_attr
719 *	union pre_op_attr switch (bool attributes_follow) {
720 *	case TRUE:
721 *		wcc_attr	attributes;
722 *	case FALSE:
723 *		void;
724 *	};
725 *
726 * wcc_data
727 *
728 *	struct wcc_data {
729 *		pre_op_attr	before;
730 *		post_op_attr	after;
731 *	};
732 */
733static int decode_pre_op_attr(struct xdr_stream *xdr, struct nfs_fattr *fattr)
734{
735	__be32 *p;
736
737	p = xdr_inline_decode(xdr, 4);
738	if (unlikely(!p))
739		return -EIO;
740	if (*p != xdr_zero)
741		return decode_wcc_attr(xdr, fattr);
742	return 0;
743}
744
745static int decode_wcc_data(struct xdr_stream *xdr, struct nfs_fattr *fattr,
746		struct user_namespace *userns)
747{
748	int error;
749
750	error = decode_pre_op_attr(xdr, fattr);
751	if (unlikely(error))
752		goto out;
753	error = decode_post_op_attr(xdr, fattr, userns);
754out:
755	return error;
756}
757
758/*
759 * post_op_fh3
760 *
761 *	union post_op_fh3 switch (bool handle_follows) {
762 *	case TRUE:
763 *		nfs_fh3  handle;
764 *	case FALSE:
765 *		void;
766 *	};
767 */
768static int decode_post_op_fh3(struct xdr_stream *xdr, struct nfs_fh *fh)
769{
770	__be32 *p = xdr_inline_decode(xdr, 4);
771	if (unlikely(!p))
772		return -EIO;
773	if (*p != xdr_zero)
774		return decode_nfs_fh3(xdr, fh);
775	zero_nfs_fh3(fh);
776	return 0;
777}
778
779/*
780 * diropargs3
781 *
782 *	struct diropargs3 {
783 *		nfs_fh3		dir;
784 *		filename3	name;
785 *	};
786 */
787static void encode_diropargs3(struct xdr_stream *xdr, const struct nfs_fh *fh,
788			      const char *name, u32 length)
789{
790	encode_nfs_fh3(xdr, fh);
791	encode_filename3(xdr, name, length);
792}
793
794
795/*
796 * NFSv3 XDR encode functions
797 *
798 * NFSv3 argument types are defined in section 3.3 of RFC 1813:
799 * "NFS Version 3 Protocol Specification".
800 */
801
802/*
803 * 3.3.1  GETATTR3args
804 *
805 *	struct GETATTR3args {
806 *		nfs_fh3  object;
807 *	};
808 */
809static void nfs3_xdr_enc_getattr3args(struct rpc_rqst *req,
810				      struct xdr_stream *xdr,
811				      const void *data)
812{
813	const struct nfs_fh *fh = data;
814
815	encode_nfs_fh3(xdr, fh);
816}
817
818/*
819 * 3.3.2  SETATTR3args
820 *
821 *	union sattrguard3 switch (bool check) {
822 *	case TRUE:
823 *		nfstime3  obj_ctime;
824 *	case FALSE:
825 *		void;
826 *	};
827 *
828 *	struct SETATTR3args {
829 *		nfs_fh3		object;
830 *		sattr3		new_attributes;
831 *		sattrguard3	guard;
832 *	};
833 */
834static void encode_sattrguard3(struct xdr_stream *xdr,
835			       const struct nfs3_sattrargs *args)
836{
837	__be32 *p;
838
839	if (args->guard) {
840		p = xdr_reserve_space(xdr, 4 + 8);
841		*p++ = xdr_one;
842		xdr_encode_nfstime3(p, &args->guardtime);
843	} else {
844		p = xdr_reserve_space(xdr, 4);
845		*p = xdr_zero;
846	}
847}
848
849static void nfs3_xdr_enc_setattr3args(struct rpc_rqst *req,
850				      struct xdr_stream *xdr,
851				      const void *data)
852{
853	const struct nfs3_sattrargs *args = data;
854	encode_nfs_fh3(xdr, args->fh);
855	encode_sattr3(xdr, args->sattr, rpc_rqst_userns(req));
856	encode_sattrguard3(xdr, args);
857}
858
859/*
860 * 3.3.3  LOOKUP3args
861 *
862 *	struct LOOKUP3args {
863 *		diropargs3  what;
864 *	};
865 */
866static void nfs3_xdr_enc_lookup3args(struct rpc_rqst *req,
867				     struct xdr_stream *xdr,
868				     const void *data)
869{
870	const struct nfs3_diropargs *args = data;
871
872	encode_diropargs3(xdr, args->fh, args->name, args->len);
873}
874
875/*
876 * 3.3.4  ACCESS3args
877 *
878 *	struct ACCESS3args {
879 *		nfs_fh3		object;
880 *		uint32		access;
881 *	};
882 */
883static void encode_access3args(struct xdr_stream *xdr,
884			       const struct nfs3_accessargs *args)
885{
886	encode_nfs_fh3(xdr, args->fh);
887	encode_uint32(xdr, args->access);
888}
889
890static void nfs3_xdr_enc_access3args(struct rpc_rqst *req,
891				     struct xdr_stream *xdr,
892				     const void *data)
893{
894	const struct nfs3_accessargs *args = data;
895
896	encode_access3args(xdr, args);
897}
898
899/*
900 * 3.3.5  READLINK3args
901 *
902 *	struct READLINK3args {
903 *		nfs_fh3	symlink;
904 *	};
905 */
906static void nfs3_xdr_enc_readlink3args(struct rpc_rqst *req,
907				       struct xdr_stream *xdr,
908				       const void *data)
909{
910	const struct nfs3_readlinkargs *args = data;
911
912	encode_nfs_fh3(xdr, args->fh);
913	rpc_prepare_reply_pages(req, args->pages, args->pgbase,
914				args->pglen, NFS3_readlinkres_sz);
915}
916
917/*
918 * 3.3.6  READ3args
919 *
920 *	struct READ3args {
921 *		nfs_fh3		file;
922 *		offset3		offset;
923 *		count3		count;
924 *	};
925 */
926static void encode_read3args(struct xdr_stream *xdr,
927			     const struct nfs_pgio_args *args)
928{
929	__be32 *p;
930
931	encode_nfs_fh3(xdr, args->fh);
932
933	p = xdr_reserve_space(xdr, 8 + 4);
934	p = xdr_encode_hyper(p, args->offset);
935	*p = cpu_to_be32(args->count);
936}
937
938static void nfs3_xdr_enc_read3args(struct rpc_rqst *req,
939				   struct xdr_stream *xdr,
940				   const void *data)
941{
942	const struct nfs_pgio_args *args = data;
943	unsigned int replen = args->replen ? args->replen : NFS3_readres_sz;
944
945	encode_read3args(xdr, args);
946	rpc_prepare_reply_pages(req, args->pages, args->pgbase,
947				args->count, replen);
948	req->rq_rcv_buf.flags |= XDRBUF_READ;
949}
950
951/*
952 * 3.3.7  WRITE3args
953 *
954 *	enum stable_how {
955 *		UNSTABLE  = 0,
956 *		DATA_SYNC = 1,
957 *		FILE_SYNC = 2
958 *	};
959 *
960 *	struct WRITE3args {
961 *		nfs_fh3		file;
962 *		offset3		offset;
963 *		count3		count;
964 *		stable_how	stable;
965 *		opaque		data<>;
966 *	};
967 */
968static void encode_write3args(struct xdr_stream *xdr,
969			      const struct nfs_pgio_args *args)
970{
971	__be32 *p;
972
973	encode_nfs_fh3(xdr, args->fh);
974
975	p = xdr_reserve_space(xdr, 8 + 4 + 4 + 4);
976	p = xdr_encode_hyper(p, args->offset);
977	*p++ = cpu_to_be32(args->count);
978	*p++ = cpu_to_be32(args->stable);
979	*p = cpu_to_be32(args->count);
980	xdr_write_pages(xdr, args->pages, args->pgbase, args->count);
981}
982
983static void nfs3_xdr_enc_write3args(struct rpc_rqst *req,
984				    struct xdr_stream *xdr,
985				    const void *data)
986{
987	const struct nfs_pgio_args *args = data;
988
989	encode_write3args(xdr, args);
990	xdr->buf->flags |= XDRBUF_WRITE;
991}
992
993/*
994 * 3.3.8  CREATE3args
995 *
996 *	enum createmode3 {
997 *		UNCHECKED = 0,
998 *		GUARDED   = 1,
999 *		EXCLUSIVE = 2
1000 *	};
1001 *
1002 *	union createhow3 switch (createmode3 mode) {
1003 *	case UNCHECKED:
1004 *	case GUARDED:
1005 *		sattr3       obj_attributes;
1006 *	case EXCLUSIVE:
1007 *		createverf3  verf;
1008 *	};
1009 *
1010 *	struct CREATE3args {
1011 *		diropargs3	where;
1012 *		createhow3	how;
1013 *	};
1014 */
1015static void encode_createhow3(struct xdr_stream *xdr,
1016			      const struct nfs3_createargs *args,
1017			      struct user_namespace *userns)
1018{
1019	encode_uint32(xdr, args->createmode);
1020	switch (args->createmode) {
1021	case NFS3_CREATE_UNCHECKED:
1022	case NFS3_CREATE_GUARDED:
1023		encode_sattr3(xdr, args->sattr, userns);
1024		break;
1025	case NFS3_CREATE_EXCLUSIVE:
1026		encode_createverf3(xdr, args->verifier);
1027		break;
1028	default:
1029		BUG();
1030	}
1031}
1032
1033static void nfs3_xdr_enc_create3args(struct rpc_rqst *req,
1034				     struct xdr_stream *xdr,
1035				     const void *data)
1036{
1037	const struct nfs3_createargs *args = data;
1038
1039	encode_diropargs3(xdr, args->fh, args->name, args->len);
1040	encode_createhow3(xdr, args, rpc_rqst_userns(req));
1041}
1042
1043/*
1044 * 3.3.9  MKDIR3args
1045 *
1046 *	struct MKDIR3args {
1047 *		diropargs3	where;
1048 *		sattr3		attributes;
1049 *	};
1050 */
1051static void nfs3_xdr_enc_mkdir3args(struct rpc_rqst *req,
1052				    struct xdr_stream *xdr,
1053				    const void *data)
1054{
1055	const struct nfs3_mkdirargs *args = data;
1056
1057	encode_diropargs3(xdr, args->fh, args->name, args->len);
1058	encode_sattr3(xdr, args->sattr, rpc_rqst_userns(req));
1059}
1060
1061/*
1062 * 3.3.10  SYMLINK3args
1063 *
1064 *	struct symlinkdata3 {
1065 *		sattr3		symlink_attributes;
1066 *		nfspath3	symlink_data;
1067 *	};
1068 *
1069 *	struct SYMLINK3args {
1070 *		diropargs3	where;
1071 *		symlinkdata3	symlink;
1072 *	};
1073 */
1074static void encode_symlinkdata3(struct xdr_stream *xdr,
1075				const void *data,
1076				struct user_namespace *userns)
1077{
1078	const struct nfs3_symlinkargs *args = data;
1079
1080	encode_sattr3(xdr, args->sattr, userns);
1081	encode_nfspath3(xdr, args->pages, args->pathlen);
1082}
1083
1084static void nfs3_xdr_enc_symlink3args(struct rpc_rqst *req,
1085				      struct xdr_stream *xdr,
1086				      const void *data)
1087{
1088	const struct nfs3_symlinkargs *args = data;
1089
1090	encode_diropargs3(xdr, args->fromfh, args->fromname, args->fromlen);
1091	encode_symlinkdata3(xdr, args, rpc_rqst_userns(req));
1092	xdr->buf->flags |= XDRBUF_WRITE;
1093}
1094
1095/*
1096 * 3.3.11  MKNOD3args
1097 *
1098 *	struct devicedata3 {
1099 *		sattr3		dev_attributes;
1100 *		specdata3	spec;
1101 *	};
1102 *
1103 *	union mknoddata3 switch (ftype3 type) {
1104 *	case NF3CHR:
1105 *	case NF3BLK:
1106 *		devicedata3	device;
1107 *	case NF3SOCK:
1108 *	case NF3FIFO:
1109 *		sattr3		pipe_attributes;
1110 *	default:
1111 *		void;
1112 *	};
1113 *
1114 *	struct MKNOD3args {
1115 *		diropargs3	where;
1116 *		mknoddata3	what;
1117 *	};
1118 */
1119static void encode_devicedata3(struct xdr_stream *xdr,
1120			       const struct nfs3_mknodargs *args,
1121			       struct user_namespace *userns)
1122{
1123	encode_sattr3(xdr, args->sattr, userns);
1124	encode_specdata3(xdr, args->rdev);
1125}
1126
1127static void encode_mknoddata3(struct xdr_stream *xdr,
1128			      const struct nfs3_mknodargs *args,
1129			      struct user_namespace *userns)
1130{
1131	encode_ftype3(xdr, args->type);
1132	switch (args->type) {
1133	case NF3CHR:
1134	case NF3BLK:
1135		encode_devicedata3(xdr, args, userns);
1136		break;
1137	case NF3SOCK:
1138	case NF3FIFO:
1139		encode_sattr3(xdr, args->sattr, userns);
1140		break;
1141	case NF3REG:
1142	case NF3DIR:
1143		break;
1144	default:
1145		BUG();
1146	}
1147}
1148
1149static void nfs3_xdr_enc_mknod3args(struct rpc_rqst *req,
1150				    struct xdr_stream *xdr,
1151				    const void *data)
1152{
1153	const struct nfs3_mknodargs *args = data;
1154
1155	encode_diropargs3(xdr, args->fh, args->name, args->len);
1156	encode_mknoddata3(xdr, args, rpc_rqst_userns(req));
1157}
1158
1159/*
1160 * 3.3.12  REMOVE3args
1161 *
1162 *	struct REMOVE3args {
1163 *		diropargs3  object;
1164 *	};
1165 */
1166static void nfs3_xdr_enc_remove3args(struct rpc_rqst *req,
1167				     struct xdr_stream *xdr,
1168				     const void *data)
1169{
1170	const struct nfs_removeargs *args = data;
1171
1172	encode_diropargs3(xdr, args->fh, args->name.name, args->name.len);
1173}
1174
1175/*
1176 * 3.3.14  RENAME3args
1177 *
1178 *	struct RENAME3args {
1179 *		diropargs3	from;
1180 *		diropargs3	to;
1181 *	};
1182 */
1183static void nfs3_xdr_enc_rename3args(struct rpc_rqst *req,
1184				     struct xdr_stream *xdr,
1185				     const void *data)
1186{
1187	const struct nfs_renameargs *args = data;
1188	const struct qstr *old = args->old_name;
1189	const struct qstr *new = args->new_name;
1190
1191	encode_diropargs3(xdr, args->old_dir, old->name, old->len);
1192	encode_diropargs3(xdr, args->new_dir, new->name, new->len);
1193}
1194
1195/*
1196 * 3.3.15  LINK3args
1197 *
1198 *	struct LINK3args {
1199 *		nfs_fh3		file;
1200 *		diropargs3	link;
1201 *	};
1202 */
1203static void nfs3_xdr_enc_link3args(struct rpc_rqst *req,
1204				   struct xdr_stream *xdr,
1205				   const void *data)
1206{
1207	const struct nfs3_linkargs *args = data;
1208
1209	encode_nfs_fh3(xdr, args->fromfh);
1210	encode_diropargs3(xdr, args->tofh, args->toname, args->tolen);
1211}
1212
1213/*
1214 * 3.3.16  READDIR3args
1215 *
1216 *	struct READDIR3args {
1217 *		nfs_fh3		dir;
1218 *		cookie3		cookie;
1219 *		cookieverf3	cookieverf;
1220 *		count3		count;
1221 *	};
1222 */
1223static void encode_readdir3args(struct xdr_stream *xdr,
1224				const struct nfs3_readdirargs *args)
1225{
1226	__be32 *p;
1227
1228	encode_nfs_fh3(xdr, args->fh);
1229
1230	p = xdr_reserve_space(xdr, 8 + NFS3_COOKIEVERFSIZE + 4);
1231	p = xdr_encode_cookie3(p, args->cookie);
1232	p = xdr_encode_cookieverf3(p, args->verf);
1233	*p = cpu_to_be32(args->count);
1234}
1235
1236static void nfs3_xdr_enc_readdir3args(struct rpc_rqst *req,
1237				      struct xdr_stream *xdr,
1238				      const void *data)
1239{
1240	const struct nfs3_readdirargs *args = data;
1241
1242	encode_readdir3args(xdr, args);
1243	rpc_prepare_reply_pages(req, args->pages, 0,
1244				args->count, NFS3_readdirres_sz);
1245}
1246
1247/*
1248 * 3.3.17  READDIRPLUS3args
1249 *
1250 *	struct READDIRPLUS3args {
1251 *		nfs_fh3		dir;
1252 *		cookie3		cookie;
1253 *		cookieverf3	cookieverf;
1254 *		count3		dircount;
1255 *		count3		maxcount;
1256 *	};
1257 */
1258static void encode_readdirplus3args(struct xdr_stream *xdr,
1259				    const struct nfs3_readdirargs *args)
1260{
1261	__be32 *p;
1262
1263	encode_nfs_fh3(xdr, args->fh);
1264
1265	p = xdr_reserve_space(xdr, 8 + NFS3_COOKIEVERFSIZE + 4 + 4);
1266	p = xdr_encode_cookie3(p, args->cookie);
1267	p = xdr_encode_cookieverf3(p, args->verf);
1268
1269	/*
1270	 * readdirplus: need dircount + buffer size.
1271	 * We just make sure we make dircount big enough
1272	 */
1273	*p++ = cpu_to_be32(args->count >> 3);
1274
1275	*p = cpu_to_be32(args->count);
1276}
1277
1278static void nfs3_xdr_enc_readdirplus3args(struct rpc_rqst *req,
1279					  struct xdr_stream *xdr,
1280					  const void *data)
1281{
1282	const struct nfs3_readdirargs *args = data;
1283
1284	encode_readdirplus3args(xdr, args);
1285	rpc_prepare_reply_pages(req, args->pages, 0,
1286				args->count, NFS3_readdirres_sz);
1287}
1288
1289/*
1290 * 3.3.21  COMMIT3args
1291 *
1292 *	struct COMMIT3args {
1293 *		nfs_fh3		file;
1294 *		offset3		offset;
1295 *		count3		count;
1296 *	};
1297 */
1298static void encode_commit3args(struct xdr_stream *xdr,
1299			       const struct nfs_commitargs *args)
1300{
1301	__be32 *p;
1302
1303	encode_nfs_fh3(xdr, args->fh);
1304
1305	p = xdr_reserve_space(xdr, 8 + 4);
1306	p = xdr_encode_hyper(p, args->offset);
1307	*p = cpu_to_be32(args->count);
1308}
1309
1310static void nfs3_xdr_enc_commit3args(struct rpc_rqst *req,
1311				     struct xdr_stream *xdr,
1312				     const void *data)
1313{
1314	const struct nfs_commitargs *args = data;
1315
1316	encode_commit3args(xdr, args);
1317}
1318
1319#ifdef CONFIG_NFS_V3_ACL
1320
1321static void nfs3_xdr_enc_getacl3args(struct rpc_rqst *req,
1322				     struct xdr_stream *xdr,
1323				     const void *data)
1324{
1325	const struct nfs3_getaclargs *args = data;
1326
1327	encode_nfs_fh3(xdr, args->fh);
1328	encode_uint32(xdr, args->mask);
1329	if (args->mask & (NFS_ACL | NFS_DFACL)) {
1330		rpc_prepare_reply_pages(req, args->pages, 0,
1331					NFSACL_MAXPAGES << PAGE_SHIFT,
1332					ACL3_getaclres_sz);
1333		req->rq_rcv_buf.flags |= XDRBUF_SPARSE_PAGES;
1334	}
1335}
1336
1337static void nfs3_xdr_enc_setacl3args(struct rpc_rqst *req,
1338				     struct xdr_stream *xdr,
1339				     const void *data)
1340{
1341	const struct nfs3_setaclargs *args = data;
1342	unsigned int base;
1343	int error;
1344
1345	encode_nfs_fh3(xdr, NFS_FH(args->inode));
1346	encode_uint32(xdr, args->mask);
1347
1348	base = req->rq_slen;
1349	if (args->npages != 0)
1350		xdr_write_pages(xdr, args->pages, 0, args->len);
1351	else
1352		xdr_reserve_space(xdr, args->len);
1353
1354	error = nfsacl_encode(xdr->buf, base, args->inode,
1355			    (args->mask & NFS_ACL) ?
1356			    args->acl_access : NULL, 1, 0);
1357	/* FIXME: this is just broken */
1358	BUG_ON(error < 0);
1359	error = nfsacl_encode(xdr->buf, base + error, args->inode,
1360			    (args->mask & NFS_DFACL) ?
1361			    args->acl_default : NULL, 1,
1362			    NFS_ACL_DEFAULT);
1363	BUG_ON(error < 0);
1364}
1365
1366#endif  /* CONFIG_NFS_V3_ACL */
1367
1368/*
1369 * NFSv3 XDR decode functions
1370 *
1371 * NFSv3 result types are defined in section 3.3 of RFC 1813:
1372 * "NFS Version 3 Protocol Specification".
1373 */
1374
1375/*
1376 * 3.3.1  GETATTR3res
1377 *
1378 *	struct GETATTR3resok {
1379 *		fattr3		obj_attributes;
1380 *	};
1381 *
1382 *	union GETATTR3res switch (nfsstat3 status) {
1383 *	case NFS3_OK:
1384 *		GETATTR3resok  resok;
1385 *	default:
1386 *		void;
1387 *	};
1388 */
1389static int nfs3_xdr_dec_getattr3res(struct rpc_rqst *req,
1390				    struct xdr_stream *xdr,
1391				    void *result)
1392{
1393	enum nfs_stat status;
1394	int error;
1395
1396	error = decode_nfsstat3(xdr, &status);
1397	if (unlikely(error))
1398		goto out;
1399	if (status != NFS3_OK)
1400		goto out_default;
1401	error = decode_fattr3(xdr, result, rpc_rqst_userns(req));
1402out:
1403	return error;
1404out_default:
1405	return nfs3_stat_to_errno(status);
1406}
1407
1408/*
1409 * 3.3.2  SETATTR3res
1410 *
1411 *	struct SETATTR3resok {
1412 *		wcc_data  obj_wcc;
1413 *	};
1414 *
1415 *	struct SETATTR3resfail {
1416 *		wcc_data  obj_wcc;
1417 *	};
1418 *
1419 *	union SETATTR3res switch (nfsstat3 status) {
1420 *	case NFS3_OK:
1421 *		SETATTR3resok   resok;
1422 *	default:
1423 *		SETATTR3resfail resfail;
1424 *	};
1425 */
1426static int nfs3_xdr_dec_setattr3res(struct rpc_rqst *req,
1427				    struct xdr_stream *xdr,
1428				    void *result)
1429{
1430	enum nfs_stat status;
1431	int error;
1432
1433	error = decode_nfsstat3(xdr, &status);
1434	if (unlikely(error))
1435		goto out;
1436	error = decode_wcc_data(xdr, result, rpc_rqst_userns(req));
1437	if (unlikely(error))
1438		goto out;
1439	if (status != NFS3_OK)
1440		goto out_status;
1441out:
1442	return error;
1443out_status:
1444	return nfs3_stat_to_errno(status);
1445}
1446
1447/*
1448 * 3.3.3  LOOKUP3res
1449 *
1450 *	struct LOOKUP3resok {
1451 *		nfs_fh3		object;
1452 *		post_op_attr	obj_attributes;
1453 *		post_op_attr	dir_attributes;
1454 *	};
1455 *
1456 *	struct LOOKUP3resfail {
1457 *		post_op_attr	dir_attributes;
1458 *	};
1459 *
1460 *	union LOOKUP3res switch (nfsstat3 status) {
1461 *	case NFS3_OK:
1462 *		LOOKUP3resok	resok;
1463 *	default:
1464 *		LOOKUP3resfail	resfail;
1465 *	};
1466 */
1467static int nfs3_xdr_dec_lookup3res(struct rpc_rqst *req,
1468				   struct xdr_stream *xdr,
1469				   void *data)
1470{
1471	struct user_namespace *userns = rpc_rqst_userns(req);
1472	struct nfs3_diropres *result = data;
1473	enum nfs_stat status;
1474	int error;
1475
1476	error = decode_nfsstat3(xdr, &status);
1477	if (unlikely(error))
1478		goto out;
1479	if (status != NFS3_OK)
1480		goto out_default;
1481	error = decode_nfs_fh3(xdr, result->fh);
1482	if (unlikely(error))
1483		goto out;
1484	error = decode_post_op_attr(xdr, result->fattr, userns);
1485	if (unlikely(error))
1486		goto out;
1487	error = decode_post_op_attr(xdr, result->dir_attr, userns);
1488out:
1489	return error;
1490out_default:
1491	error = decode_post_op_attr(xdr, result->dir_attr, userns);
1492	if (unlikely(error))
1493		goto out;
1494	return nfs3_stat_to_errno(status);
1495}
1496
1497/*
1498 * 3.3.4  ACCESS3res
1499 *
1500 *	struct ACCESS3resok {
1501 *		post_op_attr	obj_attributes;
1502 *		uint32		access;
1503 *	};
1504 *
1505 *	struct ACCESS3resfail {
1506 *		post_op_attr	obj_attributes;
1507 *	};
1508 *
1509 *	union ACCESS3res switch (nfsstat3 status) {
1510 *	case NFS3_OK:
1511 *		ACCESS3resok	resok;
1512 *	default:
1513 *		ACCESS3resfail	resfail;
1514 *	};
1515 */
1516static int nfs3_xdr_dec_access3res(struct rpc_rqst *req,
1517				   struct xdr_stream *xdr,
1518				   void *data)
1519{
1520	struct nfs3_accessres *result = data;
1521	enum nfs_stat status;
1522	int error;
1523
1524	error = decode_nfsstat3(xdr, &status);
1525	if (unlikely(error))
1526		goto out;
1527	error = decode_post_op_attr(xdr, result->fattr, rpc_rqst_userns(req));
1528	if (unlikely(error))
1529		goto out;
1530	if (status != NFS3_OK)
1531		goto out_default;
1532	error = decode_uint32(xdr, &result->access);
1533out:
1534	return error;
1535out_default:
1536	return nfs3_stat_to_errno(status);
1537}
1538
1539/*
1540 * 3.3.5  READLINK3res
1541 *
1542 *	struct READLINK3resok {
1543 *		post_op_attr	symlink_attributes;
1544 *		nfspath3	data;
1545 *	};
1546 *
1547 *	struct READLINK3resfail {
1548 *		post_op_attr	symlink_attributes;
1549 *	};
1550 *
1551 *	union READLINK3res switch (nfsstat3 status) {
1552 *	case NFS3_OK:
1553 *		READLINK3resok	resok;
1554 *	default:
1555 *		READLINK3resfail resfail;
1556 *	};
1557 */
1558static int nfs3_xdr_dec_readlink3res(struct rpc_rqst *req,
1559				     struct xdr_stream *xdr,
1560				     void *result)
1561{
1562	enum nfs_stat status;
1563	int error;
1564
1565	error = decode_nfsstat3(xdr, &status);
1566	if (unlikely(error))
1567		goto out;
1568	error = decode_post_op_attr(xdr, result, rpc_rqst_userns(req));
1569	if (unlikely(error))
1570		goto out;
1571	if (status != NFS3_OK)
1572		goto out_default;
1573	error = decode_nfspath3(xdr);
1574out:
1575	return error;
1576out_default:
1577	return nfs3_stat_to_errno(status);
1578}
1579
1580/*
1581 * 3.3.6  READ3res
1582 *
1583 *	struct READ3resok {
1584 *		post_op_attr	file_attributes;
1585 *		count3		count;
1586 *		bool		eof;
1587 *		opaque		data<>;
1588 *	};
1589 *
1590 *	struct READ3resfail {
1591 *		post_op_attr	file_attributes;
1592 *	};
1593 *
1594 *	union READ3res switch (nfsstat3 status) {
1595 *	case NFS3_OK:
1596 *		READ3resok	resok;
1597 *	default:
1598 *		READ3resfail	resfail;
1599 *	};
1600 */
1601static int decode_read3resok(struct xdr_stream *xdr,
1602			     struct nfs_pgio_res *result)
1603{
1604	u32 eof, count, ocount, recvd;
1605	__be32 *p;
1606
1607	p = xdr_inline_decode(xdr, 4 + 4 + 4);
1608	if (unlikely(!p))
1609		return -EIO;
1610	count = be32_to_cpup(p++);
1611	eof = be32_to_cpup(p++);
1612	ocount = be32_to_cpup(p++);
1613	if (unlikely(ocount != count))
1614		goto out_mismatch;
1615	recvd = xdr_read_pages(xdr, count);
1616	if (unlikely(count > recvd))
1617		goto out_cheating;
1618out:
1619	result->eof = eof;
1620	result->count = count;
1621	return count;
1622out_mismatch:
1623	dprintk("NFS: READ count doesn't match length of opaque: "
1624		"count %u != ocount %u\n", count, ocount);
1625	return -EIO;
1626out_cheating:
1627	dprintk("NFS: server cheating in read result: "
1628		"count %u > recvd %u\n", count, recvd);
1629	count = recvd;
1630	eof = 0;
1631	goto out;
1632}
1633
1634static int nfs3_xdr_dec_read3res(struct rpc_rqst *req, struct xdr_stream *xdr,
1635				 void *data)
1636{
1637	struct nfs_pgio_res *result = data;
1638	unsigned int pos;
1639	enum nfs_stat status;
1640	int error;
1641
1642	pos = xdr_stream_pos(xdr);
1643	error = decode_nfsstat3(xdr, &status);
1644	if (unlikely(error))
1645		goto out;
1646	error = decode_post_op_attr(xdr, result->fattr, rpc_rqst_userns(req));
1647	if (unlikely(error))
1648		goto out;
1649	result->op_status = status;
1650	if (status != NFS3_OK)
1651		goto out_status;
1652	result->replen = 4 + ((xdr_stream_pos(xdr) - pos) >> 2);
1653	error = decode_read3resok(xdr, result);
1654out:
1655	return error;
1656out_status:
1657	return nfs3_stat_to_errno(status);
1658}
1659
1660/*
1661 * 3.3.7  WRITE3res
1662 *
1663 *	enum stable_how {
1664 *		UNSTABLE  = 0,
1665 *		DATA_SYNC = 1,
1666 *		FILE_SYNC = 2
1667 *	};
1668 *
1669 *	struct WRITE3resok {
1670 *		wcc_data	file_wcc;
1671 *		count3		count;
1672 *		stable_how	committed;
1673 *		writeverf3	verf;
1674 *	};
1675 *
1676 *	struct WRITE3resfail {
1677 *		wcc_data	file_wcc;
1678 *	};
1679 *
1680 *	union WRITE3res switch (nfsstat3 status) {
1681 *	case NFS3_OK:
1682 *		WRITE3resok	resok;
1683 *	default:
1684 *		WRITE3resfail	resfail;
1685 *	};
1686 */
1687static int decode_write3resok(struct xdr_stream *xdr,
1688			      struct nfs_pgio_res *result)
1689{
1690	__be32 *p;
1691
1692	p = xdr_inline_decode(xdr, 4 + 4);
1693	if (unlikely(!p))
1694		return -EIO;
1695	result->count = be32_to_cpup(p++);
1696	result->verf->committed = be32_to_cpup(p++);
1697	if (unlikely(result->verf->committed > NFS_FILE_SYNC))
1698		goto out_badvalue;
1699	if (decode_writeverf3(xdr, &result->verf->verifier))
1700		return -EIO;
1701	return result->count;
1702out_badvalue:
1703	dprintk("NFS: bad stable_how value: %u\n", result->verf->committed);
1704	return -EIO;
1705}
1706
1707static int nfs3_xdr_dec_write3res(struct rpc_rqst *req, struct xdr_stream *xdr,
1708				  void *data)
1709{
1710	struct nfs_pgio_res *result = data;
1711	enum nfs_stat status;
1712	int error;
1713
1714	error = decode_nfsstat3(xdr, &status);
1715	if (unlikely(error))
1716		goto out;
1717	error = decode_wcc_data(xdr, result->fattr, rpc_rqst_userns(req));
1718	if (unlikely(error))
1719		goto out;
1720	result->op_status = status;
1721	if (status != NFS3_OK)
1722		goto out_status;
1723	error = decode_write3resok(xdr, result);
1724out:
1725	return error;
1726out_status:
1727	return nfs3_stat_to_errno(status);
1728}
1729
1730/*
1731 * 3.3.8  CREATE3res
1732 *
1733 *	struct CREATE3resok {
1734 *		post_op_fh3	obj;
1735 *		post_op_attr	obj_attributes;
1736 *		wcc_data	dir_wcc;
1737 *	};
1738 *
1739 *	struct CREATE3resfail {
1740 *		wcc_data	dir_wcc;
1741 *	};
1742 *
1743 *	union CREATE3res switch (nfsstat3 status) {
1744 *	case NFS3_OK:
1745 *		CREATE3resok	resok;
1746 *	default:
1747 *		CREATE3resfail	resfail;
1748 *	};
1749 */
1750static int decode_create3resok(struct xdr_stream *xdr,
1751			       struct nfs3_diropres *result,
1752			       struct user_namespace *userns)
1753{
1754	int error;
1755
1756	error = decode_post_op_fh3(xdr, result->fh);
1757	if (unlikely(error))
1758		goto out;
1759	error = decode_post_op_attr(xdr, result->fattr, userns);
1760	if (unlikely(error))
1761		goto out;
1762	/* The server isn't required to return a file handle.
1763	 * If it didn't, force the client to perform a LOOKUP
1764	 * to determine the correct file handle and attribute
1765	 * values for the new object. */
1766	if (result->fh->size == 0)
1767		result->fattr->valid = 0;
1768	error = decode_wcc_data(xdr, result->dir_attr, userns);
1769out:
1770	return error;
1771}
1772
1773static int nfs3_xdr_dec_create3res(struct rpc_rqst *req,
1774				   struct xdr_stream *xdr,
1775				   void *data)
1776{
1777	struct user_namespace *userns = rpc_rqst_userns(req);
1778	struct nfs3_diropres *result = data;
1779	enum nfs_stat status;
1780	int error;
1781
1782	error = decode_nfsstat3(xdr, &status);
1783	if (unlikely(error))
1784		goto out;
1785	if (status != NFS3_OK)
1786		goto out_default;
1787	error = decode_create3resok(xdr, result, userns);
1788out:
1789	return error;
1790out_default:
1791	error = decode_wcc_data(xdr, result->dir_attr, userns);
1792	if (unlikely(error))
1793		goto out;
1794	return nfs3_stat_to_errno(status);
1795}
1796
1797/*
1798 * 3.3.12  REMOVE3res
1799 *
1800 *	struct REMOVE3resok {
1801 *		wcc_data    dir_wcc;
1802 *	};
1803 *
1804 *	struct REMOVE3resfail {
1805 *		wcc_data    dir_wcc;
1806 *	};
1807 *
1808 *	union REMOVE3res switch (nfsstat3 status) {
1809 *	case NFS3_OK:
1810 *		REMOVE3resok   resok;
1811 *	default:
1812 *		REMOVE3resfail resfail;
1813 *	};
1814 */
1815static int nfs3_xdr_dec_remove3res(struct rpc_rqst *req,
1816				   struct xdr_stream *xdr,
1817				   void *data)
1818{
1819	struct nfs_removeres *result = data;
1820	enum nfs_stat status;
1821	int error;
1822
1823	error = decode_nfsstat3(xdr, &status);
1824	if (unlikely(error))
1825		goto out;
1826	error = decode_wcc_data(xdr, result->dir_attr, rpc_rqst_userns(req));
1827	if (unlikely(error))
1828		goto out;
1829	if (status != NFS3_OK)
1830		goto out_status;
1831out:
1832	return error;
1833out_status:
1834	return nfs3_stat_to_errno(status);
1835}
1836
1837/*
1838 * 3.3.14  RENAME3res
1839 *
1840 *	struct RENAME3resok {
1841 *		wcc_data	fromdir_wcc;
1842 *		wcc_data	todir_wcc;
1843 *	};
1844 *
1845 *	struct RENAME3resfail {
1846 *		wcc_data	fromdir_wcc;
1847 *		wcc_data	todir_wcc;
1848 *	};
1849 *
1850 *	union RENAME3res switch (nfsstat3 status) {
1851 *	case NFS3_OK:
1852 *		RENAME3resok   resok;
1853 *	default:
1854 *		RENAME3resfail resfail;
1855 *	};
1856 */
1857static int nfs3_xdr_dec_rename3res(struct rpc_rqst *req,
1858				   struct xdr_stream *xdr,
1859				   void *data)
1860{
1861	struct user_namespace *userns = rpc_rqst_userns(req);
1862	struct nfs_renameres *result = data;
1863	enum nfs_stat status;
1864	int error;
1865
1866	error = decode_nfsstat3(xdr, &status);
1867	if (unlikely(error))
1868		goto out;
1869	error = decode_wcc_data(xdr, result->old_fattr, userns);
1870	if (unlikely(error))
1871		goto out;
1872	error = decode_wcc_data(xdr, result->new_fattr, userns);
1873	if (unlikely(error))
1874		goto out;
1875	if (status != NFS3_OK)
1876		goto out_status;
1877out:
1878	return error;
1879out_status:
1880	return nfs3_stat_to_errno(status);
1881}
1882
1883/*
1884 * 3.3.15  LINK3res
1885 *
1886 *	struct LINK3resok {
1887 *		post_op_attr	file_attributes;
1888 *		wcc_data	linkdir_wcc;
1889 *	};
1890 *
1891 *	struct LINK3resfail {
1892 *		post_op_attr	file_attributes;
1893 *		wcc_data	linkdir_wcc;
1894 *	};
1895 *
1896 *	union LINK3res switch (nfsstat3 status) {
1897 *	case NFS3_OK:
1898 *		LINK3resok	resok;
1899 *	default:
1900 *		LINK3resfail	resfail;
1901 *	};
1902 */
1903static int nfs3_xdr_dec_link3res(struct rpc_rqst *req, struct xdr_stream *xdr,
1904				 void *data)
1905{
1906	struct user_namespace *userns = rpc_rqst_userns(req);
1907	struct nfs3_linkres *result = data;
1908	enum nfs_stat status;
1909	int error;
1910
1911	error = decode_nfsstat3(xdr, &status);
1912	if (unlikely(error))
1913		goto out;
1914	error = decode_post_op_attr(xdr, result->fattr, userns);
1915	if (unlikely(error))
1916		goto out;
1917	error = decode_wcc_data(xdr, result->dir_attr, userns);
1918	if (unlikely(error))
1919		goto out;
1920	if (status != NFS3_OK)
1921		goto out_status;
1922out:
1923	return error;
1924out_status:
1925	return nfs3_stat_to_errno(status);
1926}
1927
1928/**
1929 * nfs3_decode_dirent - Decode a single NFSv3 directory entry stored in
1930 *			the local page cache
1931 * @xdr: XDR stream where entry resides
1932 * @entry: buffer to fill in with entry data
1933 * @plus: boolean indicating whether this should be a readdirplus entry
1934 *
1935 * Returns zero if successful, otherwise a negative errno value is
1936 * returned.
1937 *
1938 * This function is not invoked during READDIR reply decoding, but
1939 * rather whenever an application invokes the getdents(2) system call
1940 * on a directory already in our cache.
1941 *
1942 * 3.3.16  entry3
1943 *
1944 *	struct entry3 {
1945 *		fileid3		fileid;
1946 *		filename3	name;
1947 *		cookie3		cookie;
1948 *		fhandle3	filehandle;
1949 *		post_op_attr3	attributes;
1950 *		entry3		*nextentry;
1951 *	};
1952 *
1953 * 3.3.17  entryplus3
1954 *	struct entryplus3 {
1955 *		fileid3		fileid;
1956 *		filename3	name;
1957 *		cookie3		cookie;
1958 *		post_op_attr	name_attributes;
1959 *		post_op_fh3	name_handle;
1960 *		entryplus3	*nextentry;
1961 *	};
1962 */
1963int nfs3_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry,
1964		       bool plus)
1965{
1966	struct user_namespace *userns = rpc_userns(entry->server->client);
1967	__be32 *p;
1968	int error;
1969	u64 new_cookie;
1970
1971	p = xdr_inline_decode(xdr, 4);
1972	if (unlikely(!p))
1973		return -EAGAIN;
1974	if (*p == xdr_zero) {
1975		p = xdr_inline_decode(xdr, 4);
1976		if (unlikely(!p))
1977			return -EAGAIN;
1978		if (*p == xdr_zero)
1979			return -EAGAIN;
1980		entry->eof = 1;
1981		return -EBADCOOKIE;
1982	}
1983
1984	error = decode_fileid3(xdr, &entry->ino);
1985	if (unlikely(error))
1986		return -EAGAIN;
1987
1988	error = decode_inline_filename3(xdr, &entry->name, &entry->len);
1989	if (unlikely(error))
1990		return error == -ENAMETOOLONG ? -ENAMETOOLONG : -EAGAIN;
1991
1992	error = decode_cookie3(xdr, &new_cookie);
1993	if (unlikely(error))
1994		return -EAGAIN;
1995
1996	entry->d_type = DT_UNKNOWN;
1997
1998	if (plus) {
1999		entry->fattr->valid = 0;
2000		error = decode_post_op_attr(xdr, entry->fattr, userns);
2001		if (unlikely(error))
2002			return -EAGAIN;
2003		if (entry->fattr->valid & NFS_ATTR_FATTR_V3)
2004			entry->d_type = nfs_umode_to_dtype(entry->fattr->mode);
2005
2006		if (entry->fattr->fileid != entry->ino) {
2007			entry->fattr->mounted_on_fileid = entry->ino;
2008			entry->fattr->valid |= NFS_ATTR_FATTR_MOUNTED_ON_FILEID;
2009		}
2010
2011		/* In fact, a post_op_fh3: */
2012		p = xdr_inline_decode(xdr, 4);
2013		if (unlikely(!p))
2014			return -EAGAIN;
2015		if (*p != xdr_zero) {
2016			error = decode_nfs_fh3(xdr, entry->fh);
2017			if (unlikely(error))
2018				return -EAGAIN;
2019		} else
2020			zero_nfs_fh3(entry->fh);
2021	}
2022
2023	entry->prev_cookie = entry->cookie;
2024	entry->cookie = new_cookie;
2025
2026	return 0;
2027}
2028
2029/*
2030 * 3.3.16  READDIR3res
2031 *
2032 *	struct dirlist3 {
2033 *		entry3		*entries;
2034 *		bool		eof;
2035 *	};
2036 *
2037 *	struct READDIR3resok {
2038 *		post_op_attr	dir_attributes;
2039 *		cookieverf3	cookieverf;
2040 *		dirlist3	reply;
2041 *	};
2042 *
2043 *	struct READDIR3resfail {
2044 *		post_op_attr	dir_attributes;
2045 *	};
2046 *
2047 *	union READDIR3res switch (nfsstat3 status) {
2048 *	case NFS3_OK:
2049 *		READDIR3resok	resok;
2050 *	default:
2051 *		READDIR3resfail	resfail;
2052 *	};
2053 *
2054 * Read the directory contents into the page cache, but otherwise
2055 * don't touch them.  The actual decoding is done by nfs3_decode_entry()
2056 * during subsequent nfs_readdir() calls.
2057 */
2058static int decode_dirlist3(struct xdr_stream *xdr)
2059{
2060	return xdr_read_pages(xdr, xdr->buf->page_len);
2061}
2062
2063static int decode_readdir3resok(struct xdr_stream *xdr,
2064				struct nfs3_readdirres *result,
2065				struct user_namespace *userns)
2066{
2067	int error;
2068
2069	error = decode_post_op_attr(xdr, result->dir_attr, userns);
2070	if (unlikely(error))
2071		goto out;
2072	/* XXX: do we need to check if result->verf != NULL ? */
2073	error = decode_cookieverf3(xdr, result->verf);
2074	if (unlikely(error))
2075		goto out;
2076	error = decode_dirlist3(xdr);
2077out:
2078	return error;
2079}
2080
2081static int nfs3_xdr_dec_readdir3res(struct rpc_rqst *req,
2082				    struct xdr_stream *xdr,
2083				    void *data)
2084{
2085	struct nfs3_readdirres *result = data;
2086	enum nfs_stat status;
2087	int error;
2088
2089	error = decode_nfsstat3(xdr, &status);
2090	if (unlikely(error))
2091		goto out;
2092	if (status != NFS3_OK)
2093		goto out_default;
2094	error = decode_readdir3resok(xdr, result, rpc_rqst_userns(req));
2095out:
2096	return error;
2097out_default:
2098	error = decode_post_op_attr(xdr, result->dir_attr, rpc_rqst_userns(req));
2099	if (unlikely(error))
2100		goto out;
2101	return nfs3_stat_to_errno(status);
2102}
2103
2104/*
2105 * 3.3.18  FSSTAT3res
2106 *
2107 *	struct FSSTAT3resok {
2108 *		post_op_attr	obj_attributes;
2109 *		size3		tbytes;
2110 *		size3		fbytes;
2111 *		size3		abytes;
2112 *		size3		tfiles;
2113 *		size3		ffiles;
2114 *		size3		afiles;
2115 *		uint32		invarsec;
2116 *	};
2117 *
2118 *	struct FSSTAT3resfail {
2119 *		post_op_attr	obj_attributes;
2120 *	};
2121 *
2122 *	union FSSTAT3res switch (nfsstat3 status) {
2123 *	case NFS3_OK:
2124 *		FSSTAT3resok	resok;
2125 *	default:
2126 *		FSSTAT3resfail	resfail;
2127 *	};
2128 */
2129static int decode_fsstat3resok(struct xdr_stream *xdr,
2130			       struct nfs_fsstat *result)
2131{
2132	__be32 *p;
2133
2134	p = xdr_inline_decode(xdr, 8 * 6 + 4);
2135	if (unlikely(!p))
2136		return -EIO;
2137	p = xdr_decode_size3(p, &result->tbytes);
2138	p = xdr_decode_size3(p, &result->fbytes);
2139	p = xdr_decode_size3(p, &result->abytes);
2140	p = xdr_decode_size3(p, &result->tfiles);
2141	p = xdr_decode_size3(p, &result->ffiles);
2142	xdr_decode_size3(p, &result->afiles);
2143	/* ignore invarsec */
2144	return 0;
2145}
2146
2147static int nfs3_xdr_dec_fsstat3res(struct rpc_rqst *req,
2148				   struct xdr_stream *xdr,
2149				   void *data)
2150{
2151	struct nfs_fsstat *result = data;
2152	enum nfs_stat status;
2153	int error;
2154
2155	error = decode_nfsstat3(xdr, &status);
2156	if (unlikely(error))
2157		goto out;
2158	error = decode_post_op_attr(xdr, result->fattr, rpc_rqst_userns(req));
2159	if (unlikely(error))
2160		goto out;
2161	if (status != NFS3_OK)
2162		goto out_status;
2163	error = decode_fsstat3resok(xdr, result);
2164out:
2165	return error;
2166out_status:
2167	return nfs3_stat_to_errno(status);
2168}
2169
2170/*
2171 * 3.3.19  FSINFO3res
2172 *
2173 *	struct FSINFO3resok {
2174 *		post_op_attr	obj_attributes;
2175 *		uint32		rtmax;
2176 *		uint32		rtpref;
2177 *		uint32		rtmult;
2178 *		uint32		wtmax;
2179 *		uint32		wtpref;
2180 *		uint32		wtmult;
2181 *		uint32		dtpref;
2182 *		size3		maxfilesize;
2183 *		nfstime3	time_delta;
2184 *		uint32		properties;
2185 *	};
2186 *
2187 *	struct FSINFO3resfail {
2188 *		post_op_attr	obj_attributes;
2189 *	};
2190 *
2191 *	union FSINFO3res switch (nfsstat3 status) {
2192 *	case NFS3_OK:
2193 *		FSINFO3resok	resok;
2194 *	default:
2195 *		FSINFO3resfail	resfail;
2196 *	};
2197 */
2198static int decode_fsinfo3resok(struct xdr_stream *xdr,
2199			       struct nfs_fsinfo *result)
2200{
2201	__be32 *p;
2202
2203	p = xdr_inline_decode(xdr, 4 * 7 + 8 + 8 + 4);
2204	if (unlikely(!p))
2205		return -EIO;
2206	result->rtmax  = be32_to_cpup(p++);
2207	result->rtpref = be32_to_cpup(p++);
2208	result->rtmult = be32_to_cpup(p++);
2209	result->wtmax  = be32_to_cpup(p++);
2210	result->wtpref = be32_to_cpup(p++);
2211	result->wtmult = be32_to_cpup(p++);
2212	result->dtpref = be32_to_cpup(p++);
2213	p = xdr_decode_size3(p, &result->maxfilesize);
2214	xdr_decode_nfstime3(p, &result->time_delta);
2215
2216	/* ignore properties */
2217	result->lease_time = 0;
2218	return 0;
2219}
2220
2221static int nfs3_xdr_dec_fsinfo3res(struct rpc_rqst *req,
2222				   struct xdr_stream *xdr,
2223				   void *data)
2224{
2225	struct nfs_fsinfo *result = data;
2226	enum nfs_stat status;
2227	int error;
2228
2229	error = decode_nfsstat3(xdr, &status);
2230	if (unlikely(error))
2231		goto out;
2232	error = decode_post_op_attr(xdr, result->fattr, rpc_rqst_userns(req));
2233	if (unlikely(error))
2234		goto out;
2235	if (status != NFS3_OK)
2236		goto out_status;
2237	error = decode_fsinfo3resok(xdr, result);
2238out:
2239	return error;
2240out_status:
2241	return nfs3_stat_to_errno(status);
2242}
2243
2244/*
2245 * 3.3.20  PATHCONF3res
2246 *
2247 *	struct PATHCONF3resok {
2248 *		post_op_attr	obj_attributes;
2249 *		uint32		linkmax;
2250 *		uint32		name_max;
2251 *		bool		no_trunc;
2252 *		bool		chown_restricted;
2253 *		bool		case_insensitive;
2254 *		bool		case_preserving;
2255 *	};
2256 *
2257 *	struct PATHCONF3resfail {
2258 *		post_op_attr	obj_attributes;
2259 *	};
2260 *
2261 *	union PATHCONF3res switch (nfsstat3 status) {
2262 *	case NFS3_OK:
2263 *		PATHCONF3resok	resok;
2264 *	default:
2265 *		PATHCONF3resfail resfail;
2266 *	};
2267 */
2268static int decode_pathconf3resok(struct xdr_stream *xdr,
2269				 struct nfs_pathconf *result)
2270{
2271	__be32 *p;
2272
2273	p = xdr_inline_decode(xdr, 4 * 6);
2274	if (unlikely(!p))
2275		return -EIO;
2276	result->max_link = be32_to_cpup(p++);
2277	result->max_namelen = be32_to_cpup(p);
2278	/* ignore remaining fields */
2279	return 0;
2280}
2281
2282static int nfs3_xdr_dec_pathconf3res(struct rpc_rqst *req,
2283				     struct xdr_stream *xdr,
2284				     void *data)
2285{
2286	struct nfs_pathconf *result = data;
2287	enum nfs_stat status;
2288	int error;
2289
2290	error = decode_nfsstat3(xdr, &status);
2291	if (unlikely(error))
2292		goto out;
2293	error = decode_post_op_attr(xdr, result->fattr, rpc_rqst_userns(req));
2294	if (unlikely(error))
2295		goto out;
2296	if (status != NFS3_OK)
2297		goto out_status;
2298	error = decode_pathconf3resok(xdr, result);
2299out:
2300	return error;
2301out_status:
2302	return nfs3_stat_to_errno(status);
2303}
2304
2305/*
2306 * 3.3.21  COMMIT3res
2307 *
2308 *	struct COMMIT3resok {
2309 *		wcc_data	file_wcc;
2310 *		writeverf3	verf;
2311 *	};
2312 *
2313 *	struct COMMIT3resfail {
2314 *		wcc_data	file_wcc;
2315 *	};
2316 *
2317 *	union COMMIT3res switch (nfsstat3 status) {
2318 *	case NFS3_OK:
2319 *		COMMIT3resok	resok;
2320 *	default:
2321 *		COMMIT3resfail	resfail;
2322 *	};
2323 */
2324static int nfs3_xdr_dec_commit3res(struct rpc_rqst *req,
2325				   struct xdr_stream *xdr,
2326				   void *data)
2327{
2328	struct nfs_commitres *result = data;
2329	struct nfs_writeverf *verf = result->verf;
2330	enum nfs_stat status;
2331	int error;
2332
2333	error = decode_nfsstat3(xdr, &status);
2334	if (unlikely(error))
2335		goto out;
2336	error = decode_wcc_data(xdr, result->fattr, rpc_rqst_userns(req));
2337	if (unlikely(error))
2338		goto out;
2339	result->op_status = status;
2340	if (status != NFS3_OK)
2341		goto out_status;
2342	error = decode_writeverf3(xdr, &verf->verifier);
2343	if (!error)
2344		verf->committed = NFS_FILE_SYNC;
2345out:
2346	return error;
2347out_status:
2348	return nfs3_stat_to_errno(status);
2349}
2350
2351#ifdef CONFIG_NFS_V3_ACL
2352
2353static inline int decode_getacl3resok(struct xdr_stream *xdr,
2354				      struct nfs3_getaclres *result,
2355				      struct user_namespace *userns)
2356{
2357	struct posix_acl **acl;
2358	unsigned int *aclcnt;
2359	size_t hdrlen;
2360	int error;
2361
2362	error = decode_post_op_attr(xdr, result->fattr, userns);
2363	if (unlikely(error))
2364		goto out;
2365	error = decode_uint32(xdr, &result->mask);
2366	if (unlikely(error))
2367		goto out;
2368	error = -EINVAL;
2369	if (result->mask & ~(NFS_ACL|NFS_ACLCNT|NFS_DFACL|NFS_DFACLCNT))
2370		goto out;
2371
2372	hdrlen = xdr_stream_pos(xdr);
2373
2374	acl = NULL;
2375	if (result->mask & NFS_ACL)
2376		acl = &result->acl_access;
2377	aclcnt = NULL;
2378	if (result->mask & NFS_ACLCNT)
2379		aclcnt = &result->acl_access_count;
2380	error = nfsacl_decode(xdr->buf, hdrlen, aclcnt, acl);
2381	if (unlikely(error <= 0))
2382		goto out;
2383
2384	acl = NULL;
2385	if (result->mask & NFS_DFACL)
2386		acl = &result->acl_default;
2387	aclcnt = NULL;
2388	if (result->mask & NFS_DFACLCNT)
2389		aclcnt = &result->acl_default_count;
2390	error = nfsacl_decode(xdr->buf, hdrlen + error, aclcnt, acl);
2391	if (unlikely(error <= 0))
2392		return error;
2393	error = 0;
2394out:
2395	return error;
2396}
2397
2398static int nfs3_xdr_dec_getacl3res(struct rpc_rqst *req,
2399				   struct xdr_stream *xdr,
2400				   void *result)
2401{
2402	enum nfs_stat status;
2403	int error;
2404
2405	error = decode_nfsstat3(xdr, &status);
2406	if (unlikely(error))
2407		goto out;
2408	if (status != NFS3_OK)
2409		goto out_default;
2410	error = decode_getacl3resok(xdr, result, rpc_rqst_userns(req));
2411out:
2412	return error;
2413out_default:
2414	return nfs3_stat_to_errno(status);
2415}
2416
2417static int nfs3_xdr_dec_setacl3res(struct rpc_rqst *req,
2418				   struct xdr_stream *xdr,
2419				   void *result)
2420{
2421	enum nfs_stat status;
2422	int error;
2423
2424	error = decode_nfsstat3(xdr, &status);
2425	if (unlikely(error))
2426		goto out;
2427	if (status != NFS3_OK)
2428		goto out_default;
2429	error = decode_post_op_attr(xdr, result, rpc_rqst_userns(req));
2430out:
2431	return error;
2432out_default:
2433	return nfs3_stat_to_errno(status);
2434}
2435
2436#endif  /* CONFIG_NFS_V3_ACL */
2437
2438
2439/*
2440 * We need to translate between nfs status return values and
2441 * the local errno values which may not be the same.
2442 */
2443static const struct {
2444	int stat;
2445	int errno;
2446} nfs_errtbl[] = {
2447	{ NFS_OK,		0		},
2448	{ NFSERR_PERM,		-EPERM		},
2449	{ NFSERR_NOENT,		-ENOENT		},
2450	{ NFSERR_IO,		-errno_NFSERR_IO},
2451	{ NFSERR_NXIO,		-ENXIO		},
2452/*	{ NFSERR_EAGAIN,	-EAGAIN		}, */
2453	{ NFSERR_ACCES,		-EACCES		},
2454	{ NFSERR_EXIST,		-EEXIST		},
2455	{ NFSERR_XDEV,		-EXDEV		},
2456	{ NFSERR_NODEV,		-ENODEV		},
2457	{ NFSERR_NOTDIR,	-ENOTDIR	},
2458	{ NFSERR_ISDIR,		-EISDIR		},
2459	{ NFSERR_INVAL,		-EINVAL		},
2460	{ NFSERR_FBIG,		-EFBIG		},
2461	{ NFSERR_NOSPC,		-ENOSPC		},
2462	{ NFSERR_ROFS,		-EROFS		},
2463	{ NFSERR_MLINK,		-EMLINK		},
2464	{ NFSERR_NAMETOOLONG,	-ENAMETOOLONG	},
2465	{ NFSERR_NOTEMPTY,	-ENOTEMPTY	},
2466	{ NFSERR_DQUOT,		-EDQUOT		},
2467	{ NFSERR_STALE,		-ESTALE		},
2468	{ NFSERR_REMOTE,	-EREMOTE	},
2469#ifdef EWFLUSH
2470	{ NFSERR_WFLUSH,	-EWFLUSH	},
2471#endif
2472	{ NFSERR_BADHANDLE,	-EBADHANDLE	},
2473	{ NFSERR_NOT_SYNC,	-ENOTSYNC	},
2474	{ NFSERR_BAD_COOKIE,	-EBADCOOKIE	},
2475	{ NFSERR_NOTSUPP,	-ENOTSUPP	},
2476	{ NFSERR_TOOSMALL,	-ETOOSMALL	},
2477	{ NFSERR_SERVERFAULT,	-EREMOTEIO	},
2478	{ NFSERR_BADTYPE,	-EBADTYPE	},
2479	{ NFSERR_JUKEBOX,	-EJUKEBOX	},
2480	{ -1,			-EIO		}
2481};
2482
2483/**
2484 * nfs3_stat_to_errno - convert an NFS status code to a local errno
2485 * @status: NFS status code to convert
2486 *
2487 * Returns a local errno value, or -EIO if the NFS status code is
2488 * not recognized.  This function is used jointly by NFSv2 and NFSv3.
2489 */
2490static int nfs3_stat_to_errno(enum nfs_stat status)
2491{
2492	int i;
2493
2494	for (i = 0; nfs_errtbl[i].stat != -1; i++) {
2495		if (nfs_errtbl[i].stat == (int)status)
2496			return nfs_errtbl[i].errno;
2497	}
2498	dprintk("NFS: Unrecognized nfs status value: %u\n", status);
2499	return nfs_errtbl[i].errno;
2500}
2501
2502
2503#define PROC(proc, argtype, restype, timer)				\
2504[NFS3PROC_##proc] = {							\
2505	.p_proc      = NFS3PROC_##proc,					\
2506	.p_encode    = nfs3_xdr_enc_##argtype##3args,			\
2507	.p_decode    = nfs3_xdr_dec_##restype##3res,			\
2508	.p_arglen    = NFS3_##argtype##args_sz,				\
2509	.p_replen    = NFS3_##restype##res_sz,				\
2510	.p_timer     = timer,						\
2511	.p_statidx   = NFS3PROC_##proc,					\
2512	.p_name      = #proc,						\
2513	}
2514
2515const struct rpc_procinfo nfs3_procedures[] = {
2516	PROC(GETATTR,		getattr,	getattr,	1),
2517	PROC(SETATTR,		setattr,	setattr,	0),
2518	PROC(LOOKUP,		lookup,		lookup,		2),
2519	PROC(ACCESS,		access,		access,		1),
2520	PROC(READLINK,		readlink,	readlink,	3),
2521	PROC(READ,		read,		read,		3),
2522	PROC(WRITE,		write,		write,		4),
2523	PROC(CREATE,		create,		create,		0),
2524	PROC(MKDIR,		mkdir,		create,		0),
2525	PROC(SYMLINK,		symlink,	create,		0),
2526	PROC(MKNOD,		mknod,		create,		0),
2527	PROC(REMOVE,		remove,		remove,		0),
2528	PROC(RMDIR,		lookup,		setattr,	0),
2529	PROC(RENAME,		rename,		rename,		0),
2530	PROC(LINK,		link,		link,		0),
2531	PROC(READDIR,		readdir,	readdir,	3),
2532	PROC(READDIRPLUS,	readdirplus,	readdir,	3),
2533	PROC(FSSTAT,		getattr,	fsstat,		0),
2534	PROC(FSINFO,		getattr,	fsinfo,		0),
2535	PROC(PATHCONF,		getattr,	pathconf,	0),
2536	PROC(COMMIT,		commit,		commit,		5),
2537};
2538
2539static unsigned int nfs_version3_counts[ARRAY_SIZE(nfs3_procedures)];
2540const struct rpc_version nfs_version3 = {
2541	.number			= 3,
2542	.nrprocs		= ARRAY_SIZE(nfs3_procedures),
2543	.procs			= nfs3_procedures,
2544	.counts			= nfs_version3_counts,
2545};
2546
2547#ifdef CONFIG_NFS_V3_ACL
2548static const struct rpc_procinfo nfs3_acl_procedures[] = {
2549	[ACLPROC3_GETACL] = {
2550		.p_proc = ACLPROC3_GETACL,
2551		.p_encode = nfs3_xdr_enc_getacl3args,
2552		.p_decode = nfs3_xdr_dec_getacl3res,
2553		.p_arglen = ACL3_getaclargs_sz,
2554		.p_replen = ACL3_getaclres_sz,
2555		.p_timer = 1,
2556		.p_name = "GETACL",
2557	},
2558	[ACLPROC3_SETACL] = {
2559		.p_proc = ACLPROC3_SETACL,
2560		.p_encode = nfs3_xdr_enc_setacl3args,
2561		.p_decode = nfs3_xdr_dec_setacl3res,
2562		.p_arglen = ACL3_setaclargs_sz,
2563		.p_replen = ACL3_setaclres_sz,
2564		.p_timer = 0,
2565		.p_name = "SETACL",
2566	},
2567};
2568
2569static unsigned int nfs3_acl_counts[ARRAY_SIZE(nfs3_acl_procedures)];
2570const struct rpc_version nfsacl_version3 = {
2571	.number			= 3,
2572	.nrprocs		= ARRAY_SIZE(nfs3_acl_procedures),
2573	.procs			= nfs3_acl_procedures,
2574	.counts			= nfs3_acl_counts,
2575};
2576#endif  /* CONFIG_NFS_V3_ACL */
2577