162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Process version 3 NFS requests. 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (C) 1996, 1997, 1998 Olaf Kirch <okir@monad.swb.de> 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#include <linux/fs.h> 962306a36Sopenharmony_ci#include <linux/ext2_fs.h> 1062306a36Sopenharmony_ci#include <linux/magic.h> 1162306a36Sopenharmony_ci#include <linux/namei.h> 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci#include "cache.h" 1462306a36Sopenharmony_ci#include "xdr3.h" 1562306a36Sopenharmony_ci#include "vfs.h" 1662306a36Sopenharmony_ci#include "filecache.h" 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci#define NFSDDBG_FACILITY NFSDDBG_PROC 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_cistatic int nfs3_ftypes[] = { 2162306a36Sopenharmony_ci 0, /* NF3NON */ 2262306a36Sopenharmony_ci S_IFREG, /* NF3REG */ 2362306a36Sopenharmony_ci S_IFDIR, /* NF3DIR */ 2462306a36Sopenharmony_ci S_IFBLK, /* NF3BLK */ 2562306a36Sopenharmony_ci S_IFCHR, /* NF3CHR */ 2662306a36Sopenharmony_ci S_IFLNK, /* NF3LNK */ 2762306a36Sopenharmony_ci S_IFSOCK, /* NF3SOCK */ 2862306a36Sopenharmony_ci S_IFIFO, /* NF3FIFO */ 2962306a36Sopenharmony_ci}; 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_ci/* 3262306a36Sopenharmony_ci * NULL call. 3362306a36Sopenharmony_ci */ 3462306a36Sopenharmony_cistatic __be32 3562306a36Sopenharmony_cinfsd3_proc_null(struct svc_rqst *rqstp) 3662306a36Sopenharmony_ci{ 3762306a36Sopenharmony_ci return rpc_success; 3862306a36Sopenharmony_ci} 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ci/* 4162306a36Sopenharmony_ci * Get a file's attributes 4262306a36Sopenharmony_ci */ 4362306a36Sopenharmony_cistatic __be32 4462306a36Sopenharmony_cinfsd3_proc_getattr(struct svc_rqst *rqstp) 4562306a36Sopenharmony_ci{ 4662306a36Sopenharmony_ci struct nfsd_fhandle *argp = rqstp->rq_argp; 4762306a36Sopenharmony_ci struct nfsd3_attrstat *resp = rqstp->rq_resp; 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_ci dprintk("nfsd: GETATTR(3) %s\n", 5062306a36Sopenharmony_ci SVCFH_fmt(&argp->fh)); 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ci fh_copy(&resp->fh, &argp->fh); 5362306a36Sopenharmony_ci resp->status = fh_verify(rqstp, &resp->fh, 0, 5462306a36Sopenharmony_ci NFSD_MAY_NOP | NFSD_MAY_BYPASS_GSS_ON_ROOT); 5562306a36Sopenharmony_ci if (resp->status != nfs_ok) 5662306a36Sopenharmony_ci goto out; 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_ci resp->status = fh_getattr(&resp->fh, &resp->stat); 5962306a36Sopenharmony_ciout: 6062306a36Sopenharmony_ci return rpc_success; 6162306a36Sopenharmony_ci} 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_ci/* 6462306a36Sopenharmony_ci * Set a file's attributes 6562306a36Sopenharmony_ci */ 6662306a36Sopenharmony_cistatic __be32 6762306a36Sopenharmony_cinfsd3_proc_setattr(struct svc_rqst *rqstp) 6862306a36Sopenharmony_ci{ 6962306a36Sopenharmony_ci struct nfsd3_sattrargs *argp = rqstp->rq_argp; 7062306a36Sopenharmony_ci struct nfsd3_attrstat *resp = rqstp->rq_resp; 7162306a36Sopenharmony_ci struct nfsd_attrs attrs = { 7262306a36Sopenharmony_ci .na_iattr = &argp->attrs, 7362306a36Sopenharmony_ci }; 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_ci dprintk("nfsd: SETATTR(3) %s\n", 7662306a36Sopenharmony_ci SVCFH_fmt(&argp->fh)); 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_ci fh_copy(&resp->fh, &argp->fh); 7962306a36Sopenharmony_ci resp->status = nfsd_setattr(rqstp, &resp->fh, &attrs, 8062306a36Sopenharmony_ci argp->check_guard, argp->guardtime); 8162306a36Sopenharmony_ci return rpc_success; 8262306a36Sopenharmony_ci} 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_ci/* 8562306a36Sopenharmony_ci * Look up a path name component 8662306a36Sopenharmony_ci */ 8762306a36Sopenharmony_cistatic __be32 8862306a36Sopenharmony_cinfsd3_proc_lookup(struct svc_rqst *rqstp) 8962306a36Sopenharmony_ci{ 9062306a36Sopenharmony_ci struct nfsd3_diropargs *argp = rqstp->rq_argp; 9162306a36Sopenharmony_ci struct nfsd3_diropres *resp = rqstp->rq_resp; 9262306a36Sopenharmony_ci 9362306a36Sopenharmony_ci dprintk("nfsd: LOOKUP(3) %s %.*s\n", 9462306a36Sopenharmony_ci SVCFH_fmt(&argp->fh), 9562306a36Sopenharmony_ci argp->len, 9662306a36Sopenharmony_ci argp->name); 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_ci fh_copy(&resp->dirfh, &argp->fh); 9962306a36Sopenharmony_ci fh_init(&resp->fh, NFS3_FHSIZE); 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_ci resp->status = nfsd_lookup(rqstp, &resp->dirfh, 10262306a36Sopenharmony_ci argp->name, argp->len, 10362306a36Sopenharmony_ci &resp->fh); 10462306a36Sopenharmony_ci return rpc_success; 10562306a36Sopenharmony_ci} 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_ci/* 10862306a36Sopenharmony_ci * Check file access 10962306a36Sopenharmony_ci */ 11062306a36Sopenharmony_cistatic __be32 11162306a36Sopenharmony_cinfsd3_proc_access(struct svc_rqst *rqstp) 11262306a36Sopenharmony_ci{ 11362306a36Sopenharmony_ci struct nfsd3_accessargs *argp = rqstp->rq_argp; 11462306a36Sopenharmony_ci struct nfsd3_accessres *resp = rqstp->rq_resp; 11562306a36Sopenharmony_ci 11662306a36Sopenharmony_ci dprintk("nfsd: ACCESS(3) %s 0x%x\n", 11762306a36Sopenharmony_ci SVCFH_fmt(&argp->fh), 11862306a36Sopenharmony_ci argp->access); 11962306a36Sopenharmony_ci 12062306a36Sopenharmony_ci fh_copy(&resp->fh, &argp->fh); 12162306a36Sopenharmony_ci resp->access = argp->access; 12262306a36Sopenharmony_ci resp->status = nfsd_access(rqstp, &resp->fh, &resp->access, NULL); 12362306a36Sopenharmony_ci return rpc_success; 12462306a36Sopenharmony_ci} 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_ci/* 12762306a36Sopenharmony_ci * Read a symlink. 12862306a36Sopenharmony_ci */ 12962306a36Sopenharmony_cistatic __be32 13062306a36Sopenharmony_cinfsd3_proc_readlink(struct svc_rqst *rqstp) 13162306a36Sopenharmony_ci{ 13262306a36Sopenharmony_ci struct nfsd_fhandle *argp = rqstp->rq_argp; 13362306a36Sopenharmony_ci struct nfsd3_readlinkres *resp = rqstp->rq_resp; 13462306a36Sopenharmony_ci 13562306a36Sopenharmony_ci dprintk("nfsd: READLINK(3) %s\n", SVCFH_fmt(&argp->fh)); 13662306a36Sopenharmony_ci 13762306a36Sopenharmony_ci /* Read the symlink. */ 13862306a36Sopenharmony_ci fh_copy(&resp->fh, &argp->fh); 13962306a36Sopenharmony_ci resp->len = NFS3_MAXPATHLEN; 14062306a36Sopenharmony_ci resp->pages = rqstp->rq_next_page++; 14162306a36Sopenharmony_ci resp->status = nfsd_readlink(rqstp, &resp->fh, 14262306a36Sopenharmony_ci page_address(*resp->pages), &resp->len); 14362306a36Sopenharmony_ci return rpc_success; 14462306a36Sopenharmony_ci} 14562306a36Sopenharmony_ci 14662306a36Sopenharmony_ci/* 14762306a36Sopenharmony_ci * Read a portion of a file. 14862306a36Sopenharmony_ci */ 14962306a36Sopenharmony_cistatic __be32 15062306a36Sopenharmony_cinfsd3_proc_read(struct svc_rqst *rqstp) 15162306a36Sopenharmony_ci{ 15262306a36Sopenharmony_ci struct nfsd3_readargs *argp = rqstp->rq_argp; 15362306a36Sopenharmony_ci struct nfsd3_readres *resp = rqstp->rq_resp; 15462306a36Sopenharmony_ci 15562306a36Sopenharmony_ci dprintk("nfsd: READ(3) %s %lu bytes at %Lu\n", 15662306a36Sopenharmony_ci SVCFH_fmt(&argp->fh), 15762306a36Sopenharmony_ci (unsigned long) argp->count, 15862306a36Sopenharmony_ci (unsigned long long) argp->offset); 15962306a36Sopenharmony_ci 16062306a36Sopenharmony_ci argp->count = min_t(u32, argp->count, svc_max_payload(rqstp)); 16162306a36Sopenharmony_ci argp->count = min_t(u32, argp->count, rqstp->rq_res.buflen); 16262306a36Sopenharmony_ci if (argp->offset > (u64)OFFSET_MAX) 16362306a36Sopenharmony_ci argp->offset = (u64)OFFSET_MAX; 16462306a36Sopenharmony_ci if (argp->offset + argp->count > (u64)OFFSET_MAX) 16562306a36Sopenharmony_ci argp->count = (u64)OFFSET_MAX - argp->offset; 16662306a36Sopenharmony_ci 16762306a36Sopenharmony_ci resp->pages = rqstp->rq_next_page; 16862306a36Sopenharmony_ci 16962306a36Sopenharmony_ci /* Obtain buffer pointer for payload. 17062306a36Sopenharmony_ci * 1 (status) + 22 (post_op_attr) + 1 (count) + 1 (eof) 17162306a36Sopenharmony_ci * + 1 (xdr opaque byte count) = 26 17262306a36Sopenharmony_ci */ 17362306a36Sopenharmony_ci resp->count = argp->count; 17462306a36Sopenharmony_ci svc_reserve_auth(rqstp, ((1 + NFS3_POST_OP_ATTR_WORDS + 3)<<2) + resp->count +4); 17562306a36Sopenharmony_ci 17662306a36Sopenharmony_ci fh_copy(&resp->fh, &argp->fh); 17762306a36Sopenharmony_ci resp->status = nfsd_read(rqstp, &resp->fh, argp->offset, 17862306a36Sopenharmony_ci &resp->count, &resp->eof); 17962306a36Sopenharmony_ci return rpc_success; 18062306a36Sopenharmony_ci} 18162306a36Sopenharmony_ci 18262306a36Sopenharmony_ci/* 18362306a36Sopenharmony_ci * Write data to a file 18462306a36Sopenharmony_ci */ 18562306a36Sopenharmony_cistatic __be32 18662306a36Sopenharmony_cinfsd3_proc_write(struct svc_rqst *rqstp) 18762306a36Sopenharmony_ci{ 18862306a36Sopenharmony_ci struct nfsd3_writeargs *argp = rqstp->rq_argp; 18962306a36Sopenharmony_ci struct nfsd3_writeres *resp = rqstp->rq_resp; 19062306a36Sopenharmony_ci unsigned long cnt = argp->len; 19162306a36Sopenharmony_ci unsigned int nvecs; 19262306a36Sopenharmony_ci 19362306a36Sopenharmony_ci dprintk("nfsd: WRITE(3) %s %d bytes at %Lu%s\n", 19462306a36Sopenharmony_ci SVCFH_fmt(&argp->fh), 19562306a36Sopenharmony_ci argp->len, 19662306a36Sopenharmony_ci (unsigned long long) argp->offset, 19762306a36Sopenharmony_ci argp->stable? " stable" : ""); 19862306a36Sopenharmony_ci 19962306a36Sopenharmony_ci resp->status = nfserr_fbig; 20062306a36Sopenharmony_ci if (argp->offset > (u64)OFFSET_MAX || 20162306a36Sopenharmony_ci argp->offset + argp->len > (u64)OFFSET_MAX) 20262306a36Sopenharmony_ci return rpc_success; 20362306a36Sopenharmony_ci 20462306a36Sopenharmony_ci fh_copy(&resp->fh, &argp->fh); 20562306a36Sopenharmony_ci resp->committed = argp->stable; 20662306a36Sopenharmony_ci nvecs = svc_fill_write_vector(rqstp, &argp->payload); 20762306a36Sopenharmony_ci 20862306a36Sopenharmony_ci resp->status = nfsd_write(rqstp, &resp->fh, argp->offset, 20962306a36Sopenharmony_ci rqstp->rq_vec, nvecs, &cnt, 21062306a36Sopenharmony_ci resp->committed, resp->verf); 21162306a36Sopenharmony_ci resp->count = cnt; 21262306a36Sopenharmony_ci return rpc_success; 21362306a36Sopenharmony_ci} 21462306a36Sopenharmony_ci 21562306a36Sopenharmony_ci/* 21662306a36Sopenharmony_ci * Implement NFSv3's unchecked, guarded, and exclusive CREATE 21762306a36Sopenharmony_ci * semantics for regular files. Except for the created file, 21862306a36Sopenharmony_ci * this operation is stateless on the server. 21962306a36Sopenharmony_ci * 22062306a36Sopenharmony_ci * Upon return, caller must release @fhp and @resfhp. 22162306a36Sopenharmony_ci */ 22262306a36Sopenharmony_cistatic __be32 22362306a36Sopenharmony_cinfsd3_create_file(struct svc_rqst *rqstp, struct svc_fh *fhp, 22462306a36Sopenharmony_ci struct svc_fh *resfhp, struct nfsd3_createargs *argp) 22562306a36Sopenharmony_ci{ 22662306a36Sopenharmony_ci struct iattr *iap = &argp->attrs; 22762306a36Sopenharmony_ci struct dentry *parent, *child; 22862306a36Sopenharmony_ci struct nfsd_attrs attrs = { 22962306a36Sopenharmony_ci .na_iattr = iap, 23062306a36Sopenharmony_ci }; 23162306a36Sopenharmony_ci __u32 v_mtime, v_atime; 23262306a36Sopenharmony_ci struct inode *inode; 23362306a36Sopenharmony_ci __be32 status; 23462306a36Sopenharmony_ci int host_err; 23562306a36Sopenharmony_ci 23662306a36Sopenharmony_ci if (isdotent(argp->name, argp->len)) 23762306a36Sopenharmony_ci return nfserr_exist; 23862306a36Sopenharmony_ci if (!(iap->ia_valid & ATTR_MODE)) 23962306a36Sopenharmony_ci iap->ia_mode = 0; 24062306a36Sopenharmony_ci 24162306a36Sopenharmony_ci status = fh_verify(rqstp, fhp, S_IFDIR, NFSD_MAY_EXEC); 24262306a36Sopenharmony_ci if (status != nfs_ok) 24362306a36Sopenharmony_ci return status; 24462306a36Sopenharmony_ci 24562306a36Sopenharmony_ci parent = fhp->fh_dentry; 24662306a36Sopenharmony_ci inode = d_inode(parent); 24762306a36Sopenharmony_ci 24862306a36Sopenharmony_ci host_err = fh_want_write(fhp); 24962306a36Sopenharmony_ci if (host_err) 25062306a36Sopenharmony_ci return nfserrno(host_err); 25162306a36Sopenharmony_ci 25262306a36Sopenharmony_ci inode_lock_nested(inode, I_MUTEX_PARENT); 25362306a36Sopenharmony_ci 25462306a36Sopenharmony_ci child = lookup_one_len(argp->name, parent, argp->len); 25562306a36Sopenharmony_ci if (IS_ERR(child)) { 25662306a36Sopenharmony_ci status = nfserrno(PTR_ERR(child)); 25762306a36Sopenharmony_ci goto out; 25862306a36Sopenharmony_ci } 25962306a36Sopenharmony_ci 26062306a36Sopenharmony_ci if (d_really_is_negative(child)) { 26162306a36Sopenharmony_ci status = fh_verify(rqstp, fhp, S_IFDIR, NFSD_MAY_CREATE); 26262306a36Sopenharmony_ci if (status != nfs_ok) 26362306a36Sopenharmony_ci goto out; 26462306a36Sopenharmony_ci } 26562306a36Sopenharmony_ci 26662306a36Sopenharmony_ci status = fh_compose(resfhp, fhp->fh_export, child, fhp); 26762306a36Sopenharmony_ci if (status != nfs_ok) 26862306a36Sopenharmony_ci goto out; 26962306a36Sopenharmony_ci 27062306a36Sopenharmony_ci v_mtime = 0; 27162306a36Sopenharmony_ci v_atime = 0; 27262306a36Sopenharmony_ci if (argp->createmode == NFS3_CREATE_EXCLUSIVE) { 27362306a36Sopenharmony_ci u32 *verifier = (u32 *)argp->verf; 27462306a36Sopenharmony_ci 27562306a36Sopenharmony_ci /* 27662306a36Sopenharmony_ci * Solaris 7 gets confused (bugid 4218508) if these have 27762306a36Sopenharmony_ci * the high bit set, as do xfs filesystems without the 27862306a36Sopenharmony_ci * "bigtime" feature. So just clear the high bits. 27962306a36Sopenharmony_ci */ 28062306a36Sopenharmony_ci v_mtime = verifier[0] & 0x7fffffff; 28162306a36Sopenharmony_ci v_atime = verifier[1] & 0x7fffffff; 28262306a36Sopenharmony_ci } 28362306a36Sopenharmony_ci 28462306a36Sopenharmony_ci if (d_really_is_positive(child)) { 28562306a36Sopenharmony_ci status = nfs_ok; 28662306a36Sopenharmony_ci 28762306a36Sopenharmony_ci switch (argp->createmode) { 28862306a36Sopenharmony_ci case NFS3_CREATE_UNCHECKED: 28962306a36Sopenharmony_ci if (!d_is_reg(child)) 29062306a36Sopenharmony_ci break; 29162306a36Sopenharmony_ci iap->ia_valid &= ATTR_SIZE; 29262306a36Sopenharmony_ci goto set_attr; 29362306a36Sopenharmony_ci case NFS3_CREATE_GUARDED: 29462306a36Sopenharmony_ci status = nfserr_exist; 29562306a36Sopenharmony_ci break; 29662306a36Sopenharmony_ci case NFS3_CREATE_EXCLUSIVE: 29762306a36Sopenharmony_ci if (d_inode(child)->i_mtime.tv_sec == v_mtime && 29862306a36Sopenharmony_ci d_inode(child)->i_atime.tv_sec == v_atime && 29962306a36Sopenharmony_ci d_inode(child)->i_size == 0) { 30062306a36Sopenharmony_ci break; 30162306a36Sopenharmony_ci } 30262306a36Sopenharmony_ci status = nfserr_exist; 30362306a36Sopenharmony_ci } 30462306a36Sopenharmony_ci goto out; 30562306a36Sopenharmony_ci } 30662306a36Sopenharmony_ci 30762306a36Sopenharmony_ci if (!IS_POSIXACL(inode)) 30862306a36Sopenharmony_ci iap->ia_mode &= ~current_umask(); 30962306a36Sopenharmony_ci 31062306a36Sopenharmony_ci status = fh_fill_pre_attrs(fhp); 31162306a36Sopenharmony_ci if (status != nfs_ok) 31262306a36Sopenharmony_ci goto out; 31362306a36Sopenharmony_ci host_err = vfs_create(&nop_mnt_idmap, inode, child, iap->ia_mode, true); 31462306a36Sopenharmony_ci if (host_err < 0) { 31562306a36Sopenharmony_ci status = nfserrno(host_err); 31662306a36Sopenharmony_ci goto out; 31762306a36Sopenharmony_ci } 31862306a36Sopenharmony_ci fh_fill_post_attrs(fhp); 31962306a36Sopenharmony_ci 32062306a36Sopenharmony_ci /* A newly created file already has a file size of zero. */ 32162306a36Sopenharmony_ci if ((iap->ia_valid & ATTR_SIZE) && (iap->ia_size == 0)) 32262306a36Sopenharmony_ci iap->ia_valid &= ~ATTR_SIZE; 32362306a36Sopenharmony_ci if (argp->createmode == NFS3_CREATE_EXCLUSIVE) { 32462306a36Sopenharmony_ci iap->ia_valid = ATTR_MTIME | ATTR_ATIME | 32562306a36Sopenharmony_ci ATTR_MTIME_SET | ATTR_ATIME_SET; 32662306a36Sopenharmony_ci iap->ia_mtime.tv_sec = v_mtime; 32762306a36Sopenharmony_ci iap->ia_atime.tv_sec = v_atime; 32862306a36Sopenharmony_ci iap->ia_mtime.tv_nsec = 0; 32962306a36Sopenharmony_ci iap->ia_atime.tv_nsec = 0; 33062306a36Sopenharmony_ci } 33162306a36Sopenharmony_ci 33262306a36Sopenharmony_ciset_attr: 33362306a36Sopenharmony_ci status = nfsd_create_setattr(rqstp, fhp, resfhp, &attrs); 33462306a36Sopenharmony_ci 33562306a36Sopenharmony_ciout: 33662306a36Sopenharmony_ci inode_unlock(inode); 33762306a36Sopenharmony_ci if (child && !IS_ERR(child)) 33862306a36Sopenharmony_ci dput(child); 33962306a36Sopenharmony_ci fh_drop_write(fhp); 34062306a36Sopenharmony_ci return status; 34162306a36Sopenharmony_ci} 34262306a36Sopenharmony_ci 34362306a36Sopenharmony_cistatic __be32 34462306a36Sopenharmony_cinfsd3_proc_create(struct svc_rqst *rqstp) 34562306a36Sopenharmony_ci{ 34662306a36Sopenharmony_ci struct nfsd3_createargs *argp = rqstp->rq_argp; 34762306a36Sopenharmony_ci struct nfsd3_diropres *resp = rqstp->rq_resp; 34862306a36Sopenharmony_ci svc_fh *dirfhp, *newfhp; 34962306a36Sopenharmony_ci 35062306a36Sopenharmony_ci dprintk("nfsd: CREATE(3) %s %.*s\n", 35162306a36Sopenharmony_ci SVCFH_fmt(&argp->fh), 35262306a36Sopenharmony_ci argp->len, 35362306a36Sopenharmony_ci argp->name); 35462306a36Sopenharmony_ci 35562306a36Sopenharmony_ci dirfhp = fh_copy(&resp->dirfh, &argp->fh); 35662306a36Sopenharmony_ci newfhp = fh_init(&resp->fh, NFS3_FHSIZE); 35762306a36Sopenharmony_ci 35862306a36Sopenharmony_ci resp->status = nfsd3_create_file(rqstp, dirfhp, newfhp, argp); 35962306a36Sopenharmony_ci return rpc_success; 36062306a36Sopenharmony_ci} 36162306a36Sopenharmony_ci 36262306a36Sopenharmony_ci/* 36362306a36Sopenharmony_ci * Make directory. This operation is not idempotent. 36462306a36Sopenharmony_ci */ 36562306a36Sopenharmony_cistatic __be32 36662306a36Sopenharmony_cinfsd3_proc_mkdir(struct svc_rqst *rqstp) 36762306a36Sopenharmony_ci{ 36862306a36Sopenharmony_ci struct nfsd3_createargs *argp = rqstp->rq_argp; 36962306a36Sopenharmony_ci struct nfsd3_diropres *resp = rqstp->rq_resp; 37062306a36Sopenharmony_ci struct nfsd_attrs attrs = { 37162306a36Sopenharmony_ci .na_iattr = &argp->attrs, 37262306a36Sopenharmony_ci }; 37362306a36Sopenharmony_ci 37462306a36Sopenharmony_ci dprintk("nfsd: MKDIR(3) %s %.*s\n", 37562306a36Sopenharmony_ci SVCFH_fmt(&argp->fh), 37662306a36Sopenharmony_ci argp->len, 37762306a36Sopenharmony_ci argp->name); 37862306a36Sopenharmony_ci 37962306a36Sopenharmony_ci argp->attrs.ia_valid &= ~ATTR_SIZE; 38062306a36Sopenharmony_ci fh_copy(&resp->dirfh, &argp->fh); 38162306a36Sopenharmony_ci fh_init(&resp->fh, NFS3_FHSIZE); 38262306a36Sopenharmony_ci resp->status = nfsd_create(rqstp, &resp->dirfh, argp->name, argp->len, 38362306a36Sopenharmony_ci &attrs, S_IFDIR, 0, &resp->fh); 38462306a36Sopenharmony_ci return rpc_success; 38562306a36Sopenharmony_ci} 38662306a36Sopenharmony_ci 38762306a36Sopenharmony_cistatic __be32 38862306a36Sopenharmony_cinfsd3_proc_symlink(struct svc_rqst *rqstp) 38962306a36Sopenharmony_ci{ 39062306a36Sopenharmony_ci struct nfsd3_symlinkargs *argp = rqstp->rq_argp; 39162306a36Sopenharmony_ci struct nfsd3_diropres *resp = rqstp->rq_resp; 39262306a36Sopenharmony_ci struct nfsd_attrs attrs = { 39362306a36Sopenharmony_ci .na_iattr = &argp->attrs, 39462306a36Sopenharmony_ci }; 39562306a36Sopenharmony_ci 39662306a36Sopenharmony_ci if (argp->tlen == 0) { 39762306a36Sopenharmony_ci resp->status = nfserr_inval; 39862306a36Sopenharmony_ci goto out; 39962306a36Sopenharmony_ci } 40062306a36Sopenharmony_ci if (argp->tlen > NFS3_MAXPATHLEN) { 40162306a36Sopenharmony_ci resp->status = nfserr_nametoolong; 40262306a36Sopenharmony_ci goto out; 40362306a36Sopenharmony_ci } 40462306a36Sopenharmony_ci 40562306a36Sopenharmony_ci argp->tname = svc_fill_symlink_pathname(rqstp, &argp->first, 40662306a36Sopenharmony_ci page_address(rqstp->rq_arg.pages[0]), 40762306a36Sopenharmony_ci argp->tlen); 40862306a36Sopenharmony_ci if (IS_ERR(argp->tname)) { 40962306a36Sopenharmony_ci resp->status = nfserrno(PTR_ERR(argp->tname)); 41062306a36Sopenharmony_ci goto out; 41162306a36Sopenharmony_ci } 41262306a36Sopenharmony_ci 41362306a36Sopenharmony_ci dprintk("nfsd: SYMLINK(3) %s %.*s -> %.*s\n", 41462306a36Sopenharmony_ci SVCFH_fmt(&argp->ffh), 41562306a36Sopenharmony_ci argp->flen, argp->fname, 41662306a36Sopenharmony_ci argp->tlen, argp->tname); 41762306a36Sopenharmony_ci 41862306a36Sopenharmony_ci fh_copy(&resp->dirfh, &argp->ffh); 41962306a36Sopenharmony_ci fh_init(&resp->fh, NFS3_FHSIZE); 42062306a36Sopenharmony_ci resp->status = nfsd_symlink(rqstp, &resp->dirfh, argp->fname, 42162306a36Sopenharmony_ci argp->flen, argp->tname, &attrs, &resp->fh); 42262306a36Sopenharmony_ci kfree(argp->tname); 42362306a36Sopenharmony_ciout: 42462306a36Sopenharmony_ci return rpc_success; 42562306a36Sopenharmony_ci} 42662306a36Sopenharmony_ci 42762306a36Sopenharmony_ci/* 42862306a36Sopenharmony_ci * Make socket/fifo/device. 42962306a36Sopenharmony_ci */ 43062306a36Sopenharmony_cistatic __be32 43162306a36Sopenharmony_cinfsd3_proc_mknod(struct svc_rqst *rqstp) 43262306a36Sopenharmony_ci{ 43362306a36Sopenharmony_ci struct nfsd3_mknodargs *argp = rqstp->rq_argp; 43462306a36Sopenharmony_ci struct nfsd3_diropres *resp = rqstp->rq_resp; 43562306a36Sopenharmony_ci struct nfsd_attrs attrs = { 43662306a36Sopenharmony_ci .na_iattr = &argp->attrs, 43762306a36Sopenharmony_ci }; 43862306a36Sopenharmony_ci int type; 43962306a36Sopenharmony_ci dev_t rdev = 0; 44062306a36Sopenharmony_ci 44162306a36Sopenharmony_ci dprintk("nfsd: MKNOD(3) %s %.*s\n", 44262306a36Sopenharmony_ci SVCFH_fmt(&argp->fh), 44362306a36Sopenharmony_ci argp->len, 44462306a36Sopenharmony_ci argp->name); 44562306a36Sopenharmony_ci 44662306a36Sopenharmony_ci fh_copy(&resp->dirfh, &argp->fh); 44762306a36Sopenharmony_ci fh_init(&resp->fh, NFS3_FHSIZE); 44862306a36Sopenharmony_ci 44962306a36Sopenharmony_ci if (argp->ftype == NF3CHR || argp->ftype == NF3BLK) { 45062306a36Sopenharmony_ci rdev = MKDEV(argp->major, argp->minor); 45162306a36Sopenharmony_ci if (MAJOR(rdev) != argp->major || 45262306a36Sopenharmony_ci MINOR(rdev) != argp->minor) { 45362306a36Sopenharmony_ci resp->status = nfserr_inval; 45462306a36Sopenharmony_ci goto out; 45562306a36Sopenharmony_ci } 45662306a36Sopenharmony_ci } else if (argp->ftype != NF3SOCK && argp->ftype != NF3FIFO) { 45762306a36Sopenharmony_ci resp->status = nfserr_badtype; 45862306a36Sopenharmony_ci goto out; 45962306a36Sopenharmony_ci } 46062306a36Sopenharmony_ci 46162306a36Sopenharmony_ci type = nfs3_ftypes[argp->ftype]; 46262306a36Sopenharmony_ci resp->status = nfsd_create(rqstp, &resp->dirfh, argp->name, argp->len, 46362306a36Sopenharmony_ci &attrs, type, rdev, &resp->fh); 46462306a36Sopenharmony_ciout: 46562306a36Sopenharmony_ci return rpc_success; 46662306a36Sopenharmony_ci} 46762306a36Sopenharmony_ci 46862306a36Sopenharmony_ci/* 46962306a36Sopenharmony_ci * Remove file/fifo/socket etc. 47062306a36Sopenharmony_ci */ 47162306a36Sopenharmony_cistatic __be32 47262306a36Sopenharmony_cinfsd3_proc_remove(struct svc_rqst *rqstp) 47362306a36Sopenharmony_ci{ 47462306a36Sopenharmony_ci struct nfsd3_diropargs *argp = rqstp->rq_argp; 47562306a36Sopenharmony_ci struct nfsd3_attrstat *resp = rqstp->rq_resp; 47662306a36Sopenharmony_ci 47762306a36Sopenharmony_ci dprintk("nfsd: REMOVE(3) %s %.*s\n", 47862306a36Sopenharmony_ci SVCFH_fmt(&argp->fh), 47962306a36Sopenharmony_ci argp->len, 48062306a36Sopenharmony_ci argp->name); 48162306a36Sopenharmony_ci 48262306a36Sopenharmony_ci /* Unlink. -S_IFDIR means file must not be a directory */ 48362306a36Sopenharmony_ci fh_copy(&resp->fh, &argp->fh); 48462306a36Sopenharmony_ci resp->status = nfsd_unlink(rqstp, &resp->fh, -S_IFDIR, 48562306a36Sopenharmony_ci argp->name, argp->len); 48662306a36Sopenharmony_ci return rpc_success; 48762306a36Sopenharmony_ci} 48862306a36Sopenharmony_ci 48962306a36Sopenharmony_ci/* 49062306a36Sopenharmony_ci * Remove a directory 49162306a36Sopenharmony_ci */ 49262306a36Sopenharmony_cistatic __be32 49362306a36Sopenharmony_cinfsd3_proc_rmdir(struct svc_rqst *rqstp) 49462306a36Sopenharmony_ci{ 49562306a36Sopenharmony_ci struct nfsd3_diropargs *argp = rqstp->rq_argp; 49662306a36Sopenharmony_ci struct nfsd3_attrstat *resp = rqstp->rq_resp; 49762306a36Sopenharmony_ci 49862306a36Sopenharmony_ci dprintk("nfsd: RMDIR(3) %s %.*s\n", 49962306a36Sopenharmony_ci SVCFH_fmt(&argp->fh), 50062306a36Sopenharmony_ci argp->len, 50162306a36Sopenharmony_ci argp->name); 50262306a36Sopenharmony_ci 50362306a36Sopenharmony_ci fh_copy(&resp->fh, &argp->fh); 50462306a36Sopenharmony_ci resp->status = nfsd_unlink(rqstp, &resp->fh, S_IFDIR, 50562306a36Sopenharmony_ci argp->name, argp->len); 50662306a36Sopenharmony_ci return rpc_success; 50762306a36Sopenharmony_ci} 50862306a36Sopenharmony_ci 50962306a36Sopenharmony_cistatic __be32 51062306a36Sopenharmony_cinfsd3_proc_rename(struct svc_rqst *rqstp) 51162306a36Sopenharmony_ci{ 51262306a36Sopenharmony_ci struct nfsd3_renameargs *argp = rqstp->rq_argp; 51362306a36Sopenharmony_ci struct nfsd3_renameres *resp = rqstp->rq_resp; 51462306a36Sopenharmony_ci 51562306a36Sopenharmony_ci dprintk("nfsd: RENAME(3) %s %.*s ->\n", 51662306a36Sopenharmony_ci SVCFH_fmt(&argp->ffh), 51762306a36Sopenharmony_ci argp->flen, 51862306a36Sopenharmony_ci argp->fname); 51962306a36Sopenharmony_ci dprintk("nfsd: -> %s %.*s\n", 52062306a36Sopenharmony_ci SVCFH_fmt(&argp->tfh), 52162306a36Sopenharmony_ci argp->tlen, 52262306a36Sopenharmony_ci argp->tname); 52362306a36Sopenharmony_ci 52462306a36Sopenharmony_ci fh_copy(&resp->ffh, &argp->ffh); 52562306a36Sopenharmony_ci fh_copy(&resp->tfh, &argp->tfh); 52662306a36Sopenharmony_ci resp->status = nfsd_rename(rqstp, &resp->ffh, argp->fname, argp->flen, 52762306a36Sopenharmony_ci &resp->tfh, argp->tname, argp->tlen); 52862306a36Sopenharmony_ci return rpc_success; 52962306a36Sopenharmony_ci} 53062306a36Sopenharmony_ci 53162306a36Sopenharmony_cistatic __be32 53262306a36Sopenharmony_cinfsd3_proc_link(struct svc_rqst *rqstp) 53362306a36Sopenharmony_ci{ 53462306a36Sopenharmony_ci struct nfsd3_linkargs *argp = rqstp->rq_argp; 53562306a36Sopenharmony_ci struct nfsd3_linkres *resp = rqstp->rq_resp; 53662306a36Sopenharmony_ci 53762306a36Sopenharmony_ci dprintk("nfsd: LINK(3) %s ->\n", 53862306a36Sopenharmony_ci SVCFH_fmt(&argp->ffh)); 53962306a36Sopenharmony_ci dprintk("nfsd: -> %s %.*s\n", 54062306a36Sopenharmony_ci SVCFH_fmt(&argp->tfh), 54162306a36Sopenharmony_ci argp->tlen, 54262306a36Sopenharmony_ci argp->tname); 54362306a36Sopenharmony_ci 54462306a36Sopenharmony_ci fh_copy(&resp->fh, &argp->ffh); 54562306a36Sopenharmony_ci fh_copy(&resp->tfh, &argp->tfh); 54662306a36Sopenharmony_ci resp->status = nfsd_link(rqstp, &resp->tfh, argp->tname, argp->tlen, 54762306a36Sopenharmony_ci &resp->fh); 54862306a36Sopenharmony_ci return rpc_success; 54962306a36Sopenharmony_ci} 55062306a36Sopenharmony_ci 55162306a36Sopenharmony_cistatic void nfsd3_init_dirlist_pages(struct svc_rqst *rqstp, 55262306a36Sopenharmony_ci struct nfsd3_readdirres *resp, 55362306a36Sopenharmony_ci u32 count) 55462306a36Sopenharmony_ci{ 55562306a36Sopenharmony_ci struct xdr_buf *buf = &resp->dirlist; 55662306a36Sopenharmony_ci struct xdr_stream *xdr = &resp->xdr; 55762306a36Sopenharmony_ci unsigned int sendbuf = min_t(unsigned int, rqstp->rq_res.buflen, 55862306a36Sopenharmony_ci svc_max_payload(rqstp)); 55962306a36Sopenharmony_ci 56062306a36Sopenharmony_ci memset(buf, 0, sizeof(*buf)); 56162306a36Sopenharmony_ci 56262306a36Sopenharmony_ci /* Reserve room for the NULL ptr & eof flag (-2 words) */ 56362306a36Sopenharmony_ci buf->buflen = clamp(count, (u32)(XDR_UNIT * 2), sendbuf); 56462306a36Sopenharmony_ci buf->buflen -= XDR_UNIT * 2; 56562306a36Sopenharmony_ci buf->pages = rqstp->rq_next_page; 56662306a36Sopenharmony_ci rqstp->rq_next_page += (buf->buflen + PAGE_SIZE - 1) >> PAGE_SHIFT; 56762306a36Sopenharmony_ci 56862306a36Sopenharmony_ci xdr_init_encode_pages(xdr, buf, buf->pages, NULL); 56962306a36Sopenharmony_ci} 57062306a36Sopenharmony_ci 57162306a36Sopenharmony_ci/* 57262306a36Sopenharmony_ci * Read a portion of a directory. 57362306a36Sopenharmony_ci */ 57462306a36Sopenharmony_cistatic __be32 57562306a36Sopenharmony_cinfsd3_proc_readdir(struct svc_rqst *rqstp) 57662306a36Sopenharmony_ci{ 57762306a36Sopenharmony_ci struct nfsd3_readdirargs *argp = rqstp->rq_argp; 57862306a36Sopenharmony_ci struct nfsd3_readdirres *resp = rqstp->rq_resp; 57962306a36Sopenharmony_ci loff_t offset; 58062306a36Sopenharmony_ci 58162306a36Sopenharmony_ci dprintk("nfsd: READDIR(3) %s %d bytes at %d\n", 58262306a36Sopenharmony_ci SVCFH_fmt(&argp->fh), 58362306a36Sopenharmony_ci argp->count, (u32) argp->cookie); 58462306a36Sopenharmony_ci 58562306a36Sopenharmony_ci nfsd3_init_dirlist_pages(rqstp, resp, argp->count); 58662306a36Sopenharmony_ci 58762306a36Sopenharmony_ci fh_copy(&resp->fh, &argp->fh); 58862306a36Sopenharmony_ci resp->common.err = nfs_ok; 58962306a36Sopenharmony_ci resp->cookie_offset = 0; 59062306a36Sopenharmony_ci resp->rqstp = rqstp; 59162306a36Sopenharmony_ci offset = argp->cookie; 59262306a36Sopenharmony_ci resp->status = nfsd_readdir(rqstp, &resp->fh, &offset, 59362306a36Sopenharmony_ci &resp->common, nfs3svc_encode_entry3); 59462306a36Sopenharmony_ci memcpy(resp->verf, argp->verf, 8); 59562306a36Sopenharmony_ci nfs3svc_encode_cookie3(resp, offset); 59662306a36Sopenharmony_ci 59762306a36Sopenharmony_ci /* Recycle only pages that were part of the reply */ 59862306a36Sopenharmony_ci rqstp->rq_next_page = resp->xdr.page_ptr + 1; 59962306a36Sopenharmony_ci 60062306a36Sopenharmony_ci return rpc_success; 60162306a36Sopenharmony_ci} 60262306a36Sopenharmony_ci 60362306a36Sopenharmony_ci/* 60462306a36Sopenharmony_ci * Read a portion of a directory, including file handles and attrs. 60562306a36Sopenharmony_ci * For now, we choose to ignore the dircount parameter. 60662306a36Sopenharmony_ci */ 60762306a36Sopenharmony_cistatic __be32 60862306a36Sopenharmony_cinfsd3_proc_readdirplus(struct svc_rqst *rqstp) 60962306a36Sopenharmony_ci{ 61062306a36Sopenharmony_ci struct nfsd3_readdirargs *argp = rqstp->rq_argp; 61162306a36Sopenharmony_ci struct nfsd3_readdirres *resp = rqstp->rq_resp; 61262306a36Sopenharmony_ci loff_t offset; 61362306a36Sopenharmony_ci 61462306a36Sopenharmony_ci dprintk("nfsd: READDIR+(3) %s %d bytes at %d\n", 61562306a36Sopenharmony_ci SVCFH_fmt(&argp->fh), 61662306a36Sopenharmony_ci argp->count, (u32) argp->cookie); 61762306a36Sopenharmony_ci 61862306a36Sopenharmony_ci nfsd3_init_dirlist_pages(rqstp, resp, argp->count); 61962306a36Sopenharmony_ci 62062306a36Sopenharmony_ci fh_copy(&resp->fh, &argp->fh); 62162306a36Sopenharmony_ci resp->common.err = nfs_ok; 62262306a36Sopenharmony_ci resp->cookie_offset = 0; 62362306a36Sopenharmony_ci resp->rqstp = rqstp; 62462306a36Sopenharmony_ci offset = argp->cookie; 62562306a36Sopenharmony_ci 62662306a36Sopenharmony_ci resp->status = fh_verify(rqstp, &resp->fh, S_IFDIR, NFSD_MAY_NOP); 62762306a36Sopenharmony_ci if (resp->status != nfs_ok) 62862306a36Sopenharmony_ci goto out; 62962306a36Sopenharmony_ci 63062306a36Sopenharmony_ci if (resp->fh.fh_export->ex_flags & NFSEXP_NOREADDIRPLUS) { 63162306a36Sopenharmony_ci resp->status = nfserr_notsupp; 63262306a36Sopenharmony_ci goto out; 63362306a36Sopenharmony_ci } 63462306a36Sopenharmony_ci 63562306a36Sopenharmony_ci resp->status = nfsd_readdir(rqstp, &resp->fh, &offset, 63662306a36Sopenharmony_ci &resp->common, nfs3svc_encode_entryplus3); 63762306a36Sopenharmony_ci memcpy(resp->verf, argp->verf, 8); 63862306a36Sopenharmony_ci nfs3svc_encode_cookie3(resp, offset); 63962306a36Sopenharmony_ci 64062306a36Sopenharmony_ci /* Recycle only pages that were part of the reply */ 64162306a36Sopenharmony_ci rqstp->rq_next_page = resp->xdr.page_ptr + 1; 64262306a36Sopenharmony_ci 64362306a36Sopenharmony_ciout: 64462306a36Sopenharmony_ci return rpc_success; 64562306a36Sopenharmony_ci} 64662306a36Sopenharmony_ci 64762306a36Sopenharmony_ci/* 64862306a36Sopenharmony_ci * Get file system stats 64962306a36Sopenharmony_ci */ 65062306a36Sopenharmony_cistatic __be32 65162306a36Sopenharmony_cinfsd3_proc_fsstat(struct svc_rqst *rqstp) 65262306a36Sopenharmony_ci{ 65362306a36Sopenharmony_ci struct nfsd_fhandle *argp = rqstp->rq_argp; 65462306a36Sopenharmony_ci struct nfsd3_fsstatres *resp = rqstp->rq_resp; 65562306a36Sopenharmony_ci 65662306a36Sopenharmony_ci dprintk("nfsd: FSSTAT(3) %s\n", 65762306a36Sopenharmony_ci SVCFH_fmt(&argp->fh)); 65862306a36Sopenharmony_ci 65962306a36Sopenharmony_ci resp->status = nfsd_statfs(rqstp, &argp->fh, &resp->stats, 0); 66062306a36Sopenharmony_ci fh_put(&argp->fh); 66162306a36Sopenharmony_ci return rpc_success; 66262306a36Sopenharmony_ci} 66362306a36Sopenharmony_ci 66462306a36Sopenharmony_ci/* 66562306a36Sopenharmony_ci * Get file system info 66662306a36Sopenharmony_ci */ 66762306a36Sopenharmony_cistatic __be32 66862306a36Sopenharmony_cinfsd3_proc_fsinfo(struct svc_rqst *rqstp) 66962306a36Sopenharmony_ci{ 67062306a36Sopenharmony_ci struct nfsd_fhandle *argp = rqstp->rq_argp; 67162306a36Sopenharmony_ci struct nfsd3_fsinfores *resp = rqstp->rq_resp; 67262306a36Sopenharmony_ci u32 max_blocksize = svc_max_payload(rqstp); 67362306a36Sopenharmony_ci 67462306a36Sopenharmony_ci dprintk("nfsd: FSINFO(3) %s\n", 67562306a36Sopenharmony_ci SVCFH_fmt(&argp->fh)); 67662306a36Sopenharmony_ci 67762306a36Sopenharmony_ci resp->f_rtmax = max_blocksize; 67862306a36Sopenharmony_ci resp->f_rtpref = max_blocksize; 67962306a36Sopenharmony_ci resp->f_rtmult = PAGE_SIZE; 68062306a36Sopenharmony_ci resp->f_wtmax = max_blocksize; 68162306a36Sopenharmony_ci resp->f_wtpref = max_blocksize; 68262306a36Sopenharmony_ci resp->f_wtmult = PAGE_SIZE; 68362306a36Sopenharmony_ci resp->f_dtpref = max_blocksize; 68462306a36Sopenharmony_ci resp->f_maxfilesize = ~(u32) 0; 68562306a36Sopenharmony_ci resp->f_properties = NFS3_FSF_DEFAULT; 68662306a36Sopenharmony_ci 68762306a36Sopenharmony_ci resp->status = fh_verify(rqstp, &argp->fh, 0, 68862306a36Sopenharmony_ci NFSD_MAY_NOP | NFSD_MAY_BYPASS_GSS_ON_ROOT); 68962306a36Sopenharmony_ci 69062306a36Sopenharmony_ci /* Check special features of the file system. May request 69162306a36Sopenharmony_ci * different read/write sizes for file systems known to have 69262306a36Sopenharmony_ci * problems with large blocks */ 69362306a36Sopenharmony_ci if (resp->status == nfs_ok) { 69462306a36Sopenharmony_ci struct super_block *sb = argp->fh.fh_dentry->d_sb; 69562306a36Sopenharmony_ci 69662306a36Sopenharmony_ci /* Note that we don't care for remote fs's here */ 69762306a36Sopenharmony_ci if (sb->s_magic == MSDOS_SUPER_MAGIC) { 69862306a36Sopenharmony_ci resp->f_properties = NFS3_FSF_BILLYBOY; 69962306a36Sopenharmony_ci } 70062306a36Sopenharmony_ci resp->f_maxfilesize = sb->s_maxbytes; 70162306a36Sopenharmony_ci } 70262306a36Sopenharmony_ci 70362306a36Sopenharmony_ci fh_put(&argp->fh); 70462306a36Sopenharmony_ci return rpc_success; 70562306a36Sopenharmony_ci} 70662306a36Sopenharmony_ci 70762306a36Sopenharmony_ci/* 70862306a36Sopenharmony_ci * Get pathconf info for the specified file 70962306a36Sopenharmony_ci */ 71062306a36Sopenharmony_cistatic __be32 71162306a36Sopenharmony_cinfsd3_proc_pathconf(struct svc_rqst *rqstp) 71262306a36Sopenharmony_ci{ 71362306a36Sopenharmony_ci struct nfsd_fhandle *argp = rqstp->rq_argp; 71462306a36Sopenharmony_ci struct nfsd3_pathconfres *resp = rqstp->rq_resp; 71562306a36Sopenharmony_ci 71662306a36Sopenharmony_ci dprintk("nfsd: PATHCONF(3) %s\n", 71762306a36Sopenharmony_ci SVCFH_fmt(&argp->fh)); 71862306a36Sopenharmony_ci 71962306a36Sopenharmony_ci /* Set default pathconf */ 72062306a36Sopenharmony_ci resp->p_link_max = 255; /* at least */ 72162306a36Sopenharmony_ci resp->p_name_max = 255; /* at least */ 72262306a36Sopenharmony_ci resp->p_no_trunc = 0; 72362306a36Sopenharmony_ci resp->p_chown_restricted = 1; 72462306a36Sopenharmony_ci resp->p_case_insensitive = 0; 72562306a36Sopenharmony_ci resp->p_case_preserving = 1; 72662306a36Sopenharmony_ci 72762306a36Sopenharmony_ci resp->status = fh_verify(rqstp, &argp->fh, 0, NFSD_MAY_NOP); 72862306a36Sopenharmony_ci 72962306a36Sopenharmony_ci if (resp->status == nfs_ok) { 73062306a36Sopenharmony_ci struct super_block *sb = argp->fh.fh_dentry->d_sb; 73162306a36Sopenharmony_ci 73262306a36Sopenharmony_ci /* Note that we don't care for remote fs's here */ 73362306a36Sopenharmony_ci switch (sb->s_magic) { 73462306a36Sopenharmony_ci case EXT2_SUPER_MAGIC: 73562306a36Sopenharmony_ci resp->p_link_max = EXT2_LINK_MAX; 73662306a36Sopenharmony_ci resp->p_name_max = EXT2_NAME_LEN; 73762306a36Sopenharmony_ci break; 73862306a36Sopenharmony_ci case MSDOS_SUPER_MAGIC: 73962306a36Sopenharmony_ci resp->p_case_insensitive = 1; 74062306a36Sopenharmony_ci resp->p_case_preserving = 0; 74162306a36Sopenharmony_ci break; 74262306a36Sopenharmony_ci } 74362306a36Sopenharmony_ci } 74462306a36Sopenharmony_ci 74562306a36Sopenharmony_ci fh_put(&argp->fh); 74662306a36Sopenharmony_ci return rpc_success; 74762306a36Sopenharmony_ci} 74862306a36Sopenharmony_ci 74962306a36Sopenharmony_ci/* 75062306a36Sopenharmony_ci * Commit a file (range) to stable storage. 75162306a36Sopenharmony_ci */ 75262306a36Sopenharmony_cistatic __be32 75362306a36Sopenharmony_cinfsd3_proc_commit(struct svc_rqst *rqstp) 75462306a36Sopenharmony_ci{ 75562306a36Sopenharmony_ci struct nfsd3_commitargs *argp = rqstp->rq_argp; 75662306a36Sopenharmony_ci struct nfsd3_commitres *resp = rqstp->rq_resp; 75762306a36Sopenharmony_ci struct nfsd_file *nf; 75862306a36Sopenharmony_ci 75962306a36Sopenharmony_ci dprintk("nfsd: COMMIT(3) %s %u@%Lu\n", 76062306a36Sopenharmony_ci SVCFH_fmt(&argp->fh), 76162306a36Sopenharmony_ci argp->count, 76262306a36Sopenharmony_ci (unsigned long long) argp->offset); 76362306a36Sopenharmony_ci 76462306a36Sopenharmony_ci fh_copy(&resp->fh, &argp->fh); 76562306a36Sopenharmony_ci resp->status = nfsd_file_acquire_gc(rqstp, &resp->fh, NFSD_MAY_WRITE | 76662306a36Sopenharmony_ci NFSD_MAY_NOT_BREAK_LEASE, &nf); 76762306a36Sopenharmony_ci if (resp->status) 76862306a36Sopenharmony_ci goto out; 76962306a36Sopenharmony_ci resp->status = nfsd_commit(rqstp, &resp->fh, nf, argp->offset, 77062306a36Sopenharmony_ci argp->count, resp->verf); 77162306a36Sopenharmony_ci nfsd_file_put(nf); 77262306a36Sopenharmony_ciout: 77362306a36Sopenharmony_ci return rpc_success; 77462306a36Sopenharmony_ci} 77562306a36Sopenharmony_ci 77662306a36Sopenharmony_ci 77762306a36Sopenharmony_ci/* 77862306a36Sopenharmony_ci * NFSv3 Server procedures. 77962306a36Sopenharmony_ci * Only the results of non-idempotent operations are cached. 78062306a36Sopenharmony_ci */ 78162306a36Sopenharmony_ci#define nfs3svc_encode_attrstatres nfs3svc_encode_attrstat 78262306a36Sopenharmony_ci#define nfs3svc_encode_wccstatres nfs3svc_encode_wccstat 78362306a36Sopenharmony_ci#define nfsd3_mkdirargs nfsd3_createargs 78462306a36Sopenharmony_ci#define nfsd3_readdirplusargs nfsd3_readdirargs 78562306a36Sopenharmony_ci#define nfsd3_fhandleargs nfsd_fhandle 78662306a36Sopenharmony_ci#define nfsd3_attrstatres nfsd3_attrstat 78762306a36Sopenharmony_ci#define nfsd3_wccstatres nfsd3_attrstat 78862306a36Sopenharmony_ci#define nfsd3_createres nfsd3_diropres 78962306a36Sopenharmony_ci 79062306a36Sopenharmony_ci#define ST 1 /* status*/ 79162306a36Sopenharmony_ci#define FH 17 /* filehandle with length */ 79262306a36Sopenharmony_ci#define AT 21 /* attributes */ 79362306a36Sopenharmony_ci#define pAT (1+AT) /* post attributes - conditional */ 79462306a36Sopenharmony_ci#define WC (7+pAT) /* WCC attributes */ 79562306a36Sopenharmony_ci 79662306a36Sopenharmony_cistatic const struct svc_procedure nfsd_procedures3[22] = { 79762306a36Sopenharmony_ci [NFS3PROC_NULL] = { 79862306a36Sopenharmony_ci .pc_func = nfsd3_proc_null, 79962306a36Sopenharmony_ci .pc_decode = nfssvc_decode_voidarg, 80062306a36Sopenharmony_ci .pc_encode = nfssvc_encode_voidres, 80162306a36Sopenharmony_ci .pc_argsize = sizeof(struct nfsd_voidargs), 80262306a36Sopenharmony_ci .pc_argzero = sizeof(struct nfsd_voidargs), 80362306a36Sopenharmony_ci .pc_ressize = sizeof(struct nfsd_voidres), 80462306a36Sopenharmony_ci .pc_cachetype = RC_NOCACHE, 80562306a36Sopenharmony_ci .pc_xdrressize = ST, 80662306a36Sopenharmony_ci .pc_name = "NULL", 80762306a36Sopenharmony_ci }, 80862306a36Sopenharmony_ci [NFS3PROC_GETATTR] = { 80962306a36Sopenharmony_ci .pc_func = nfsd3_proc_getattr, 81062306a36Sopenharmony_ci .pc_decode = nfs3svc_decode_fhandleargs, 81162306a36Sopenharmony_ci .pc_encode = nfs3svc_encode_getattrres, 81262306a36Sopenharmony_ci .pc_release = nfs3svc_release_fhandle, 81362306a36Sopenharmony_ci .pc_argsize = sizeof(struct nfsd_fhandle), 81462306a36Sopenharmony_ci .pc_argzero = sizeof(struct nfsd_fhandle), 81562306a36Sopenharmony_ci .pc_ressize = sizeof(struct nfsd3_attrstatres), 81662306a36Sopenharmony_ci .pc_cachetype = RC_NOCACHE, 81762306a36Sopenharmony_ci .pc_xdrressize = ST+AT, 81862306a36Sopenharmony_ci .pc_name = "GETATTR", 81962306a36Sopenharmony_ci }, 82062306a36Sopenharmony_ci [NFS3PROC_SETATTR] = { 82162306a36Sopenharmony_ci .pc_func = nfsd3_proc_setattr, 82262306a36Sopenharmony_ci .pc_decode = nfs3svc_decode_sattrargs, 82362306a36Sopenharmony_ci .pc_encode = nfs3svc_encode_wccstatres, 82462306a36Sopenharmony_ci .pc_release = nfs3svc_release_fhandle, 82562306a36Sopenharmony_ci .pc_argsize = sizeof(struct nfsd3_sattrargs), 82662306a36Sopenharmony_ci .pc_argzero = sizeof(struct nfsd3_sattrargs), 82762306a36Sopenharmony_ci .pc_ressize = sizeof(struct nfsd3_wccstatres), 82862306a36Sopenharmony_ci .pc_cachetype = RC_REPLBUFF, 82962306a36Sopenharmony_ci .pc_xdrressize = ST+WC, 83062306a36Sopenharmony_ci .pc_name = "SETATTR", 83162306a36Sopenharmony_ci }, 83262306a36Sopenharmony_ci [NFS3PROC_LOOKUP] = { 83362306a36Sopenharmony_ci .pc_func = nfsd3_proc_lookup, 83462306a36Sopenharmony_ci .pc_decode = nfs3svc_decode_diropargs, 83562306a36Sopenharmony_ci .pc_encode = nfs3svc_encode_lookupres, 83662306a36Sopenharmony_ci .pc_release = nfs3svc_release_fhandle2, 83762306a36Sopenharmony_ci .pc_argsize = sizeof(struct nfsd3_diropargs), 83862306a36Sopenharmony_ci .pc_argzero = sizeof(struct nfsd3_diropargs), 83962306a36Sopenharmony_ci .pc_ressize = sizeof(struct nfsd3_diropres), 84062306a36Sopenharmony_ci .pc_cachetype = RC_NOCACHE, 84162306a36Sopenharmony_ci .pc_xdrressize = ST+FH+pAT+pAT, 84262306a36Sopenharmony_ci .pc_name = "LOOKUP", 84362306a36Sopenharmony_ci }, 84462306a36Sopenharmony_ci [NFS3PROC_ACCESS] = { 84562306a36Sopenharmony_ci .pc_func = nfsd3_proc_access, 84662306a36Sopenharmony_ci .pc_decode = nfs3svc_decode_accessargs, 84762306a36Sopenharmony_ci .pc_encode = nfs3svc_encode_accessres, 84862306a36Sopenharmony_ci .pc_release = nfs3svc_release_fhandle, 84962306a36Sopenharmony_ci .pc_argsize = sizeof(struct nfsd3_accessargs), 85062306a36Sopenharmony_ci .pc_argzero = sizeof(struct nfsd3_accessargs), 85162306a36Sopenharmony_ci .pc_ressize = sizeof(struct nfsd3_accessres), 85262306a36Sopenharmony_ci .pc_cachetype = RC_NOCACHE, 85362306a36Sopenharmony_ci .pc_xdrressize = ST+pAT+1, 85462306a36Sopenharmony_ci .pc_name = "ACCESS", 85562306a36Sopenharmony_ci }, 85662306a36Sopenharmony_ci [NFS3PROC_READLINK] = { 85762306a36Sopenharmony_ci .pc_func = nfsd3_proc_readlink, 85862306a36Sopenharmony_ci .pc_decode = nfs3svc_decode_fhandleargs, 85962306a36Sopenharmony_ci .pc_encode = nfs3svc_encode_readlinkres, 86062306a36Sopenharmony_ci .pc_release = nfs3svc_release_fhandle, 86162306a36Sopenharmony_ci .pc_argsize = sizeof(struct nfsd_fhandle), 86262306a36Sopenharmony_ci .pc_argzero = sizeof(struct nfsd_fhandle), 86362306a36Sopenharmony_ci .pc_ressize = sizeof(struct nfsd3_readlinkres), 86462306a36Sopenharmony_ci .pc_cachetype = RC_NOCACHE, 86562306a36Sopenharmony_ci .pc_xdrressize = ST+pAT+1+NFS3_MAXPATHLEN/4, 86662306a36Sopenharmony_ci .pc_name = "READLINK", 86762306a36Sopenharmony_ci }, 86862306a36Sopenharmony_ci [NFS3PROC_READ] = { 86962306a36Sopenharmony_ci .pc_func = nfsd3_proc_read, 87062306a36Sopenharmony_ci .pc_decode = nfs3svc_decode_readargs, 87162306a36Sopenharmony_ci .pc_encode = nfs3svc_encode_readres, 87262306a36Sopenharmony_ci .pc_release = nfs3svc_release_fhandle, 87362306a36Sopenharmony_ci .pc_argsize = sizeof(struct nfsd3_readargs), 87462306a36Sopenharmony_ci .pc_argzero = sizeof(struct nfsd3_readargs), 87562306a36Sopenharmony_ci .pc_ressize = sizeof(struct nfsd3_readres), 87662306a36Sopenharmony_ci .pc_cachetype = RC_NOCACHE, 87762306a36Sopenharmony_ci .pc_xdrressize = ST+pAT+4+NFSSVC_MAXBLKSIZE/4, 87862306a36Sopenharmony_ci .pc_name = "READ", 87962306a36Sopenharmony_ci }, 88062306a36Sopenharmony_ci [NFS3PROC_WRITE] = { 88162306a36Sopenharmony_ci .pc_func = nfsd3_proc_write, 88262306a36Sopenharmony_ci .pc_decode = nfs3svc_decode_writeargs, 88362306a36Sopenharmony_ci .pc_encode = nfs3svc_encode_writeres, 88462306a36Sopenharmony_ci .pc_release = nfs3svc_release_fhandle, 88562306a36Sopenharmony_ci .pc_argsize = sizeof(struct nfsd3_writeargs), 88662306a36Sopenharmony_ci .pc_argzero = sizeof(struct nfsd3_writeargs), 88762306a36Sopenharmony_ci .pc_ressize = sizeof(struct nfsd3_writeres), 88862306a36Sopenharmony_ci .pc_cachetype = RC_REPLBUFF, 88962306a36Sopenharmony_ci .pc_xdrressize = ST+WC+4, 89062306a36Sopenharmony_ci .pc_name = "WRITE", 89162306a36Sopenharmony_ci }, 89262306a36Sopenharmony_ci [NFS3PROC_CREATE] = { 89362306a36Sopenharmony_ci .pc_func = nfsd3_proc_create, 89462306a36Sopenharmony_ci .pc_decode = nfs3svc_decode_createargs, 89562306a36Sopenharmony_ci .pc_encode = nfs3svc_encode_createres, 89662306a36Sopenharmony_ci .pc_release = nfs3svc_release_fhandle2, 89762306a36Sopenharmony_ci .pc_argsize = sizeof(struct nfsd3_createargs), 89862306a36Sopenharmony_ci .pc_argzero = sizeof(struct nfsd3_createargs), 89962306a36Sopenharmony_ci .pc_ressize = sizeof(struct nfsd3_createres), 90062306a36Sopenharmony_ci .pc_cachetype = RC_REPLBUFF, 90162306a36Sopenharmony_ci .pc_xdrressize = ST+(1+FH+pAT)+WC, 90262306a36Sopenharmony_ci .pc_name = "CREATE", 90362306a36Sopenharmony_ci }, 90462306a36Sopenharmony_ci [NFS3PROC_MKDIR] = { 90562306a36Sopenharmony_ci .pc_func = nfsd3_proc_mkdir, 90662306a36Sopenharmony_ci .pc_decode = nfs3svc_decode_mkdirargs, 90762306a36Sopenharmony_ci .pc_encode = nfs3svc_encode_createres, 90862306a36Sopenharmony_ci .pc_release = nfs3svc_release_fhandle2, 90962306a36Sopenharmony_ci .pc_argsize = sizeof(struct nfsd3_mkdirargs), 91062306a36Sopenharmony_ci .pc_argzero = sizeof(struct nfsd3_mkdirargs), 91162306a36Sopenharmony_ci .pc_ressize = sizeof(struct nfsd3_createres), 91262306a36Sopenharmony_ci .pc_cachetype = RC_REPLBUFF, 91362306a36Sopenharmony_ci .pc_xdrressize = ST+(1+FH+pAT)+WC, 91462306a36Sopenharmony_ci .pc_name = "MKDIR", 91562306a36Sopenharmony_ci }, 91662306a36Sopenharmony_ci [NFS3PROC_SYMLINK] = { 91762306a36Sopenharmony_ci .pc_func = nfsd3_proc_symlink, 91862306a36Sopenharmony_ci .pc_decode = nfs3svc_decode_symlinkargs, 91962306a36Sopenharmony_ci .pc_encode = nfs3svc_encode_createres, 92062306a36Sopenharmony_ci .pc_release = nfs3svc_release_fhandle2, 92162306a36Sopenharmony_ci .pc_argsize = sizeof(struct nfsd3_symlinkargs), 92262306a36Sopenharmony_ci .pc_argzero = sizeof(struct nfsd3_symlinkargs), 92362306a36Sopenharmony_ci .pc_ressize = sizeof(struct nfsd3_createres), 92462306a36Sopenharmony_ci .pc_cachetype = RC_REPLBUFF, 92562306a36Sopenharmony_ci .pc_xdrressize = ST+(1+FH+pAT)+WC, 92662306a36Sopenharmony_ci .pc_name = "SYMLINK", 92762306a36Sopenharmony_ci }, 92862306a36Sopenharmony_ci [NFS3PROC_MKNOD] = { 92962306a36Sopenharmony_ci .pc_func = nfsd3_proc_mknod, 93062306a36Sopenharmony_ci .pc_decode = nfs3svc_decode_mknodargs, 93162306a36Sopenharmony_ci .pc_encode = nfs3svc_encode_createres, 93262306a36Sopenharmony_ci .pc_release = nfs3svc_release_fhandle2, 93362306a36Sopenharmony_ci .pc_argsize = sizeof(struct nfsd3_mknodargs), 93462306a36Sopenharmony_ci .pc_argzero = sizeof(struct nfsd3_mknodargs), 93562306a36Sopenharmony_ci .pc_ressize = sizeof(struct nfsd3_createres), 93662306a36Sopenharmony_ci .pc_cachetype = RC_REPLBUFF, 93762306a36Sopenharmony_ci .pc_xdrressize = ST+(1+FH+pAT)+WC, 93862306a36Sopenharmony_ci .pc_name = "MKNOD", 93962306a36Sopenharmony_ci }, 94062306a36Sopenharmony_ci [NFS3PROC_REMOVE] = { 94162306a36Sopenharmony_ci .pc_func = nfsd3_proc_remove, 94262306a36Sopenharmony_ci .pc_decode = nfs3svc_decode_diropargs, 94362306a36Sopenharmony_ci .pc_encode = nfs3svc_encode_wccstatres, 94462306a36Sopenharmony_ci .pc_release = nfs3svc_release_fhandle, 94562306a36Sopenharmony_ci .pc_argsize = sizeof(struct nfsd3_diropargs), 94662306a36Sopenharmony_ci .pc_argzero = sizeof(struct nfsd3_diropargs), 94762306a36Sopenharmony_ci .pc_ressize = sizeof(struct nfsd3_wccstatres), 94862306a36Sopenharmony_ci .pc_cachetype = RC_REPLBUFF, 94962306a36Sopenharmony_ci .pc_xdrressize = ST+WC, 95062306a36Sopenharmony_ci .pc_name = "REMOVE", 95162306a36Sopenharmony_ci }, 95262306a36Sopenharmony_ci [NFS3PROC_RMDIR] = { 95362306a36Sopenharmony_ci .pc_func = nfsd3_proc_rmdir, 95462306a36Sopenharmony_ci .pc_decode = nfs3svc_decode_diropargs, 95562306a36Sopenharmony_ci .pc_encode = nfs3svc_encode_wccstatres, 95662306a36Sopenharmony_ci .pc_release = nfs3svc_release_fhandle, 95762306a36Sopenharmony_ci .pc_argsize = sizeof(struct nfsd3_diropargs), 95862306a36Sopenharmony_ci .pc_argzero = sizeof(struct nfsd3_diropargs), 95962306a36Sopenharmony_ci .pc_ressize = sizeof(struct nfsd3_wccstatres), 96062306a36Sopenharmony_ci .pc_cachetype = RC_REPLBUFF, 96162306a36Sopenharmony_ci .pc_xdrressize = ST+WC, 96262306a36Sopenharmony_ci .pc_name = "RMDIR", 96362306a36Sopenharmony_ci }, 96462306a36Sopenharmony_ci [NFS3PROC_RENAME] = { 96562306a36Sopenharmony_ci .pc_func = nfsd3_proc_rename, 96662306a36Sopenharmony_ci .pc_decode = nfs3svc_decode_renameargs, 96762306a36Sopenharmony_ci .pc_encode = nfs3svc_encode_renameres, 96862306a36Sopenharmony_ci .pc_release = nfs3svc_release_fhandle2, 96962306a36Sopenharmony_ci .pc_argsize = sizeof(struct nfsd3_renameargs), 97062306a36Sopenharmony_ci .pc_argzero = sizeof(struct nfsd3_renameargs), 97162306a36Sopenharmony_ci .pc_ressize = sizeof(struct nfsd3_renameres), 97262306a36Sopenharmony_ci .pc_cachetype = RC_REPLBUFF, 97362306a36Sopenharmony_ci .pc_xdrressize = ST+WC+WC, 97462306a36Sopenharmony_ci .pc_name = "RENAME", 97562306a36Sopenharmony_ci }, 97662306a36Sopenharmony_ci [NFS3PROC_LINK] = { 97762306a36Sopenharmony_ci .pc_func = nfsd3_proc_link, 97862306a36Sopenharmony_ci .pc_decode = nfs3svc_decode_linkargs, 97962306a36Sopenharmony_ci .pc_encode = nfs3svc_encode_linkres, 98062306a36Sopenharmony_ci .pc_release = nfs3svc_release_fhandle2, 98162306a36Sopenharmony_ci .pc_argsize = sizeof(struct nfsd3_linkargs), 98262306a36Sopenharmony_ci .pc_argzero = sizeof(struct nfsd3_linkargs), 98362306a36Sopenharmony_ci .pc_ressize = sizeof(struct nfsd3_linkres), 98462306a36Sopenharmony_ci .pc_cachetype = RC_REPLBUFF, 98562306a36Sopenharmony_ci .pc_xdrressize = ST+pAT+WC, 98662306a36Sopenharmony_ci .pc_name = "LINK", 98762306a36Sopenharmony_ci }, 98862306a36Sopenharmony_ci [NFS3PROC_READDIR] = { 98962306a36Sopenharmony_ci .pc_func = nfsd3_proc_readdir, 99062306a36Sopenharmony_ci .pc_decode = nfs3svc_decode_readdirargs, 99162306a36Sopenharmony_ci .pc_encode = nfs3svc_encode_readdirres, 99262306a36Sopenharmony_ci .pc_release = nfs3svc_release_fhandle, 99362306a36Sopenharmony_ci .pc_argsize = sizeof(struct nfsd3_readdirargs), 99462306a36Sopenharmony_ci .pc_argzero = sizeof(struct nfsd3_readdirargs), 99562306a36Sopenharmony_ci .pc_ressize = sizeof(struct nfsd3_readdirres), 99662306a36Sopenharmony_ci .pc_cachetype = RC_NOCACHE, 99762306a36Sopenharmony_ci .pc_name = "READDIR", 99862306a36Sopenharmony_ci }, 99962306a36Sopenharmony_ci [NFS3PROC_READDIRPLUS] = { 100062306a36Sopenharmony_ci .pc_func = nfsd3_proc_readdirplus, 100162306a36Sopenharmony_ci .pc_decode = nfs3svc_decode_readdirplusargs, 100262306a36Sopenharmony_ci .pc_encode = nfs3svc_encode_readdirres, 100362306a36Sopenharmony_ci .pc_release = nfs3svc_release_fhandle, 100462306a36Sopenharmony_ci .pc_argsize = sizeof(struct nfsd3_readdirplusargs), 100562306a36Sopenharmony_ci .pc_argzero = sizeof(struct nfsd3_readdirplusargs), 100662306a36Sopenharmony_ci .pc_ressize = sizeof(struct nfsd3_readdirres), 100762306a36Sopenharmony_ci .pc_cachetype = RC_NOCACHE, 100862306a36Sopenharmony_ci .pc_name = "READDIRPLUS", 100962306a36Sopenharmony_ci }, 101062306a36Sopenharmony_ci [NFS3PROC_FSSTAT] = { 101162306a36Sopenharmony_ci .pc_func = nfsd3_proc_fsstat, 101262306a36Sopenharmony_ci .pc_decode = nfs3svc_decode_fhandleargs, 101362306a36Sopenharmony_ci .pc_encode = nfs3svc_encode_fsstatres, 101462306a36Sopenharmony_ci .pc_argsize = sizeof(struct nfsd3_fhandleargs), 101562306a36Sopenharmony_ci .pc_argzero = sizeof(struct nfsd3_fhandleargs), 101662306a36Sopenharmony_ci .pc_ressize = sizeof(struct nfsd3_fsstatres), 101762306a36Sopenharmony_ci .pc_cachetype = RC_NOCACHE, 101862306a36Sopenharmony_ci .pc_xdrressize = ST+pAT+2*6+1, 101962306a36Sopenharmony_ci .pc_name = "FSSTAT", 102062306a36Sopenharmony_ci }, 102162306a36Sopenharmony_ci [NFS3PROC_FSINFO] = { 102262306a36Sopenharmony_ci .pc_func = nfsd3_proc_fsinfo, 102362306a36Sopenharmony_ci .pc_decode = nfs3svc_decode_fhandleargs, 102462306a36Sopenharmony_ci .pc_encode = nfs3svc_encode_fsinfores, 102562306a36Sopenharmony_ci .pc_argsize = sizeof(struct nfsd3_fhandleargs), 102662306a36Sopenharmony_ci .pc_argzero = sizeof(struct nfsd3_fhandleargs), 102762306a36Sopenharmony_ci .pc_ressize = sizeof(struct nfsd3_fsinfores), 102862306a36Sopenharmony_ci .pc_cachetype = RC_NOCACHE, 102962306a36Sopenharmony_ci .pc_xdrressize = ST+pAT+12, 103062306a36Sopenharmony_ci .pc_name = "FSINFO", 103162306a36Sopenharmony_ci }, 103262306a36Sopenharmony_ci [NFS3PROC_PATHCONF] = { 103362306a36Sopenharmony_ci .pc_func = nfsd3_proc_pathconf, 103462306a36Sopenharmony_ci .pc_decode = nfs3svc_decode_fhandleargs, 103562306a36Sopenharmony_ci .pc_encode = nfs3svc_encode_pathconfres, 103662306a36Sopenharmony_ci .pc_argsize = sizeof(struct nfsd3_fhandleargs), 103762306a36Sopenharmony_ci .pc_argzero = sizeof(struct nfsd3_fhandleargs), 103862306a36Sopenharmony_ci .pc_ressize = sizeof(struct nfsd3_pathconfres), 103962306a36Sopenharmony_ci .pc_cachetype = RC_NOCACHE, 104062306a36Sopenharmony_ci .pc_xdrressize = ST+pAT+6, 104162306a36Sopenharmony_ci .pc_name = "PATHCONF", 104262306a36Sopenharmony_ci }, 104362306a36Sopenharmony_ci [NFS3PROC_COMMIT] = { 104462306a36Sopenharmony_ci .pc_func = nfsd3_proc_commit, 104562306a36Sopenharmony_ci .pc_decode = nfs3svc_decode_commitargs, 104662306a36Sopenharmony_ci .pc_encode = nfs3svc_encode_commitres, 104762306a36Sopenharmony_ci .pc_release = nfs3svc_release_fhandle, 104862306a36Sopenharmony_ci .pc_argsize = sizeof(struct nfsd3_commitargs), 104962306a36Sopenharmony_ci .pc_argzero = sizeof(struct nfsd3_commitargs), 105062306a36Sopenharmony_ci .pc_ressize = sizeof(struct nfsd3_commitres), 105162306a36Sopenharmony_ci .pc_cachetype = RC_NOCACHE, 105262306a36Sopenharmony_ci .pc_xdrressize = ST+WC+2, 105362306a36Sopenharmony_ci .pc_name = "COMMIT", 105462306a36Sopenharmony_ci }, 105562306a36Sopenharmony_ci}; 105662306a36Sopenharmony_ci 105762306a36Sopenharmony_cistatic DEFINE_PER_CPU_ALIGNED(unsigned long, 105862306a36Sopenharmony_ci nfsd_count3[ARRAY_SIZE(nfsd_procedures3)]); 105962306a36Sopenharmony_ciconst struct svc_version nfsd_version3 = { 106062306a36Sopenharmony_ci .vs_vers = 3, 106162306a36Sopenharmony_ci .vs_nproc = ARRAY_SIZE(nfsd_procedures3), 106262306a36Sopenharmony_ci .vs_proc = nfsd_procedures3, 106362306a36Sopenharmony_ci .vs_dispatch = nfsd_dispatch, 106462306a36Sopenharmony_ci .vs_count = nfsd_count3, 106562306a36Sopenharmony_ci .vs_xdrsize = NFS3_SVC_XDRSIZE, 106662306a36Sopenharmony_ci}; 1067