^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(©->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(©->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(©->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(©->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 = ©->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) ©->cp_dst_stateid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) WR_STATE, ©->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(©->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, ©->cp_src_stateid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) ©->nf_src, ©->cp_dst_stateid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) ©->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(©->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(©->cp_clp->async_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) list_del(©->copies);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) spin_unlock(©->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, ©->c_fh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) ©->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, ©->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, ©->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) ©->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(©->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(©->cp_res.cb_stateid, ©->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(©->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(©->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) */