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) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    2)  *  Server-side procedures for NFSv4.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  *  Copyright (c) 2002 The Regents of the University of Michigan.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  *  All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7)  *  Kendrick Smith <kmsmith@umich.edu>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8)  *  Andy Adamson   <andros@umich.edu>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10)  *  Redistribution and use in source and binary forms, with or without
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11)  *  modification, are permitted provided that the following conditions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12)  *  are met:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14)  *  1. Redistributions of source code must retain the above copyright
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15)  *     notice, this list of conditions and the following disclaimer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16)  *  2. Redistributions in binary form must reproduce the above copyright
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17)  *     notice, this list of conditions and the following disclaimer in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18)  *     documentation and/or other materials provided with the distribution.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19)  *  3. Neither the name of the University nor the names of its
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20)  *     contributors may be used to endorse or promote products derived
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21)  *     from this software without specific prior written permission.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23)  *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24)  *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25)  *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26)  *  DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27)  *  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28)  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29)  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30)  *  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31)  *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32)  *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33)  *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) #include <linux/fs_struct.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) #include <linux/file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) #include <linux/falloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) #include <linux/kthread.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) #include <linux/sunrpc/addr.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) #include <linux/nfs_ssc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) #include "idmap.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) #include "cache.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) #include "xdr4.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) #include "vfs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) #include "current_stateid.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) #include "netns.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) #include "acl.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) #include "pnfs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) #include "trace.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) #ifdef CONFIG_NFSD_V4_SECURITY_LABEL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) #include <linux/security.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) nfsd4_security_inode_setsecctx(struct svc_fh *resfh, struct xdr_netobj *label, u32 *bmval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) 	struct inode *inode = d_inode(resfh->fh_dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) 	int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) 	inode_lock(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) 	status = security_inode_setsecctx(resfh->fh_dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) 		label->data, label->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) 	inode_unlock(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) 	if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) 		 * XXX: We should really fail the whole open, but we may
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) 		 * already have created a new file, so it may be too
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) 		 * late.  For now this seems the least of evils:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) 		bmval[2] &= ~FATTR4_WORD2_SECURITY_LABEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) nfsd4_security_inode_setsecctx(struct svc_fh *resfh, struct xdr_netobj *label, u32 *bmval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) #define NFSDDBG_FACILITY		NFSDDBG_PROC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) static u32 nfsd_attrmask[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) 	NFSD_WRITEABLE_ATTRS_WORD0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) 	NFSD_WRITEABLE_ATTRS_WORD1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) 	NFSD_WRITEABLE_ATTRS_WORD2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) static u32 nfsd41_ex_attrmask[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) 	NFSD_SUPPATTR_EXCLCREAT_WORD0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) 	NFSD_SUPPATTR_EXCLCREAT_WORD1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) 	NFSD_SUPPATTR_EXCLCREAT_WORD2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) check_attr_support(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) 		   u32 *bmval, u32 *writable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) 	struct dentry *dentry = cstate->current_fh.fh_dentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) 	struct svc_export *exp = cstate->current_fh.fh_export;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) 	if (!nfsd_attrs_supported(cstate->minorversion, bmval))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) 		return nfserr_attrnotsupp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) 	if ((bmval[0] & FATTR4_WORD0_ACL) && !IS_POSIXACL(d_inode(dentry)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) 		return nfserr_attrnotsupp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) 	if ((bmval[2] & FATTR4_WORD2_SECURITY_LABEL) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) 			!(exp->ex_flags & NFSEXP_SECURITY_LABEL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) 		return nfserr_attrnotsupp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) 	if (writable && !bmval_is_subset(bmval, writable))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) 		return nfserr_inval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) 	if (writable && (bmval[2] & FATTR4_WORD2_MODE_UMASK) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) 			(bmval[1] & FATTR4_WORD1_MODE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) 		return nfserr_inval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) 	return nfs_ok;
^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) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) nfsd4_check_open_attributes(struct svc_rqst *rqstp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) 	struct nfsd4_compound_state *cstate, struct nfsd4_open *open)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) 	__be32 status = nfs_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) 	if (open->op_create == NFS4_OPEN_CREATE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) 		if (open->op_createmode == NFS4_CREATE_UNCHECKED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) 		    || open->op_createmode == NFS4_CREATE_GUARDED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) 			status = check_attr_support(rqstp, cstate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) 					open->op_bmval, nfsd_attrmask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) 		else if (open->op_createmode == NFS4_CREATE_EXCLUSIVE4_1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) 			status = check_attr_support(rqstp, cstate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) 					open->op_bmval, nfsd41_ex_attrmask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) 	return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) is_create_with_attrs(struct nfsd4_open *open)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) 	return open->op_create == NFS4_OPEN_CREATE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) 		&& (open->op_createmode == NFS4_CREATE_UNCHECKED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) 		    || open->op_createmode == NFS4_CREATE_GUARDED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) 		    || open->op_createmode == NFS4_CREATE_EXCLUSIVE4_1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148)  * if error occurs when setting the acl, just clear the acl bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149)  * in the returned attr bitmap.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) do_set_nfs4_acl(struct svc_rqst *rqstp, struct svc_fh *fhp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) 		struct nfs4_acl *acl, u32 *bmval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) 	__be32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) 	status = nfsd4_set_nfs4_acl(rqstp, fhp, acl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) 	if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) 		 * We should probably fail the whole open at this point,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) 		 * but we've already created the file, so it's too late;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 		 * So this seems the least of evils:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) 		bmval[0] &= ~FATTR4_WORD0_ACL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) fh_dup2(struct svc_fh *dst, struct svc_fh *src)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) 	fh_put(dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) 	dget(src->fh_dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) 	if (src->fh_export)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) 		exp_get(src->fh_export);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 	*dst = *src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) do_open_permission(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open, int accmode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) 	__be32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 	if (open->op_truncate &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 		!(open->op_share_access & NFS4_SHARE_ACCESS_WRITE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 		return nfserr_inval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 	accmode |= NFSD_MAY_READ_IF_EXEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) 	if (open->op_share_access & NFS4_SHARE_ACCESS_READ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) 		accmode |= NFSD_MAY_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) 	if (open->op_share_access & NFS4_SHARE_ACCESS_WRITE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) 		accmode |= (NFSD_MAY_WRITE | NFSD_MAY_TRUNC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) 	if (open->op_share_deny & NFS4_SHARE_DENY_READ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) 		accmode |= NFSD_MAY_WRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 	status = fh_verify(rqstp, current_fh, S_IFREG, accmode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 	return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) static __be32 nfsd_check_obj_isreg(struct svc_fh *fh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) 	umode_t mode = d_inode(fh->fh_dentry)->i_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) 	if (S_ISREG(mode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 		return nfs_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 	if (S_ISDIR(mode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 		return nfserr_isdir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 	 * Using err_symlink as our catch-all case may look odd; but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) 	 * there's no other obvious error for this case in 4.0, and we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 	 * happen to know that it will cause the linux v4 client to do
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 	 * the right thing on attempts to open something other than a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) 	 * regular file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 	return nfserr_symlink;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) static void nfsd4_set_open_owner_reply_cache(struct nfsd4_compound_state *cstate, struct nfsd4_open *open, struct svc_fh *resfh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 	if (nfsd4_has_session(cstate))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 	fh_copy_shallow(&open->op_openowner->oo_owner.so_replay.rp_openfh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 			&resfh->fh_handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) do_open_lookup(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_open *open, struct svc_fh **resfh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) 	struct svc_fh *current_fh = &cstate->current_fh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 	int accmode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) 	__be32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 	*resfh = kmalloc(sizeof(struct svc_fh), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) 	if (!*resfh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 		return nfserr_jukebox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) 	fh_init(*resfh, NFS4_FHSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 	open->op_truncate = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 	if (open->op_create) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 		/* FIXME: check session persistence and pnfs flags.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 		 * The nfsv4.1 spec requires the following semantics:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 		 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 		 * Persistent   | pNFS   | Server REQUIRED | Client Allowed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) 		 * Reply Cache  | server |                 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) 		 * -------------+--------+-----------------+--------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) 		 * no           | no     | EXCLUSIVE4_1    | EXCLUSIVE4_1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 		 *              |        |                 | (SHOULD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) 		 *              |        | and EXCLUSIVE4  | or EXCLUSIVE4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) 		 *              |        |                 | (SHOULD NOT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) 		 * no           | yes    | EXCLUSIVE4_1    | EXCLUSIVE4_1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 		 * yes          | no     | GUARDED4        | GUARDED4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 		 * yes          | yes    | GUARDED4        | GUARDED4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 		 * Note: create modes (UNCHECKED,GUARDED...) are the same
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 		 * in NFSv4 as in v3 except EXCLUSIVE4_1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 		current->fs->umask = open->op_umask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 		status = do_nfsd_create(rqstp, current_fh, open->op_fname.data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) 					open->op_fname.len, &open->op_iattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 					*resfh, open->op_createmode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 					(u32 *)open->op_verf.data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) 					&open->op_truncate, &open->op_created);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) 		current->fs->umask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) 		if (!status && open->op_label.len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) 			nfsd4_security_inode_setsecctx(*resfh, &open->op_label, open->op_bmval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 		 * Following rfc 3530 14.2.16, and rfc 5661 18.16.4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 		 * use the returned bitmask to indicate which attributes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 		 * we used to store the verifier:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 		if (nfsd_create_is_exclusive(open->op_createmode) && status == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 			open->op_bmval[1] |= (FATTR4_WORD1_TIME_ACCESS |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) 						FATTR4_WORD1_TIME_MODIFY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) 		 * Note this may exit with the parent still locked.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) 		 * We will hold the lock until nfsd4_open's final
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) 		 * lookup, to prevent renames or unlinks until we've had
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 		 * a chance to an acquire a delegation if appropriate.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) 		status = nfsd_lookup(rqstp, current_fh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) 				     open->op_fname.data, open->op_fname.len, *resfh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 	if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) 	status = nfsd_check_obj_isreg(*resfh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 	if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) 	if (is_create_with_attrs(open) && open->op_acl != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) 		do_set_nfs4_acl(rqstp, *resfh, open->op_acl, open->op_bmval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 	nfsd4_set_open_owner_reply_cache(cstate, open, *resfh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 	accmode = NFSD_MAY_NOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 	if (open->op_created ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 			open->op_claim_type == NFS4_OPEN_CLAIM_DELEGATE_CUR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 		accmode |= NFSD_MAY_OWNER_OVERRIDE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 	status = do_open_permission(rqstp, *resfh, open, accmode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) 	set_change_info(&open->op_cinfo, current_fh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) 	return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) do_open_fhandle(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_open *open)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 	struct svc_fh *current_fh = &cstate->current_fh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 	__be32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 	int accmode = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) 	/* We don't know the target directory, and therefore can not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) 	* set the change info
^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) 	memset(&open->op_cinfo, 0, sizeof(struct nfsd4_change_info));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 	nfsd4_set_open_owner_reply_cache(cstate, open, current_fh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) 	open->op_truncate = (open->op_iattr.ia_valid & ATTR_SIZE) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 		(open->op_iattr.ia_size == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) 	 * In the delegation case, the client is telling us about an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 	 * open that it *already* performed locally, some time ago.  We
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 	 * should let it succeed now if possible.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 	 * In the case of a CLAIM_FH open, on the other hand, the client
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 	 * may be counting on us to enforce permissions (the Linux 4.1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 	 * client uses this for normal opens, for example).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 	if (open->op_claim_type == NFS4_OPEN_CLAIM_DELEG_CUR_FH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 		accmode = NFSD_MAY_OWNER_OVERRIDE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 	status = do_open_permission(rqstp, current_fh, open, accmode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 	return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) copy_clientid(clientid_t *clid, struct nfsd4_session *session)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 	struct nfsd4_sessionid *sid =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) 			(struct nfsd4_sessionid *)session->se_sessionid.data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) 	clid->cl_boot = sid->clientid.cl_boot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 	clid->cl_id = sid->clientid.cl_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 	   union nfsd4_op_u *u)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) 	struct nfsd4_open *open = &u->open;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 	__be32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) 	struct svc_fh *resfh = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 	struct net *net = SVC_NET(rqstp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 	struct nfsd_net *nn = net_generic(net, nfsd_net_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) 	bool reclaim = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) 	dprintk("NFSD: nfsd4_open filename %.*s op_openowner %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 		(int)open->op_fname.len, open->op_fname.data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) 		open->op_openowner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 	/* This check required by spec. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 	if (open->op_create && open->op_claim_type != NFS4_OPEN_CLAIM_NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) 		return nfserr_inval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 	open->op_created = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 	 * RFC5661 18.51.3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 	 * Before RECLAIM_COMPLETE done, server should deny new lock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) 	if (nfsd4_has_session(cstate) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) 	    !test_bit(NFSD4_CLIENT_RECLAIM_COMPLETE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 		      &cstate->session->se_client->cl_flags) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 	    open->op_claim_type != NFS4_OPEN_CLAIM_PREVIOUS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 		return nfserr_grace;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) 	if (nfsd4_has_session(cstate))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) 		copy_clientid(&open->op_clientid, cstate->session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) 	/* check seqid for replay. set nfs4_owner */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) 	status = nfsd4_process_open1(cstate, open, nn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 	if (status == nfserr_replay_me) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 		struct nfs4_replay *rp = &open->op_openowner->oo_owner.so_replay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) 		fh_put(&cstate->current_fh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 		fh_copy_shallow(&cstate->current_fh.fh_handle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) 				&rp->rp_openfh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 		status = fh_verify(rqstp, &cstate->current_fh, 0, NFSD_MAY_NOP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) 		if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 			dprintk("nfsd4_open: replay failed"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 				" restoring previous filehandle\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 			status = nfserr_replay_me;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 	if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 	if (open->op_xdr_error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 		status = open->op_xdr_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 	status = nfsd4_check_open_attributes(rqstp, cstate, open);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 	if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 	/* Openowner is now set, so sequence id will get bumped.  Now we need
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 	 * these checks before we do any creates: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 	status = nfserr_grace;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 	if (opens_in_grace(net) && open->op_claim_type != NFS4_OPEN_CLAIM_PREVIOUS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 	status = nfserr_no_grace;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 	if (!opens_in_grace(net) && open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 	switch (open->op_claim_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 		case NFS4_OPEN_CLAIM_DELEGATE_CUR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) 		case NFS4_OPEN_CLAIM_NULL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 			status = do_open_lookup(rqstp, cstate, open, &resfh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 			if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 				goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 		case NFS4_OPEN_CLAIM_PREVIOUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) 			status = nfs4_check_open_reclaim(&open->op_clientid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) 							 cstate, nn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) 			if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) 				goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) 			open->op_openowner->oo_flags |= NFS4_OO_CONFIRMED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) 			reclaim = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 			fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 		case NFS4_OPEN_CLAIM_FH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 		case NFS4_OPEN_CLAIM_DELEG_CUR_FH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 			status = do_open_fhandle(rqstp, cstate, open);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 			if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 				goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 			resfh = &cstate->current_fh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 		case NFS4_OPEN_CLAIM_DELEG_PREV_FH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441)              	case NFS4_OPEN_CLAIM_DELEGATE_PREV:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 			dprintk("NFSD: unsupported OPEN claim type %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 				open->op_claim_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 			status = nfserr_notsupp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 			dprintk("NFSD: Invalid OPEN claim type %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 				open->op_claim_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 			status = nfserr_inval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 	 * nfsd4_process_open2() does the actual opening of the file.  If
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 	 * successful, it (1) truncates the file if open->op_truncate was
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 	 * set, (2) sets open->op_stateid, (3) sets open->op_delegation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) 	status = nfsd4_process_open2(rqstp, resfh, open);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 	WARN(status && open->op_created,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) 	     "nfsd4_process_open2 failed to open newly-created file! status=%u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) 	     be32_to_cpu(status));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 	if (reclaim && !status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) 		nn->somebody_reclaimed = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 	if (resfh && resfh != &cstate->current_fh) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 		fh_dup2(&cstate->current_fh, resfh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 		fh_put(resfh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 		kfree(resfh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 	nfsd4_cleanup_open_state(cstate, open);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 	nfsd4_bump_seqid(cstate, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 	return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475)  * OPEN is the only seqid-mutating operation whose decoding can fail
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476)  * with a seqid-mutating error (specifically, decoding of user names in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477)  * the attributes).  Therefore we have to do some processing to look up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478)  * the stateowner so that we can bump the seqid.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) static __be32 nfsd4_open_omfg(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_op *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 	struct nfsd4_open *open = &op->u.open;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 	if (!seqid_mutating_err(ntohl(op->status)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 		return op->status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) 	if (nfsd4_has_session(cstate))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 		return op->status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 	open->op_xdr_error = op->status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 	return nfsd4_open(rqstp, cstate, &op->u);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) }
^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)  * filehandle-manipulating ops.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) nfsd4_getfh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 	    union nfsd4_op_u *u)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 	u->getfh = &cstate->current_fh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 	return nfs_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) nfsd4_putfh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 	    union nfsd4_op_u *u)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) 	struct nfsd4_putfh *putfh = &u->putfh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) 	__be32 ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) 	fh_put(&cstate->current_fh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) 	cstate->current_fh.fh_handle.fh_size = putfh->pf_fhlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 	memcpy(&cstate->current_fh.fh_handle.fh_base, putfh->pf_fhval,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) 	       putfh->pf_fhlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 	ret = fh_verify(rqstp, &cstate->current_fh, 0, NFSD_MAY_BYPASS_GSS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) #ifdef CONFIG_NFSD_V4_2_INTER_SSC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 	if (ret == nfserr_stale && putfh->no_verify) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 		SET_FH_FLAG(&cstate->current_fh, NFSD4_FH_FOREIGN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 		ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) nfsd4_putrootfh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 		union nfsd4_op_u *u)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 	__be32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 	fh_put(&cstate->current_fh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 	status = exp_pseudoroot(rqstp, &cstate->current_fh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) 	return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) nfsd4_restorefh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 		union nfsd4_op_u *u)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 	if (!cstate->save_fh.fh_dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) 		return nfserr_restorefh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 	fh_dup2(&cstate->current_fh, &cstate->save_fh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 	if (HAS_CSTATE_FLAG(cstate, SAVED_STATE_ID_FLAG)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 		memcpy(&cstate->current_stateid, &cstate->save_stateid, sizeof(stateid_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 		SET_CSTATE_FLAG(cstate, CURRENT_STATE_ID_FLAG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 	return nfs_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) nfsd4_savefh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 	     union nfsd4_op_u *u)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 	fh_dup2(&cstate->save_fh, &cstate->current_fh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 	if (HAS_CSTATE_FLAG(cstate, CURRENT_STATE_ID_FLAG)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 		memcpy(&cstate->save_stateid, &cstate->current_stateid, sizeof(stateid_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 		SET_CSTATE_FLAG(cstate, SAVED_STATE_ID_FLAG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) 	return nfs_ok;
^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) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563)  * misc nfsv4 ops
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) nfsd4_access(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 	     union nfsd4_op_u *u)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) 	struct nfsd4_access *access = &u->access;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 	u32 access_full;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 	access_full = NFS3_ACCESS_FULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) 	if (cstate->minorversion >= 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) 		access_full |= NFS4_ACCESS_XALIST | NFS4_ACCESS_XAREAD |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) 			       NFS4_ACCESS_XAWRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 	if (access->ac_req_access & ~access_full)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) 		return nfserr_inval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) 	access->ac_resp_access = access->ac_req_access;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 	return nfsd_access(rqstp, &cstate->current_fh, &access->ac_resp_access,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) 			   &access->ac_supported);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) static void gen_boot_verifier(nfs4_verifier *verifier, struct net *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 	__be32 *verf = (__be32 *)verifier->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 	BUILD_BUG_ON(2*sizeof(*verf) != sizeof(verifier->data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 	nfsd_copy_boot_verifier(verf, net_generic(net, nfsd_net_id));
^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) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) nfsd4_commit(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 	     union nfsd4_op_u *u)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 	struct nfsd4_commit *commit = &u->commit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 	return nfsd_commit(rqstp, &cstate->current_fh, commit->co_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) 			     commit->co_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 			     (__be32 *)commit->co_verf.data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) nfsd4_create(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) 	     union nfsd4_op_u *u)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 	struct nfsd4_create *create = &u->create;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 	struct svc_fh resfh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 	__be32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 	dev_t rdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 	fh_init(&resfh, NFS4_FHSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 	status = fh_verify(rqstp, &cstate->current_fh, S_IFDIR, NFSD_MAY_NOP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 	if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) 		return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) 	status = check_attr_support(rqstp, cstate, create->cr_bmval,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) 				    nfsd_attrmask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) 	if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 		return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 	current->fs->umask = create->cr_umask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 	switch (create->cr_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 	case NF4LNK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 		status = nfsd_symlink(rqstp, &cstate->current_fh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) 				      create->cr_name, create->cr_namelen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 				      create->cr_data, &resfh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) 	case NF4BLK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 		status = nfserr_inval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) 		rdev = MKDEV(create->cr_specdata1, create->cr_specdata2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 		if (MAJOR(rdev) != create->cr_specdata1 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 		    MINOR(rdev) != create->cr_specdata2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 			goto out_umask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 		status = nfsd_create(rqstp, &cstate->current_fh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 				     create->cr_name, create->cr_namelen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 				     &create->cr_iattr, S_IFBLK, rdev, &resfh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 	case NF4CHR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 		status = nfserr_inval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 		rdev = MKDEV(create->cr_specdata1, create->cr_specdata2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 		if (MAJOR(rdev) != create->cr_specdata1 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 		    MINOR(rdev) != create->cr_specdata2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 			goto out_umask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 		status = nfsd_create(rqstp, &cstate->current_fh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 				     create->cr_name, create->cr_namelen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 				     &create->cr_iattr,S_IFCHR, rdev, &resfh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) 	case NF4SOCK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 		status = nfsd_create(rqstp, &cstate->current_fh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) 				     create->cr_name, create->cr_namelen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 				     &create->cr_iattr, S_IFSOCK, 0, &resfh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 	case NF4FIFO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 		status = nfsd_create(rqstp, &cstate->current_fh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 				     create->cr_name, create->cr_namelen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 				     &create->cr_iattr, S_IFIFO, 0, &resfh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) 	case NF4DIR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) 		create->cr_iattr.ia_valid &= ~ATTR_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 		status = nfsd_create(rqstp, &cstate->current_fh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) 				     create->cr_name, create->cr_namelen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 				     &create->cr_iattr, S_IFDIR, 0, &resfh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 		status = nfserr_badtype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 	if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 	if (create->cr_label.len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 		nfsd4_security_inode_setsecctx(&resfh, &create->cr_label, create->cr_bmval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) 	if (create->cr_acl != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 		do_set_nfs4_acl(rqstp, &resfh, create->cr_acl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 				create->cr_bmval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 	fh_unlock(&cstate->current_fh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 	set_change_info(&create->cr_cinfo, &cstate->current_fh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 	fh_dup2(&cstate->current_fh, &resfh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 	fh_put(&resfh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) out_umask:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 	current->fs->umask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 	return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) nfsd4_getattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 	      union nfsd4_op_u *u)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 	struct nfsd4_getattr *getattr = &u->getattr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 	__be32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 	status = fh_verify(rqstp, &cstate->current_fh, 0, NFSD_MAY_NOP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 	if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 		return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 	if (getattr->ga_bmval[1] & NFSD_WRITEONLY_ATTRS_WORD1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 		return nfserr_inval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) 	getattr->ga_bmval[0] &= nfsd_suppattrs[cstate->minorversion][0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 	getattr->ga_bmval[1] &= nfsd_suppattrs[cstate->minorversion][1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) 	getattr->ga_bmval[2] &= nfsd_suppattrs[cstate->minorversion][2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) 	getattr->ga_fhp = &cstate->current_fh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) 	return nfs_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) nfsd4_link(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 	   union nfsd4_op_u *u)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 	struct nfsd4_link *link = &u->link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 	__be32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 	status = nfsd_link(rqstp, &cstate->current_fh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 			   link->li_name, link->li_namelen, &cstate->save_fh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 	if (!status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 		set_change_info(&link->li_cinfo, &cstate->current_fh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 	return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) static __be32 nfsd4_do_lookupp(struct svc_rqst *rqstp, struct svc_fh *fh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 	struct svc_fh tmp_fh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 	__be32 ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 	fh_init(&tmp_fh, NFS4_FHSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 	ret = exp_pseudoroot(rqstp, &tmp_fh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 	if (tmp_fh.fh_dentry == fh->fh_dentry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 		fh_put(&tmp_fh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 		return nfserr_noent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 	fh_put(&tmp_fh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 	return nfsd_lookup(rqstp, fh, "..", 2, fh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) nfsd4_lookupp(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 	      union nfsd4_op_u *u)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 	return nfsd4_do_lookupp(rqstp, &cstate->current_fh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) nfsd4_lookup(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 	     union nfsd4_op_u *u)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 	return nfsd_lookup(rqstp, &cstate->current_fh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 			   u->lookup.lo_name, u->lookup.lo_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 			   &cstate->current_fh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) nfsd4_read(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 	   union nfsd4_op_u *u)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 	struct nfsd4_read *read = &u->read;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 	__be32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 	read->rd_nf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 	if (read->rd_offset >= OFFSET_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 		return nfserr_inval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 	trace_nfsd_read_start(rqstp, &cstate->current_fh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 			      read->rd_offset, read->rd_length);
^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) 	 * If we do a zero copy read, then a client will see read data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 	 * that reflects the state of the file *after* performing the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 	 * following compound.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 	 * To ensure proper ordering, we therefore turn off zero copy if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 	 * the client wants us to do more in this compound:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 	if (!nfsd4_last_compound_op(rqstp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 		clear_bit(RQ_SPLICE_OK, &rqstp->rq_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 	/* check stateid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 	status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->current_fh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 					&read->rd_stateid, RD_STATE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 					&read->rd_nf, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 	if (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 		dprintk("NFSD: nfsd4_read: couldn't process stateid!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 	status = nfs_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) 	read->rd_rqstp = rqstp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 	read->rd_fhp = &cstate->current_fh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 	return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) nfsd4_read_release(union nfsd4_op_u *u)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 	if (u->read.rd_nf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 		nfsd_file_put(u->read.rd_nf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 	trace_nfsd_read_done(u->read.rd_rqstp, u->read.rd_fhp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 			     u->read.rd_offset, u->read.rd_length);
^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 __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) nfsd4_readdir(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 	      union nfsd4_op_u *u)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 	struct nfsd4_readdir *readdir = &u->readdir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) 	u64 cookie = readdir->rd_cookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 	static const nfs4_verifier zeroverf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 	/* no need to check permission - this will be done in nfsd_readdir() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 	if (readdir->rd_bmval[1] & NFSD_WRITEONLY_ATTRS_WORD1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 		return nfserr_inval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 	readdir->rd_bmval[0] &= nfsd_suppattrs[cstate->minorversion][0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 	readdir->rd_bmval[1] &= nfsd_suppattrs[cstate->minorversion][1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 	readdir->rd_bmval[2] &= nfsd_suppattrs[cstate->minorversion][2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 	if ((cookie == 1) || (cookie == 2) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 	    (cookie == 0 && memcmp(readdir->rd_verf.data, zeroverf.data, NFS4_VERIFIER_SIZE)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 		return nfserr_bad_cookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 	readdir->rd_rqstp = rqstp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 	readdir->rd_fhp = &cstate->current_fh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 	return nfs_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) nfsd4_readlink(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 	       union nfsd4_op_u *u)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 	u->readlink.rl_rqstp = rqstp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 	u->readlink.rl_fhp = &cstate->current_fh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 	return nfs_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) nfsd4_remove(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 	     union nfsd4_op_u *u)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 	struct nfsd4_remove *remove = &u->remove;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 	__be32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 	if (opens_in_grace(SVC_NET(rqstp)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 		return nfserr_grace;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 	status = nfsd_unlink(rqstp, &cstate->current_fh, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 			     remove->rm_name, remove->rm_namelen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 	if (!status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 		fh_unlock(&cstate->current_fh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 		set_change_info(&remove->rm_cinfo, &cstate->current_fh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 	return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) nfsd4_rename(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 	     union nfsd4_op_u *u)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 	struct nfsd4_rename *rename = &u->rename;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 	__be32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 	if (opens_in_grace(SVC_NET(rqstp)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 		return nfserr_grace;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 	status = nfsd_rename(rqstp, &cstate->save_fh, rename->rn_sname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 			     rename->rn_snamelen, &cstate->current_fh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 			     rename->rn_tname, rename->rn_tnamelen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 	if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 		return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 	set_change_info(&rename->rn_sinfo, &cstate->current_fh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 	set_change_info(&rename->rn_tinfo, &cstate->save_fh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 	return nfs_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) nfsd4_secinfo(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 	      union nfsd4_op_u *u)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 	struct nfsd4_secinfo *secinfo = &u->secinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 	struct svc_export *exp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 	struct dentry *dentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 	__be32 err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 	err = fh_verify(rqstp, &cstate->current_fh, S_IFDIR, NFSD_MAY_EXEC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) 	err = nfsd_lookup_dentry(rqstp, &cstate->current_fh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 				    secinfo->si_name, secinfo->si_namelen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 				    &exp, &dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 	fh_unlock(&cstate->current_fh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 	if (d_really_is_negative(dentry)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 		exp_put(exp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 		err = nfserr_noent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 		secinfo->si_exp = exp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) 	dput(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 	if (cstate->minorversion)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 		/* See rfc 5661 section 2.6.3.1.1.8 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) 		fh_put(&cstate->current_fh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) nfsd4_secinfo_no_name(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 		union nfsd4_op_u *u)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 	__be32 err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 	switch (u->secinfo_no_name.sin_style) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 	case NFS4_SECINFO_STYLE4_CURRENT_FH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 	case NFS4_SECINFO_STYLE4_PARENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 		err = nfsd4_do_lookupp(rqstp, &cstate->current_fh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 		return nfserr_inval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 	u->secinfo_no_name.sin_exp = exp_get(cstate->current_fh.fh_export);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 	fh_put(&cstate->current_fh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 	return nfs_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) nfsd4_secinfo_release(union nfsd4_op_u *u)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 	if (u->secinfo.si_exp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 		exp_put(u->secinfo.si_exp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) nfsd4_secinfo_no_name_release(union nfsd4_op_u *u)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 	if (u->secinfo_no_name.sin_exp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 		exp_put(u->secinfo_no_name.sin_exp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) nfsd4_setattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 	      union nfsd4_op_u *u)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 	struct nfsd4_setattr *setattr = &u->setattr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 	__be32 status = nfs_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 	if (setattr->sa_iattr.ia_valid & ATTR_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 		status = nfs4_preprocess_stateid_op(rqstp, cstate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 				&cstate->current_fh, &setattr->sa_stateid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 				WR_STATE, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 		if (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 			dprintk("NFSD: nfsd4_setattr: couldn't process stateid!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 			return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 	err = fh_want_write(&cstate->current_fh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 		return nfserrno(err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 	status = nfs_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 	status = check_attr_support(rqstp, cstate, setattr->sa_bmval,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 				    nfsd_attrmask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 	if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 	if (setattr->sa_acl != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 		status = nfsd4_set_nfs4_acl(rqstp, &cstate->current_fh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 					    setattr->sa_acl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 	if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 	if (setattr->sa_label.len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 		status = nfsd4_set_nfs4_label(rqstp, &cstate->current_fh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 				&setattr->sa_label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 	if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 	status = nfsd_setattr(rqstp, &cstate->current_fh, &setattr->sa_iattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 				0, (time64_t)0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 	fh_drop_write(&cstate->current_fh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 	return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) 	    union nfsd4_op_u *u)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 	struct nfsd4_write *write = &u->write;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 	stateid_t *stateid = &write->wr_stateid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 	struct nfsd_file *nf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 	__be32 status = nfs_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 	unsigned long cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 	int nvecs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 	if (write->wr_offset > (u64)OFFSET_MAX ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 	    write->wr_offset + write->wr_buflen > (u64)OFFSET_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 		return nfserr_fbig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) 	cnt = write->wr_buflen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 	trace_nfsd_write_start(rqstp, &cstate->current_fh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 			       write->wr_offset, cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 	status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->current_fh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 						stateid, WR_STATE, &nf, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 	if (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 		dprintk("NFSD: nfsd4_write: couldn't process stateid!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 		return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 	write->wr_how_written = write->wr_stable_how;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 	nvecs = svc_fill_write_vector(rqstp, write->wr_pagelist,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 				      &write->wr_head, write->wr_buflen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 	WARN_ON_ONCE(nvecs > ARRAY_SIZE(rqstp->rq_vec));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 	status = nfsd_vfs_write(rqstp, &cstate->current_fh, nf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 				write->wr_offset, rqstp->rq_vec, nvecs, &cnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 				write->wr_how_written,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 				(__be32 *)write->wr_verifier.data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 	nfsd_file_put(nf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 	write->wr_bytes_written = cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 	trace_nfsd_write_done(rqstp, &cstate->current_fh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 			      write->wr_offset, cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 	return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) nfsd4_verify_copy(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 		  stateid_t *src_stateid, struct nfsd_file **src,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 		  stateid_t *dst_stateid, struct nfsd_file **dst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 	__be32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 	if (!cstate->save_fh.fh_dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 		return nfserr_nofilehandle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) 	status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->save_fh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) 					    src_stateid, RD_STATE, src, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 	if (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) 		dprintk("NFSD: %s: couldn't process src stateid!\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 	status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->current_fh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 					    dst_stateid, WR_STATE, dst, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 	if (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 		dprintk("NFSD: %s: couldn't process dst stateid!\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 		goto out_put_src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 	/* fix up for NFS-specific error code */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 	if (!S_ISREG(file_inode((*src)->nf_file)->i_mode) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 	    !S_ISREG(file_inode((*dst)->nf_file)->i_mode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 		status = nfserr_wrong_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 		goto out_put_dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 	return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) out_put_dst:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 	nfsd_file_put(*dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) out_put_src:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 	nfsd_file_put(*src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 	goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) nfsd4_clone(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 		union nfsd4_op_u *u)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 	struct nfsd4_clone *clone = &u->clone;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 	struct nfsd_file *src, *dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 	__be32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) 	status = nfsd4_verify_copy(rqstp, cstate, &clone->cl_src_stateid, &src,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) 				   &clone->cl_dst_stateid, &dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) 	if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) 	status = nfsd4_clone_file_range(src, clone->cl_src_pos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 			dst, clone->cl_dst_pos, clone->cl_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 			EX_ISSYNC(cstate->current_fh.fh_export));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) 	nfsd_file_put(dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 	nfsd_file_put(src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) 	return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) void nfs4_put_copy(struct nfsd4_copy *copy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 	if (!refcount_dec_and_test(&copy->refcount))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) 	kfree(copy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) static bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) check_and_set_stop_copy(struct nfsd4_copy *copy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) 	bool value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 	spin_lock(&copy->cp_clp->async_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 	value = copy->stopped;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 	if (!copy->stopped)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 		copy->stopped = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 	spin_unlock(&copy->cp_clp->async_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 	return value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) static void nfsd4_stop_copy(struct nfsd4_copy *copy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) 	/* only 1 thread should stop the copy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) 	if (!check_and_set_stop_copy(copy))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) 		kthread_stop(copy->copy_task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) 	nfs4_put_copy(copy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) static struct nfsd4_copy *nfsd4_get_copy(struct nfs4_client *clp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) 	struct nfsd4_copy *copy = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) 	spin_lock(&clp->async_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) 	if (!list_empty(&clp->async_copies)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) 		copy = list_first_entry(&clp->async_copies, struct nfsd4_copy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) 					copies);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) 		refcount_inc(&copy->refcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) 	spin_unlock(&clp->async_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) 	return copy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) void nfsd4_shutdown_copy(struct nfs4_client *clp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) 	struct nfsd4_copy *copy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) 	while ((copy = nfsd4_get_copy(clp)) != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) 		nfsd4_stop_copy(copy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) #ifdef CONFIG_NFSD_V4_2_INTER_SSC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) extern struct file *nfs42_ssc_open(struct vfsmount *ss_mnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) 				   struct nfs_fh *src_fh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) 				   nfs4_stateid *stateid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) extern void nfs42_ssc_close(struct file *filep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) extern void nfs_sb_deactive(struct super_block *sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) #define NFSD42_INTERSSC_MOUNTOPS "vers=4.2,addr=%s,sec=sys"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167)  * Support one copy source server for now.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) nfsd4_interssc_connect(struct nl4_server *nss, struct svc_rqst *rqstp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) 		       struct vfsmount **mount)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) 	struct file_system_type *type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) 	struct vfsmount *ss_mnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) 	struct nfs42_netaddr *naddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) 	struct sockaddr_storage tmp_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) 	size_t tmp_addrlen, match_netid_len = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) 	char *startsep = "", *endsep = "", *match_netid = "tcp";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) 	char *ipaddr, *dev_name, *raw_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) 	int len, raw_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) 	__be32 status = nfserr_inval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) 	naddr = &nss->u.nl4_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) 	tmp_addrlen = rpc_uaddr2sockaddr(SVC_NET(rqstp), naddr->addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) 					 naddr->addr_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) 					 (struct sockaddr *)&tmp_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) 					 sizeof(tmp_addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) 	if (tmp_addrlen == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) 		goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) 	if (tmp_addr.ss_family == AF_INET6) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) 		startsep = "[";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) 		endsep = "]";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) 		match_netid = "tcp6";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) 		match_netid_len = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) 	if (naddr->netid_len != match_netid_len ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) 		strncmp(naddr->netid, match_netid, naddr->netid_len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) 		goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) 	/* Construct the raw data for the vfs_kern_mount call */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) 	len = RPC_MAX_ADDRBUFLEN + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) 	ipaddr = kzalloc(len, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) 	if (!ipaddr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) 		goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) 	rpc_ntop((struct sockaddr *)&tmp_addr, ipaddr, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) 	/* 2 for ipv6 endsep and startsep. 3 for ":/" and trailing '/0'*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) 	raw_len = strlen(NFSD42_INTERSSC_MOUNTOPS) + strlen(ipaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) 	raw_data = kzalloc(raw_len, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) 	if (!raw_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) 		goto out_free_ipaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) 	snprintf(raw_data, raw_len, NFSD42_INTERSSC_MOUNTOPS, ipaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) 	status = nfserr_nodev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) 	type = get_fs_type("nfs");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) 	if (!type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) 		goto out_free_rawdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) 	/* Set the server:<export> for the vfs_kern_mount call */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) 	dev_name = kzalloc(len + 5, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) 	if (!dev_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) 		goto out_free_rawdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) 	snprintf(dev_name, len + 5, "%s%s%s:/", startsep, ipaddr, endsep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) 	/* Use an 'internal' mount: SB_KERNMOUNT -> MNT_INTERNAL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) 	ss_mnt = vfs_kern_mount(type, SB_KERNMOUNT, dev_name, raw_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) 	module_put(type->owner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) 	if (IS_ERR(ss_mnt))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) 		goto out_free_devname;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) 	status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) 	*mount = ss_mnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) out_free_devname:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) 	kfree(dev_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) out_free_rawdata:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) 	kfree(raw_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) out_free_ipaddr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) 	kfree(ipaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) out_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) 	return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) nfsd4_interssc_disconnect(struct vfsmount *ss_mnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) 	nfs_do_sb_deactive(ss_mnt->mnt_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) 	mntput(ss_mnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257)  * Verify COPY destination stateid.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259)  * Connect to the source server with NFSv4.1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260)  * Create the source struct file for nfsd_copy_range.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261)  * Called with COPY cstate:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262)  *    SAVED_FH: source filehandle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263)  *    CURRENT_FH: destination filehandle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) nfsd4_setup_inter_ssc(struct svc_rqst *rqstp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) 		      struct nfsd4_compound_state *cstate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) 		      struct nfsd4_copy *copy, struct vfsmount **mount)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) 	struct svc_fh *s_fh = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) 	stateid_t *s_stid = &copy->cp_src_stateid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) 	__be32 status = nfserr_inval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) 	/* Verify the destination stateid and set dst struct file*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) 	status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->current_fh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) 					    &copy->cp_dst_stateid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) 					    WR_STATE, &copy->nf_dst, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) 	if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) 	status = nfsd4_interssc_connect(&copy->cp_src, rqstp, mount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) 	if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) 	s_fh = &cstate->save_fh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) 	copy->c_fh.size = s_fh->fh_handle.fh_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) 	memcpy(copy->c_fh.data, &s_fh->fh_handle.fh_base, copy->c_fh.size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) 	copy->stateid.seqid = cpu_to_be32(s_stid->si_generation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) 	memcpy(copy->stateid.other, (void *)&s_stid->si_opaque,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) 	       sizeof(stateid_opaque_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) 	status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) 	return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) nfsd4_cleanup_inter_ssc(struct vfsmount *ss_mnt, struct nfsd_file *src,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) 			struct nfsd_file *dst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) 	nfs42_ssc_close(src->nf_file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) 	fput(src->nf_file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) 	nfsd_file_put(dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) 	mntput(ss_mnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) #else /* CONFIG_NFSD_V4_2_INTER_SSC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) nfsd4_setup_inter_ssc(struct svc_rqst *rqstp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) 		      struct nfsd4_compound_state *cstate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) 		      struct nfsd4_copy *copy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) 		      struct vfsmount **mount)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) 	*mount = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) 	return nfserr_inval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) nfsd4_cleanup_inter_ssc(struct vfsmount *ss_mnt, struct nfsd_file *src,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) 			struct nfsd_file *dst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) nfsd4_interssc_disconnect(struct vfsmount *ss_mnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) static struct file *nfs42_ssc_open(struct vfsmount *ss_mnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) 				   struct nfs_fh *src_fh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) 				   nfs4_stateid *stateid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) #endif /* CONFIG_NFSD_V4_2_INTER_SSC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) nfsd4_setup_intra_ssc(struct svc_rqst *rqstp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) 		      struct nfsd4_compound_state *cstate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) 		      struct nfsd4_copy *copy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) 	return nfsd4_verify_copy(rqstp, cstate, &copy->cp_src_stateid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) 				 &copy->nf_src, &copy->cp_dst_stateid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) 				 &copy->nf_dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) nfsd4_cleanup_intra_ssc(struct nfsd_file *src, struct nfsd_file *dst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) 	nfsd_file_put(src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) 	nfsd_file_put(dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) static void nfsd4_cb_offload_release(struct nfsd4_callback *cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) 	struct nfsd4_copy *copy = container_of(cb, struct nfsd4_copy, cp_cb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) 	nfs4_put_copy(copy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) static int nfsd4_cb_offload_done(struct nfsd4_callback *cb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) 				 struct rpc_task *task)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) static const struct nfsd4_callback_ops nfsd4_cb_offload_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) 	.release = nfsd4_cb_offload_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) 	.done = nfsd4_cb_offload_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) static void nfsd4_init_copy_res(struct nfsd4_copy *copy, bool sync)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) 	copy->cp_res.wr_stable_how = NFS_UNSTABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) 	copy->cp_synchronous = sync;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) 	gen_boot_verifier(&copy->cp_res.wr_verifier, copy->cp_clp->net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) static ssize_t _nfsd_copy_file_range(struct nfsd4_copy *copy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) 	ssize_t bytes_copied = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) 	size_t bytes_total = copy->cp_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) 	u64 src_pos = copy->cp_src_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) 	u64 dst_pos = copy->cp_dst_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) 		if (kthread_should_stop())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) 		bytes_copied = nfsd_copy_file_range(copy->nf_src->nf_file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) 				src_pos, copy->nf_dst->nf_file, dst_pos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) 				bytes_total);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) 		if (bytes_copied <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) 		bytes_total -= bytes_copied;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) 		copy->cp_res.wr_bytes_written += bytes_copied;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) 		src_pos += bytes_copied;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) 		dst_pos += bytes_copied;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) 	} while (bytes_total > 0 && !copy->cp_synchronous);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) 	return bytes_copied;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) static __be32 nfsd4_do_copy(struct nfsd4_copy *copy, bool sync)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) 	__be32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) 	ssize_t bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) 	bytes = _nfsd_copy_file_range(copy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) 	/* for async copy, we ignore the error, client can always retry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) 	 * to get the error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) 	if (bytes < 0 && !copy->cp_res.wr_bytes_written)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) 		status = nfserrno(bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) 		nfsd4_init_copy_res(copy, sync);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) 		status = nfs_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) 	if (!copy->cp_intra) /* Inter server SSC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) 		nfsd4_cleanup_inter_ssc(copy->ss_mnt, copy->nf_src,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) 					copy->nf_dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) 		nfsd4_cleanup_intra_ssc(copy->nf_src, copy->nf_dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) 	return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) static void dup_copy_fields(struct nfsd4_copy *src, struct nfsd4_copy *dst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) 	dst->cp_src_pos = src->cp_src_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) 	dst->cp_dst_pos = src->cp_dst_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) 	dst->cp_count = src->cp_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) 	dst->cp_synchronous = src->cp_synchronous;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) 	memcpy(&dst->cp_res, &src->cp_res, sizeof(src->cp_res));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) 	memcpy(&dst->fh, &src->fh, sizeof(src->fh));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) 	dst->cp_clp = src->cp_clp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) 	dst->nf_dst = nfsd_file_get(src->nf_dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) 	dst->cp_intra = src->cp_intra;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) 	if (src->cp_intra) /* for inter, file_src doesn't exist yet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) 		dst->nf_src = nfsd_file_get(src->nf_src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) 	memcpy(&dst->cp_stateid, &src->cp_stateid, sizeof(src->cp_stateid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) 	memcpy(&dst->cp_src, &src->cp_src, sizeof(struct nl4_server));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) 	memcpy(&dst->stateid, &src->stateid, sizeof(src->stateid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) 	memcpy(&dst->c_fh, &src->c_fh, sizeof(src->c_fh));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) 	dst->ss_mnt = src->ss_mnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) static void cleanup_async_copy(struct nfsd4_copy *copy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) 	nfs4_free_copy_state(copy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) 	nfsd_file_put(copy->nf_dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) 	if (copy->cp_intra)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) 		nfsd_file_put(copy->nf_src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) 	spin_lock(&copy->cp_clp->async_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) 	list_del(&copy->copies);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) 	spin_unlock(&copy->cp_clp->async_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) 	nfs4_put_copy(copy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) static int nfsd4_do_async_copy(void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) 	struct nfsd4_copy *copy = (struct nfsd4_copy *)data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) 	struct nfsd4_copy *cb_copy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) 	if (!copy->cp_intra) { /* Inter server SSC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) 		copy->nf_src = kzalloc(sizeof(struct nfsd_file), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) 		if (!copy->nf_src) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) 			copy->nfserr = nfserr_serverfault;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) 			nfsd4_interssc_disconnect(copy->ss_mnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) 			goto do_callback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) 		copy->nf_src->nf_file = nfs42_ssc_open(copy->ss_mnt, &copy->c_fh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) 					      &copy->stateid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) 		if (IS_ERR(copy->nf_src->nf_file)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) 			copy->nfserr = nfserr_offload_denied;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) 			nfsd4_interssc_disconnect(copy->ss_mnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) 			goto do_callback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) 	copy->nfserr = nfsd4_do_copy(copy, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) do_callback:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) 	cb_copy = kzalloc(sizeof(struct nfsd4_copy), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) 	if (!cb_copy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) 	refcount_set(&cb_copy->refcount, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) 	memcpy(&cb_copy->cp_res, &copy->cp_res, sizeof(copy->cp_res));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) 	cb_copy->cp_clp = copy->cp_clp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) 	cb_copy->nfserr = copy->nfserr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) 	memcpy(&cb_copy->fh, &copy->fh, sizeof(copy->fh));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) 	nfsd4_init_cb(&cb_copy->cp_cb, cb_copy->cp_clp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) 			&nfsd4_cb_offload_ops, NFSPROC4_CLNT_CB_OFFLOAD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) 	nfsd4_run_cb(&cb_copy->cp_cb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) 	if (!copy->cp_intra)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) 		kfree(copy->nf_src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) 	cleanup_async_copy(copy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) nfsd4_copy(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) 		union nfsd4_op_u *u)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) 	struct nfsd4_copy *copy = &u->copy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) 	__be32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) 	struct nfsd4_copy *async_copy = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) 	if (!copy->cp_intra) { /* Inter server SSC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) 		if (!inter_copy_offload_enable || copy->cp_synchronous) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) 			status = nfserr_notsupp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) 		status = nfsd4_setup_inter_ssc(rqstp, cstate, copy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) 				&copy->ss_mnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) 		if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) 			return nfserr_offload_denied;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) 		status = nfsd4_setup_intra_ssc(rqstp, cstate, copy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) 		if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) 			return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) 	copy->cp_clp = cstate->clp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) 	memcpy(&copy->fh, &cstate->current_fh.fh_handle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) 		sizeof(struct knfsd_fh));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) 	if (!copy->cp_synchronous) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) 		struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) 		status = nfserrno(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) 		async_copy = kzalloc(sizeof(struct nfsd4_copy), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) 		if (!async_copy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) 			goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) 		if (!nfs4_init_copy_state(nn, copy))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) 			goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) 		refcount_set(&async_copy->refcount, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) 		memcpy(&copy->cp_res.cb_stateid, &copy->cp_stateid.stid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) 			sizeof(copy->cp_res.cb_stateid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) 		dup_copy_fields(copy, async_copy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) 		async_copy->copy_task = kthread_create(nfsd4_do_async_copy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) 				async_copy, "%s", "copy thread");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) 		if (IS_ERR(async_copy->copy_task))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) 			goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) 		spin_lock(&async_copy->cp_clp->async_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) 		list_add(&async_copy->copies,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) 				&async_copy->cp_clp->async_copies);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) 		spin_unlock(&async_copy->cp_clp->async_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) 		wake_up_process(async_copy->copy_task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) 		status = nfs_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) 		status = nfsd4_do_copy(copy, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) 	return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) out_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) 	if (async_copy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) 		cleanup_async_copy(async_copy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) 	status = nfserrno(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) 	if (!copy->cp_intra)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) 		nfsd4_interssc_disconnect(copy->ss_mnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) 	goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) struct nfsd4_copy *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) find_async_copy(struct nfs4_client *clp, stateid_t *stateid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) 	struct nfsd4_copy *copy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) 	spin_lock(&clp->async_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) 	list_for_each_entry(copy, &clp->async_copies, copies) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) 		if (memcmp(&copy->cp_stateid.stid, stateid, NFS4_STATEID_SIZE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) 		refcount_inc(&copy->refcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) 		spin_unlock(&clp->async_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) 		return copy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) 	spin_unlock(&clp->async_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) nfsd4_offload_cancel(struct svc_rqst *rqstp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) 		     struct nfsd4_compound_state *cstate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) 		     union nfsd4_op_u *u)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) 	struct nfsd4_offload_status *os = &u->offload_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) 	struct nfsd4_copy *copy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) 	struct nfs4_client *clp = cstate->clp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) 	copy = find_async_copy(clp, &os->stateid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) 	if (!copy) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) 		struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) 		return manage_cpntf_state(nn, &os->stateid, clp, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) 		nfsd4_stop_copy(copy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) 	return nfs_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) nfsd4_copy_notify(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) 		  union nfsd4_op_u *u)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) 	struct nfsd4_copy_notify *cn = &u->copy_notify;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) 	__be32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) 	struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) 	struct nfs4_stid *stid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) 	struct nfs4_cpntf_state *cps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) 	struct nfs4_client *clp = cstate->clp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) 	status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->current_fh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) 					&cn->cpn_src_stateid, RD_STATE, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) 					&stid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) 	if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) 		return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) 	cn->cpn_sec = nn->nfsd4_lease;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) 	cn->cpn_nsec = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) 	status = nfserrno(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) 	cps = nfs4_alloc_init_cpntf_state(nn, stid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) 	if (!cps)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) 	memcpy(&cn->cpn_cnr_stateid, &cps->cp_stateid.stid, sizeof(stateid_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) 	memcpy(&cps->cp_p_stateid, &stid->sc_stateid, sizeof(stateid_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) 	memcpy(&cps->cp_p_clid, &clp->cl_clientid, sizeof(clientid_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) 	/* For now, only return one server address in cpn_src, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) 	 * address used by the client to connect to this server.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) 	cn->cpn_src.nl4_type = NL4_NETADDR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) 	status = nfsd4_set_netaddr((struct sockaddr *)&rqstp->rq_daddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) 				 &cn->cpn_src.u.nl4_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) 	WARN_ON_ONCE(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) 	if (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) 		nfs4_put_cpntf_state(nn, cps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) 	nfs4_put_stid(stid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) 	return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) nfsd4_fallocate(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) 		struct nfsd4_fallocate *fallocate, int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) 	__be32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) 	struct nfsd_file *nf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) 	status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->current_fh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) 					    &fallocate->falloc_stateid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) 					    WR_STATE, &nf, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) 	if (status != nfs_ok) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) 		dprintk("NFSD: nfsd4_fallocate: couldn't process stateid!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) 		return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) 	status = nfsd4_vfs_fallocate(rqstp, &cstate->current_fh, nf->nf_file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) 				     fallocate->falloc_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) 				     fallocate->falloc_length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) 				     flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) 	nfsd_file_put(nf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) 	return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) nfsd4_offload_status(struct svc_rqst *rqstp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) 		     struct nfsd4_compound_state *cstate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) 		     union nfsd4_op_u *u)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) 	struct nfsd4_offload_status *os = &u->offload_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) 	__be32 status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) 	struct nfsd4_copy *copy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) 	struct nfs4_client *clp = cstate->clp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) 	copy = find_async_copy(clp, &os->stateid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) 	if (copy) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) 		os->count = copy->cp_res.wr_bytes_written;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) 		nfs4_put_copy(copy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) 		status = nfserr_bad_stateid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) 	return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) nfsd4_allocate(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) 	       union nfsd4_op_u *u)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) 	return nfsd4_fallocate(rqstp, cstate, &u->allocate, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) nfsd4_deallocate(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) 		 union nfsd4_op_u *u)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) 	return nfsd4_fallocate(rqstp, cstate, &u->deallocate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) 			       FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) nfsd4_seek(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) 	   union nfsd4_op_u *u)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) 	struct nfsd4_seek *seek = &u->seek;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) 	int whence;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) 	__be32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) 	struct nfsd_file *nf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) 	status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->current_fh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) 					    &seek->seek_stateid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) 					    RD_STATE, &nf, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) 	if (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) 		dprintk("NFSD: nfsd4_seek: couldn't process stateid!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) 		return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) 	switch (seek->seek_whence) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) 	case NFS4_CONTENT_DATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) 		whence = SEEK_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) 	case NFS4_CONTENT_HOLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) 		whence = SEEK_HOLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) 		status = nfserr_union_notsupp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) 	 * Note:  This call does change file->f_pos, but nothing in NFSD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) 	 *        should ever file->f_pos.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) 	seek->seek_pos = vfs_llseek(nf->nf_file, seek->seek_offset, whence);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) 	if (seek->seek_pos < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) 		status = nfserrno(seek->seek_pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) 	else if (seek->seek_pos >= i_size_read(file_inode(nf->nf_file)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) 		seek->seek_eof = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) 	nfsd_file_put(nf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) 	return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) /* This routine never returns NFS_OK!  If there are no other errors, it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749)  * will return NFSERR_SAME or NFSERR_NOT_SAME depending on whether the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750)  * attributes matched.  VERIFY is implemented by mapping NFSERR_SAME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751)  * to NFS_OK after the call; NVERIFY by mapping NFSERR_NOT_SAME to NFS_OK.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) _nfsd4_verify(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) 	     struct nfsd4_verify *verify)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) 	__be32 *buf, *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) 	int count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) 	__be32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) 	status = fh_verify(rqstp, &cstate->current_fh, 0, NFSD_MAY_NOP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) 	if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) 		return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) 	status = check_attr_support(rqstp, cstate, verify->ve_bmval, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) 	if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) 		return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) 	if ((verify->ve_bmval[0] & FATTR4_WORD0_RDATTR_ERROR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) 	    || (verify->ve_bmval[1] & NFSD_WRITEONLY_ATTRS_WORD1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) 		return nfserr_inval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) 	if (verify->ve_attrlen & 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) 		return nfserr_inval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) 	/* count in words:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) 	 *   bitmap_len(1) + bitmap(2) + attr_len(1) = 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) 	count = 4 + (verify->ve_attrlen >> 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) 	buf = kmalloc(count << 2, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) 	if (!buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) 		return nfserr_jukebox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) 	p = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) 	status = nfsd4_encode_fattr_to_buf(&p, count, &cstate->current_fh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) 				    cstate->current_fh.fh_export,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) 				    cstate->current_fh.fh_dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) 				    verify->ve_bmval,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) 				    rqstp, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) 	 * If nfsd4_encode_fattr() ran out of space, assume that's because
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) 	 * the attributes are longer (hence different) than those given:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) 	if (status == nfserr_resource)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) 		status = nfserr_not_same;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) 	if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) 		goto out_kfree;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) 	/* skip bitmap */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) 	p = buf + 1 + ntohl(buf[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) 	status = nfserr_not_same;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) 	if (ntohl(*p++) != verify->ve_attrlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) 		goto out_kfree;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) 	if (!memcmp(p, verify->ve_attrval, verify->ve_attrlen))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) 		status = nfserr_same;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) out_kfree:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) 	kfree(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) 	return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) nfsd4_nverify(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) 	      union nfsd4_op_u *u)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) 	__be32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) 	status = _nfsd4_verify(rqstp, cstate, &u->verify);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) 	return status == nfserr_not_same ? nfs_ok : status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) nfsd4_verify(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) 	     union nfsd4_op_u *u)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) 	__be32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) 	status = _nfsd4_verify(rqstp, cstate, &u->nverify);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) 	return status == nfserr_same ? nfs_ok : status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) #ifdef CONFIG_NFSD_PNFS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) static const struct nfsd4_layout_ops *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) nfsd4_layout_verify(struct svc_export *exp, unsigned int layout_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) 	if (!exp->ex_layout_types) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) 		dprintk("%s: export does not support pNFS\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) 	if (layout_type >= LAYOUT_TYPE_MAX ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) 	    !(exp->ex_layout_types & (1 << layout_type))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) 		dprintk("%s: layout type %d not supported\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) 			__func__, layout_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) 	return nfsd4_layout_ops[layout_type];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) nfsd4_getdeviceinfo(struct svc_rqst *rqstp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) 		struct nfsd4_compound_state *cstate, union nfsd4_op_u *u)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) 	struct nfsd4_getdeviceinfo *gdp = &u->getdeviceinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) 	const struct nfsd4_layout_ops *ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) 	struct nfsd4_deviceid_map *map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) 	struct svc_export *exp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) 	__be32 nfserr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) 	dprintk("%s: layout_type %u dev_id [0x%llx:0x%x] maxcnt %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) 	       __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) 	       gdp->gd_layout_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) 	       gdp->gd_devid.fsid_idx, gdp->gd_devid.generation,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) 	       gdp->gd_maxcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) 	map = nfsd4_find_devid_map(gdp->gd_devid.fsid_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) 	if (!map) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) 		dprintk("%s: couldn't find device ID to export mapping!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) 			__func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) 		return nfserr_noent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) 	exp = rqst_exp_find(rqstp, map->fsid_type, map->fsid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) 	if (IS_ERR(exp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) 		dprintk("%s: could not find device id\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) 		return nfserr_noent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) 	nfserr = nfserr_layoutunavailable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) 	ops = nfsd4_layout_verify(exp, gdp->gd_layout_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) 	if (!ops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) 	nfserr = nfs_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) 	if (gdp->gd_maxcount != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) 		nfserr = ops->proc_getdeviceinfo(exp->ex_path.mnt->mnt_sb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) 				rqstp, cstate->session->se_client, gdp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) 	gdp->gd_notify_types &= ops->notify_types;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) 	exp_put(exp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) 	return nfserr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) nfsd4_getdeviceinfo_release(union nfsd4_op_u *u)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) 	kfree(u->getdeviceinfo.gd_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) nfsd4_layoutget(struct svc_rqst *rqstp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) 		struct nfsd4_compound_state *cstate, union nfsd4_op_u *u)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) 	struct nfsd4_layoutget *lgp = &u->layoutget;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) 	struct svc_fh *current_fh = &cstate->current_fh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) 	const struct nfsd4_layout_ops *ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) 	struct nfs4_layout_stateid *ls;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) 	__be32 nfserr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) 	int accmode = NFSD_MAY_READ_IF_EXEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) 	switch (lgp->lg_seg.iomode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) 	case IOMODE_READ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) 		accmode |= NFSD_MAY_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) 	case IOMODE_RW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) 		accmode |= NFSD_MAY_READ | NFSD_MAY_WRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) 		dprintk("%s: invalid iomode %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) 			__func__, lgp->lg_seg.iomode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) 		nfserr = nfserr_badiomode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) 	nfserr = fh_verify(rqstp, current_fh, 0, accmode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) 	if (nfserr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) 	nfserr = nfserr_layoutunavailable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) 	ops = nfsd4_layout_verify(current_fh->fh_export, lgp->lg_layout_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) 	if (!ops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) 	 * Verify minlength and range as per RFC5661:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) 	 *  o  If loga_length is less than loga_minlength,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) 	 *     the metadata server MUST return NFS4ERR_INVAL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) 	 *  o  If the sum of loga_offset and loga_minlength exceeds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) 	 *     NFS4_UINT64_MAX, and loga_minlength is not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) 	 *     NFS4_UINT64_MAX, the error NFS4ERR_INVAL MUST result.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) 	 *  o  If the sum of loga_offset and loga_length exceeds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) 	 *     NFS4_UINT64_MAX, and loga_length is not NFS4_UINT64_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) 	 *     the error NFS4ERR_INVAL MUST result.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) 	nfserr = nfserr_inval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) 	if (lgp->lg_seg.length < lgp->lg_minlength ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) 	    (lgp->lg_minlength != NFS4_MAX_UINT64 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) 	     lgp->lg_minlength > NFS4_MAX_UINT64 - lgp->lg_seg.offset) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) 	    (lgp->lg_seg.length != NFS4_MAX_UINT64 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) 	     lgp->lg_seg.length > NFS4_MAX_UINT64 - lgp->lg_seg.offset))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) 	if (lgp->lg_seg.length == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) 	nfserr = nfsd4_preprocess_layout_stateid(rqstp, cstate, &lgp->lg_sid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) 						true, lgp->lg_layout_type, &ls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) 	if (nfserr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) 		trace_nfsd_layout_get_lookup_fail(&lgp->lg_sid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) 	nfserr = nfserr_recallconflict;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) 	if (atomic_read(&ls->ls_stid.sc_file->fi_lo_recalls))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) 		goto out_put_stid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) 	nfserr = ops->proc_layoutget(d_inode(current_fh->fh_dentry),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) 				     current_fh, lgp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) 	if (nfserr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) 		goto out_put_stid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) 	nfserr = nfsd4_insert_layout(lgp, ls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) out_put_stid:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) 	mutex_unlock(&ls->ls_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) 	nfs4_put_stid(&ls->ls_stid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) 	return nfserr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) nfsd4_layoutget_release(union nfsd4_op_u *u)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) 	kfree(u->layoutget.lg_content);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) nfsd4_layoutcommit(struct svc_rqst *rqstp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) 		struct nfsd4_compound_state *cstate, union nfsd4_op_u *u)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) 	struct nfsd4_layoutcommit *lcp = &u->layoutcommit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) 	const struct nfsd4_layout_seg *seg = &lcp->lc_seg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) 	struct svc_fh *current_fh = &cstate->current_fh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) 	const struct nfsd4_layout_ops *ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) 	loff_t new_size = lcp->lc_last_wr + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) 	struct inode *inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) 	struct nfs4_layout_stateid *ls;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) 	__be32 nfserr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) 	nfserr = fh_verify(rqstp, current_fh, 0, NFSD_MAY_WRITE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) 	if (nfserr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) 	nfserr = nfserr_layoutunavailable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) 	ops = nfsd4_layout_verify(current_fh->fh_export, lcp->lc_layout_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) 	if (!ops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) 	inode = d_inode(current_fh->fh_dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) 	nfserr = nfserr_inval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) 	if (new_size <= seg->offset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) 		dprintk("pnfsd: last write before layout segment\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) 	if (new_size > seg->offset + seg->length) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) 		dprintk("pnfsd: last write beyond layout segment\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) 	if (!lcp->lc_newoffset && new_size > i_size_read(inode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) 		dprintk("pnfsd: layoutcommit beyond EOF\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) 	nfserr = nfsd4_preprocess_layout_stateid(rqstp, cstate, &lcp->lc_sid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) 						false, lcp->lc_layout_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) 						&ls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) 	if (nfserr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) 		trace_nfsd_layout_commit_lookup_fail(&lcp->lc_sid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) 		/* fixup error code as per RFC5661 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) 		if (nfserr == nfserr_bad_stateid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) 			nfserr = nfserr_badlayout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) 	/* LAYOUTCOMMIT does not require any serialization */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) 	mutex_unlock(&ls->ls_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) 	if (new_size > i_size_read(inode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) 		lcp->lc_size_chg = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) 		lcp->lc_newsize = new_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) 		lcp->lc_size_chg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) 	nfserr = ops->proc_layoutcommit(inode, lcp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) 	nfs4_put_stid(&ls->ls_stid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) 	return nfserr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) nfsd4_layoutreturn(struct svc_rqst *rqstp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) 		struct nfsd4_compound_state *cstate, union nfsd4_op_u *u)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) 	struct nfsd4_layoutreturn *lrp = &u->layoutreturn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) 	struct svc_fh *current_fh = &cstate->current_fh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) 	__be32 nfserr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) 	nfserr = fh_verify(rqstp, current_fh, 0, NFSD_MAY_NOP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) 	if (nfserr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) 	nfserr = nfserr_layoutunavailable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) 	if (!nfsd4_layout_verify(current_fh->fh_export, lrp->lr_layout_type))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) 	switch (lrp->lr_seg.iomode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) 	case IOMODE_READ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) 	case IOMODE_RW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) 	case IOMODE_ANY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) 		dprintk("%s: invalid iomode %d\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) 			lrp->lr_seg.iomode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) 		nfserr = nfserr_inval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) 	switch (lrp->lr_return_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) 	case RETURN_FILE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) 		nfserr = nfsd4_return_file_layouts(rqstp, cstate, lrp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) 	case RETURN_FSID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) 	case RETURN_ALL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) 		nfserr = nfsd4_return_client_layouts(rqstp, cstate, lrp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) 		dprintk("%s: invalid return_type %d\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) 			lrp->lr_return_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) 		nfserr = nfserr_inval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) 	return nfserr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) #endif /* CONFIG_NFSD_PNFS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) nfsd4_getxattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) 	       union nfsd4_op_u *u)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) 	struct nfsd4_getxattr *getxattr = &u->getxattr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) 	return nfsd_getxattr(rqstp, &cstate->current_fh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) 			     getxattr->getxa_name, &getxattr->getxa_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) 			     &getxattr->getxa_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) nfsd4_setxattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) 	   union nfsd4_op_u *u)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) 	struct nfsd4_setxattr *setxattr = &u->setxattr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) 	__be32 ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) 	if (opens_in_grace(SVC_NET(rqstp)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) 		return nfserr_grace;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) 	ret = nfsd_setxattr(rqstp, &cstate->current_fh, setxattr->setxa_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) 			    setxattr->setxa_buf, setxattr->setxa_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) 			    setxattr->setxa_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) 	if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) 		set_change_info(&setxattr->setxa_cinfo, &cstate->current_fh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) nfsd4_listxattrs(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) 	   union nfsd4_op_u *u)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) 	 * Get the entire list, then copy out only the user attributes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) 	 * in the encode function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) 	return nfsd_listxattr(rqstp, &cstate->current_fh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) 			     &u->listxattrs.lsxa_buf, &u->listxattrs.lsxa_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) nfsd4_removexattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) 	   union nfsd4_op_u *u)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) 	struct nfsd4_removexattr *removexattr = &u->removexattr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) 	__be32 ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) 	if (opens_in_grace(SVC_NET(rqstp)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) 		return nfserr_grace;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) 	ret = nfsd_removexattr(rqstp, &cstate->current_fh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) 	    removexattr->rmxa_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) 	if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) 		set_change_info(&removexattr->rmxa_cinfo, &cstate->current_fh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162)  * NULL call.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) nfsd4_proc_null(struct svc_rqst *rqstp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) 	return rpc_success;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) static inline void nfsd4_increment_op_stats(u32 opnum)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) 	if (opnum >= FIRST_NFS4_OP && opnum <= LAST_NFS4_OP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) 		nfsdstats.nfs4_opcount[opnum]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) static const struct nfsd4_operation nfsd4_ops[];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) static const char *nfsd4_op_name(unsigned opnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181)  * Enforce NFSv4.1 COMPOUND ordering rules:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183)  * Also note, enforced elsewhere:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184)  *	- SEQUENCE other than as first op results in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185)  *	  NFS4ERR_SEQUENCE_POS. (Enforced in nfsd4_sequence().)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186)  *	- BIND_CONN_TO_SESSION must be the only op in its compound.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187)  *	  (Enforced in nfsd4_bind_conn_to_session().)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188)  *	- DESTROY_SESSION must be the final operation in a compound, if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189)  *	  sessionid's in SEQUENCE and DESTROY_SESSION are the same.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190)  *	  (Enforced in nfsd4_destroy_session().)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) static __be32 nfs41_check_op_ordering(struct nfsd4_compoundargs *args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) 	struct nfsd4_op *first_op = &args->ops[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) 	/* These ordering requirements don't apply to NFSv4.0: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) 	if (args->minorversion == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) 		return nfs_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) 	/* This is weird, but OK, not our problem: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) 	if (args->opcnt == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) 		return nfs_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) 	if (first_op->status == nfserr_op_illegal)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) 		return nfs_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) 	if (!(nfsd4_ops[first_op->opnum].op_flags & ALLOWED_AS_FIRST_OP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) 		return nfserr_op_not_in_session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) 	if (first_op->opnum == OP_SEQUENCE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) 		return nfs_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) 	 * So first_op is something allowed outside a session, like
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) 	 * EXCHANGE_ID; but then it has to be the only op in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) 	 * compound:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) 	if (args->opcnt != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) 		return nfserr_not_only_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) 	return nfs_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) const struct nfsd4_operation *OPDESC(struct nfsd4_op *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) 	return &nfsd4_ops[op->opnum];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) bool nfsd4_cache_this_op(struct nfsd4_op *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) 	if (op->opnum == OP_ILLEGAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) 	return OPDESC(op)->op_flags & OP_CACHEME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) static bool need_wrongsec_check(struct svc_rqst *rqstp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) 	struct nfsd4_compoundres *resp = rqstp->rq_resp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) 	struct nfsd4_compoundargs *argp = rqstp->rq_argp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) 	struct nfsd4_op *this = &argp->ops[resp->opcnt - 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) 	struct nfsd4_op *next = &argp->ops[resp->opcnt];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) 	const struct nfsd4_operation *thisd = OPDESC(this);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) 	const struct nfsd4_operation *nextd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) 	 * Most ops check wronsec on our own; only the putfh-like ops
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) 	 * have special rules.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) 	if (!(thisd->op_flags & OP_IS_PUTFH_LIKE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) 	 * rfc 5661 2.6.3.1.1.6: don't bother erroring out a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) 	 * put-filehandle operation if we're not going to use the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) 	 * result:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) 	if (argp->opcnt == resp->opcnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) 	if (next->opnum == OP_ILLEGAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) 	nextd = OPDESC(next);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) 	 * Rest of 2.6.3.1.1: certain operations will return WRONGSEC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) 	 * errors themselves as necessary; others should check for them
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) 	 * now:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) 	return !(nextd->op_flags & OP_HANDLES_WRONGSEC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) static void svcxdr_init_encode(struct svc_rqst *rqstp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) 			       struct nfsd4_compoundres *resp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) 	struct xdr_stream *xdr = &resp->xdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) 	struct xdr_buf *buf = &rqstp->rq_res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) 	struct kvec *head = buf->head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) 	xdr->buf = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) 	xdr->iov = head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) 	xdr->p   = head->iov_base + head->iov_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) 	xdr->end = head->iov_base + PAGE_SIZE - rqstp->rq_auth_slack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) 	/* Tail and page_len should be zero at this point: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) 	buf->len = buf->head[0].iov_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) 	xdr->scratch.iov_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) 	xdr->page_ptr = buf->pages - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) 	buf->buflen = PAGE_SIZE * (1 + rqstp->rq_page_end - buf->pages)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) 		- rqstp->rq_auth_slack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) #ifdef CONFIG_NFSD_V4_2_INTER_SSC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) check_if_stalefh_allowed(struct nfsd4_compoundargs *args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) 	struct nfsd4_op	*op, *current_op = NULL, *saved_op = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) 	struct nfsd4_copy *copy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) 	struct nfsd4_putfh *putfh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) 	/* traverse all operation and if it's a COPY compound, mark the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) 	 * source filehandle to skip verification
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) 	for (i = 0; i < args->opcnt; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) 		op = &args->ops[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) 		if (op->opnum == OP_PUTFH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) 			current_op = op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) 		else if (op->opnum == OP_SAVEFH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) 			saved_op = current_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) 		else if (op->opnum == OP_RESTOREFH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) 			current_op = saved_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) 		else if (op->opnum == OP_COPY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) 			copy = (struct nfsd4_copy *)&op->u;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) 			if (!saved_op) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) 				op->status = nfserr_nofilehandle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) 				return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) 			putfh = (struct nfsd4_putfh *)&saved_op->u;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) 			if (!copy->cp_intra)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) 				putfh->no_verify = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) check_if_stalefh_allowed(struct nfsd4_compoundargs *args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322)  * COMPOUND call.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) nfsd4_proc_compound(struct svc_rqst *rqstp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) 	struct nfsd4_compoundargs *args = rqstp->rq_argp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) 	struct nfsd4_compoundres *resp = rqstp->rq_resp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) 	struct nfsd4_op	*op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) 	struct nfsd4_compound_state *cstate = &resp->cstate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) 	struct svc_fh *current_fh = &cstate->current_fh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) 	struct svc_fh *save_fh = &cstate->save_fh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) 	struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) 	__be32		status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) 	svcxdr_init_encode(rqstp, resp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) 	resp->tagp = resp->xdr.p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) 	/* reserve space for: taglen, tag, and opcnt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) 	xdr_reserve_space(&resp->xdr, 8 + args->taglen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) 	resp->taglen = args->taglen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) 	resp->tag = args->tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) 	resp->rqstp = rqstp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) 	cstate->minorversion = args->minorversion;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) 	fh_init(current_fh, NFS4_FHSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) 	fh_init(save_fh, NFS4_FHSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) 	 * Don't use the deferral mechanism for NFSv4; compounds make it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) 	 * too hard to avoid non-idempotency problems.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) 	clear_bit(RQ_USEDEFERRAL, &rqstp->rq_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) 	 * According to RFC3010, this takes precedence over all other errors.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) 	status = nfserr_minor_vers_mismatch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) 	if (nfsd_minorversion(nn, args->minorversion, NFSD_TEST) <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) 	status = nfserr_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) 	if (args->opcnt > NFSD_MAX_OPS_PER_COMPOUND)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) 	status = nfs41_check_op_ordering(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) 	if (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) 		op = &args->ops[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) 		op->status = status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) 		resp->opcnt = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) 		goto encode_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) 	check_if_stalefh_allowed(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) 	rqstp->rq_lease_breaker = (void **)&cstate->clp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) 	trace_nfsd_compound(rqstp, args->opcnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) 	while (!status && resp->opcnt < args->opcnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) 		op = &args->ops[resp->opcnt++];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) 		 * The XDR decode routines may have pre-set op->status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) 		 * for example, if there is a miscellaneous XDR error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) 		 * it will be set to nfserr_bad_xdr.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) 		if (op->status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) 			if (op->opnum == OP_OPEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) 				op->status = nfsd4_open_omfg(rqstp, cstate, op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) 			goto encode_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) 		if (!current_fh->fh_dentry &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) 				!HAS_FH_FLAG(current_fh, NFSD4_FH_FOREIGN)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) 			if (!(op->opdesc->op_flags & ALLOWED_WITHOUT_FH)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) 				op->status = nfserr_nofilehandle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) 				goto encode_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) 		} else if (current_fh->fh_export &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) 			   current_fh->fh_export->ex_fslocs.migrated &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) 			  !(op->opdesc->op_flags & ALLOWED_ON_ABSENT_FS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) 			op->status = nfserr_moved;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) 			goto encode_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) 		fh_clear_wcc(current_fh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) 		/* If op is non-idempotent */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) 		if (op->opdesc->op_flags & OP_MODIFIES_SOMETHING) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) 			 * Don't execute this op if we couldn't encode a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) 			 * succesful reply:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) 			u32 plen = op->opdesc->op_rsize_bop(rqstp, op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) 			 * Plus if there's another operation, make sure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) 			 * we'll have space to at least encode an error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) 			if (resp->opcnt < args->opcnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) 				plen += COMPOUND_ERR_SLACK_SPACE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) 			op->status = nfsd4_check_resp_size(resp, plen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) 		if (op->status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) 			goto encode_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) 		if (op->opdesc->op_get_currentstateid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) 			op->opdesc->op_get_currentstateid(cstate, &op->u);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) 		op->status = op->opdesc->op_func(rqstp, cstate, &op->u);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) 		/* Only from SEQUENCE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) 		if (cstate->status == nfserr_replay_cache) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) 			dprintk("%s NFS4.1 replay from cache\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) 			status = op->status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) 		if (!op->status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) 			if (op->opdesc->op_set_currentstateid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) 				op->opdesc->op_set_currentstateid(cstate, &op->u);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) 			if (op->opdesc->op_flags & OP_CLEAR_STATEID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) 				clear_current_stateid(cstate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) 			if (current_fh->fh_export &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) 					need_wrongsec_check(rqstp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) 				op->status = check_nfsd_access(current_fh->fh_export, rqstp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) encode_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) 		if (op->status == nfserr_replay_me) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) 			op->replay = &cstate->replay_owner->so_replay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) 			nfsd4_encode_replay(&resp->xdr, op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) 			status = op->status = op->replay->rp_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) 			nfsd4_encode_operation(resp, op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) 			status = op->status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) 		trace_nfsd_compound_status(args->opcnt, resp->opcnt, status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) 					   nfsd4_op_name(op->opnum));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) 		nfsd4_cstate_clear_replay(cstate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) 		nfsd4_increment_op_stats(op->opnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) 	fh_put(current_fh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) 	fh_put(save_fh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) 	BUG_ON(cstate->replay_owner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) 	cstate->status = status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) 	/* Reset deferral mechanism for RPC deferrals */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) 	set_bit(RQ_USEDEFERRAL, &rqstp->rq_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) 	return rpc_success;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) #define op_encode_hdr_size		(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) #define op_encode_stateid_maxsz		(XDR_QUADLEN(NFS4_STATEID_SIZE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) #define op_encode_verifier_maxsz	(XDR_QUADLEN(NFS4_VERIFIER_SIZE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) #define op_encode_change_info_maxsz	(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) #define nfs4_fattr_bitmap_maxsz		(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) /* We'll fall back on returning no lockowner if run out of space: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) #define op_encode_lockowner_maxsz	(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) #define op_encode_lock_denied_maxsz	(8 + op_encode_lockowner_maxsz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) #define nfs4_owner_maxsz		(1 + XDR_QUADLEN(IDMAP_NAMESZ))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) #define op_encode_ace_maxsz		(3 + nfs4_owner_maxsz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) #define op_encode_delegation_maxsz	(1 + op_encode_stateid_maxsz + 1 + \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) 					 op_encode_ace_maxsz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) #define op_encode_channel_attrs_maxsz	(6 + 1 + 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) static inline u32 nfsd4_only_status_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) 	return (op_encode_hdr_size) * sizeof(__be32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) static inline u32 nfsd4_status_stateid_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) 	return (op_encode_hdr_size + op_encode_stateid_maxsz)* sizeof(__be32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) static inline u32 nfsd4_access_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) 	/* ac_supported, ac_resp_access */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) 	return (op_encode_hdr_size + 2)* sizeof(__be32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) static inline u32 nfsd4_commit_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) 	return (op_encode_hdr_size + op_encode_verifier_maxsz) * sizeof(__be32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) static inline u32 nfsd4_create_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) 	return (op_encode_hdr_size + op_encode_change_info_maxsz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) 		+ nfs4_fattr_bitmap_maxsz) * sizeof(__be32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515)  * Note since this is an idempotent operation we won't insist on failing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516)  * the op prematurely if the estimate is too large.  We may turn off splice
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517)  * reads unnecessarily.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) static inline u32 nfsd4_getattr_rsize(struct svc_rqst *rqstp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) 				      struct nfsd4_op *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) 	u32 *bmap = op->u.getattr.ga_bmval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) 	u32 bmap0 = bmap[0], bmap1 = bmap[1], bmap2 = bmap[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) 	u32 ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) 	if (bmap0 & FATTR4_WORD0_ACL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) 		return svc_max_payload(rqstp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) 	if (bmap0 & FATTR4_WORD0_FS_LOCATIONS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) 		return svc_max_payload(rqstp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) 	if (bmap1 & FATTR4_WORD1_OWNER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) 		ret += IDMAP_NAMESZ + 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) 		bmap1 &= ~FATTR4_WORD1_OWNER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) 	if (bmap1 & FATTR4_WORD1_OWNER_GROUP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) 		ret += IDMAP_NAMESZ + 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) 		bmap1 &= ~FATTR4_WORD1_OWNER_GROUP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539) 	if (bmap0 & FATTR4_WORD0_FILEHANDLE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540) 		ret += NFS4_FHSIZE + 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) 		bmap0 &= ~FATTR4_WORD0_FILEHANDLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) 	if (bmap2 & FATTR4_WORD2_SECURITY_LABEL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) 		ret += NFS4_MAXLABELLEN + 12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) 		bmap2 &= ~FATTR4_WORD2_SECURITY_LABEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) 	 * Largest of remaining attributes are 16 bytes (e.g.,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) 	 * supported_attributes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) 	ret += 16 * (hweight32(bmap0) + hweight32(bmap1) + hweight32(bmap2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552) 	/* bitmask, length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) 	ret += 20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) static inline u32 nfsd4_getfh_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) 	return (op_encode_hdr_size + 1) * sizeof(__be32) + NFS4_FHSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) static inline u32 nfsd4_link_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564) 	return (op_encode_hdr_size + op_encode_change_info_maxsz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) 		* sizeof(__be32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) static inline u32 nfsd4_lock_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) 	return (op_encode_hdr_size + op_encode_lock_denied_maxsz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) 		* sizeof(__be32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) static inline u32 nfsd4_open_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576) 	return (op_encode_hdr_size + op_encode_stateid_maxsz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577) 		+ op_encode_change_info_maxsz + 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) 		+ nfs4_fattr_bitmap_maxsz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579) 		+ op_encode_delegation_maxsz) * sizeof(__be32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582) static inline u32 nfsd4_read_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584) 	u32 maxcount = 0, rlen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586) 	maxcount = svc_max_payload(rqstp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) 	rlen = min(op->u.read.rd_length, maxcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589) 	return (op_encode_hdr_size + 2 + XDR_QUADLEN(rlen)) * sizeof(__be32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) static inline u32 nfsd4_read_plus_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594) 	u32 maxcount = svc_max_payload(rqstp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595) 	u32 rlen = min(op->u.read.rd_length, maxcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597) 	 * If we detect that the file changed during hole encoding, then we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) 	 * recover by encoding the remaining reply as data. This means we need
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599) 	 * to set aside enough room to encode two data segments.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) 	u32 seg_len = 2 * (1 + 2 + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) 	return (op_encode_hdr_size + 2 + seg_len + XDR_QUADLEN(rlen)) * sizeof(__be32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) static inline u32 nfsd4_readdir_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608) 	u32 maxcount = 0, rlen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610) 	maxcount = svc_max_payload(rqstp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) 	rlen = min(op->u.readdir.rd_maxcount, maxcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613) 	return (op_encode_hdr_size + op_encode_verifier_maxsz +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614) 		XDR_QUADLEN(rlen)) * sizeof(__be32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617) static inline u32 nfsd4_readlink_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) 	return (op_encode_hdr_size + 1) * sizeof(__be32) + PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622) static inline u32 nfsd4_remove_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624) 	return (op_encode_hdr_size + op_encode_change_info_maxsz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625) 		* sizeof(__be32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628) static inline u32 nfsd4_rename_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630) 	return (op_encode_hdr_size + op_encode_change_info_maxsz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) 		+ op_encode_change_info_maxsz) * sizeof(__be32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634) static inline u32 nfsd4_sequence_rsize(struct svc_rqst *rqstp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) 				       struct nfsd4_op *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637) 	return (op_encode_hdr_size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) 		+ XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + 5) * sizeof(__be32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) static inline u32 nfsd4_test_stateid_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643) 	return (op_encode_hdr_size + 1 + op->u.test_stateid.ts_num_ids)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644) 		* sizeof(__be32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647) static inline u32 nfsd4_setattr_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) 	return (op_encode_hdr_size + nfs4_fattr_bitmap_maxsz) * sizeof(__be32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652) static inline u32 nfsd4_secinfo_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654) 	return (op_encode_hdr_size + RPC_AUTH_MAXFLAVOR *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) 		(4 + XDR_QUADLEN(GSS_OID_MAX_LEN))) * sizeof(__be32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658) static inline u32 nfsd4_setclientid_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660) 	return (op_encode_hdr_size + 2 + XDR_QUADLEN(NFS4_VERIFIER_SIZE)) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661) 								sizeof(__be32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664) static inline u32 nfsd4_write_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666) 	return (op_encode_hdr_size + 2 + op_encode_verifier_maxsz) * sizeof(__be32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669) static inline u32 nfsd4_exchange_id_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671) 	return (op_encode_hdr_size + 2 + 1 + /* eir_clientid, eir_sequenceid */\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672) 		1 + 1 + /* eir_flags, spr_how */\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) 		4 + /* spo_must_enforce & _allow with bitmap */\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674) 		2 + /*eir_server_owner.so_minor_id */\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675) 		/* eir_server_owner.so_major_id<> */\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676) 		XDR_QUADLEN(NFS4_OPAQUE_LIMIT) + 1 +\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) 		/* eir_server_scope<> */\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678) 		XDR_QUADLEN(NFS4_OPAQUE_LIMIT) + 1 +\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679) 		1 + /* eir_server_impl_id array length */\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680) 		0 /* ignored eir_server_impl_id contents */) * sizeof(__be32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683) static inline u32 nfsd4_bind_conn_to_session_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685) 	return (op_encode_hdr_size + \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686) 		XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + /* bctsr_sessid */\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687) 		2 /* bctsr_dir, use_conn_in_rdma_mode */) * sizeof(__be32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690) static inline u32 nfsd4_create_session_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692) 	return (op_encode_hdr_size + \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693) 		XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + /* sessionid */\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694) 		2 + /* csr_sequence, csr_flags */\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695) 		op_encode_channel_attrs_maxsz + \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696) 		op_encode_channel_attrs_maxsz) * sizeof(__be32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699) static inline u32 nfsd4_copy_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701) 	return (op_encode_hdr_size +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702) 		1 /* wr_callback */ +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703) 		op_encode_stateid_maxsz /* wr_callback */ +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704) 		2 /* wr_count */ +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705) 		1 /* wr_committed */ +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706) 		op_encode_verifier_maxsz +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707) 		1 /* cr_consecutive */ +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708) 		1 /* cr_synchronous */) * sizeof(__be32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711) static inline u32 nfsd4_offload_status_rsize(struct svc_rqst *rqstp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712) 					     struct nfsd4_op *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714) 	return (op_encode_hdr_size +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715) 		2 /* osr_count */ +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716) 		1 /* osr_complete<1> optional 0 for now */) * sizeof(__be32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719) static inline u32 nfsd4_copy_notify_rsize(struct svc_rqst *rqstp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720) 					struct nfsd4_op *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722) 	return (op_encode_hdr_size +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723) 		3 /* cnr_lease_time */ +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724) 		1 /* We support one cnr_source_server */ +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725) 		1 /* cnr_stateid seq */ +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726) 		op_encode_stateid_maxsz /* cnr_stateid */ +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727) 		1 /* num cnr_source_server*/ +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728) 		1 /* nl4_type */ +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729) 		1 /* nl4 size */ +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730) 		XDR_QUADLEN(NFS4_OPAQUE_LIMIT) /*nl4_loc + nl4_loc_sz */)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731) 		* sizeof(__be32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734) #ifdef CONFIG_NFSD_PNFS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735) static inline u32 nfsd4_getdeviceinfo_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737) 	u32 maxcount = 0, rlen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739) 	maxcount = svc_max_payload(rqstp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740) 	rlen = min(op->u.getdeviceinfo.gd_maxcount, maxcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742) 	return (op_encode_hdr_size +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743) 		1 /* gd_layout_type*/ +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744) 		XDR_QUADLEN(rlen) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745) 		2 /* gd_notify_types */) * sizeof(__be32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749)  * At this stage we don't really know what layout driver will handle the request,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750)  * so we need to define an arbitrary upper bound here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752) #define MAX_LAYOUT_SIZE		128
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753) static inline u32 nfsd4_layoutget_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755) 	return (op_encode_hdr_size +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2756) 		1 /* logr_return_on_close */ +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2757) 		op_encode_stateid_maxsz +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2758) 		1 /* nr of layouts */ +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2759) 		MAX_LAYOUT_SIZE) * sizeof(__be32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2760) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2761) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2762) static inline u32 nfsd4_layoutcommit_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2763) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2764) 	return (op_encode_hdr_size +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2765) 		1 /* locr_newsize */ +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2766) 		2 /* ns_size */) * sizeof(__be32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2767) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2768) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2769) static inline u32 nfsd4_layoutreturn_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2770) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2771) 	return (op_encode_hdr_size +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2772) 		1 /* lrs_stateid */ +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2773) 		op_encode_stateid_maxsz) * sizeof(__be32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2774) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2775) #endif /* CONFIG_NFSD_PNFS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2776) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2777) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2778) static inline u32 nfsd4_seek_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2779) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2780) 	return (op_encode_hdr_size + 3) * sizeof(__be32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2781) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2782) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2783) static inline u32 nfsd4_getxattr_rsize(struct svc_rqst *rqstp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2784) 				       struct nfsd4_op *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2785) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2786) 	u32 maxcount, rlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2787) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2788) 	maxcount = svc_max_payload(rqstp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2789) 	rlen = min_t(u32, XATTR_SIZE_MAX, maxcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2790) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2791) 	return (op_encode_hdr_size + 1 + XDR_QUADLEN(rlen)) * sizeof(__be32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2792) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2793) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2794) static inline u32 nfsd4_setxattr_rsize(struct svc_rqst *rqstp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2795) 				       struct nfsd4_op *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2796) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2797) 	return (op_encode_hdr_size + op_encode_change_info_maxsz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2798) 		* sizeof(__be32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2799) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2800) static inline u32 nfsd4_listxattrs_rsize(struct svc_rqst *rqstp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2801) 					 struct nfsd4_op *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2802) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2803) 	u32 maxcount, rlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2804) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2805) 	maxcount = svc_max_payload(rqstp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2806) 	rlen = min(op->u.listxattrs.lsxa_maxcount, maxcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2807) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2808) 	return (op_encode_hdr_size + 4 + XDR_QUADLEN(rlen)) * sizeof(__be32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2809) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2810) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2811) static inline u32 nfsd4_removexattr_rsize(struct svc_rqst *rqstp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2812) 					  struct nfsd4_op *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2813) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2814) 	return (op_encode_hdr_size + op_encode_change_info_maxsz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2815) 		* sizeof(__be32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2816) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2817) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2818) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2819) static const struct nfsd4_operation nfsd4_ops[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2820) 	[OP_ACCESS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2821) 		.op_func = nfsd4_access,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2822) 		.op_name = "OP_ACCESS",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2823) 		.op_rsize_bop = nfsd4_access_rsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2824) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2825) 	[OP_CLOSE] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2826) 		.op_func = nfsd4_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2827) 		.op_flags = OP_MODIFIES_SOMETHING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2828) 		.op_name = "OP_CLOSE",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2829) 		.op_rsize_bop = nfsd4_status_stateid_rsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2830) 		.op_get_currentstateid = nfsd4_get_closestateid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2831) 		.op_set_currentstateid = nfsd4_set_closestateid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2832) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2833) 	[OP_COMMIT] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2834) 		.op_func = nfsd4_commit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2835) 		.op_flags = OP_MODIFIES_SOMETHING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2836) 		.op_name = "OP_COMMIT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2837) 		.op_rsize_bop = nfsd4_commit_rsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2838) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2839) 	[OP_CREATE] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2840) 		.op_func = nfsd4_create,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2841) 		.op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME | OP_CLEAR_STATEID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2842) 		.op_name = "OP_CREATE",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2843) 		.op_rsize_bop = nfsd4_create_rsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2844) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2845) 	[OP_DELEGRETURN] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2846) 		.op_func = nfsd4_delegreturn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2847) 		.op_flags = OP_MODIFIES_SOMETHING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2848) 		.op_name = "OP_DELEGRETURN",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2849) 		.op_rsize_bop = nfsd4_only_status_rsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2850) 		.op_get_currentstateid = nfsd4_get_delegreturnstateid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2851) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2852) 	[OP_GETATTR] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2853) 		.op_func = nfsd4_getattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2854) 		.op_flags = ALLOWED_ON_ABSENT_FS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2855) 		.op_rsize_bop = nfsd4_getattr_rsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2856) 		.op_name = "OP_GETATTR",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2857) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2858) 	[OP_GETFH] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2859) 		.op_func = nfsd4_getfh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2860) 		.op_name = "OP_GETFH",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2861) 		.op_rsize_bop = nfsd4_getfh_rsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2862) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2863) 	[OP_LINK] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2864) 		.op_func = nfsd4_link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2865) 		.op_flags = ALLOWED_ON_ABSENT_FS | OP_MODIFIES_SOMETHING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2866) 				| OP_CACHEME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2867) 		.op_name = "OP_LINK",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2868) 		.op_rsize_bop = nfsd4_link_rsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2869) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2870) 	[OP_LOCK] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2871) 		.op_func = nfsd4_lock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2872) 		.op_flags = OP_MODIFIES_SOMETHING |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2873) 				OP_NONTRIVIAL_ERROR_ENCODE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2874) 		.op_name = "OP_LOCK",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2875) 		.op_rsize_bop = nfsd4_lock_rsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2876) 		.op_set_currentstateid = nfsd4_set_lockstateid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2877) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2878) 	[OP_LOCKT] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2879) 		.op_func = nfsd4_lockt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2880) 		.op_flags = OP_NONTRIVIAL_ERROR_ENCODE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2881) 		.op_name = "OP_LOCKT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2882) 		.op_rsize_bop = nfsd4_lock_rsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2883) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2884) 	[OP_LOCKU] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2885) 		.op_func = nfsd4_locku,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2886) 		.op_flags = OP_MODIFIES_SOMETHING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2887) 		.op_name = "OP_LOCKU",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2888) 		.op_rsize_bop = nfsd4_status_stateid_rsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2889) 		.op_get_currentstateid = nfsd4_get_lockustateid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2890) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2891) 	[OP_LOOKUP] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2892) 		.op_func = nfsd4_lookup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2893) 		.op_flags = OP_HANDLES_WRONGSEC | OP_CLEAR_STATEID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2894) 		.op_name = "OP_LOOKUP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2895) 		.op_rsize_bop = nfsd4_only_status_rsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2896) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2897) 	[OP_LOOKUPP] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2898) 		.op_func = nfsd4_lookupp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2899) 		.op_flags = OP_HANDLES_WRONGSEC | OP_CLEAR_STATEID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2900) 		.op_name = "OP_LOOKUPP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2901) 		.op_rsize_bop = nfsd4_only_status_rsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2902) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2903) 	[OP_NVERIFY] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2904) 		.op_func = nfsd4_nverify,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2905) 		.op_name = "OP_NVERIFY",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2906) 		.op_rsize_bop = nfsd4_only_status_rsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2907) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2908) 	[OP_OPEN] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2909) 		.op_func = nfsd4_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2910) 		.op_flags = OP_HANDLES_WRONGSEC | OP_MODIFIES_SOMETHING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2911) 		.op_name = "OP_OPEN",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2912) 		.op_rsize_bop = nfsd4_open_rsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2913) 		.op_set_currentstateid = nfsd4_set_openstateid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2914) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2915) 	[OP_OPEN_CONFIRM] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2916) 		.op_func = nfsd4_open_confirm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2917) 		.op_flags = OP_MODIFIES_SOMETHING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2918) 		.op_name = "OP_OPEN_CONFIRM",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2919) 		.op_rsize_bop = nfsd4_status_stateid_rsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2920) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2921) 	[OP_OPEN_DOWNGRADE] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2922) 		.op_func = nfsd4_open_downgrade,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2923) 		.op_flags = OP_MODIFIES_SOMETHING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2924) 		.op_name = "OP_OPEN_DOWNGRADE",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2925) 		.op_rsize_bop = nfsd4_status_stateid_rsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2926) 		.op_get_currentstateid = nfsd4_get_opendowngradestateid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2927) 		.op_set_currentstateid = nfsd4_set_opendowngradestateid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2928) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2929) 	[OP_PUTFH] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2930) 		.op_func = nfsd4_putfh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2931) 		.op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2932) 				| OP_IS_PUTFH_LIKE | OP_CLEAR_STATEID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2933) 		.op_name = "OP_PUTFH",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2934) 		.op_rsize_bop = nfsd4_only_status_rsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2935) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2936) 	[OP_PUTPUBFH] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2937) 		.op_func = nfsd4_putrootfh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2938) 		.op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2939) 				| OP_IS_PUTFH_LIKE | OP_CLEAR_STATEID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2940) 		.op_name = "OP_PUTPUBFH",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2941) 		.op_rsize_bop = nfsd4_only_status_rsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2942) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2943) 	[OP_PUTROOTFH] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2944) 		.op_func = nfsd4_putrootfh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2945) 		.op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2946) 				| OP_IS_PUTFH_LIKE | OP_CLEAR_STATEID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2947) 		.op_name = "OP_PUTROOTFH",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2948) 		.op_rsize_bop = nfsd4_only_status_rsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2949) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2950) 	[OP_READ] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2951) 		.op_func = nfsd4_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2952) 		.op_release = nfsd4_read_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2953) 		.op_name = "OP_READ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2954) 		.op_rsize_bop = nfsd4_read_rsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2955) 		.op_get_currentstateid = nfsd4_get_readstateid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2956) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2957) 	[OP_READDIR] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2958) 		.op_func = nfsd4_readdir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2959) 		.op_name = "OP_READDIR",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2960) 		.op_rsize_bop = nfsd4_readdir_rsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2961) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2962) 	[OP_READLINK] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2963) 		.op_func = nfsd4_readlink,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2964) 		.op_name = "OP_READLINK",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2965) 		.op_rsize_bop = nfsd4_readlink_rsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2966) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2967) 	[OP_REMOVE] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2968) 		.op_func = nfsd4_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2969) 		.op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2970) 		.op_name = "OP_REMOVE",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2971) 		.op_rsize_bop = nfsd4_remove_rsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2972) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2973) 	[OP_RENAME] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2974) 		.op_func = nfsd4_rename,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2975) 		.op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2976) 		.op_name = "OP_RENAME",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2977) 		.op_rsize_bop = nfsd4_rename_rsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2978) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2979) 	[OP_RENEW] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2980) 		.op_func = nfsd4_renew,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2981) 		.op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2982) 				| OP_MODIFIES_SOMETHING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2983) 		.op_name = "OP_RENEW",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2984) 		.op_rsize_bop = nfsd4_only_status_rsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2985) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2986) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2987) 	[OP_RESTOREFH] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2988) 		.op_func = nfsd4_restorefh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2989) 		.op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2990) 				| OP_IS_PUTFH_LIKE | OP_MODIFIES_SOMETHING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2991) 		.op_name = "OP_RESTOREFH",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2992) 		.op_rsize_bop = nfsd4_only_status_rsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2993) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2994) 	[OP_SAVEFH] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2995) 		.op_func = nfsd4_savefh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2996) 		.op_flags = OP_HANDLES_WRONGSEC | OP_MODIFIES_SOMETHING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2997) 		.op_name = "OP_SAVEFH",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2998) 		.op_rsize_bop = nfsd4_only_status_rsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2999) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3000) 	[OP_SECINFO] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3001) 		.op_func = nfsd4_secinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3002) 		.op_release = nfsd4_secinfo_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3003) 		.op_flags = OP_HANDLES_WRONGSEC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3004) 		.op_name = "OP_SECINFO",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3005) 		.op_rsize_bop = nfsd4_secinfo_rsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3006) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3007) 	[OP_SETATTR] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3008) 		.op_func = nfsd4_setattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3009) 		.op_name = "OP_SETATTR",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3010) 		.op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3011) 				| OP_NONTRIVIAL_ERROR_ENCODE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3012) 		.op_rsize_bop = nfsd4_setattr_rsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3013) 		.op_get_currentstateid = nfsd4_get_setattrstateid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3014) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3015) 	[OP_SETCLIENTID] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3016) 		.op_func = nfsd4_setclientid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3017) 		.op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3018) 				| OP_MODIFIES_SOMETHING | OP_CACHEME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3019) 				| OP_NONTRIVIAL_ERROR_ENCODE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3020) 		.op_name = "OP_SETCLIENTID",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3021) 		.op_rsize_bop = nfsd4_setclientid_rsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3022) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3023) 	[OP_SETCLIENTID_CONFIRM] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3024) 		.op_func = nfsd4_setclientid_confirm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3025) 		.op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3026) 				| OP_MODIFIES_SOMETHING | OP_CACHEME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3027) 		.op_name = "OP_SETCLIENTID_CONFIRM",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3028) 		.op_rsize_bop = nfsd4_only_status_rsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3029) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3030) 	[OP_VERIFY] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3031) 		.op_func = nfsd4_verify,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3032) 		.op_name = "OP_VERIFY",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3033) 		.op_rsize_bop = nfsd4_only_status_rsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3034) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3035) 	[OP_WRITE] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3036) 		.op_func = nfsd4_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3037) 		.op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3038) 		.op_name = "OP_WRITE",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3039) 		.op_rsize_bop = nfsd4_write_rsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3040) 		.op_get_currentstateid = nfsd4_get_writestateid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3041) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3042) 	[OP_RELEASE_LOCKOWNER] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3043) 		.op_func = nfsd4_release_lockowner,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3044) 		.op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3045) 				| OP_MODIFIES_SOMETHING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3046) 		.op_name = "OP_RELEASE_LOCKOWNER",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3047) 		.op_rsize_bop = nfsd4_only_status_rsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3048) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3049) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3050) 	/* NFSv4.1 operations */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3051) 	[OP_EXCHANGE_ID] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3052) 		.op_func = nfsd4_exchange_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3053) 		.op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3054) 				| OP_MODIFIES_SOMETHING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3055) 		.op_name = "OP_EXCHANGE_ID",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3056) 		.op_rsize_bop = nfsd4_exchange_id_rsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3057) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3058) 	[OP_BACKCHANNEL_CTL] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3059) 		.op_func = nfsd4_backchannel_ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3060) 		.op_flags = ALLOWED_WITHOUT_FH | OP_MODIFIES_SOMETHING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3061) 		.op_name = "OP_BACKCHANNEL_CTL",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3062) 		.op_rsize_bop = nfsd4_only_status_rsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3063) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3064) 	[OP_BIND_CONN_TO_SESSION] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3065) 		.op_func = nfsd4_bind_conn_to_session,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3066) 		.op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3067) 				| OP_MODIFIES_SOMETHING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3068) 		.op_name = "OP_BIND_CONN_TO_SESSION",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3069) 		.op_rsize_bop = nfsd4_bind_conn_to_session_rsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3070) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3071) 	[OP_CREATE_SESSION] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3072) 		.op_func = nfsd4_create_session,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3073) 		.op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3074) 				| OP_MODIFIES_SOMETHING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3075) 		.op_name = "OP_CREATE_SESSION",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3076) 		.op_rsize_bop = nfsd4_create_session_rsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3077) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3078) 	[OP_DESTROY_SESSION] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3079) 		.op_func = nfsd4_destroy_session,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3080) 		.op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3081) 				| OP_MODIFIES_SOMETHING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3082) 		.op_name = "OP_DESTROY_SESSION",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3083) 		.op_rsize_bop = nfsd4_only_status_rsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3084) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3085) 	[OP_SEQUENCE] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3086) 		.op_func = nfsd4_sequence,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3087) 		.op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3088) 		.op_name = "OP_SEQUENCE",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3089) 		.op_rsize_bop = nfsd4_sequence_rsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3090) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3091) 	[OP_DESTROY_CLIENTID] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3092) 		.op_func = nfsd4_destroy_clientid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3093) 		.op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3094) 				| OP_MODIFIES_SOMETHING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3095) 		.op_name = "OP_DESTROY_CLIENTID",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3096) 		.op_rsize_bop = nfsd4_only_status_rsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3097) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3098) 	[OP_RECLAIM_COMPLETE] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3099) 		.op_func = nfsd4_reclaim_complete,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3100) 		.op_flags = ALLOWED_WITHOUT_FH | OP_MODIFIES_SOMETHING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3101) 		.op_name = "OP_RECLAIM_COMPLETE",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3102) 		.op_rsize_bop = nfsd4_only_status_rsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3103) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3104) 	[OP_SECINFO_NO_NAME] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3105) 		.op_func = nfsd4_secinfo_no_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3106) 		.op_release = nfsd4_secinfo_no_name_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3107) 		.op_flags = OP_HANDLES_WRONGSEC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3108) 		.op_name = "OP_SECINFO_NO_NAME",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3109) 		.op_rsize_bop = nfsd4_secinfo_rsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3110) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3111) 	[OP_TEST_STATEID] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3112) 		.op_func = nfsd4_test_stateid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3113) 		.op_flags = ALLOWED_WITHOUT_FH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3114) 		.op_name = "OP_TEST_STATEID",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3115) 		.op_rsize_bop = nfsd4_test_stateid_rsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3116) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3117) 	[OP_FREE_STATEID] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3118) 		.op_func = nfsd4_free_stateid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3119) 		.op_flags = ALLOWED_WITHOUT_FH | OP_MODIFIES_SOMETHING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3120) 		.op_name = "OP_FREE_STATEID",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3121) 		.op_get_currentstateid = nfsd4_get_freestateid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3122) 		.op_rsize_bop = nfsd4_only_status_rsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3123) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3124) #ifdef CONFIG_NFSD_PNFS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3125) 	[OP_GETDEVICEINFO] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3126) 		.op_func = nfsd4_getdeviceinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3127) 		.op_release = nfsd4_getdeviceinfo_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3128) 		.op_flags = ALLOWED_WITHOUT_FH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3129) 		.op_name = "OP_GETDEVICEINFO",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3130) 		.op_rsize_bop = nfsd4_getdeviceinfo_rsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3131) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3132) 	[OP_LAYOUTGET] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3133) 		.op_func = nfsd4_layoutget,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3134) 		.op_release = nfsd4_layoutget_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3135) 		.op_flags = OP_MODIFIES_SOMETHING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3136) 		.op_name = "OP_LAYOUTGET",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3137) 		.op_rsize_bop = nfsd4_layoutget_rsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3138) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3139) 	[OP_LAYOUTCOMMIT] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3140) 		.op_func = nfsd4_layoutcommit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3141) 		.op_flags = OP_MODIFIES_SOMETHING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3142) 		.op_name = "OP_LAYOUTCOMMIT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3143) 		.op_rsize_bop = nfsd4_layoutcommit_rsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3144) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3145) 	[OP_LAYOUTRETURN] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3146) 		.op_func = nfsd4_layoutreturn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3147) 		.op_flags = OP_MODIFIES_SOMETHING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3148) 		.op_name = "OP_LAYOUTRETURN",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3149) 		.op_rsize_bop = nfsd4_layoutreturn_rsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3150) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3151) #endif /* CONFIG_NFSD_PNFS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3152) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3153) 	/* NFSv4.2 operations */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3154) 	[OP_ALLOCATE] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3155) 		.op_func = nfsd4_allocate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3156) 		.op_flags = OP_MODIFIES_SOMETHING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3157) 		.op_name = "OP_ALLOCATE",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3158) 		.op_rsize_bop = nfsd4_only_status_rsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3159) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3160) 	[OP_DEALLOCATE] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3161) 		.op_func = nfsd4_deallocate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3162) 		.op_flags = OP_MODIFIES_SOMETHING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3163) 		.op_name = "OP_DEALLOCATE",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3164) 		.op_rsize_bop = nfsd4_only_status_rsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3165) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3166) 	[OP_CLONE] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3167) 		.op_func = nfsd4_clone,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3168) 		.op_flags = OP_MODIFIES_SOMETHING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3169) 		.op_name = "OP_CLONE",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3170) 		.op_rsize_bop = nfsd4_only_status_rsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3171) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3172) 	[OP_COPY] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3173) 		.op_func = nfsd4_copy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3174) 		.op_flags = OP_MODIFIES_SOMETHING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3175) 		.op_name = "OP_COPY",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3176) 		.op_rsize_bop = nfsd4_copy_rsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3177) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3178) 	[OP_READ_PLUS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3179) 		.op_func = nfsd4_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3180) 		.op_release = nfsd4_read_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3181) 		.op_name = "OP_READ_PLUS",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3182) 		.op_rsize_bop = nfsd4_read_plus_rsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3183) 		.op_get_currentstateid = nfsd4_get_readstateid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3184) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3185) 	[OP_SEEK] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3186) 		.op_func = nfsd4_seek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3187) 		.op_name = "OP_SEEK",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3188) 		.op_rsize_bop = nfsd4_seek_rsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3189) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3190) 	[OP_OFFLOAD_STATUS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3191) 		.op_func = nfsd4_offload_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3192) 		.op_name = "OP_OFFLOAD_STATUS",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3193) 		.op_rsize_bop = nfsd4_offload_status_rsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3194) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3195) 	[OP_OFFLOAD_CANCEL] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3196) 		.op_func = nfsd4_offload_cancel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3197) 		.op_flags = OP_MODIFIES_SOMETHING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3198) 		.op_name = "OP_OFFLOAD_CANCEL",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3199) 		.op_rsize_bop = nfsd4_only_status_rsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3200) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3201) 	[OP_COPY_NOTIFY] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3202) 		.op_func = nfsd4_copy_notify,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3203) 		.op_flags = OP_MODIFIES_SOMETHING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3204) 		.op_name = "OP_COPY_NOTIFY",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3205) 		.op_rsize_bop = nfsd4_copy_notify_rsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3206) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3207) 	[OP_GETXATTR] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3208) 		.op_func = nfsd4_getxattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3209) 		.op_name = "OP_GETXATTR",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3210) 		.op_rsize_bop = nfsd4_getxattr_rsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3211) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3212) 	[OP_SETXATTR] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3213) 		.op_func = nfsd4_setxattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3214) 		.op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3215) 		.op_name = "OP_SETXATTR",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3216) 		.op_rsize_bop = nfsd4_setxattr_rsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3217) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3218) 	[OP_LISTXATTRS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3219) 		.op_func = nfsd4_listxattrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3220) 		.op_name = "OP_LISTXATTRS",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3221) 		.op_rsize_bop = nfsd4_listxattrs_rsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3222) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3223) 	[OP_REMOVEXATTR] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3224) 		.op_func = nfsd4_removexattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3225) 		.op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3226) 		.op_name = "OP_REMOVEXATTR",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3227) 		.op_rsize_bop = nfsd4_removexattr_rsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3228) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3229) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3231) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3232)  * nfsd4_spo_must_allow - Determine if the compound op contains an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3233)  * operation that is allowed to be sent with machine credentials
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3234)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3235)  * @rqstp: a pointer to the struct svc_rqst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3236)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3237)  * Checks to see if the compound contains a spo_must_allow op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3238)  * and confirms that it was sent with the proper machine creds.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3239)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3240) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3241) bool nfsd4_spo_must_allow(struct svc_rqst *rqstp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3242) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3243) 	struct nfsd4_compoundres *resp = rqstp->rq_resp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3244) 	struct nfsd4_compoundargs *argp = rqstp->rq_argp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3245) 	struct nfsd4_op *this = &argp->ops[resp->opcnt - 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3246) 	struct nfsd4_compound_state *cstate = &resp->cstate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3247) 	struct nfs4_op_map *allow = &cstate->clp->cl_spo_must_allow;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3248) 	u32 opiter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3249) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3250) 	if (!cstate->minorversion)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3251) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3252) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3253) 	if (cstate->spo_must_allowed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3254) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3255) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3256) 	opiter = resp->opcnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3257) 	while (opiter < argp->opcnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3258) 		this = &argp->ops[opiter++];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3259) 		if (test_bit(this->opnum, allow->u.longs) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3260) 			cstate->clp->cl_mach_cred &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3261) 			nfsd4_mach_creds_match(cstate->clp, rqstp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3262) 			cstate->spo_must_allowed = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3263) 			return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3264) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3265) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3266) 	cstate->spo_must_allowed = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3267) 	return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3269) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3270) int nfsd4_max_reply(struct svc_rqst *rqstp, struct nfsd4_op *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3271) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3272) 	if (op->opnum == OP_ILLEGAL || op->status == nfserr_notsupp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3273) 		return op_encode_hdr_size * sizeof(__be32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3274) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3275) 	BUG_ON(OPDESC(op)->op_rsize_bop == NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3276) 	return OPDESC(op)->op_rsize_bop(rqstp, op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3279) void warn_on_nonidempotent_op(struct nfsd4_op *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3280) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3281) 	if (OPDESC(op)->op_flags & OP_MODIFIES_SOMETHING) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3282) 		pr_err("unable to encode reply to nonidempotent op %d (%s)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3283) 			op->opnum, nfsd4_op_name(op->opnum));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3284) 		WARN_ON_ONCE(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3285) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3288) static const char *nfsd4_op_name(unsigned opnum)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3289) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3290) 	if (opnum < ARRAY_SIZE(nfsd4_ops))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3291) 		return nfsd4_ops[opnum].op_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3292) 	return "unknown_operation";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3293) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3294) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3295) #define nfsd4_voidres			nfsd4_voidargs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3296) struct nfsd4_voidargs { int dummy; };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3297) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3298) static const struct svc_procedure nfsd_procedures4[2] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3299) 	[NFSPROC4_NULL] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3300) 		.pc_func = nfsd4_proc_null,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3301) 		.pc_decode = nfs4svc_decode_voidarg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3302) 		.pc_encode = nfs4svc_encode_voidres,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3303) 		.pc_argsize = sizeof(struct nfsd4_voidargs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3304) 		.pc_ressize = sizeof(struct nfsd4_voidres),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3305) 		.pc_cachetype = RC_NOCACHE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3306) 		.pc_xdrressize = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3307) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3308) 	[NFSPROC4_COMPOUND] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3309) 		.pc_func = nfsd4_proc_compound,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3310) 		.pc_decode = nfs4svc_decode_compoundargs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3311) 		.pc_encode = nfs4svc_encode_compoundres,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3312) 		.pc_argsize = sizeof(struct nfsd4_compoundargs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3313) 		.pc_ressize = sizeof(struct nfsd4_compoundres),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3314) 		.pc_release = nfsd4_release_compoundargs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3315) 		.pc_cachetype = RC_NOCACHE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3316) 		.pc_xdrressize = NFSD_BUFSIZE/4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3317) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3318) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3319) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3320) static unsigned int nfsd_count3[ARRAY_SIZE(nfsd_procedures4)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3321) const struct svc_version nfsd_version4 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3322) 	.vs_vers		= 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3323) 	.vs_nproc		= 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3324) 	.vs_proc		= nfsd_procedures4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3325) 	.vs_count		= nfsd_count3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3326) 	.vs_dispatch		= nfsd_dispatch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3327) 	.vs_xdrsize		= NFS4_SVC_XDRSIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3328) 	.vs_rpcb_optnl		= true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3329) 	.vs_need_cong_ctrl	= true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3330) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3331) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3332) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3333)  * Local variables:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3334)  *  c-basic-offset: 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3335)  * End:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3336)  */