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