^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) };