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