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)  * XDR support for nfsd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include "vfs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include "xdr.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include "auth.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #define NFSDDBG_FACILITY		NFSDDBG_XDR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15)  * Mapping of S_IF* types to NFS file types
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) static u32	nfs_ftypes[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 	NFNON,  NFCHR,  NFCHR, NFBAD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) 	NFDIR,  NFBAD,  NFBLK, NFBAD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) 	NFREG,  NFBAD,  NFLNK, NFBAD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 	NFSOCK, NFBAD,  NFLNK, NFBAD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26)  * XDR functions for basic NFS types
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) static __be32 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) decode_fh(__be32 *p, struct svc_fh *fhp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 	fh_init(fhp, NFS_FHSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 	memcpy(&fhp->fh_handle.fh_base, p, NFS_FHSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 	fhp->fh_handle.fh_size = NFS_FHSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	/* FIXME: Look up export pointer here and verify
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 	 * Sun Secure RPC if requested */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	return p + (NFS_FHSIZE >> 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) /* Helper function for NFSv2 ACL code */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) __be32 *nfs2svc_decode_fh(__be32 *p, struct svc_fh *fhp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	return decode_fh(p, fhp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) static __be32 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) encode_fh(__be32 *p, struct svc_fh *fhp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	memcpy(p, &fhp->fh_handle.fh_base, NFS_FHSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	return p + (NFS_FHSIZE>> 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54)  * Decode a file name and make sure that the path contains
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55)  * no slashes or null bytes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) static __be32 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) decode_filename(__be32 *p, char **namp, unsigned int *lenp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	char		*name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	unsigned int	i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	if ((p = xdr_decode_string_inplace(p, namp, lenp, NFS_MAXNAMLEN)) != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 		for (i = 0, name = *namp; i < *lenp; i++, name++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 			if (*name == '\0' || *name == '/')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 				return NULL;
^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) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	return p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) static __be32 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) decode_sattr(__be32 *p, struct iattr *iap, struct user_namespace *userns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	u32	tmp, tmp1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	iap->ia_valid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	/* Sun client bug compatibility check: some sun clients seem to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	 * put 0xffff in the mode field when they mean 0xffffffff.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	 * Quoting the 4.4BSD nfs server code: Nah nah nah nah na nah.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	if ((tmp = ntohl(*p++)) != (u32)-1 && tmp != 0xffff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 		iap->ia_valid |= ATTR_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 		iap->ia_mode = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	if ((tmp = ntohl(*p++)) != (u32)-1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 		iap->ia_uid = make_kuid(userns, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 		if (uid_valid(iap->ia_uid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 			iap->ia_valid |= ATTR_UID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	if ((tmp = ntohl(*p++)) != (u32)-1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 		iap->ia_gid = make_kgid(userns, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 		if (gid_valid(iap->ia_gid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 			iap->ia_valid |= ATTR_GID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	if ((tmp = ntohl(*p++)) != (u32)-1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 		iap->ia_valid |= ATTR_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 		iap->ia_size = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	tmp  = ntohl(*p++); tmp1 = ntohl(*p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	if (tmp != (u32)-1 && tmp1 != (u32)-1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 		iap->ia_valid |= ATTR_ATIME | ATTR_ATIME_SET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 		iap->ia_atime.tv_sec = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 		iap->ia_atime.tv_nsec = tmp1 * 1000; 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	tmp  = ntohl(*p++); tmp1 = ntohl(*p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	if (tmp != (u32)-1 && tmp1 != (u32)-1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 		iap->ia_valid |= ATTR_MTIME | ATTR_MTIME_SET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 		iap->ia_mtime.tv_sec = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 		iap->ia_mtime.tv_nsec = tmp1 * 1000; 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 		 * Passing the invalid value useconds=1000000 for mtime
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 		 * is a Sun convention for "set both mtime and atime to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 		 * current server time".  It's needed to make permissions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 		 * checks for the "touch" program across v2 mounts to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 		 * Solaris and Irix boxes work correctly. See description of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 		 * sattr in section 6.1 of "NFS Illustrated" by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 		 * Brent Callaghan, Addison-Wesley, ISBN 0-201-32750-5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 		if (tmp1 == 1000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 			iap->ia_valid &= ~(ATTR_ATIME_SET|ATTR_MTIME_SET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	return p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) static __be32 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) encode_fattr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	     struct kstat *stat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	struct user_namespace *userns = nfsd_user_namespace(rqstp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	struct dentry	*dentry = fhp->fh_dentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	int type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	struct timespec64 time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	u32 f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	type = (stat->mode & S_IFMT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	*p++ = htonl(nfs_ftypes[type >> 12]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	*p++ = htonl((u32) stat->mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	*p++ = htonl((u32) stat->nlink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	*p++ = htonl((u32) from_kuid_munged(userns, stat->uid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	*p++ = htonl((u32) from_kgid_munged(userns, stat->gid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	if (S_ISLNK(type) && stat->size > NFS_MAXPATHLEN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 		*p++ = htonl(NFS_MAXPATHLEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 		*p++ = htonl((u32) stat->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	*p++ = htonl((u32) stat->blksize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	if (S_ISCHR(type) || S_ISBLK(type))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 		*p++ = htonl(new_encode_dev(stat->rdev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 		*p++ = htonl(0xffffffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	*p++ = htonl((u32) stat->blocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	switch (fsid_source(fhp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	case FSIDSOURCE_DEV:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 		*p++ = htonl(new_encode_dev(stat->dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	case FSIDSOURCE_FSID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 		*p++ = htonl((u32) fhp->fh_export->ex_fsid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	case FSIDSOURCE_UUID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 		f = ((u32*)fhp->fh_export->ex_uuid)[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 		f ^= ((u32*)fhp->fh_export->ex_uuid)[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 		f ^= ((u32*)fhp->fh_export->ex_uuid)[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 		f ^= ((u32*)fhp->fh_export->ex_uuid)[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 		*p++ = htonl(f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	*p++ = htonl((u32) stat->ino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	*p++ = htonl((u32) stat->atime.tv_sec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	*p++ = htonl(stat->atime.tv_nsec ? stat->atime.tv_nsec / 1000 : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	time = stat->mtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	lease_get_mtime(d_inode(dentry), &time); 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	*p++ = htonl((u32) time.tv_sec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	*p++ = htonl(time.tv_nsec ? time.tv_nsec / 1000 : 0); 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	*p++ = htonl((u32) stat->ctime.tv_sec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	*p++ = htonl(stat->ctime.tv_nsec ? stat->ctime.tv_nsec / 1000 : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	return p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) /* Helper function for NFSv2 ACL code */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) __be32 *nfs2svc_encode_fattr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp, struct kstat *stat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	return encode_fattr(rqstp, p, fhp, stat);
^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) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)  * XDR decode functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) nfssvc_decode_void(struct svc_rqst *rqstp, __be32 *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	return xdr_argsize_check(rqstp, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) nfssvc_decode_fhandle(struct svc_rqst *rqstp, __be32 *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	struct nfsd_fhandle *args = rqstp->rq_argp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	p = decode_fh(p, &args->fh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 	return xdr_argsize_check(rqstp, p);
^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) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) nfssvc_decode_sattrargs(struct svc_rqst *rqstp, __be32 *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	struct nfsd_sattrargs *args = rqstp->rq_argp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	p = decode_fh(p, &args->fh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 	if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	p = decode_sattr(p, &args->attrs, nfsd_user_namespace(rqstp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	return xdr_argsize_check(rqstp, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) nfssvc_decode_diropargs(struct svc_rqst *rqstp, __be32 *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	struct nfsd_diropargs *args = rqstp->rq_argp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 	if (!(p = decode_fh(p, &args->fh))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	 || !(p = decode_filename(p, &args->name, &args->len)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	return xdr_argsize_check(rqstp, 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) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) nfssvc_decode_readargs(struct svc_rqst *rqstp, __be32 *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	struct nfsd_readargs *args = rqstp->rq_argp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 	unsigned int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 	int v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	p = decode_fh(p, &args->fh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 	args->offset    = ntohl(*p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	len = args->count     = ntohl(*p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	p++; /* totalcount - unused */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	len = min_t(unsigned int, len, NFSSVC_MAXBLKSIZE_V2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 	/* set up somewhere to store response.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	 * We take pages, put them on reslist and include in iovec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	v=0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 	while (len > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 		struct page *p = *(rqstp->rq_next_page++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 		rqstp->rq_vec[v].iov_base = page_address(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 		rqstp->rq_vec[v].iov_len = min_t(unsigned int, len, PAGE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 		len -= rqstp->rq_vec[v].iov_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 		v++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 	args->vlen = v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	return xdr_argsize_check(rqstp, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) nfssvc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	struct nfsd_writeargs *args = rqstp->rq_argp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 	unsigned int len, hdr, dlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 	struct kvec *head = rqstp->rq_arg.head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 	p = decode_fh(p, &args->fh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 	if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	p++;				/* beginoffset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 	args->offset = ntohl(*p++);	/* offset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 	p++;				/* totalcount */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	len = args->len = ntohl(*p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	 * The protocol specifies a maximum of 8192 bytes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 	if (len > NFSSVC_MAXBLKSIZE_V2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	 * Check to make sure that we got the right number of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 	 * bytes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	hdr = (void*)p - head->iov_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 	if (hdr > head->iov_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	dlen = head->iov_len + rqstp->rq_arg.page_len - hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 	 * Round the length of the data which was specified up to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 	 * the next multiple of XDR units and then compare that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 	 * against the length which was actually received.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 	 * Note that when RPCSEC/GSS (for example) is used, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	 * data buffer can be padded so dlen might be larger
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	 * than required.  It must never be smaller.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 	if (dlen < XDR_QUADLEN(len)*4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 	args->first.iov_base = (void *)p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 	args->first.iov_len = head->iov_len - hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) nfssvc_decode_createargs(struct svc_rqst *rqstp, __be32 *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	struct nfsd_createargs *args = rqstp->rq_argp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 	if (   !(p = decode_fh(p, &args->fh))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 	    || !(p = decode_filename(p, &args->name, &args->len)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 	p = decode_sattr(p, &args->attrs, nfsd_user_namespace(rqstp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	return xdr_argsize_check(rqstp, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) nfssvc_decode_renameargs(struct svc_rqst *rqstp, __be32 *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 	struct nfsd_renameargs *args = rqstp->rq_argp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 	if (!(p = decode_fh(p, &args->ffh))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 	 || !(p = decode_filename(p, &args->fname, &args->flen))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 	 || !(p = decode_fh(p, &args->tfh))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 	 || !(p = decode_filename(p, &args->tname, &args->tlen)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 	return xdr_argsize_check(rqstp, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) nfssvc_decode_readlinkargs(struct svc_rqst *rqstp, __be32 *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 	struct nfsd_readlinkargs *args = rqstp->rq_argp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 	p = decode_fh(p, &args->fh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 	if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 	args->buffer = page_address(*(rqstp->rq_next_page++));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 	return xdr_argsize_check(rqstp, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) nfssvc_decode_linkargs(struct svc_rqst *rqstp, __be32 *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 	struct nfsd_linkargs *args = rqstp->rq_argp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 	if (!(p = decode_fh(p, &args->ffh))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 	 || !(p = decode_fh(p, &args->tfh))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 	 || !(p = decode_filename(p, &args->tname, &args->tlen)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 	return xdr_argsize_check(rqstp, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) nfssvc_decode_symlinkargs(struct svc_rqst *rqstp, __be32 *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 	struct nfsd_symlinkargs *args = rqstp->rq_argp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 	char *base = (char *)p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 	size_t xdrlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 	if (   !(p = decode_fh(p, &args->ffh))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 	    || !(p = decode_filename(p, &args->fname, &args->flen)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 	args->tlen = ntohl(*p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 	if (args->tlen == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 	args->first.iov_base = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 	args->first.iov_len = rqstp->rq_arg.head[0].iov_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 	args->first.iov_len -= (char *)p - base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 	/* This request is never larger than a page. Therefore,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 	 * transport will deliver either:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 	 * 1. pathname in the pagelist -> sattr is in the tail.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 	 * 2. everything in the head buffer -> sattr is in the head.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 	if (rqstp->rq_arg.page_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 		if (args->tlen != rqstp->rq_arg.page_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 		p = rqstp->rq_arg.tail[0].iov_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 		xdrlen = XDR_QUADLEN(args->tlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 		if (xdrlen > args->first.iov_len - (8 * sizeof(__be32)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 		p += xdrlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 	decode_sattr(p, &args->attrs, nfsd_user_namespace(rqstp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) nfssvc_decode_readdirargs(struct svc_rqst *rqstp, __be32 *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 	struct nfsd_readdirargs *args = rqstp->rq_argp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 	p = decode_fh(p, &args->fh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 	if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 	args->cookie = ntohl(*p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 	args->count  = ntohl(*p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 	args->count  = min_t(u32, args->count, PAGE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 	args->buffer = page_address(*(rqstp->rq_next_page++));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 	return xdr_argsize_check(rqstp, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)  * XDR encode functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) nfssvc_encode_void(struct svc_rqst *rqstp, __be32 *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 	return xdr_ressize_check(rqstp, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) nfssvc_encode_stat(struct svc_rqst *rqstp, __be32 *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 	struct nfsd_stat *resp = rqstp->rq_resp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 	*p++ = resp->status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 	return xdr_ressize_check(rqstp, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) nfssvc_encode_attrstat(struct svc_rqst *rqstp, __be32 *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 	struct nfsd_attrstat *resp = rqstp->rq_resp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 	*p++ = resp->status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 	if (resp->status != nfs_ok)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 	p = encode_fattr(rqstp, p, &resp->fh, &resp->stat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 	return xdr_ressize_check(rqstp, p);
^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) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) nfssvc_encode_diropres(struct svc_rqst *rqstp, __be32 *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 	struct nfsd_diropres *resp = rqstp->rq_resp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 	*p++ = resp->status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 	if (resp->status != nfs_ok)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 	p = encode_fh(p, &resp->fh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 	p = encode_fattr(rqstp, p, &resp->fh, &resp->stat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 	return xdr_ressize_check(rqstp, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) nfssvc_encode_readlinkres(struct svc_rqst *rqstp, __be32 *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 	struct nfsd_readlinkres *resp = rqstp->rq_resp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 	*p++ = resp->status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 	if (resp->status != nfs_ok)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 		return xdr_ressize_check(rqstp, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 	*p++ = htonl(resp->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 	xdr_ressize_check(rqstp, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 	rqstp->rq_res.page_len = resp->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 	if (resp->len & 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 		/* need to pad the tail */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 		rqstp->rq_res.tail[0].iov_base = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 		*p = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 		rqstp->rq_res.tail[0].iov_len = 4 - (resp->len&3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) nfssvc_encode_readres(struct svc_rqst *rqstp, __be32 *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 	struct nfsd_readres *resp = rqstp->rq_resp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 	*p++ = resp->status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 	if (resp->status != nfs_ok)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 		return xdr_ressize_check(rqstp, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 	p = encode_fattr(rqstp, p, &resp->fh, &resp->stat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 	*p++ = htonl(resp->count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 	xdr_ressize_check(rqstp, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 	/* now update rqstp->rq_res to reflect data as well */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 	rqstp->rq_res.page_len = resp->count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 	if (resp->count & 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 		/* need to pad the tail */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 		rqstp->rq_res.tail[0].iov_base = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 		*p = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 		rqstp->rq_res.tail[0].iov_len = 4 - (resp->count&3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 	return 1;
^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) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) nfssvc_encode_readdirres(struct svc_rqst *rqstp, __be32 *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 	struct nfsd_readdirres *resp = rqstp->rq_resp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 	*p++ = resp->status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 	if (resp->status != nfs_ok)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 		return xdr_ressize_check(rqstp, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 	xdr_ressize_check(rqstp, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 	p = resp->buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 	*p++ = 0;			/* no more entries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 	*p++ = htonl((resp->common.err == nfserr_eof));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 	rqstp->rq_res.page_len = (((unsigned long)p-1) & ~PAGE_MASK)+1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) nfssvc_encode_statfsres(struct svc_rqst *rqstp, __be32 *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 	struct nfsd_statfsres *resp = rqstp->rq_resp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 	struct kstatfs	*stat = &resp->stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 	*p++ = resp->status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 	if (resp->status != nfs_ok)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 		return xdr_ressize_check(rqstp, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 	*p++ = htonl(NFSSVC_MAXBLKSIZE_V2);	/* max transfer size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 	*p++ = htonl(stat->f_bsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 	*p++ = htonl(stat->f_blocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 	*p++ = htonl(stat->f_bfree);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 	*p++ = htonl(stat->f_bavail);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 	return xdr_ressize_check(rqstp, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) nfssvc_encode_entry(void *ccdv, const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 		    int namlen, loff_t offset, u64 ino, unsigned int d_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 	struct readdir_cd *ccd = ccdv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 	struct nfsd_readdirres *cd = container_of(ccd, struct nfsd_readdirres, common);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 	__be32	*p = cd->buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 	int	buflen, slen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 	dprintk("nfsd: entry(%.*s off %ld ino %ld)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 			namlen, name, offset, ino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 	if (offset > ~((u32) 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 		cd->common.err = nfserr_fbig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 	if (cd->offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 		*cd->offset = htonl(offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 	/* truncate filename */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 	namlen = min(namlen, NFS2_MAXNAMLEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 	slen = XDR_QUADLEN(namlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 	if ((buflen = cd->buflen - slen - 4) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 		cd->common.err = nfserr_toosmall;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 	if (ino > ~((u32) 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 		cd->common.err = nfserr_fbig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 	*p++ = xdr_one;				/* mark entry present */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 	*p++ = htonl((u32) ino);		/* file id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 	p    = xdr_encode_array(p, name, namlen);/* name length & name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 	cd->offset = p;			/* remember pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 	*p++ = htonl(~0U);		/* offset of next entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 	cd->buflen = buflen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 	cd->buffer = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 	cd->common.err = nfs_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595)  * XDR release functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) void nfssvc_release_attrstat(struct svc_rqst *rqstp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 	struct nfsd_attrstat *resp = rqstp->rq_resp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 	fh_put(&resp->fh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) void nfssvc_release_diropres(struct svc_rqst *rqstp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 	struct nfsd_diropres *resp = rqstp->rq_resp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 	fh_put(&resp->fh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) void nfssvc_release_readres(struct svc_rqst *rqstp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 	struct nfsd_readres *resp = rqstp->rq_resp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) 	fh_put(&resp->fh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) }