xref: /openbmc/linux/fs/nfs/nfs2xdr.c (revision 05bcf503)
1 /*
2  * linux/fs/nfs/nfs2xdr.c
3  *
4  * XDR functions to encode/decode NFS RPC arguments and results.
5  *
6  * Copyright (C) 1992, 1993, 1994  Rick Sladkey
7  * Copyright (C) 1996 Olaf Kirch
8  * 04 Aug 1998  Ion Badulescu <ionut@cs.columbia.edu>
9  * 		FIFO's need special handling in NFSv2
10  */
11 
12 #include <linux/param.h>
13 #include <linux/time.h>
14 #include <linux/mm.h>
15 #include <linux/errno.h>
16 #include <linux/string.h>
17 #include <linux/in.h>
18 #include <linux/pagemap.h>
19 #include <linux/proc_fs.h>
20 #include <linux/sunrpc/clnt.h>
21 #include <linux/nfs.h>
22 #include <linux/nfs2.h>
23 #include <linux/nfs_fs.h>
24 #include "internal.h"
25 
26 #define NFSDBG_FACILITY		NFSDBG_XDR
27 
28 /* Mapping from NFS error code to "errno" error code. */
29 #define errno_NFSERR_IO		EIO
30 
31 /*
32  * Declare the space requirements for NFS arguments and replies as
33  * number of 32bit-words
34  */
35 #define NFS_fhandle_sz		(8)
36 #define NFS_sattr_sz		(8)
37 #define NFS_filename_sz		(1+(NFS2_MAXNAMLEN>>2))
38 #define NFS_path_sz		(1+(NFS2_MAXPATHLEN>>2))
39 #define NFS_fattr_sz		(17)
40 #define NFS_info_sz		(5)
41 #define NFS_entry_sz		(NFS_filename_sz+3)
42 
43 #define NFS_diropargs_sz	(NFS_fhandle_sz+NFS_filename_sz)
44 #define NFS_removeargs_sz	(NFS_fhandle_sz+NFS_filename_sz)
45 #define NFS_sattrargs_sz	(NFS_fhandle_sz+NFS_sattr_sz)
46 #define NFS_readlinkargs_sz	(NFS_fhandle_sz)
47 #define NFS_readargs_sz		(NFS_fhandle_sz+3)
48 #define NFS_writeargs_sz	(NFS_fhandle_sz+4)
49 #define NFS_createargs_sz	(NFS_diropargs_sz+NFS_sattr_sz)
50 #define NFS_renameargs_sz	(NFS_diropargs_sz+NFS_diropargs_sz)
51 #define NFS_linkargs_sz		(NFS_fhandle_sz+NFS_diropargs_sz)
52 #define NFS_symlinkargs_sz	(NFS_diropargs_sz+1+NFS_sattr_sz)
53 #define NFS_readdirargs_sz	(NFS_fhandle_sz+2)
54 
55 #define NFS_attrstat_sz		(1+NFS_fattr_sz)
56 #define NFS_diropres_sz		(1+NFS_fhandle_sz+NFS_fattr_sz)
57 #define NFS_readlinkres_sz	(2)
58 #define NFS_readres_sz		(1+NFS_fattr_sz+1)
59 #define NFS_writeres_sz         (NFS_attrstat_sz)
60 #define NFS_stat_sz		(1)
61 #define NFS_readdirres_sz	(1)
62 #define NFS_statfsres_sz	(1+NFS_info_sz)
63 
64 static int nfs_stat_to_errno(enum nfs_stat);
65 
66 /*
67  * While encoding arguments, set up the reply buffer in advance to
68  * receive reply data directly into the page cache.
69  */
70 static void prepare_reply_buffer(struct rpc_rqst *req, struct page **pages,
71 				 unsigned int base, unsigned int len,
72 				 unsigned int bufsize)
73 {
74 	struct rpc_auth	*auth = req->rq_cred->cr_auth;
75 	unsigned int replen;
76 
77 	replen = RPC_REPHDRSIZE + auth->au_rslack + bufsize;
78 	xdr_inline_pages(&req->rq_rcv_buf, replen << 2, pages, base, len);
79 }
80 
81 /*
82  * Handle decode buffer overflows out-of-line.
83  */
84 static void print_overflow_msg(const char *func, const struct xdr_stream *xdr)
85 {
86 	dprintk("NFS: %s prematurely hit the end of our receive buffer. "
87 		"Remaining buffer length is %tu words.\n",
88 		func, xdr->end - xdr->p);
89 }
90 
91 
92 /*
93  * Encode/decode NFSv2 basic data types
94  *
95  * Basic NFSv2 data types are defined in section 2.3 of RFC 1094:
96  * "NFS: Network File System Protocol Specification".
97  *
98  * Not all basic data types have their own encoding and decoding
99  * functions.  For run-time efficiency, some data types are encoded
100  * or decoded inline.
101  */
102 
103 /*
104  *	typedef opaque	nfsdata<>;
105  */
106 static int decode_nfsdata(struct xdr_stream *xdr, struct nfs_readres *result)
107 {
108 	u32 recvd, count;
109 	__be32 *p;
110 
111 	p = xdr_inline_decode(xdr, 4);
112 	if (unlikely(p == NULL))
113 		goto out_overflow;
114 	count = be32_to_cpup(p);
115 	recvd = xdr_read_pages(xdr, count);
116 	if (unlikely(count > recvd))
117 		goto out_cheating;
118 out:
119 	result->eof = 0;	/* NFSv2 does not pass EOF flag on the wire. */
120 	result->count = count;
121 	return count;
122 out_cheating:
123 	dprintk("NFS: server cheating in read result: "
124 		"count %u > recvd %u\n", count, recvd);
125 	count = recvd;
126 	goto out;
127 out_overflow:
128 	print_overflow_msg(__func__, xdr);
129 	return -EIO;
130 }
131 
132 /*
133  *	enum stat {
134  *		NFS_OK = 0,
135  *		NFSERR_PERM = 1,
136  *		NFSERR_NOENT = 2,
137  *		NFSERR_IO = 5,
138  *		NFSERR_NXIO = 6,
139  *		NFSERR_ACCES = 13,
140  *		NFSERR_EXIST = 17,
141  *		NFSERR_NODEV = 19,
142  *		NFSERR_NOTDIR = 20,
143  *		NFSERR_ISDIR = 21,
144  *		NFSERR_FBIG = 27,
145  *		NFSERR_NOSPC = 28,
146  *		NFSERR_ROFS = 30,
147  *		NFSERR_NAMETOOLONG = 63,
148  *		NFSERR_NOTEMPTY = 66,
149  *		NFSERR_DQUOT = 69,
150  *		NFSERR_STALE = 70,
151  *		NFSERR_WFLUSH = 99
152  *	};
153  */
154 static int decode_stat(struct xdr_stream *xdr, enum nfs_stat *status)
155 {
156 	__be32 *p;
157 
158 	p = xdr_inline_decode(xdr, 4);
159 	if (unlikely(p == NULL))
160 		goto out_overflow;
161 	*status = be32_to_cpup(p);
162 	return 0;
163 out_overflow:
164 	print_overflow_msg(__func__, xdr);
165 	return -EIO;
166 }
167 
168 /*
169  * 2.3.2.  ftype
170  *
171  *	enum ftype {
172  *		NFNON = 0,
173  *		NFREG = 1,
174  *		NFDIR = 2,
175  *		NFBLK = 3,
176  *		NFCHR = 4,
177  *		NFLNK = 5
178  *	};
179  *
180  */
181 static __be32 *xdr_decode_ftype(__be32 *p, u32 *type)
182 {
183 	*type = be32_to_cpup(p++);
184 	if (unlikely(*type > NF2FIFO))
185 		*type = NFBAD;
186 	return p;
187 }
188 
189 /*
190  * 2.3.3.  fhandle
191  *
192  *	typedef opaque fhandle[FHSIZE];
193  */
194 static void encode_fhandle(struct xdr_stream *xdr, const struct nfs_fh *fh)
195 {
196 	__be32 *p;
197 
198 	BUG_ON(fh->size != NFS2_FHSIZE);
199 	p = xdr_reserve_space(xdr, NFS2_FHSIZE);
200 	memcpy(p, fh->data, NFS2_FHSIZE);
201 }
202 
203 static int decode_fhandle(struct xdr_stream *xdr, struct nfs_fh *fh)
204 {
205 	__be32 *p;
206 
207 	p = xdr_inline_decode(xdr, NFS2_FHSIZE);
208 	if (unlikely(p == NULL))
209 		goto out_overflow;
210 	fh->size = NFS2_FHSIZE;
211 	memcpy(fh->data, p, NFS2_FHSIZE);
212 	return 0;
213 out_overflow:
214 	print_overflow_msg(__func__, xdr);
215 	return -EIO;
216 }
217 
218 /*
219  * 2.3.4.  timeval
220  *
221  *	struct timeval {
222  *		unsigned int seconds;
223  *		unsigned int useconds;
224  *	};
225  */
226 static __be32 *xdr_encode_time(__be32 *p, const struct timespec *timep)
227 {
228 	*p++ = cpu_to_be32(timep->tv_sec);
229 	if (timep->tv_nsec != 0)
230 		*p++ = cpu_to_be32(timep->tv_nsec / NSEC_PER_USEC);
231 	else
232 		*p++ = cpu_to_be32(0);
233 	return p;
234 }
235 
236 /*
237  * Passing the invalid value useconds=1000000 is a Sun convention for
238  * "set to current server time".  It's needed to make permissions checks
239  * for the "touch" program across v2 mounts to Solaris and Irix servers
240  * work correctly.  See description of sattr in section 6.1 of "NFS
241  * Illustrated" by Brent Callaghan, Addison-Wesley, ISBN 0-201-32750-5.
242  */
243 static __be32 *xdr_encode_current_server_time(__be32 *p,
244 					      const struct timespec *timep)
245 {
246 	*p++ = cpu_to_be32(timep->tv_sec);
247 	*p++ = cpu_to_be32(1000000);
248 	return p;
249 }
250 
251 static __be32 *xdr_decode_time(__be32 *p, struct timespec *timep)
252 {
253 	timep->tv_sec = be32_to_cpup(p++);
254 	timep->tv_nsec = be32_to_cpup(p++) * NSEC_PER_USEC;
255 	return p;
256 }
257 
258 /*
259  * 2.3.5.  fattr
260  *
261  *	struct fattr {
262  *		ftype		type;
263  *		unsigned int	mode;
264  *		unsigned int	nlink;
265  *		unsigned int	uid;
266  *		unsigned int	gid;
267  *		unsigned int	size;
268  *		unsigned int	blocksize;
269  *		unsigned int	rdev;
270  *		unsigned int	blocks;
271  *		unsigned int	fsid;
272  *		unsigned int	fileid;
273  *		timeval		atime;
274  *		timeval		mtime;
275  *		timeval		ctime;
276  *	};
277  *
278  */
279 static int decode_fattr(struct xdr_stream *xdr, struct nfs_fattr *fattr)
280 {
281 	u32 rdev, type;
282 	__be32 *p;
283 
284 	p = xdr_inline_decode(xdr, NFS_fattr_sz << 2);
285 	if (unlikely(p == NULL))
286 		goto out_overflow;
287 
288 	fattr->valid |= NFS_ATTR_FATTR_V2;
289 
290 	p = xdr_decode_ftype(p, &type);
291 
292 	fattr->mode = be32_to_cpup(p++);
293 	fattr->nlink = be32_to_cpup(p++);
294 	fattr->uid = be32_to_cpup(p++);
295 	fattr->gid = be32_to_cpup(p++);
296 	fattr->size = be32_to_cpup(p++);
297 	fattr->du.nfs2.blocksize = be32_to_cpup(p++);
298 
299 	rdev = be32_to_cpup(p++);
300 	fattr->rdev = new_decode_dev(rdev);
301 	if (type == (u32)NFCHR && rdev == (u32)NFS2_FIFO_DEV) {
302 		fattr->mode = (fattr->mode & ~S_IFMT) | S_IFIFO;
303 		fattr->rdev = 0;
304 	}
305 
306 	fattr->du.nfs2.blocks = be32_to_cpup(p++);
307 	fattr->fsid.major = be32_to_cpup(p++);
308 	fattr->fsid.minor = 0;
309 	fattr->fileid = be32_to_cpup(p++);
310 
311 	p = xdr_decode_time(p, &fattr->atime);
312 	p = xdr_decode_time(p, &fattr->mtime);
313 	xdr_decode_time(p, &fattr->ctime);
314 	fattr->change_attr = nfs_timespec_to_change_attr(&fattr->ctime);
315 
316 	return 0;
317 out_overflow:
318 	print_overflow_msg(__func__, xdr);
319 	return -EIO;
320 }
321 
322 /*
323  * 2.3.6.  sattr
324  *
325  *	struct sattr {
326  *		unsigned int	mode;
327  *		unsigned int	uid;
328  *		unsigned int	gid;
329  *		unsigned int	size;
330  *		timeval		atime;
331  *		timeval		mtime;
332  *	};
333  */
334 
335 #define NFS2_SATTR_NOT_SET	(0xffffffff)
336 
337 static __be32 *xdr_time_not_set(__be32 *p)
338 {
339 	*p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
340 	*p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
341 	return p;
342 }
343 
344 static void encode_sattr(struct xdr_stream *xdr, const struct iattr *attr)
345 {
346 	__be32 *p;
347 
348 	p = xdr_reserve_space(xdr, NFS_sattr_sz << 2);
349 
350 	if (attr->ia_valid & ATTR_MODE)
351 		*p++ = cpu_to_be32(attr->ia_mode);
352 	else
353 		*p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
354 	if (attr->ia_valid & ATTR_UID)
355 		*p++ = cpu_to_be32(attr->ia_uid);
356 	else
357 		*p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
358 	if (attr->ia_valid & ATTR_GID)
359 		*p++ = cpu_to_be32(attr->ia_gid);
360 	else
361 		*p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
362 	if (attr->ia_valid & ATTR_SIZE)
363 		*p++ = cpu_to_be32((u32)attr->ia_size);
364 	else
365 		*p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
366 
367 	if (attr->ia_valid & ATTR_ATIME_SET)
368 		p = xdr_encode_time(p, &attr->ia_atime);
369 	else if (attr->ia_valid & ATTR_ATIME)
370 		p = xdr_encode_current_server_time(p, &attr->ia_atime);
371 	else
372 		p = xdr_time_not_set(p);
373 	if (attr->ia_valid & ATTR_MTIME_SET)
374 		xdr_encode_time(p, &attr->ia_mtime);
375 	else if (attr->ia_valid & ATTR_MTIME)
376 		xdr_encode_current_server_time(p, &attr->ia_mtime);
377 	else
378 		xdr_time_not_set(p);
379 }
380 
381 /*
382  * 2.3.7.  filename
383  *
384  *	typedef string filename<MAXNAMLEN>;
385  */
386 static void encode_filename(struct xdr_stream *xdr,
387 			    const char *name, u32 length)
388 {
389 	__be32 *p;
390 
391 	BUG_ON(length > NFS2_MAXNAMLEN);
392 	p = xdr_reserve_space(xdr, 4 + length);
393 	xdr_encode_opaque(p, name, length);
394 }
395 
396 static int decode_filename_inline(struct xdr_stream *xdr,
397 				  const char **name, u32 *length)
398 {
399 	__be32 *p;
400 	u32 count;
401 
402 	p = xdr_inline_decode(xdr, 4);
403 	if (unlikely(p == NULL))
404 		goto out_overflow;
405 	count = be32_to_cpup(p);
406 	if (count > NFS3_MAXNAMLEN)
407 		goto out_nametoolong;
408 	p = xdr_inline_decode(xdr, count);
409 	if (unlikely(p == NULL))
410 		goto out_overflow;
411 	*name = (const char *)p;
412 	*length = count;
413 	return 0;
414 out_nametoolong:
415 	dprintk("NFS: returned filename too long: %u\n", count);
416 	return -ENAMETOOLONG;
417 out_overflow:
418 	print_overflow_msg(__func__, xdr);
419 	return -EIO;
420 }
421 
422 /*
423  * 2.3.8.  path
424  *
425  *	typedef string path<MAXPATHLEN>;
426  */
427 static void encode_path(struct xdr_stream *xdr, struct page **pages, u32 length)
428 {
429 	__be32 *p;
430 
431 	BUG_ON(length > NFS2_MAXPATHLEN);
432 	p = xdr_reserve_space(xdr, 4);
433 	*p = cpu_to_be32(length);
434 	xdr_write_pages(xdr, pages, 0, length);
435 }
436 
437 static int decode_path(struct xdr_stream *xdr)
438 {
439 	u32 length, recvd;
440 	__be32 *p;
441 
442 	p = xdr_inline_decode(xdr, 4);
443 	if (unlikely(p == NULL))
444 		goto out_overflow;
445 	length = be32_to_cpup(p);
446 	if (unlikely(length >= xdr->buf->page_len || length > NFS_MAXPATHLEN))
447 		goto out_size;
448 	recvd = xdr_read_pages(xdr, length);
449 	if (unlikely(length > recvd))
450 		goto out_cheating;
451 	xdr_terminate_string(xdr->buf, length);
452 	return 0;
453 out_size:
454 	dprintk("NFS: returned pathname too long: %u\n", length);
455 	return -ENAMETOOLONG;
456 out_cheating:
457 	dprintk("NFS: server cheating in pathname result: "
458 		"length %u > received %u\n", length, recvd);
459 	return -EIO;
460 out_overflow:
461 	print_overflow_msg(__func__, xdr);
462 	return -EIO;
463 }
464 
465 /*
466  * 2.3.9.  attrstat
467  *
468  *	union attrstat switch (stat status) {
469  *	case NFS_OK:
470  *		fattr attributes;
471  *	default:
472  *		void;
473  *	};
474  */
475 static int decode_attrstat(struct xdr_stream *xdr, struct nfs_fattr *result)
476 {
477 	enum nfs_stat status;
478 	int error;
479 
480 	error = decode_stat(xdr, &status);
481 	if (unlikely(error))
482 		goto out;
483 	if (status != NFS_OK)
484 		goto out_default;
485 	error = decode_fattr(xdr, result);
486 out:
487 	return error;
488 out_default:
489 	return nfs_stat_to_errno(status);
490 }
491 
492 /*
493  * 2.3.10.  diropargs
494  *
495  *	struct diropargs {
496  *		fhandle  dir;
497  *		filename name;
498  *	};
499  */
500 static void encode_diropargs(struct xdr_stream *xdr, const struct nfs_fh *fh,
501 			     const char *name, u32 length)
502 {
503 	encode_fhandle(xdr, fh);
504 	encode_filename(xdr, name, length);
505 }
506 
507 /*
508  * 2.3.11.  diropres
509  *
510  *	union diropres switch (stat status) {
511  *	case NFS_OK:
512  *		struct {
513  *			fhandle file;
514  *			fattr   attributes;
515  *		} diropok;
516  *	default:
517  *		void;
518  *	};
519  */
520 static int decode_diropok(struct xdr_stream *xdr, struct nfs_diropok *result)
521 {
522 	int error;
523 
524 	error = decode_fhandle(xdr, result->fh);
525 	if (unlikely(error))
526 		goto out;
527 	error = decode_fattr(xdr, result->fattr);
528 out:
529 	return error;
530 }
531 
532 static int decode_diropres(struct xdr_stream *xdr, struct nfs_diropok *result)
533 {
534 	enum nfs_stat status;
535 	int error;
536 
537 	error = decode_stat(xdr, &status);
538 	if (unlikely(error))
539 		goto out;
540 	if (status != NFS_OK)
541 		goto out_default;
542 	error = decode_diropok(xdr, result);
543 out:
544 	return error;
545 out_default:
546 	return nfs_stat_to_errno(status);
547 }
548 
549 
550 /*
551  * NFSv2 XDR encode functions
552  *
553  * NFSv2 argument types are defined in section 2.2 of RFC 1094:
554  * "NFS: Network File System Protocol Specification".
555  */
556 
557 static void nfs2_xdr_enc_fhandle(struct rpc_rqst *req,
558 				 struct xdr_stream *xdr,
559 				 const struct nfs_fh *fh)
560 {
561 	encode_fhandle(xdr, fh);
562 }
563 
564 /*
565  * 2.2.3.  sattrargs
566  *
567  *	struct sattrargs {
568  *		fhandle file;
569  *		sattr attributes;
570  *	};
571  */
572 static void nfs2_xdr_enc_sattrargs(struct rpc_rqst *req,
573 				   struct xdr_stream *xdr,
574 				   const struct nfs_sattrargs *args)
575 {
576 	encode_fhandle(xdr, args->fh);
577 	encode_sattr(xdr, args->sattr);
578 }
579 
580 static void nfs2_xdr_enc_diropargs(struct rpc_rqst *req,
581 				   struct xdr_stream *xdr,
582 				   const struct nfs_diropargs *args)
583 {
584 	encode_diropargs(xdr, args->fh, args->name, args->len);
585 }
586 
587 static void nfs2_xdr_enc_readlinkargs(struct rpc_rqst *req,
588 				      struct xdr_stream *xdr,
589 				      const struct nfs_readlinkargs *args)
590 {
591 	encode_fhandle(xdr, args->fh);
592 	prepare_reply_buffer(req, args->pages, args->pgbase,
593 					args->pglen, NFS_readlinkres_sz);
594 }
595 
596 /*
597  * 2.2.7.  readargs
598  *
599  *	struct readargs {
600  *		fhandle file;
601  *		unsigned offset;
602  *		unsigned count;
603  *		unsigned totalcount;
604  *	};
605  */
606 static void encode_readargs(struct xdr_stream *xdr,
607 			    const struct nfs_readargs *args)
608 {
609 	u32 offset = args->offset;
610 	u32 count = args->count;
611 	__be32 *p;
612 
613 	encode_fhandle(xdr, args->fh);
614 
615 	p = xdr_reserve_space(xdr, 4 + 4 + 4);
616 	*p++ = cpu_to_be32(offset);
617 	*p++ = cpu_to_be32(count);
618 	*p = cpu_to_be32(count);
619 }
620 
621 static void nfs2_xdr_enc_readargs(struct rpc_rqst *req,
622 				  struct xdr_stream *xdr,
623 				  const struct nfs_readargs *args)
624 {
625 	encode_readargs(xdr, args);
626 	prepare_reply_buffer(req, args->pages, args->pgbase,
627 					args->count, NFS_readres_sz);
628 	req->rq_rcv_buf.flags |= XDRBUF_READ;
629 }
630 
631 /*
632  * 2.2.9.  writeargs
633  *
634  *	struct writeargs {
635  *		fhandle file;
636  *		unsigned beginoffset;
637  *		unsigned offset;
638  *		unsigned totalcount;
639  *		nfsdata data;
640  *	};
641  */
642 static void encode_writeargs(struct xdr_stream *xdr,
643 			     const struct nfs_writeargs *args)
644 {
645 	u32 offset = args->offset;
646 	u32 count = args->count;
647 	__be32 *p;
648 
649 	encode_fhandle(xdr, args->fh);
650 
651 	p = xdr_reserve_space(xdr, 4 + 4 + 4 + 4);
652 	*p++ = cpu_to_be32(offset);
653 	*p++ = cpu_to_be32(offset);
654 	*p++ = cpu_to_be32(count);
655 
656 	/* nfsdata */
657 	*p = cpu_to_be32(count);
658 	xdr_write_pages(xdr, args->pages, args->pgbase, count);
659 }
660 
661 static void nfs2_xdr_enc_writeargs(struct rpc_rqst *req,
662 				   struct xdr_stream *xdr,
663 				   const struct nfs_writeargs *args)
664 {
665 	encode_writeargs(xdr, args);
666 	xdr->buf->flags |= XDRBUF_WRITE;
667 }
668 
669 /*
670  * 2.2.10.  createargs
671  *
672  *	struct createargs {
673  *		diropargs where;
674  *		sattr attributes;
675  *	};
676  */
677 static void nfs2_xdr_enc_createargs(struct rpc_rqst *req,
678 				    struct xdr_stream *xdr,
679 				    const struct nfs_createargs *args)
680 {
681 	encode_diropargs(xdr, args->fh, args->name, args->len);
682 	encode_sattr(xdr, args->sattr);
683 }
684 
685 static void nfs2_xdr_enc_removeargs(struct rpc_rqst *req,
686 				    struct xdr_stream *xdr,
687 				    const struct nfs_removeargs *args)
688 {
689 	encode_diropargs(xdr, args->fh, args->name.name, args->name.len);
690 }
691 
692 /*
693  * 2.2.12.  renameargs
694  *
695  *	struct renameargs {
696  *		diropargs from;
697  *		diropargs to;
698  *	};
699  */
700 static void nfs2_xdr_enc_renameargs(struct rpc_rqst *req,
701 				    struct xdr_stream *xdr,
702 				    const struct nfs_renameargs *args)
703 {
704 	const struct qstr *old = args->old_name;
705 	const struct qstr *new = args->new_name;
706 
707 	encode_diropargs(xdr, args->old_dir, old->name, old->len);
708 	encode_diropargs(xdr, args->new_dir, new->name, new->len);
709 }
710 
711 /*
712  * 2.2.13.  linkargs
713  *
714  *	struct linkargs {
715  *		fhandle from;
716  *		diropargs to;
717  *	};
718  */
719 static void nfs2_xdr_enc_linkargs(struct rpc_rqst *req,
720 				  struct xdr_stream *xdr,
721 				  const struct nfs_linkargs *args)
722 {
723 	encode_fhandle(xdr, args->fromfh);
724 	encode_diropargs(xdr, args->tofh, args->toname, args->tolen);
725 }
726 
727 /*
728  * 2.2.14.  symlinkargs
729  *
730  *	struct symlinkargs {
731  *		diropargs from;
732  *		path to;
733  *		sattr attributes;
734  *	};
735  */
736 static void nfs2_xdr_enc_symlinkargs(struct rpc_rqst *req,
737 				     struct xdr_stream *xdr,
738 				     const struct nfs_symlinkargs *args)
739 {
740 	encode_diropargs(xdr, args->fromfh, args->fromname, args->fromlen);
741 	encode_path(xdr, args->pages, args->pathlen);
742 	encode_sattr(xdr, args->sattr);
743 }
744 
745 /*
746  * 2.2.17.  readdirargs
747  *
748  *	struct readdirargs {
749  *		fhandle dir;
750  *		nfscookie cookie;
751  *		unsigned count;
752  *	};
753  */
754 static void encode_readdirargs(struct xdr_stream *xdr,
755 			       const struct nfs_readdirargs *args)
756 {
757 	__be32 *p;
758 
759 	encode_fhandle(xdr, args->fh);
760 
761 	p = xdr_reserve_space(xdr, 4 + 4);
762 	*p++ = cpu_to_be32(args->cookie);
763 	*p = cpu_to_be32(args->count);
764 }
765 
766 static void nfs2_xdr_enc_readdirargs(struct rpc_rqst *req,
767 				     struct xdr_stream *xdr,
768 				     const struct nfs_readdirargs *args)
769 {
770 	encode_readdirargs(xdr, args);
771 	prepare_reply_buffer(req, args->pages, 0,
772 					args->count, NFS_readdirres_sz);
773 }
774 
775 /*
776  * NFSv2 XDR decode functions
777  *
778  * NFSv2 result types are defined in section 2.2 of RFC 1094:
779  * "NFS: Network File System Protocol Specification".
780  */
781 
782 static int nfs2_xdr_dec_stat(struct rpc_rqst *req, struct xdr_stream *xdr,
783 			     void *__unused)
784 {
785 	enum nfs_stat status;
786 	int error;
787 
788 	error = decode_stat(xdr, &status);
789 	if (unlikely(error))
790 		goto out;
791 	if (status != NFS_OK)
792 		goto out_default;
793 out:
794 	return error;
795 out_default:
796 	return nfs_stat_to_errno(status);
797 }
798 
799 static int nfs2_xdr_dec_attrstat(struct rpc_rqst *req, struct xdr_stream *xdr,
800 				 struct nfs_fattr *result)
801 {
802 	return decode_attrstat(xdr, result);
803 }
804 
805 static int nfs2_xdr_dec_diropres(struct rpc_rqst *req, struct xdr_stream *xdr,
806 				 struct nfs_diropok *result)
807 {
808 	return decode_diropres(xdr, result);
809 }
810 
811 /*
812  * 2.2.6.  readlinkres
813  *
814  *	union readlinkres switch (stat status) {
815  *	case NFS_OK:
816  *		path data;
817  *	default:
818  *		void;
819  *	};
820  */
821 static int nfs2_xdr_dec_readlinkres(struct rpc_rqst *req,
822 				    struct xdr_stream *xdr, void *__unused)
823 {
824 	enum nfs_stat status;
825 	int error;
826 
827 	error = decode_stat(xdr, &status);
828 	if (unlikely(error))
829 		goto out;
830 	if (status != NFS_OK)
831 		goto out_default;
832 	error = decode_path(xdr);
833 out:
834 	return error;
835 out_default:
836 	return nfs_stat_to_errno(status);
837 }
838 
839 /*
840  * 2.2.7.  readres
841  *
842  *	union readres switch (stat status) {
843  *	case NFS_OK:
844  *		fattr attributes;
845  *		nfsdata data;
846  *	default:
847  *		void;
848  *	};
849  */
850 static int nfs2_xdr_dec_readres(struct rpc_rqst *req, struct xdr_stream *xdr,
851 				struct nfs_readres *result)
852 {
853 	enum nfs_stat status;
854 	int error;
855 
856 	error = decode_stat(xdr, &status);
857 	if (unlikely(error))
858 		goto out;
859 	if (status != NFS_OK)
860 		goto out_default;
861 	error = decode_fattr(xdr, result->fattr);
862 	if (unlikely(error))
863 		goto out;
864 	error = decode_nfsdata(xdr, result);
865 out:
866 	return error;
867 out_default:
868 	return nfs_stat_to_errno(status);
869 }
870 
871 static int nfs2_xdr_dec_writeres(struct rpc_rqst *req, struct xdr_stream *xdr,
872 				 struct nfs_writeres *result)
873 {
874 	/* All NFSv2 writes are "file sync" writes */
875 	result->verf->committed = NFS_FILE_SYNC;
876 	return decode_attrstat(xdr, result->fattr);
877 }
878 
879 /**
880  * nfs2_decode_dirent - Decode a single NFSv2 directory entry stored in
881  *                      the local page cache.
882  * @xdr: XDR stream where entry resides
883  * @entry: buffer to fill in with entry data
884  * @plus: boolean indicating whether this should be a readdirplus entry
885  *
886  * Returns zero if successful, otherwise a negative errno value is
887  * returned.
888  *
889  * This function is not invoked during READDIR reply decoding, but
890  * rather whenever an application invokes the getdents(2) system call
891  * on a directory already in our cache.
892  *
893  * 2.2.17.  entry
894  *
895  *	struct entry {
896  *		unsigned	fileid;
897  *		filename	name;
898  *		nfscookie	cookie;
899  *		entry		*nextentry;
900  *	};
901  */
902 int nfs2_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry,
903 		       int plus)
904 {
905 	__be32 *p;
906 	int error;
907 
908 	p = xdr_inline_decode(xdr, 4);
909 	if (unlikely(p == NULL))
910 		goto out_overflow;
911 	if (*p++ == xdr_zero) {
912 		p = xdr_inline_decode(xdr, 4);
913 		if (unlikely(p == NULL))
914 			goto out_overflow;
915 		if (*p++ == xdr_zero)
916 			return -EAGAIN;
917 		entry->eof = 1;
918 		return -EBADCOOKIE;
919 	}
920 
921 	p = xdr_inline_decode(xdr, 4);
922 	if (unlikely(p == NULL))
923 		goto out_overflow;
924 	entry->ino = be32_to_cpup(p);
925 
926 	error = decode_filename_inline(xdr, &entry->name, &entry->len);
927 	if (unlikely(error))
928 		return error;
929 
930 	/*
931 	 * The type (size and byte order) of nfscookie isn't defined in
932 	 * RFC 1094.  This implementation assumes that it's an XDR uint32.
933 	 */
934 	entry->prev_cookie = entry->cookie;
935 	p = xdr_inline_decode(xdr, 4);
936 	if (unlikely(p == NULL))
937 		goto out_overflow;
938 	entry->cookie = be32_to_cpup(p);
939 
940 	entry->d_type = DT_UNKNOWN;
941 
942 	return 0;
943 
944 out_overflow:
945 	print_overflow_msg(__func__, xdr);
946 	return -EAGAIN;
947 }
948 
949 /*
950  * 2.2.17.  readdirres
951  *
952  *	union readdirres switch (stat status) {
953  *	case NFS_OK:
954  *		struct {
955  *			entry *entries;
956  *			bool eof;
957  *		} readdirok;
958  *	default:
959  *		void;
960  *	};
961  *
962  * Read the directory contents into the page cache, but don't
963  * touch them.  The actual decoding is done by nfs2_decode_dirent()
964  * during subsequent nfs_readdir() calls.
965  */
966 static int decode_readdirok(struct xdr_stream *xdr)
967 {
968 	return xdr_read_pages(xdr, xdr->buf->page_len);
969 }
970 
971 static int nfs2_xdr_dec_readdirres(struct rpc_rqst *req,
972 				   struct xdr_stream *xdr, void *__unused)
973 {
974 	enum nfs_stat status;
975 	int error;
976 
977 	error = decode_stat(xdr, &status);
978 	if (unlikely(error))
979 		goto out;
980 	if (status != NFS_OK)
981 		goto out_default;
982 	error = decode_readdirok(xdr);
983 out:
984 	return error;
985 out_default:
986 	return nfs_stat_to_errno(status);
987 }
988 
989 /*
990  * 2.2.18.  statfsres
991  *
992  *	union statfsres (stat status) {
993  *	case NFS_OK:
994  *		struct {
995  *			unsigned tsize;
996  *			unsigned bsize;
997  *			unsigned blocks;
998  *			unsigned bfree;
999  *			unsigned bavail;
1000  *		} info;
1001  *	default:
1002  *		void;
1003  *	};
1004  */
1005 static int decode_info(struct xdr_stream *xdr, struct nfs2_fsstat *result)
1006 {
1007 	__be32 *p;
1008 
1009 	p = xdr_inline_decode(xdr, NFS_info_sz << 2);
1010 	if (unlikely(p == NULL))
1011 		goto out_overflow;
1012 	result->tsize  = be32_to_cpup(p++);
1013 	result->bsize  = be32_to_cpup(p++);
1014 	result->blocks = be32_to_cpup(p++);
1015 	result->bfree  = be32_to_cpup(p++);
1016 	result->bavail = be32_to_cpup(p);
1017 	return 0;
1018 out_overflow:
1019 	print_overflow_msg(__func__, xdr);
1020 	return -EIO;
1021 }
1022 
1023 static int nfs2_xdr_dec_statfsres(struct rpc_rqst *req, struct xdr_stream *xdr,
1024 				  struct nfs2_fsstat *result)
1025 {
1026 	enum nfs_stat status;
1027 	int error;
1028 
1029 	error = decode_stat(xdr, &status);
1030 	if (unlikely(error))
1031 		goto out;
1032 	if (status != NFS_OK)
1033 		goto out_default;
1034 	error = decode_info(xdr, result);
1035 out:
1036 	return error;
1037 out_default:
1038 	return nfs_stat_to_errno(status);
1039 }
1040 
1041 
1042 /*
1043  * We need to translate between nfs status return values and
1044  * the local errno values which may not be the same.
1045  */
1046 static const struct {
1047 	int stat;
1048 	int errno;
1049 } nfs_errtbl[] = {
1050 	{ NFS_OK,		0		},
1051 	{ NFSERR_PERM,		-EPERM		},
1052 	{ NFSERR_NOENT,		-ENOENT		},
1053 	{ NFSERR_IO,		-errno_NFSERR_IO},
1054 	{ NFSERR_NXIO,		-ENXIO		},
1055 /*	{ NFSERR_EAGAIN,	-EAGAIN		}, */
1056 	{ NFSERR_ACCES,		-EACCES		},
1057 	{ NFSERR_EXIST,		-EEXIST		},
1058 	{ NFSERR_XDEV,		-EXDEV		},
1059 	{ NFSERR_NODEV,		-ENODEV		},
1060 	{ NFSERR_NOTDIR,	-ENOTDIR	},
1061 	{ NFSERR_ISDIR,		-EISDIR		},
1062 	{ NFSERR_INVAL,		-EINVAL		},
1063 	{ NFSERR_FBIG,		-EFBIG		},
1064 	{ NFSERR_NOSPC,		-ENOSPC		},
1065 	{ NFSERR_ROFS,		-EROFS		},
1066 	{ NFSERR_MLINK,		-EMLINK		},
1067 	{ NFSERR_NAMETOOLONG,	-ENAMETOOLONG	},
1068 	{ NFSERR_NOTEMPTY,	-ENOTEMPTY	},
1069 	{ NFSERR_DQUOT,		-EDQUOT		},
1070 	{ NFSERR_STALE,		-ESTALE		},
1071 	{ NFSERR_REMOTE,	-EREMOTE	},
1072 #ifdef EWFLUSH
1073 	{ NFSERR_WFLUSH,	-EWFLUSH	},
1074 #endif
1075 	{ NFSERR_BADHANDLE,	-EBADHANDLE	},
1076 	{ NFSERR_NOT_SYNC,	-ENOTSYNC	},
1077 	{ NFSERR_BAD_COOKIE,	-EBADCOOKIE	},
1078 	{ NFSERR_NOTSUPP,	-ENOTSUPP	},
1079 	{ NFSERR_TOOSMALL,	-ETOOSMALL	},
1080 	{ NFSERR_SERVERFAULT,	-EREMOTEIO	},
1081 	{ NFSERR_BADTYPE,	-EBADTYPE	},
1082 	{ NFSERR_JUKEBOX,	-EJUKEBOX	},
1083 	{ -1,			-EIO		}
1084 };
1085 
1086 /**
1087  * nfs_stat_to_errno - convert an NFS status code to a local errno
1088  * @status: NFS status code to convert
1089  *
1090  * Returns a local errno value, or -EIO if the NFS status code is
1091  * not recognized.  This function is used jointly by NFSv2 and NFSv3.
1092  */
1093 static int nfs_stat_to_errno(enum nfs_stat status)
1094 {
1095 	int i;
1096 
1097 	for (i = 0; nfs_errtbl[i].stat != -1; i++) {
1098 		if (nfs_errtbl[i].stat == (int)status)
1099 			return nfs_errtbl[i].errno;
1100 	}
1101 	dprintk("NFS: Unrecognized nfs status value: %u\n", status);
1102 	return nfs_errtbl[i].errno;
1103 }
1104 
1105 #define PROC(proc, argtype, restype, timer)				\
1106 [NFSPROC_##proc] = {							\
1107 	.p_proc	    =  NFSPROC_##proc,					\
1108 	.p_encode   =  (kxdreproc_t)nfs2_xdr_enc_##argtype,		\
1109 	.p_decode   =  (kxdrdproc_t)nfs2_xdr_dec_##restype,		\
1110 	.p_arglen   =  NFS_##argtype##_sz,				\
1111 	.p_replen   =  NFS_##restype##_sz,				\
1112 	.p_timer    =  timer,						\
1113 	.p_statidx  =  NFSPROC_##proc,					\
1114 	.p_name     =  #proc,						\
1115 	}
1116 struct rpc_procinfo	nfs_procedures[] = {
1117 	PROC(GETATTR,	fhandle,	attrstat,	1),
1118 	PROC(SETATTR,	sattrargs,	attrstat,	0),
1119 	PROC(LOOKUP,	diropargs,	diropres,	2),
1120 	PROC(READLINK,	readlinkargs,	readlinkres,	3),
1121 	PROC(READ,	readargs,	readres,	3),
1122 	PROC(WRITE,	writeargs,	writeres,	4),
1123 	PROC(CREATE,	createargs,	diropres,	0),
1124 	PROC(REMOVE,	removeargs,	stat,		0),
1125 	PROC(RENAME,	renameargs,	stat,		0),
1126 	PROC(LINK,	linkargs,	stat,		0),
1127 	PROC(SYMLINK,	symlinkargs,	stat,		0),
1128 	PROC(MKDIR,	createargs,	diropres,	0),
1129 	PROC(RMDIR,	diropargs,	stat,		0),
1130 	PROC(READDIR,	readdirargs,	readdirres,	3),
1131 	PROC(STATFS,	fhandle,	statfsres,	0),
1132 };
1133 
1134 const struct rpc_version nfs_version2 = {
1135 	.number			= 2,
1136 	.nrprocs		= ARRAY_SIZE(nfs_procedures),
1137 	.procs			= nfs_procedures
1138 };
1139