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