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