Changeset View
Changeset View
Standalone View
Standalone View
sys/fs/nfs/nfs_commonport.c
Show All 36 Lines | |||||
__FBSDID("$FreeBSD$"); | __FBSDID("$FreeBSD$"); | ||||
/* | /* | ||||
* Functions that need to be different for different versions of BSD | * Functions that need to be different for different versions of BSD | ||||
* kernel should be kept here, along with any global storage specific | * kernel should be kept here, along with any global storage specific | ||||
* to this BSD variant. | * to this BSD variant. | ||||
*/ | */ | ||||
#include <fs/nfs/nfsport.h> | #include <fs/nfs/nfsport.h> | ||||
#include <sys/osd.h> | |||||
#include <sys/smp.h> | #include <sys/smp.h> | ||||
#include <sys/sysctl.h> | #include <sys/sysctl.h> | ||||
#include <sys/taskqueue.h> | #include <sys/taskqueue.h> | ||||
#include <rpc/rpc_com.h> | #include <rpc/rpc_com.h> | ||||
#include <vm/vm.h> | #include <vm/vm.h> | ||||
#include <vm/vm_object.h> | #include <vm/vm_object.h> | ||||
#include <vm/vm_page.h> | #include <vm/vm_page.h> | ||||
#include <vm/vm_param.h> | #include <vm/vm_param.h> | ||||
#include <vm/vm_map.h> | #include <vm/vm_map.h> | ||||
#include <vm/vm_kern.h> | #include <vm/vm_kern.h> | ||||
#include <vm/vm_extern.h> | #include <vm/vm_extern.h> | ||||
#include <vm/uma.h> | #include <vm/uma.h> | ||||
extern int nfscl_ticks; | extern int nfscl_ticks; | ||||
extern nfsuserd_state nfsrv_nfsuserd; | |||||
extern struct nfssockreq nfsrv_nfsuserdsock; | |||||
extern void (*nfsd_call_recall)(struct vnode *, int, struct ucred *, | extern void (*nfsd_call_recall)(struct vnode *, int, struct ucred *, | ||||
struct thread *); | struct thread *); | ||||
extern int nfsrv_useacl; | extern int nfsrv_useacl; | ||||
struct mount nfsv4root_mnt; | |||||
int newnfs_numnfsd = 0; | int newnfs_numnfsd = 0; | ||||
struct nfsstatsv1 nfsstatsv1; | struct nfsstatsv1 nfsstatsv1; | ||||
int nfs_numnfscbd = 0; | int nfs_numnfscbd = 0; | ||||
int nfscl_debuglevel = 0; | int nfscl_debuglevel = 0; | ||||
char nfsv4_callbackaddr[INET6_ADDRSTRLEN]; | char nfsv4_callbackaddr[INET6_ADDRSTRLEN]; | ||||
int nfsrv_lughashsize = 100; | int nfsrv_lughashsize = 100; | ||||
struct mtx nfsrv_dslock_mtx; | struct mtx nfsrv_dslock_mtx; | ||||
struct nfsdevicehead nfsrv_devidhead; | struct nfsdevicehead nfsrv_devidhead; | ||||
volatile int nfsrv_devidcnt = 0; | volatile int nfsrv_devidcnt = 0; | ||||
void (*ncl_call_invalcaches)(struct vnode *) = NULL; | void (*ncl_call_invalcaches)(struct vnode *) = NULL; | ||||
vop_advlock_t *nfs_advlock_p = NULL; | vop_advlock_t *nfs_advlock_p = NULL; | ||||
vop_reclaim_t *nfs_reclaim_p = NULL; | vop_reclaim_t *nfs_reclaim_p = NULL; | ||||
uint32_t nfs_srvmaxio = NFS_SRVMAXIO; | uint32_t nfs_srvmaxio = NFS_SRVMAXIO; | ||||
NFSD_VNET_DECLARE(struct nfsrv_lughash *, nfsuserhash); | |||||
NFSD_VNET_DECLARE(struct nfsrv_lughash *, nfsusernamehash); | |||||
NFSD_VNET_DECLARE(struct nfsrv_lughash *, nfsgrouphash); | |||||
NFSD_VNET_DECLARE(struct nfsrv_lughash *, nfsgroupnamehash); | |||||
NFSD_VNET_DECLARE(u_char *, nfsrv_dnsname); | |||||
NFSD_VNET_DECLARE(struct nfssockreq, nfsrv_nfsuserdsock); | |||||
NFSD_VNET_DECLARE(nfsuserd_state, nfsrv_nfsuserd); | |||||
NFSDSTATSDEFINE(nfsstatsv1); | |||||
int nfs_pnfsio(task_fn_t *, void *); | int nfs_pnfsio(task_fn_t *, void *); | ||||
static int nfs_realign_test; | static int nfs_realign_test; | ||||
static int nfs_realign_count; | static int nfs_realign_count; | ||||
static struct ext_nfsstats oldnfsstats; | static struct ext_nfsstats oldnfsstats; | ||||
static struct nfsstatsov1 nfsstatsov1; | static struct nfsstatsov1 nfsstatsov1; | ||||
SYSCTL_NODE(_vfs, OID_AUTO, nfs, CTLFLAG_RW | CTLFLAG_MPSAFE, 0, | SYSCTL_NODE(_vfs, OID_AUTO, nfs, CTLFLAG_RW | CTLFLAG_MPSAFE, 0, | ||||
▲ Show 20 Lines • Show All 57 Lines • ▼ Show 20 Lines | |||||
struct mtx nfs_state_mutex; | struct mtx nfs_state_mutex; | ||||
struct mtx nfs_nameid_mutex; | struct mtx nfs_nameid_mutex; | ||||
struct mtx nfs_req_mutex; | struct mtx nfs_req_mutex; | ||||
struct mtx nfs_slock_mutex; | struct mtx nfs_slock_mutex; | ||||
struct mtx nfs_clstate_mutex; | struct mtx nfs_clstate_mutex; | ||||
/* local functions */ | /* local functions */ | ||||
static int nfssvc_call(struct thread *, struct nfssvc_args *, struct ucred *); | static int nfssvc_call(struct thread *, struct nfssvc_args *, struct ucred *); | ||||
static void nfsrv_cleanusergroup(struct prison *); | |||||
#ifdef __NO_STRICT_ALIGNMENT | #ifdef __NO_STRICT_ALIGNMENT | ||||
/* | /* | ||||
* These architectures don't need re-alignment, so just return. | * These architectures don't need re-alignment, so just return. | ||||
*/ | */ | ||||
int | int | ||||
newnfs_realign(struct mbuf **pm, int how) | newnfs_realign(struct mbuf **pm, int how) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 268 Lines • ▼ Show 20 Lines | nfsv4root_getreferral(struct vnode *vp, struct vnode *dvp, u_int32_t fileno) | ||||
return (NULL); | return (NULL); | ||||
} | } | ||||
static int | static int | ||||
nfssvc_nfscommon(struct thread *td, struct nfssvc_args *uap) | nfssvc_nfscommon(struct thread *td, struct nfssvc_args *uap) | ||||
{ | { | ||||
int error; | int error; | ||||
NFSD_CURVNET_SET(NFSD_TD_TO_VNET(td)); | |||||
error = nfssvc_call(td, uap, td->td_ucred); | error = nfssvc_call(td, uap, td->td_ucred); | ||||
NFSD_CURVNET_RESTORE(); | |||||
NFSEXITCODE(error); | NFSEXITCODE(error); | ||||
return (error); | return (error); | ||||
} | } | ||||
static int | static int | ||||
nfssvc_call(struct thread *p, struct nfssvc_args *uap, struct ucred *cred) | nfssvc_call(struct thread *p, struct nfssvc_args *uap, struct ucred *cred) | ||||
{ | { | ||||
int error = EINVAL, i, j; | int error = EINVAL, i, j; | ||||
struct nfsd_idargs nid; | struct nfsd_idargs nid; | ||||
struct nfsd_oidargs onid; | struct nfsd_oidargs onid; | ||||
struct { | struct { | ||||
int vers; /* Just the first field of nfsstats. */ | int vers; /* Just the first field of nfsstats. */ | ||||
} nfsstatver; | } nfsstatver; | ||||
struct nfsstatsv1 *outstats; | |||||
if (uap->flag & NFSSVC_IDNAME) { | if (uap->flag & NFSSVC_IDNAME) { | ||||
if ((uap->flag & NFSSVC_NEWSTRUCT) != 0) | if ((uap->flag & NFSSVC_NEWSTRUCT) != 0) | ||||
error = copyin(uap->argp, &nid, sizeof(nid)); | error = copyin(uap->argp, &nid, sizeof(nid)); | ||||
else { | else { | ||||
error = copyin(uap->argp, &onid, sizeof(onid)); | error = copyin(uap->argp, &onid, sizeof(onid)); | ||||
if (error == 0) { | if (error == 0) { | ||||
nid.nid_flag = onid.nid_flag; | nid.nid_flag = onid.nid_flag; | ||||
nid.nid_uid = onid.nid_uid; | nid.nid_uid = onid.nid_uid; | ||||
nid.nid_gid = onid.nid_gid; | nid.nid_gid = onid.nid_gid; | ||||
nid.nid_usermax = onid.nid_usermax; | nid.nid_usermax = onid.nid_usermax; | ||||
nid.nid_usertimeout = onid.nid_usertimeout; | nid.nid_usertimeout = onid.nid_usertimeout; | ||||
nid.nid_name = onid.nid_name; | nid.nid_name = onid.nid_name; | ||||
nid.nid_namelen = onid.nid_namelen; | nid.nid_namelen = onid.nid_namelen; | ||||
nid.nid_ngroup = 0; | nid.nid_ngroup = 0; | ||||
nid.nid_grps = NULL; | nid.nid_grps = NULL; | ||||
} | } | ||||
} | } | ||||
if (error) | if (error) | ||||
goto out; | goto out; | ||||
error = nfssvc_idname(&nid); | error = nfssvc_idname(&nid); | ||||
goto out; | goto out; | ||||
} else if (uap->flag & NFSSVC_GETSTATS) { | } else if (uap->flag & NFSSVC_GETSTATS) { | ||||
#ifdef VIMAGE | |||||
outstats = malloc(sizeof(*outstats), M_TEMP, M_WAITOK | M_ZERO); | |||||
#else | |||||
outstats = &nfsstatsv1; | |||||
#endif | |||||
nfsd_copy_vnetstats(); | |||||
if ((uap->flag & NFSSVC_NEWSTRUCT) == 0) { | if ((uap->flag & NFSSVC_NEWSTRUCT) == 0) { | ||||
/* Copy fields to the old ext_nfsstat structure. */ | /* Copy fields to the old ext_nfsstat structure. */ | ||||
oldnfsstats.attrcache_hits = | oldnfsstats.attrcache_hits = | ||||
nfsstatsv1.attrcache_hits; | outstats->attrcache_hits; | ||||
oldnfsstats.attrcache_misses = | oldnfsstats.attrcache_misses = | ||||
nfsstatsv1.attrcache_misses; | outstats->attrcache_misses; | ||||
oldnfsstats.lookupcache_hits = | oldnfsstats.lookupcache_hits = | ||||
nfsstatsv1.lookupcache_hits; | outstats->lookupcache_hits; | ||||
oldnfsstats.lookupcache_misses = | oldnfsstats.lookupcache_misses = | ||||
nfsstatsv1.lookupcache_misses; | outstats->lookupcache_misses; | ||||
oldnfsstats.direofcache_hits = | oldnfsstats.direofcache_hits = | ||||
nfsstatsv1.direofcache_hits; | outstats->direofcache_hits; | ||||
oldnfsstats.direofcache_misses = | oldnfsstats.direofcache_misses = | ||||
nfsstatsv1.direofcache_misses; | outstats->direofcache_misses; | ||||
oldnfsstats.accesscache_hits = | oldnfsstats.accesscache_hits = | ||||
nfsstatsv1.accesscache_hits; | outstats->accesscache_hits; | ||||
oldnfsstats.accesscache_misses = | oldnfsstats.accesscache_misses = | ||||
nfsstatsv1.accesscache_misses; | outstats->accesscache_misses; | ||||
oldnfsstats.biocache_reads = | oldnfsstats.biocache_reads = | ||||
nfsstatsv1.biocache_reads; | outstats->biocache_reads; | ||||
oldnfsstats.read_bios = | oldnfsstats.read_bios = | ||||
nfsstatsv1.read_bios; | outstats->read_bios; | ||||
oldnfsstats.read_physios = | oldnfsstats.read_physios = | ||||
nfsstatsv1.read_physios; | outstats->read_physios; | ||||
oldnfsstats.biocache_writes = | oldnfsstats.biocache_writes = | ||||
nfsstatsv1.biocache_writes; | outstats->biocache_writes; | ||||
oldnfsstats.write_bios = | oldnfsstats.write_bios = | ||||
nfsstatsv1.write_bios; | outstats->write_bios; | ||||
oldnfsstats.write_physios = | oldnfsstats.write_physios = | ||||
nfsstatsv1.write_physios; | outstats->write_physios; | ||||
oldnfsstats.biocache_readlinks = | oldnfsstats.biocache_readlinks = | ||||
nfsstatsv1.biocache_readlinks; | outstats->biocache_readlinks; | ||||
oldnfsstats.readlink_bios = | oldnfsstats.readlink_bios = | ||||
nfsstatsv1.readlink_bios; | outstats->readlink_bios; | ||||
oldnfsstats.biocache_readdirs = | oldnfsstats.biocache_readdirs = | ||||
nfsstatsv1.biocache_readdirs; | outstats->biocache_readdirs; | ||||
oldnfsstats.readdir_bios = | oldnfsstats.readdir_bios = | ||||
nfsstatsv1.readdir_bios; | outstats->readdir_bios; | ||||
for (i = 0; i < NFSV4_NPROCS; i++) | for (i = 0; i < NFSV4_NPROCS; i++) | ||||
oldnfsstats.rpccnt[i] = nfsstatsv1.rpccnt[i]; | oldnfsstats.rpccnt[i] = outstats->rpccnt[i]; | ||||
oldnfsstats.rpcretries = nfsstatsv1.rpcretries; | oldnfsstats.rpcretries = outstats->rpcretries; | ||||
for (i = 0; i < NFSV4OP_NOPS; i++) | for (i = 0; i < NFSV4OP_NOPS; i++) | ||||
oldnfsstats.srvrpccnt[i] = | oldnfsstats.srvrpccnt[i] = | ||||
nfsstatsv1.srvrpccnt[i]; | outstats->srvrpccnt[i]; | ||||
for (i = NFSV42_NOPS, j = NFSV4OP_NOPS; | for (i = NFSV42_NOPS, j = NFSV4OP_NOPS; | ||||
i < NFSV42_NOPS + NFSV4OP_FAKENOPS; i++, j++) | i < NFSV42_NOPS + NFSV4OP_FAKENOPS; i++, j++) | ||||
oldnfsstats.srvrpccnt[j] = | oldnfsstats.srvrpccnt[j] = | ||||
nfsstatsv1.srvrpccnt[i]; | outstats->srvrpccnt[i]; | ||||
oldnfsstats.reserved_0 = 0; | oldnfsstats.reserved_0 = 0; | ||||
oldnfsstats.reserved_1 = 0; | oldnfsstats.reserved_1 = 0; | ||||
oldnfsstats.rpcrequests = nfsstatsv1.rpcrequests; | oldnfsstats.rpcrequests = outstats->rpcrequests; | ||||
oldnfsstats.rpctimeouts = nfsstatsv1.rpctimeouts; | oldnfsstats.rpctimeouts = outstats->rpctimeouts; | ||||
oldnfsstats.rpcunexpected = nfsstatsv1.rpcunexpected; | oldnfsstats.rpcunexpected = outstats->rpcunexpected; | ||||
oldnfsstats.rpcinvalid = nfsstatsv1.rpcinvalid; | oldnfsstats.rpcinvalid = outstats->rpcinvalid; | ||||
oldnfsstats.srvcache_inproghits = | oldnfsstats.srvcache_inproghits = | ||||
nfsstatsv1.srvcache_inproghits; | outstats->srvcache_inproghits; | ||||
oldnfsstats.reserved_2 = 0; | oldnfsstats.reserved_2 = 0; | ||||
oldnfsstats.srvcache_nonidemdonehits = | oldnfsstats.srvcache_nonidemdonehits = | ||||
nfsstatsv1.srvcache_nonidemdonehits; | outstats->srvcache_nonidemdonehits; | ||||
oldnfsstats.srvcache_misses = | oldnfsstats.srvcache_misses = | ||||
nfsstatsv1.srvcache_misses; | outstats->srvcache_misses; | ||||
oldnfsstats.srvcache_tcppeak = | oldnfsstats.srvcache_tcppeak = | ||||
nfsstatsv1.srvcache_tcppeak; | outstats->srvcache_tcppeak; | ||||
oldnfsstats.srvcache_size = nfsstatsv1.srvcache_size; | oldnfsstats.srvcache_size = outstats->srvcache_size; | ||||
oldnfsstats.srvclients = nfsstatsv1.srvclients; | oldnfsstats.srvclients = outstats->srvclients; | ||||
oldnfsstats.srvopenowners = nfsstatsv1.srvopenowners; | oldnfsstats.srvopenowners = outstats->srvopenowners; | ||||
oldnfsstats.srvopens = nfsstatsv1.srvopens; | oldnfsstats.srvopens = outstats->srvopens; | ||||
oldnfsstats.srvlockowners = nfsstatsv1.srvlockowners; | oldnfsstats.srvlockowners = outstats->srvlockowners; | ||||
oldnfsstats.srvlocks = nfsstatsv1.srvlocks; | oldnfsstats.srvlocks = outstats->srvlocks; | ||||
oldnfsstats.srvdelegates = nfsstatsv1.srvdelegates; | oldnfsstats.srvdelegates = outstats->srvdelegates; | ||||
for (i = 0; i < NFSV4OP_CBNOPS; i++) | for (i = 0; i < NFSV4OP_CBNOPS; i++) | ||||
oldnfsstats.cbrpccnt[i] = | oldnfsstats.cbrpccnt[i] = | ||||
nfsstatsv1.cbrpccnt[i]; | outstats->cbrpccnt[i]; | ||||
oldnfsstats.clopenowners = nfsstatsv1.clopenowners; | oldnfsstats.clopenowners = outstats->clopenowners; | ||||
oldnfsstats.clopens = nfsstatsv1.clopens; | oldnfsstats.clopens = outstats->clopens; | ||||
oldnfsstats.cllockowners = nfsstatsv1.cllockowners; | oldnfsstats.cllockowners = outstats->cllockowners; | ||||
oldnfsstats.cllocks = nfsstatsv1.cllocks; | oldnfsstats.cllocks = outstats->cllocks; | ||||
oldnfsstats.cldelegates = nfsstatsv1.cldelegates; | oldnfsstats.cldelegates = outstats->cldelegates; | ||||
oldnfsstats.cllocalopenowners = | oldnfsstats.cllocalopenowners = | ||||
nfsstatsv1.cllocalopenowners; | outstats->cllocalopenowners; | ||||
oldnfsstats.cllocalopens = nfsstatsv1.cllocalopens; | oldnfsstats.cllocalopens = outstats->cllocalopens; | ||||
oldnfsstats.cllocallockowners = | oldnfsstats.cllocallockowners = | ||||
nfsstatsv1.cllocallockowners; | outstats->cllocallockowners; | ||||
oldnfsstats.cllocallocks = nfsstatsv1.cllocallocks; | oldnfsstats.cllocallocks = outstats->cllocallocks; | ||||
error = copyout(&oldnfsstats, uap->argp, | error = copyout(&oldnfsstats, uap->argp, | ||||
sizeof (oldnfsstats)); | sizeof (oldnfsstats)); | ||||
} else { | } else { | ||||
error = copyin(uap->argp, &nfsstatver, | error = copyin(uap->argp, &nfsstatver, | ||||
sizeof(nfsstatver)); | sizeof(nfsstatver)); | ||||
if (error == 0) { | if (error == 0) { | ||||
if (nfsstatver.vers == NFSSTATS_OV1) { | if (nfsstatver.vers == NFSSTATS_OV1) { | ||||
/* Copy nfsstatsv1 to nfsstatsov1. */ | /* Copy outstats to nfsstatsov1. */ | ||||
nfsstatsov1.attrcache_hits = | nfsstatsov1.attrcache_hits = | ||||
nfsstatsv1.attrcache_hits; | outstats->attrcache_hits; | ||||
nfsstatsov1.attrcache_misses = | nfsstatsov1.attrcache_misses = | ||||
nfsstatsv1.attrcache_misses; | outstats->attrcache_misses; | ||||
nfsstatsov1.lookupcache_hits = | nfsstatsov1.lookupcache_hits = | ||||
nfsstatsv1.lookupcache_hits; | outstats->lookupcache_hits; | ||||
nfsstatsov1.lookupcache_misses = | nfsstatsov1.lookupcache_misses = | ||||
nfsstatsv1.lookupcache_misses; | outstats->lookupcache_misses; | ||||
nfsstatsov1.direofcache_hits = | nfsstatsov1.direofcache_hits = | ||||
nfsstatsv1.direofcache_hits; | outstats->direofcache_hits; | ||||
nfsstatsov1.direofcache_misses = | nfsstatsov1.direofcache_misses = | ||||
nfsstatsv1.direofcache_misses; | outstats->direofcache_misses; | ||||
nfsstatsov1.accesscache_hits = | nfsstatsov1.accesscache_hits = | ||||
nfsstatsv1.accesscache_hits; | outstats->accesscache_hits; | ||||
nfsstatsov1.accesscache_misses = | nfsstatsov1.accesscache_misses = | ||||
nfsstatsv1.accesscache_misses; | outstats->accesscache_misses; | ||||
nfsstatsov1.biocache_reads = | nfsstatsov1.biocache_reads = | ||||
nfsstatsv1.biocache_reads; | outstats->biocache_reads; | ||||
nfsstatsov1.read_bios = | nfsstatsov1.read_bios = | ||||
nfsstatsv1.read_bios; | outstats->read_bios; | ||||
nfsstatsov1.read_physios = | nfsstatsov1.read_physios = | ||||
nfsstatsv1.read_physios; | outstats->read_physios; | ||||
nfsstatsov1.biocache_writes = | nfsstatsov1.biocache_writes = | ||||
nfsstatsv1.biocache_writes; | outstats->biocache_writes; | ||||
nfsstatsov1.write_bios = | nfsstatsov1.write_bios = | ||||
nfsstatsv1.write_bios; | outstats->write_bios; | ||||
nfsstatsov1.write_physios = | nfsstatsov1.write_physios = | ||||
nfsstatsv1.write_physios; | outstats->write_physios; | ||||
nfsstatsov1.biocache_readlinks = | nfsstatsov1.biocache_readlinks = | ||||
nfsstatsv1.biocache_readlinks; | outstats->biocache_readlinks; | ||||
nfsstatsov1.readlink_bios = | nfsstatsov1.readlink_bios = | ||||
nfsstatsv1.readlink_bios; | outstats->readlink_bios; | ||||
nfsstatsov1.biocache_readdirs = | nfsstatsov1.biocache_readdirs = | ||||
nfsstatsv1.biocache_readdirs; | outstats->biocache_readdirs; | ||||
nfsstatsov1.readdir_bios = | nfsstatsov1.readdir_bios = | ||||
nfsstatsv1.readdir_bios; | outstats->readdir_bios; | ||||
for (i = 0; i < NFSV42_OLDNPROCS; i++) | for (i = 0; i < NFSV42_OLDNPROCS; i++) | ||||
nfsstatsov1.rpccnt[i] = | nfsstatsov1.rpccnt[i] = | ||||
nfsstatsv1.rpccnt[i]; | outstats->rpccnt[i]; | ||||
nfsstatsov1.rpcretries = | nfsstatsov1.rpcretries = | ||||
nfsstatsv1.rpcretries; | outstats->rpcretries; | ||||
for (i = 0; i < NFSV42_PURENOPS; i++) | for (i = 0; i < NFSV42_PURENOPS; i++) | ||||
nfsstatsov1.srvrpccnt[i] = | nfsstatsov1.srvrpccnt[i] = | ||||
nfsstatsv1.srvrpccnt[i]; | outstats->srvrpccnt[i]; | ||||
for (i = NFSV42_NOPS, | for (i = NFSV42_NOPS, | ||||
j = NFSV42_PURENOPS; | j = NFSV42_PURENOPS; | ||||
i < NFSV42_NOPS + NFSV4OP_FAKENOPS; | i < NFSV42_NOPS + NFSV4OP_FAKENOPS; | ||||
i++, j++) | i++, j++) | ||||
nfsstatsov1.srvrpccnt[j] = | nfsstatsov1.srvrpccnt[j] = | ||||
nfsstatsv1.srvrpccnt[i]; | outstats->srvrpccnt[i]; | ||||
nfsstatsov1.reserved_0 = 0; | nfsstatsov1.reserved_0 = 0; | ||||
nfsstatsov1.reserved_1 = 0; | nfsstatsov1.reserved_1 = 0; | ||||
nfsstatsov1.rpcrequests = | nfsstatsov1.rpcrequests = | ||||
nfsstatsv1.rpcrequests; | outstats->rpcrequests; | ||||
nfsstatsov1.rpctimeouts = | nfsstatsov1.rpctimeouts = | ||||
nfsstatsv1.rpctimeouts; | outstats->rpctimeouts; | ||||
nfsstatsov1.rpcunexpected = | nfsstatsov1.rpcunexpected = | ||||
nfsstatsv1.rpcunexpected; | outstats->rpcunexpected; | ||||
nfsstatsov1.rpcinvalid = | nfsstatsov1.rpcinvalid = | ||||
nfsstatsv1.rpcinvalid; | outstats->rpcinvalid; | ||||
nfsstatsov1.srvcache_inproghits = | nfsstatsov1.srvcache_inproghits = | ||||
nfsstatsv1.srvcache_inproghits; | outstats->srvcache_inproghits; | ||||
nfsstatsov1.reserved_2 = 0; | nfsstatsov1.reserved_2 = 0; | ||||
nfsstatsov1.srvcache_nonidemdonehits = | nfsstatsov1.srvcache_nonidemdonehits = | ||||
nfsstatsv1.srvcache_nonidemdonehits; | outstats->srvcache_nonidemdonehits; | ||||
nfsstatsov1.srvcache_misses = | nfsstatsov1.srvcache_misses = | ||||
nfsstatsv1.srvcache_misses; | outstats->srvcache_misses; | ||||
nfsstatsov1.srvcache_tcppeak = | nfsstatsov1.srvcache_tcppeak = | ||||
nfsstatsv1.srvcache_tcppeak; | outstats->srvcache_tcppeak; | ||||
nfsstatsov1.srvcache_size = | nfsstatsov1.srvcache_size = | ||||
nfsstatsv1.srvcache_size; | outstats->srvcache_size; | ||||
nfsstatsov1.srvclients = | nfsstatsov1.srvclients = | ||||
nfsstatsv1.srvclients; | outstats->srvclients; | ||||
nfsstatsov1.srvopenowners = | nfsstatsov1.srvopenowners = | ||||
nfsstatsv1.srvopenowners; | outstats->srvopenowners; | ||||
nfsstatsov1.srvopens = | nfsstatsov1.srvopens = | ||||
nfsstatsv1.srvopens; | outstats->srvopens; | ||||
nfsstatsov1.srvlockowners = | nfsstatsov1.srvlockowners = | ||||
nfsstatsv1.srvlockowners; | outstats->srvlockowners; | ||||
nfsstatsov1.srvlocks = | nfsstatsov1.srvlocks = | ||||
nfsstatsv1.srvlocks; | outstats->srvlocks; | ||||
nfsstatsov1.srvdelegates = | nfsstatsov1.srvdelegates = | ||||
nfsstatsv1.srvdelegates; | outstats->srvdelegates; | ||||
for (i = 0; i < NFSV42_CBNOPS; i++) | for (i = 0; i < NFSV42_CBNOPS; i++) | ||||
nfsstatsov1.cbrpccnt[i] = | nfsstatsov1.cbrpccnt[i] = | ||||
nfsstatsv1.cbrpccnt[i]; | outstats->cbrpccnt[i]; | ||||
nfsstatsov1.clopenowners = | nfsstatsov1.clopenowners = | ||||
nfsstatsv1.clopenowners; | outstats->clopenowners; | ||||
nfsstatsov1.clopens = | nfsstatsov1.clopens = | ||||
nfsstatsv1.clopens; | outstats->clopens; | ||||
nfsstatsov1.cllockowners = | nfsstatsov1.cllockowners = | ||||
nfsstatsv1.cllockowners; | outstats->cllockowners; | ||||
nfsstatsov1.cllocks = | nfsstatsov1.cllocks = | ||||
nfsstatsv1.cllocks; | outstats->cllocks; | ||||
nfsstatsov1.cldelegates = | nfsstatsov1.cldelegates = | ||||
nfsstatsv1.cldelegates; | outstats->cldelegates; | ||||
nfsstatsov1.cllocalopenowners = | nfsstatsov1.cllocalopenowners = | ||||
nfsstatsv1.cllocalopenowners; | outstats->cllocalopenowners; | ||||
nfsstatsov1.cllocalopens = | nfsstatsov1.cllocalopens = | ||||
nfsstatsv1.cllocalopens; | outstats->cllocalopens; | ||||
nfsstatsov1.cllocallockowners = | nfsstatsov1.cllocallockowners = | ||||
nfsstatsv1.cllocallockowners; | outstats->cllocallockowners; | ||||
nfsstatsov1.cllocallocks = | nfsstatsov1.cllocallocks = | ||||
nfsstatsv1.cllocallocks; | outstats->cllocallocks; | ||||
nfsstatsov1.srvstartcnt = | nfsstatsov1.srvstartcnt = | ||||
nfsstatsv1.srvstartcnt; | outstats->srvstartcnt; | ||||
nfsstatsov1.srvdonecnt = | nfsstatsov1.srvdonecnt = | ||||
nfsstatsv1.srvdonecnt; | outstats->srvdonecnt; | ||||
for (i = NFSV42_NOPS, | for (i = NFSV42_NOPS, | ||||
j = NFSV42_PURENOPS; | j = NFSV42_PURENOPS; | ||||
i < NFSV42_NOPS + NFSV4OP_FAKENOPS; | i < NFSV42_NOPS + NFSV4OP_FAKENOPS; | ||||
i++, j++) { | i++, j++) { | ||||
nfsstatsov1.srvbytes[j] = | nfsstatsov1.srvbytes[j] = | ||||
nfsstatsv1.srvbytes[i]; | outstats->srvbytes[i]; | ||||
nfsstatsov1.srvops[j] = | nfsstatsov1.srvops[j] = | ||||
nfsstatsv1.srvops[i]; | outstats->srvops[i]; | ||||
nfsstatsov1.srvduration[j] = | nfsstatsov1.srvduration[j] = | ||||
nfsstatsv1.srvduration[i]; | outstats->srvduration[i]; | ||||
} | } | ||||
nfsstatsov1.busyfrom = | nfsstatsov1.busyfrom = | ||||
nfsstatsv1.busyfrom; | outstats->busyfrom; | ||||
nfsstatsov1.busyfrom = | nfsstatsov1.busyfrom = | ||||
nfsstatsv1.busyfrom; | outstats->busyfrom; | ||||
error = copyout(&nfsstatsov1, uap->argp, | error = copyout(&nfsstatsov1, uap->argp, | ||||
sizeof(nfsstatsov1)); | sizeof(nfsstatsov1)); | ||||
} else if (nfsstatver.vers != NFSSTATS_V1) | } else if (nfsstatver.vers != NFSSTATS_V1) | ||||
error = EPERM; | error = EPERM; | ||||
else | else | ||||
error = copyout(&nfsstatsv1, uap->argp, | error = copyout(outstats, uap->argp, | ||||
sizeof(nfsstatsv1)); | sizeof(nfsstatsv1)); | ||||
} | } | ||||
} | } | ||||
if (error == 0) { | if (error == 0) { | ||||
if ((uap->flag & NFSSVC_ZEROCLTSTATS) != 0) { | if ((uap->flag & NFSSVC_ZEROCLTSTATS) != 0) { | ||||
nfsstatsv1.attrcache_hits = 0; | nfsstatsv1.attrcache_hits = 0; | ||||
nfsstatsv1.attrcache_misses = 0; | nfsstatsv1.attrcache_misses = 0; | ||||
nfsstatsv1.lookupcache_hits = 0; | nfsstatsv1.lookupcache_hits = 0; | ||||
Show All 14 Lines | if (error == 0) { | ||||
nfsstatsv1.readdir_bios = 0; | nfsstatsv1.readdir_bios = 0; | ||||
nfsstatsv1.rpcretries = 0; | nfsstatsv1.rpcretries = 0; | ||||
nfsstatsv1.rpcrequests = 0; | nfsstatsv1.rpcrequests = 0; | ||||
nfsstatsv1.rpctimeouts = 0; | nfsstatsv1.rpctimeouts = 0; | ||||
nfsstatsv1.rpcunexpected = 0; | nfsstatsv1.rpcunexpected = 0; | ||||
nfsstatsv1.rpcinvalid = 0; | nfsstatsv1.rpcinvalid = 0; | ||||
bzero(nfsstatsv1.rpccnt, | bzero(nfsstatsv1.rpccnt, | ||||
sizeof(nfsstatsv1.rpccnt)); | sizeof(nfsstatsv1.rpccnt)); | ||||
bzero(nfsstatsv1.cbrpccnt, | |||||
sizeof(nfsstatsv1.cbrpccnt)); | |||||
} | } | ||||
if ((uap->flag & NFSSVC_ZEROSRVSTATS) != 0) { | if ((uap->flag & NFSSVC_ZEROSRVSTATS) != 0) { | ||||
nfsd_zero_vnetstats(); | |||||
nfsstatsv1.srvcache_inproghits = 0; | nfsstatsv1.srvcache_inproghits = 0; | ||||
nfsstatsv1.srvcache_nonidemdonehits = 0; | nfsstatsv1.srvcache_nonidemdonehits = 0; | ||||
nfsstatsv1.srvcache_misses = 0; | nfsstatsv1.srvcache_misses = 0; | ||||
nfsstatsv1.srvcache_tcppeak = 0; | nfsstatsv1.srvcache_tcppeak = 0; | ||||
bzero(nfsstatsv1.srvrpccnt, | bzero(nfsstatsv1.srvrpccnt, | ||||
sizeof(nfsstatsv1.srvrpccnt)); | sizeof(nfsstatsv1.srvrpccnt)); | ||||
bzero(nfsstatsv1.cbrpccnt, | |||||
sizeof(nfsstatsv1.cbrpccnt)); | |||||
} | } | ||||
} | } | ||||
#ifdef VIMAGE | |||||
free(outstats, M_TEMP); | |||||
#endif | |||||
goto out; | goto out; | ||||
} else if (uap->flag & NFSSVC_NFSUSERDPORT) { | } else if (uap->flag & NFSSVC_NFSUSERDPORT) { | ||||
u_short sockport; | u_short sockport; | ||||
struct nfsuserd_args nargs; | struct nfsuserd_args nargs; | ||||
if ((uap->flag & NFSSVC_NEWSTRUCT) == 0) { | if ((uap->flag & NFSSVC_NEWSTRUCT) == 0) { | ||||
error = copyin(uap->argp, (caddr_t)&sockport, | error = copyin(uap->argp, (caddr_t)&sockport, | ||||
sizeof (u_short)); | sizeof (u_short)); | ||||
▲ Show 20 Lines • Show All 99 Lines • ▼ Show 20 Lines | nfs_pnfsio(task_fn_t *func, void *context) | ||||
pio->inprog = 1; | pio->inprog = 1; | ||||
TASK_INIT(&pio->tsk, 0, func, context); | TASK_INIT(&pio->tsk, 0, func, context); | ||||
ret = taskqueue_enqueue(pnfsioq, &pio->tsk); | ret = taskqueue_enqueue(pnfsioq, &pio->tsk); | ||||
if (ret != 0) | if (ret != 0) | ||||
pio->inprog = 0; | pio->inprog = 0; | ||||
return (ret); | return (ret); | ||||
} | } | ||||
/* | |||||
* Free up all the allocations related to the name<-->id cache. | |||||
* This function should only be called when the nfsuserd daemon isn't | |||||
* running, since it doesn't do any locking. | |||||
* This function is meant to be called when a vnet jail is destroyed. | |||||
*/ | |||||
static void | |||||
nfsrv_cleanusergroup(struct prison *pr) | |||||
{ | |||||
struct nfsrv_lughash *hp, *hp2; | |||||
struct nfsusrgrp *nusrp, *usrp; | |||||
int i; | |||||
NFSD_CURVNET_SET(pr->pr_vnet); | |||||
mtx_destroy(&NFSD_VNET(nfsrv_nfsuserdsock).nr_mtx); | |||||
if (NFSD_VNET(nfsuserhash) == NULL) { | |||||
NFSD_CURVNET_RESTORE(); | |||||
return; | |||||
} | |||||
for (i = 0; i < nfsrv_lughashsize; i++) { | |||||
hp = &NFSD_VNET(nfsuserhash)[i]; | |||||
TAILQ_FOREACH_SAFE(usrp, &hp->lughead, lug_numhash, nusrp) { | |||||
TAILQ_REMOVE(&hp->lughead, usrp, lug_numhash); | |||||
hp2 = NFSUSERNAMEHASH(usrp->lug_name, | |||||
usrp->lug_namelen); | |||||
TAILQ_REMOVE(&hp2->lughead, usrp, lug_namehash); | |||||
if (usrp->lug_cred != NULL) | |||||
crfree(usrp->lug_cred); | |||||
free(usrp, M_NFSUSERGROUP); | |||||
} | |||||
hp = &NFSD_VNET(nfsgrouphash)[i]; | |||||
TAILQ_FOREACH_SAFE(usrp, &hp->lughead, lug_numhash, nusrp) { | |||||
TAILQ_REMOVE(&hp->lughead, usrp, lug_numhash); | |||||
hp2 = NFSGROUPNAMEHASH(usrp->lug_name, | |||||
usrp->lug_namelen); | |||||
TAILQ_REMOVE(&hp2->lughead, usrp, lug_namehash); | |||||
if (usrp->lug_cred != NULL) | |||||
crfree(usrp->lug_cred); | |||||
free(usrp, M_NFSUSERGROUP); | |||||
} | |||||
mtx_destroy(&NFSD_VNET(nfsuserhash)[i].mtx); | |||||
mtx_destroy(&NFSD_VNET(nfsusernamehash)[i].mtx); | |||||
mtx_destroy(&NFSD_VNET(nfsgroupnamehash)[i].mtx); | |||||
mtx_destroy(&NFSD_VNET(nfsgrouphash)[i].mtx); | |||||
} | |||||
free(NFSD_VNET(nfsuserhash), M_NFSUSERGROUP); | |||||
free(NFSD_VNET(nfsusernamehash), M_NFSUSERGROUP); | |||||
free(NFSD_VNET(nfsgrouphash), M_NFSUSERGROUP); | |||||
free(NFSD_VNET(nfsgroupnamehash), M_NFSUSERGROUP); | |||||
free(NFSD_VNET(nfsrv_dnsname), M_NFSSTRING); | |||||
NFSD_CURVNET_RESTORE(); | |||||
} | |||||
/* | |||||
* Initialize everything that needs to be initialized for a vnet. | |||||
*/ | |||||
static void | |||||
nfs_vnetinit(const void *unused __unused) | |||||
{ | |||||
mtx_init(&NFSD_VNET(nfsrv_nfsuserdsock).nr_mtx, "nfsuserd", | |||||
NULL, MTX_DEF); | |||||
} | |||||
VNET_SYSINIT(nfs_vnetinit, SI_SUB_VNET_DONE, SI_ORDER_ANY, | |||||
nfs_vnetinit, NULL); | |||||
/* Osd entry for nfsrv_cleanup. */ | |||||
static int | |||||
nfs_prison_cleanup(void *obj, void *data __unused) | |||||
{ | |||||
struct prison *pr = obj; | |||||
if ((pr->pr_flags & PR_VNET) == 0) | |||||
return (0); | |||||
nfsrv_cleanusergroup(pr); | |||||
return (0); | |||||
} | |||||
extern int (*nfsd_call_nfscommon)(struct thread *, struct nfssvc_args *); | extern int (*nfsd_call_nfscommon)(struct thread *, struct nfssvc_args *); | ||||
/* | /* | ||||
* Called once to initialize data structures... | * Called once to initialize data structures... | ||||
*/ | */ | ||||
static int | static int | ||||
nfscommon_modevent(module_t mod, int type, void *data) | nfscommon_modevent(module_t mod, int type, void *data) | ||||
{ | { | ||||
int error = 0; | int error = 0; | ||||
osd_method_t methods[PR_MAXMETHOD] = { | |||||
[PR_METHOD_REMOVE] = nfs_prison_cleanup, | |||||
}; | |||||
static int loaded = 0; | static int loaded = 0; | ||||
switch (type) { | switch (type) { | ||||
case MOD_LOAD: | case MOD_LOAD: | ||||
if (loaded) | if (loaded) | ||||
goto out; | goto out; | ||||
newnfs_portinit(); | newnfs_portinit(); | ||||
mtx_init(&nfs_nameid_mutex, "nfs_nameid_mutex", NULL, MTX_DEF); | mtx_init(&nfs_nameid_mutex, "nfs_nameid_mutex", NULL, MTX_DEF); | ||||
mtx_init(&nfs_sockl_mutex, "nfs_sockl_mutex", NULL, MTX_DEF); | mtx_init(&nfs_sockl_mutex, "nfs_sockl_mutex", NULL, MTX_DEF); | ||||
mtx_init(&nfs_slock_mutex, "nfs_slock_mutex", NULL, MTX_DEF); | mtx_init(&nfs_slock_mutex, "nfs_slock_mutex", NULL, MTX_DEF); | ||||
mtx_init(&nfs_req_mutex, "nfs_req_mutex", NULL, MTX_DEF); | mtx_init(&nfs_req_mutex, "nfs_req_mutex", NULL, MTX_DEF); | ||||
mtx_init(&nfsrv_nfsuserdsock.nr_mtx, "nfsuserd", NULL, | /* XXX-BZ OSD to VNET? */ | ||||
MTX_DEF); | osd_jail_register(NULL, methods); | ||||
mtx_init(&nfsrv_dslock_mtx, "nfs4ds", NULL, MTX_DEF); | mtx_init(&nfsrv_dslock_mtx, "nfs4ds", NULL, MTX_DEF); | ||||
TAILQ_INIT(&nfsrv_devidhead); | TAILQ_INIT(&nfsrv_devidhead); | ||||
newnfs_init(); | newnfs_init(); | ||||
nfsd_call_nfscommon = nfssvc_nfscommon; | nfsd_call_nfscommon = nfssvc_nfscommon; | ||||
loaded = 1; | loaded = 1; | ||||
break; | break; | ||||
case MOD_UNLOAD: | case MOD_UNLOAD: | ||||
if (newnfs_numnfsd != 0 || nfsrv_nfsuserd != NOTRUNNING || | if (newnfs_numnfsd != 0 || | ||||
NFSD_VNET(nfsrv_nfsuserd) != NOTRUNNING || | |||||
nfs_numnfscbd != 0) { | nfs_numnfscbd != 0) { | ||||
error = EBUSY; | error = EBUSY; | ||||
break; | break; | ||||
} | } | ||||
nfsd_call_nfscommon = NULL; | nfsd_call_nfscommon = NULL; | ||||
/* Clean out the name<-->id cache. */ | /* Clean out the name<-->id cache. */ | ||||
nfsrv_cleanusergroup(); | nfsrv_cleanusergroup(&prison0); | ||||
/* and get rid of the mutexes */ | /* and get rid of the mutexes */ | ||||
mtx_destroy(&nfs_nameid_mutex); | mtx_destroy(&nfs_nameid_mutex); | ||||
mtx_destroy(&newnfsd_mtx); | mtx_destroy(&newnfsd_mtx); | ||||
mtx_destroy(&nfs_state_mutex); | mtx_destroy(&nfs_state_mutex); | ||||
mtx_destroy(&nfs_clstate_mutex); | mtx_destroy(&nfs_clstate_mutex); | ||||
mtx_destroy(&nfs_sockl_mutex); | mtx_destroy(&nfs_sockl_mutex); | ||||
mtx_destroy(&nfs_slock_mutex); | mtx_destroy(&nfs_slock_mutex); | ||||
mtx_destroy(&nfs_req_mutex); | mtx_destroy(&nfs_req_mutex); | ||||
mtx_destroy(&nfsrv_nfsuserdsock.nr_mtx); | |||||
mtx_destroy(&nfsrv_dslock_mtx); | mtx_destroy(&nfsrv_dslock_mtx); | ||||
loaded = 0; | loaded = 0; | ||||
break; | break; | ||||
default: | default: | ||||
error = EOPNOTSUPP; | error = EOPNOTSUPP; | ||||
break; | break; | ||||
} | } | ||||
Show All 15 Lines |