Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

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