linux/fs/nfs/nfs2xdr.c

// SPDX-License-Identifier: GPL-2.0
/*
 * linux/fs/nfs/nfs2xdr.c
 *
 * XDR functions to encode/decode NFS RPC arguments and results.
 *
 * Copyright (C) 1992, 1993, 1994  Rick Sladkey
 * Copyright (C) 1996 Olaf Kirch
 * 04 Aug 1998  Ion Badulescu <[email protected]>
 * 		FIFO's need special handling in NFSv2
 */

#include <linux/param.h>
#include <linux/time.h>
#include <linux/mm.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/in.h>
#include <linux/pagemap.h>
#include <linux/proc_fs.h>
#include <linux/sunrpc/clnt.h>
#include <linux/nfs.h>
#include <linux/nfs2.h>
#include <linux/nfs_fs.h>
#include "nfstrace.h"
#include "internal.h"

#define NFSDBG_FACILITY

/* Mapping from NFS error code to "errno" error code. */
#define errno_NFSERR_IO

/*
 * Declare the space requirements for NFS arguments and replies as
 * number of 32bit-words
 */
#define NFS_pagepad_sz
#define NFS_fhandle_sz
#define NFS_sattr_sz
#define NFS_filename_sz
#define NFS_path_sz
#define NFS_fattr_sz
#define NFS_info_sz
#define NFS_entry_sz

#define NFS_diropargs_sz
#define NFS_removeargs_sz
#define NFS_sattrargs_sz
#define NFS_readlinkargs_sz
#define NFS_readargs_sz
#define NFS_writeargs_sz
#define NFS_createargs_sz
#define NFS_renameargs_sz
#define NFS_linkargs_sz
#define NFS_symlinkargs_sz
#define NFS_readdirargs_sz

#define NFS_attrstat_sz
#define NFS_diropres_sz
#define NFS_readlinkres_sz
#define NFS_readres_sz
#define NFS_writeres_sz
#define NFS_stat_sz
#define NFS_readdirres_sz
#define NFS_statfsres_sz

static int nfs_stat_to_errno(enum nfs_stat);

/*
 * Encode/decode NFSv2 basic data types
 *
 * Basic NFSv2 data types are defined in section 2.3 of RFC 1094:
 * "NFS: Network File System Protocol Specification".
 *
 * Not all basic data types have their own encoding and decoding
 * functions.  For run-time efficiency, some data types are encoded
 * or decoded inline.
 */

static struct user_namespace *rpc_userns(const struct rpc_clnt *clnt)
{}

static struct user_namespace *rpc_rqst_userns(const struct rpc_rqst *rqstp)
{}

/*
 *	typedef opaque	nfsdata<>;
 */
static int decode_nfsdata(struct xdr_stream *xdr, struct nfs_pgio_res *result)
{}

/*
 *	enum stat {
 *		NFS_OK = 0,
 *		NFSERR_PERM = 1,
 *		NFSERR_NOENT = 2,
 *		NFSERR_IO = 5,
 *		NFSERR_NXIO = 6,
 *		NFSERR_ACCES = 13,
 *		NFSERR_EXIST = 17,
 *		NFSERR_NODEV = 19,
 *		NFSERR_NOTDIR = 20,
 *		NFSERR_ISDIR = 21,
 *		NFSERR_FBIG = 27,
 *		NFSERR_NOSPC = 28,
 *		NFSERR_ROFS = 30,
 *		NFSERR_NAMETOOLONG = 63,
 *		NFSERR_NOTEMPTY = 66,
 *		NFSERR_DQUOT = 69,
 *		NFSERR_STALE = 70,
 *		NFSERR_WFLUSH = 99
 *	};
 */
static int decode_stat(struct xdr_stream *xdr, enum nfs_stat *status)
{}

/*
 * 2.3.2.  ftype
 *
 *	enum ftype {
 *		NFNON = 0,
 *		NFREG = 1,
 *		NFDIR = 2,
 *		NFBLK = 3,
 *		NFCHR = 4,
 *		NFLNK = 5
 *	};
 *
 */
static __be32 *xdr_decode_ftype(__be32 *p, u32 *type)
{}

/*
 * 2.3.3.  fhandle
 *
 *	typedef opaque fhandle[FHSIZE];
 */
static void encode_fhandle(struct xdr_stream *xdr, const struct nfs_fh *fh)
{}

static int decode_fhandle(struct xdr_stream *xdr, struct nfs_fh *fh)
{}

/*
 * 2.3.4.  timeval
 *
 *	struct timeval {
 *		unsigned int seconds;
 *		unsigned int useconds;
 *	};
 */
static __be32 *xdr_encode_time(__be32 *p, const struct timespec64 *timep)
{}

/*
 * Passing the invalid value useconds=1000000 is a Sun convention for
 * "set to current server time".  It's needed to make permissions checks
 * for the "touch" program across v2 mounts to Solaris and Irix servers
 * work correctly.  See description of sattr in section 6.1 of "NFS
 * Illustrated" by Brent Callaghan, Addison-Wesley, ISBN 0-201-32750-5.
 */
static __be32 *xdr_encode_current_server_time(__be32 *p,
					      const struct timespec64 *timep)
{}

static __be32 *xdr_decode_time(__be32 *p, struct timespec64 *timep)
{}

/*
 * 2.3.5.  fattr
 *
 *	struct fattr {
 *		ftype		type;
 *		unsigned int	mode;
 *		unsigned int	nlink;
 *		unsigned int	uid;
 *		unsigned int	gid;
 *		unsigned int	size;
 *		unsigned int	blocksize;
 *		unsigned int	rdev;
 *		unsigned int	blocks;
 *		unsigned int	fsid;
 *		unsigned int	fileid;
 *		timeval		atime;
 *		timeval		mtime;
 *		timeval		ctime;
 *	};
 *
 */
static int decode_fattr(struct xdr_stream *xdr, struct nfs_fattr *fattr,
		struct user_namespace *userns)
{}

/*
 * 2.3.6.  sattr
 *
 *	struct sattr {
 *		unsigned int	mode;
 *		unsigned int	uid;
 *		unsigned int	gid;
 *		unsigned int	size;
 *		timeval		atime;
 *		timeval		mtime;
 *	};
 */

#define NFS2_SATTR_NOT_SET

static __be32 *xdr_time_not_set(__be32 *p)
{}

static void encode_sattr(struct xdr_stream *xdr, const struct iattr *attr,
		struct user_namespace *userns)
{}

/*
 * 2.3.7.  filename
 *
 *	typedef string filename<MAXNAMLEN>;
 */
static void encode_filename(struct xdr_stream *xdr,
			    const char *name, u32 length)
{}

static int decode_filename_inline(struct xdr_stream *xdr,
				  const char **name, u32 *length)
{}

/*
 * 2.3.8.  path
 *
 *	typedef string path<MAXPATHLEN>;
 */
static void encode_path(struct xdr_stream *xdr, struct page **pages, u32 length)
{}

static int decode_path(struct xdr_stream *xdr)
{}

/*
 * 2.3.9.  attrstat
 *
 *	union attrstat switch (stat status) {
 *	case NFS_OK:
 *		fattr attributes;
 *	default:
 *		void;
 *	};
 */
static int decode_attrstat(struct xdr_stream *xdr, struct nfs_fattr *result,
			   __u32 *op_status,
			   struct user_namespace *userns)
{}

/*
 * 2.3.10.  diropargs
 *
 *	struct diropargs {
 *		fhandle  dir;
 *		filename name;
 *	};
 */
static void encode_diropargs(struct xdr_stream *xdr, const struct nfs_fh *fh,
			     const char *name, u32 length)
{}

/*
 * 2.3.11.  diropres
 *
 *	union diropres switch (stat status) {
 *	case NFS_OK:
 *		struct {
 *			fhandle file;
 *			fattr   attributes;
 *		} diropok;
 *	default:
 *		void;
 *	};
 */
static int decode_diropok(struct xdr_stream *xdr, struct nfs_diropok *result,
		struct user_namespace *userns)
{}

static int decode_diropres(struct xdr_stream *xdr, struct nfs_diropok *result,
		struct user_namespace *userns)
{}


/*
 * NFSv2 XDR encode functions
 *
 * NFSv2 argument types are defined in section 2.2 of RFC 1094:
 * "NFS: Network File System Protocol Specification".
 */

static void nfs2_xdr_enc_fhandle(struct rpc_rqst *req,
				 struct xdr_stream *xdr,
				 const void *data)
{}

/*
 * 2.2.3.  sattrargs
 *
 *	struct sattrargs {
 *		fhandle file;
 *		sattr attributes;
 *	};
 */
static void nfs2_xdr_enc_sattrargs(struct rpc_rqst *req,
				   struct xdr_stream *xdr,
				   const void *data)
{}

static void nfs2_xdr_enc_diropargs(struct rpc_rqst *req,
				   struct xdr_stream *xdr,
				   const void *data)
{}

static void nfs2_xdr_enc_readlinkargs(struct rpc_rqst *req,
				      struct xdr_stream *xdr,
				      const void *data)
{}

/*
 * 2.2.7.  readargs
 *
 *	struct readargs {
 *		fhandle file;
 *		unsigned offset;
 *		unsigned count;
 *		unsigned totalcount;
 *	};
 */
static void encode_readargs(struct xdr_stream *xdr,
			    const struct nfs_pgio_args *args)
{}

static void nfs2_xdr_enc_readargs(struct rpc_rqst *req,
				  struct xdr_stream *xdr,
				  const void *data)
{}

/*
 * 2.2.9.  writeargs
 *
 *	struct writeargs {
 *		fhandle file;
 *		unsigned beginoffset;
 *		unsigned offset;
 *		unsigned totalcount;
 *		nfsdata data;
 *	};
 */
static void encode_writeargs(struct xdr_stream *xdr,
			     const struct nfs_pgio_args *args)
{}

static void nfs2_xdr_enc_writeargs(struct rpc_rqst *req,
				   struct xdr_stream *xdr,
				   const void *data)
{}

/*
 * 2.2.10.  createargs
 *
 *	struct createargs {
 *		diropargs where;
 *		sattr attributes;
 *	};
 */
static void nfs2_xdr_enc_createargs(struct rpc_rqst *req,
				    struct xdr_stream *xdr,
				    const void *data)
{}

static void nfs2_xdr_enc_removeargs(struct rpc_rqst *req,
				    struct xdr_stream *xdr,
				    const void *data)
{}

/*
 * 2.2.12.  renameargs
 *
 *	struct renameargs {
 *		diropargs from;
 *		diropargs to;
 *	};
 */
static void nfs2_xdr_enc_renameargs(struct rpc_rqst *req,
				    struct xdr_stream *xdr,
				    const void *data)
{}

/*
 * 2.2.13.  linkargs
 *
 *	struct linkargs {
 *		fhandle from;
 *		diropargs to;
 *	};
 */
static void nfs2_xdr_enc_linkargs(struct rpc_rqst *req,
				  struct xdr_stream *xdr,
				  const void *data)
{}

/*
 * 2.2.14.  symlinkargs
 *
 *	struct symlinkargs {
 *		diropargs from;
 *		path to;
 *		sattr attributes;
 *	};
 */
static void nfs2_xdr_enc_symlinkargs(struct rpc_rqst *req,
				     struct xdr_stream *xdr,
				     const void *data)
{}

/*
 * 2.2.17.  readdirargs
 *
 *	struct readdirargs {
 *		fhandle dir;
 *		nfscookie cookie;
 *		unsigned count;
 *	};
 */
static void encode_readdirargs(struct xdr_stream *xdr,
			       const struct nfs_readdirargs *args)
{}

static void nfs2_xdr_enc_readdirargs(struct rpc_rqst *req,
				     struct xdr_stream *xdr,
				     const void *data)
{}

/*
 * NFSv2 XDR decode functions
 *
 * NFSv2 result types are defined in section 2.2 of RFC 1094:
 * "NFS: Network File System Protocol Specification".
 */

static int nfs2_xdr_dec_stat(struct rpc_rqst *req, struct xdr_stream *xdr,
			     void *__unused)
{}

static int nfs2_xdr_dec_attrstat(struct rpc_rqst *req, struct xdr_stream *xdr,
				 void *result)
{}

static int nfs2_xdr_dec_diropres(struct rpc_rqst *req, struct xdr_stream *xdr,
				 void *result)
{}

/*
 * 2.2.6.  readlinkres
 *
 *	union readlinkres switch (stat status) {
 *	case NFS_OK:
 *		path data;
 *	default:
 *		void;
 *	};
 */
static int nfs2_xdr_dec_readlinkres(struct rpc_rqst *req,
				    struct xdr_stream *xdr, void *__unused)
{}

/*
 * 2.2.7.  readres
 *
 *	union readres switch (stat status) {
 *	case NFS_OK:
 *		fattr attributes;
 *		nfsdata data;
 *	default:
 *		void;
 *	};
 */
static int nfs2_xdr_dec_readres(struct rpc_rqst *req, struct xdr_stream *xdr,
				void *data)
{}

static int nfs2_xdr_dec_writeres(struct rpc_rqst *req, struct xdr_stream *xdr,
				 void *data)
{}

/**
 * nfs2_decode_dirent - Decode a single NFSv2 directory entry stored in
 *                      the local page cache.
 * @xdr: XDR stream where entry resides
 * @entry: buffer to fill in with entry data
 * @plus: boolean indicating whether this should be a readdirplus entry
 *
 * Returns zero if successful, otherwise a negative errno value is
 * returned.
 *
 * This function is not invoked during READDIR reply decoding, but
 * rather whenever an application invokes the getdents(2) system call
 * on a directory already in our cache.
 *
 * 2.2.17.  entry
 *
 *	struct entry {
 *		unsigned	fileid;
 *		filename	name;
 *		nfscookie	cookie;
 *		entry		*nextentry;
 *	};
 */
int nfs2_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry,
		       bool plus)
{}

/*
 * 2.2.17.  readdirres
 *
 *	union readdirres switch (stat status) {
 *	case NFS_OK:
 *		struct {
 *			entry *entries;
 *			bool eof;
 *		} readdirok;
 *	default:
 *		void;
 *	};
 *
 * Read the directory contents into the page cache, but don't
 * touch them.  The actual decoding is done by nfs2_decode_dirent()
 * during subsequent nfs_readdir() calls.
 */
static int decode_readdirok(struct xdr_stream *xdr)
{}

static int nfs2_xdr_dec_readdirres(struct rpc_rqst *req,
				   struct xdr_stream *xdr, void *__unused)
{}

/*
 * 2.2.18.  statfsres
 *
 *	union statfsres (stat status) {
 *	case NFS_OK:
 *		struct {
 *			unsigned tsize;
 *			unsigned bsize;
 *			unsigned blocks;
 *			unsigned bfree;
 *			unsigned bavail;
 *		} info;
 *	default:
 *		void;
 *	};
 */
static int decode_info(struct xdr_stream *xdr, struct nfs2_fsstat *result)
{}

static int nfs2_xdr_dec_statfsres(struct rpc_rqst *req, struct xdr_stream *xdr,
				  void *result)
{}


/*
 * We need to translate between nfs status return values and
 * the local errno values which may not be the same.
 */
static const struct {} nfs_errtbl[] =;

/**
 * nfs_stat_to_errno - convert an NFS status code to a local errno
 * @status: NFS status code to convert
 *
 * Returns a local errno value, or -EIO if the NFS status code is
 * not recognized.  This function is used jointly by NFSv2 and NFSv3.
 */
static int nfs_stat_to_errno(enum nfs_stat status)
{}

#define PROC(proc, argtype, restype, timer)
const struct rpc_procinfo nfs_procedures[] =;

static unsigned int nfs_version2_counts[ARRAY_SIZE(nfs_procedures)];
const struct rpc_version nfs_version2 =;