git: 7e44856e3a6d - main - nfsd: Prepare the NFS server code to run in a vnet prison
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sat, 11 Feb 2023 23:52:35 UTC
The branch main has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=7e44856e3a6deb194c2c376e886854b256360c40 commit 7e44856e3a6deb194c2c376e886854b256360c40 Author: Rick Macklem <rmacklem@FreeBSD.org> AuthorDate: 2023-02-11 23:51:19 +0000 Commit: Rick Macklem <rmacklem@FreeBSD.org> CommitDate: 2023-02-11 23:51:19 +0000 nfsd: Prepare the NFS server code to run in a vnet prison This patch defines null macros that can be used to apply the vnet macros for global variables and SYSCTL flags. It also applies these macros to many of the global variables and some of the SYSCTLs. Since the macros do nothing, these changes should not result in semantics changes, although the changes are large in number. The patch does change several global variables that were arrays or structures to pointers to same. For these variables, modified initialization and cleanup code malloc's and free's the arrays/structures. This was done so that the vnet footprint would be about 300bytes when the macros are defined as vnet macros, allowing nfsd.ko to load dynamically. I believe the comments in D37519 have been addressed, although it has never been reviewed, due in part to the large size of the patch. This is the first of a series of patches that will put D37519 in main. Once everything is in main, the macros will be defined as front end macros to the vnet ones. MFC after: 3 months Differential Revision: https://reviews.freebsd.org/D37519 --- sys/fs/nfs/nfs_var.h | 2 +- sys/fs/nfs/nfsport.h | 14 ++ sys/fs/nfsserver/nfs_fha_new.c | 5 +- sys/fs/nfsserver/nfs_nfsdcache.c | 155 +++++++++++--------- sys/fs/nfsserver/nfs_nfsdkrpc.c | 100 ++++++++----- sys/fs/nfsserver/nfs_nfsdport.c | 292 +++++++++++++++++++++++++------------- sys/fs/nfsserver/nfs_nfsdsocket.c | 70 +++++---- sys/fs/nfsserver/nfs_nfsdstate.c | 188 +++++++++++++----------- sys/fs/nfsserver/nfs_nfsdsubs.c | 45 +++--- 9 files changed, 524 insertions(+), 347 deletions(-) diff --git a/sys/fs/nfs/nfs_var.h b/sys/fs/nfs/nfs_var.h index f8fd2229095f..0a6d46964ffd 100644 --- a/sys/fs/nfs/nfs_var.h +++ b/sys/fs/nfs/nfs_var.h @@ -122,7 +122,7 @@ int nfsrv_delegupdate(struct nfsrv_descript *, nfsquad_t, nfsv4stateid_t *, int nfsrv_releaselckown(struct nfsstate *, nfsquad_t, NFSPROC_T *); void nfsrv_zapclient(struct nfsclient *, NFSPROC_T *); int nfssvc_idname(struct nfsd_idargs *); -void nfsrv_servertimer(void); +void nfsrv_servertimer(void * __unused); int nfsrv_getclientipaddr(struct nfsrv_descript *, struct nfsclient *); void nfsrv_setupstable(NFSPROC_T *); void nfsrv_updatestable(NFSPROC_T *); diff --git a/sys/fs/nfs/nfsport.h b/sys/fs/nfs/nfsport.h index 2060ed03de34..bf59aea285f1 100644 --- a/sys/fs/nfs/nfsport.h +++ b/sys/fs/nfs/nfsport.h @@ -181,6 +181,20 @@ */ #define NFSMUTEX_T struct mtx +/* Define the NFSD_VNET macros similar to !VIMAGE. */ +#define NFSD_VNET_NAME(n) n +#define NFSD_VNET_DECLARE(t, n) extern t n +#define NFSD_VNET_DEFINE(t, n) t n +#define NFSD_VNET_DEFINE_STATIC(t, n) static t n +#define NFSD_VNET(n) (n) + +#define CTLFLAG_NFSD_VNET 0 + +#define NFSD_CURVNET_SET(n) +#define NFSD_CURVNET_SET_QUIET(n) +#define NFSD_CURVNET_RESTORE() +#define NFSD_TD_TO_VNET(n) NULL + #endif /* _KERNEL */ /* diff --git a/sys/fs/nfsserver/nfs_fha_new.c b/sys/fs/nfsserver/nfs_fha_new.c index 1f66842da5b8..59933ef01bd4 100644 --- a/sys/fs/nfsserver/nfs_fha_new.c +++ b/sys/fs/nfsserver/nfs_fha_new.c @@ -61,7 +61,8 @@ static struct fha_params fhanew_softc; SYSCTL_DECL(_vfs_nfsd); extern int newnfs_nfsv3_procid[]; -extern SVCPOOL *nfsrvd_pool; + +NFSD_VNET_DECLARE(SVCPOOL *, nfsrvd_pool); SYSINIT(nfs_fhanew, SI_SUB_ROOT_CONF, SI_ORDER_ANY, fhanew_init, NULL); SYSUNINIT(nfs_fhanew, SI_SUB_ROOT_CONF, SI_ORDER_ANY, fhanew_uninit, NULL); @@ -79,7 +80,7 @@ fhanew_init(void *foo) snprintf(softc->server_name, sizeof(softc->server_name), FHANEW_SERVER_NAME); - softc->pool = &nfsrvd_pool; + softc->pool = &NFSD_VNET(nfsrvd_pool); /* * Initialize the sysctl context list for the fha module. diff --git a/sys/fs/nfsserver/nfs_nfsdcache.c b/sys/fs/nfsserver/nfs_nfsdcache.c index 5efcb90411e0..e94d58481286 100644 --- a/sys/fs/nfsserver/nfs_nfsdcache.c +++ b/sys/fs/nfsserver/nfs_nfsdcache.c @@ -160,11 +160,15 @@ __FBSDID("$FreeBSD$"); */ #include <fs/nfs/nfsport.h> -extern struct nfsstatsv1 nfsstatsv1; extern struct mtx nfsrc_udpmtx; -extern struct nfsrchash_bucket nfsrchash_table[NFSRVCACHE_HASHSIZE]; -extern struct nfsrchash_bucket nfsrcahash_table[NFSRVCACHE_HASHSIZE]; -int nfsrc_floodlevel = NFSRVCACHE_FLOODLEVEL, nfsrc_tcpsavedreplies = 0; + +NFSD_VNET_DECLARE(struct nfsrvhashhead *, nfsrvudphashtbl); +NFSD_VNET_DECLARE(struct nfsrchash_bucket *, nfsrchash_table); +NFSD_VNET_DECLARE(struct nfsrchash_bucket *, nfsrcahash_table); +NFSD_VNET_DECLARE(struct nfsstatsv1 *, nfsstatsv1_p); + +NFSD_VNET_DEFINE(int, nfsrc_floodlevel) = NFSRVCACHE_FLOODLEVEL; +NFSD_VNET_DEFINE(int, nfsrc_tcpsavedreplies) = 0; SYSCTL_DECL(_vfs_nfsd); @@ -180,8 +184,8 @@ sysctl_tcphighwater(SYSCTL_HANDLER_ARGS) return (error); if (newhighwater < 0) return (EINVAL); - if (newhighwater >= nfsrc_floodlevel) - nfsrc_floodlevel = newhighwater + newhighwater / 5; + if (newhighwater >= NFSD_VNET(nfsrc_floodlevel)) + NFSD_VNET(nfsrc_floodlevel) = newhighwater + newhighwater / 5; nfsrc_tcphighwater = newhighwater; return (0); } @@ -202,9 +206,8 @@ SYSCTL_UINT(_vfs_nfsd, OID_AUTO, cachetcp, CTLFLAG_RW, &nfsrc_tcpnonidempotent, 0, "Enable the DRC for NFS over TCP"); -static int nfsrc_udpcachesize = 0; -static TAILQ_HEAD(, nfsrvcache) nfsrvudplru; -static struct nfsrvhashhead nfsrvudphashtbl[NFSRVCACHE_HASHSIZE]; +NFSD_VNET_DEFINE_STATIC(int, nfsrc_udpcachesize) = 0; +NFSD_VNET_DEFINE_STATIC(TAILQ_HEAD(, nfsrvcache), nfsrvudplru); /* * and the reverse mapping from generic to Version 2 procedure numbers @@ -236,10 +239,10 @@ static int newnfsv2_procid[NFS_V3NPROCS] = { #define nfsrc_hash(xid) (((xid) + ((xid) >> 24)) % NFSRVCACHE_HASHSIZE) #define NFSRCUDPHASH(xid) \ - (&nfsrvudphashtbl[nfsrc_hash(xid)]) + (&NFSD_VNET(nfsrvudphashtbl)[nfsrc_hash(xid)]) #define NFSRCHASH(xid) \ - (&nfsrchash_table[nfsrc_hash(xid)].tbl) -#define NFSRCAHASH(xid) (&nfsrcahash_table[nfsrc_hash(xid)]) + (&NFSD_VNET(nfsrchash_table)[nfsrc_hash(xid)].tbl) +#define NFSRCAHASH(xid) (&NFSD_VNET(nfsrcahash_table)[nfsrc_hash(xid)]) #define TRUE 1 #define FALSE 0 #define NFSRVCACHE_CHECKLEN 100 @@ -295,7 +298,7 @@ nfsrc_cachemutex(struct nfsrvcache *rp) if ((rp->rc_flag & RC_UDP) != 0) return (&nfsrc_udpmtx); - return (&nfsrchash_table[nfsrc_hash(rp->rc_xid)].mtx); + return (&NFSD_VNET(nfsrchash_table)[nfsrc_hash(rp->rc_xid)].mtx); } /* @@ -305,21 +308,27 @@ void nfsrvd_initcache(void) { int i; - static int inited = 0; - if (inited) - return; - inited = 1; + NFSD_VNET(nfsrvudphashtbl) = malloc(sizeof(struct nfsrvhashhead) * + NFSRVCACHE_HASHSIZE, M_NFSRVCACHE, M_WAITOK | M_ZERO); + NFSD_VNET(nfsrchash_table) = malloc(sizeof(struct nfsrchash_bucket) * + NFSRVCACHE_HASHSIZE, M_NFSRVCACHE, M_WAITOK | M_ZERO); + NFSD_VNET(nfsrcahash_table) = malloc(sizeof(struct nfsrchash_bucket) * + NFSRVCACHE_HASHSIZE, M_NFSRVCACHE, M_WAITOK | M_ZERO); + for (i = 0; i < NFSRVCACHE_HASHSIZE; i++) { + mtx_init(&NFSD_VNET(nfsrchash_table)[i].mtx, "nfsrtc", NULL, + MTX_DEF); + mtx_init(&NFSD_VNET(nfsrcahash_table)[i].mtx, "nfsrtca", NULL, + MTX_DEF); + } for (i = 0; i < NFSRVCACHE_HASHSIZE; i++) { - LIST_INIT(&nfsrvudphashtbl[i]); - LIST_INIT(&nfsrchash_table[i].tbl); - LIST_INIT(&nfsrcahash_table[i].tbl); + LIST_INIT(&NFSD_VNET(nfsrvudphashtbl)[i]); + LIST_INIT(&NFSD_VNET(nfsrchash_table)[i].tbl); + LIST_INIT(&NFSD_VNET(nfsrcahash_table)[i].tbl); } - TAILQ_INIT(&nfsrvudplru); - nfsrc_tcpsavedreplies = 0; - nfsrc_udpcachesize = 0; - nfsstatsv1.srvcache_tcppeak = 0; - nfsstatsv1.srvcache_size = 0; + TAILQ_INIT(&NFSD_VNET(nfsrvudplru)); + NFSD_VNET(nfsrc_tcpsavedreplies) = 0; + NFSD_VNET(nfsrc_udpcachesize) = 0; } /* @@ -392,17 +401,17 @@ loop: if (rp->rc_flag == 0) panic("nfs udp cache0"); rp->rc_flag |= RC_LOCKED; - TAILQ_REMOVE(&nfsrvudplru, rp, rc_lru); - TAILQ_INSERT_TAIL(&nfsrvudplru, rp, rc_lru); + TAILQ_REMOVE(&NFSD_VNET(nfsrvudplru), rp, rc_lru); + TAILQ_INSERT_TAIL(&NFSD_VNET(nfsrvudplru), rp, rc_lru); if (rp->rc_flag & RC_INPROG) { - nfsstatsv1.srvcache_inproghits++; + nfsstatsv1_p->srvcache_inproghits++; mtx_unlock(mutex); ret = RC_DROPIT; } else if (rp->rc_flag & RC_REPSTATUS) { /* * V2 only. */ - nfsstatsv1.srvcache_nonidemdonehits++; + nfsstatsv1_p->srvcache_nonidemdonehits++; mtx_unlock(mutex); nfsrvd_rephead(nd); *(nd->nd_errp) = rp->rc_status; @@ -410,7 +419,7 @@ loop: rp->rc_timestamp = NFSD_MONOSEC + NFSRVCACHE_UDPTIMEOUT; } else if (rp->rc_flag & RC_REPMBUF) { - nfsstatsv1.srvcache_nonidemdonehits++; + nfsstatsv1_p->srvcache_nonidemdonehits++; mtx_unlock(mutex); nd->nd_mreq = m_copym(rp->rc_reply, 0, M_COPYALL, M_WAITOK); @@ -425,9 +434,9 @@ loop: goto out; } } - nfsstatsv1.srvcache_misses++; - atomic_add_int(&nfsstatsv1.srvcache_size, 1); - nfsrc_udpcachesize++; + nfsstatsv1_p->srvcache_misses++; + atomic_add_int(&nfsstatsv1_p->srvcache_size, 1); + NFSD_VNET(nfsrc_udpcachesize)++; newrp->rc_flag |= RC_INPROG; saddr = NFSSOCKADDR(nd->nd_nam, struct sockaddr_in *); @@ -440,7 +449,7 @@ loop: newrp->rc_flag |= RC_INETIPV6; } LIST_INSERT_HEAD(hp, newrp, rc_hash); - TAILQ_INSERT_TAIL(&nfsrvudplru, newrp, rc_lru); + TAILQ_INSERT_TAIL(&NFSD_VNET(nfsrvudplru), newrp, rc_lru); mtx_unlock(mutex); nd->nd_rp = newrp; ret = RC_DOIT; @@ -472,15 +481,15 @@ nfsrvd_updatecache(struct nfsrv_descript *nd) panic("nfsrvd_updatecache not inprog"); rp->rc_flag &= ~RC_INPROG; if (rp->rc_flag & RC_UDP) { - TAILQ_REMOVE(&nfsrvudplru, rp, rc_lru); - TAILQ_INSERT_TAIL(&nfsrvudplru, rp, rc_lru); + TAILQ_REMOVE(&NFSD_VNET(nfsrvudplru), rp, rc_lru); + TAILQ_INSERT_TAIL(&NFSD_VNET(nfsrvudplru), rp, rc_lru); } /* * Reply from cache is a special case returned by nfsrv_checkseqid(). */ if (nd->nd_repstat == NFSERR_REPLYFROMCACHE) { - nfsstatsv1.srvcache_nonidemdonehits++; + nfsstatsv1_p->srvcache_nonidemdonehits++; mtx_unlock(mutex); nd->nd_repstat = 0; if (nd->nd_mreq) @@ -503,7 +512,7 @@ nfsrvd_updatecache(struct nfsrv_descript *nd) (rp->rc_refcnt > 0 || ((nd->nd_flag & ND_SAVEREPLY) && (rp->rc_flag & RC_UDP)) || ((nd->nd_flag & ND_SAVEREPLY) && !(rp->rc_flag & RC_UDP) && - nfsrc_tcpsavedreplies <= nfsrc_floodlevel && + NFSD_VNET(nfsrc_tcpsavedreplies) <= NFSD_VNET(nfsrc_floodlevel) && nfsrc_tcpnonidempotent))) { if (rp->rc_refcnt > 0) { if (!(rp->rc_flag & RC_NFSV4)) @@ -517,11 +526,12 @@ nfsrvd_updatecache(struct nfsrv_descript *nd) mtx_unlock(mutex); } else { if (!(rp->rc_flag & RC_UDP)) { - atomic_add_int(&nfsrc_tcpsavedreplies, 1); - if (nfsrc_tcpsavedreplies > - nfsstatsv1.srvcache_tcppeak) - nfsstatsv1.srvcache_tcppeak = - nfsrc_tcpsavedreplies; + atomic_add_int(&NFSD_VNET(nfsrc_tcpsavedreplies), + 1); + if (NFSD_VNET(nfsrc_tcpsavedreplies) > + nfsstatsv1_p->srvcache_tcppeak) + nfsstatsv1_p->srvcache_tcppeak = + NFSD_VNET(nfsrc_tcpsavedreplies); } mtx_unlock(mutex); m = m_copym(nd->nd_mreq, 0, M_COPYALL, M_WAITOK); @@ -678,7 +688,7 @@ tryagain: panic("nfs tcp cache0"); rp->rc_flag |= RC_LOCKED; if (rp->rc_flag & RC_INPROG) { - nfsstatsv1.srvcache_inproghits++; + nfsstatsv1_p->srvcache_inproghits++; mtx_unlock(mutex); if (newrp->rc_sockref == rp->rc_sockref) nfsrc_marksametcpconn(rp->rc_sockref); @@ -687,7 +697,7 @@ tryagain: /* * V2 only. */ - nfsstatsv1.srvcache_nonidemdonehits++; + nfsstatsv1_p->srvcache_nonidemdonehits++; mtx_unlock(mutex); if (newrp->rc_sockref == rp->rc_sockref) nfsrc_marksametcpconn(rp->rc_sockref); @@ -696,7 +706,7 @@ tryagain: *(nd->nd_errp) = rp->rc_status; rp->rc_timestamp = NFSD_MONOSEC + nfsrc_tcptimeout; } else if (rp->rc_flag & RC_REPMBUF) { - nfsstatsv1.srvcache_nonidemdonehits++; + nfsstatsv1_p->srvcache_nonidemdonehits++; mtx_unlock(mutex); if (newrp->rc_sockref == rp->rc_sockref) nfsrc_marksametcpconn(rp->rc_sockref); @@ -711,8 +721,8 @@ tryagain: free(newrp, M_NFSRVCACHE); goto out; } - nfsstatsv1.srvcache_misses++; - atomic_add_int(&nfsstatsv1.srvcache_size, 1); + nfsstatsv1_p->srvcache_misses++; + atomic_add_int(&nfsstatsv1_p->srvcache_size, 1); /* * For TCP, multiple entries for a key are allowed, so don't @@ -785,8 +795,8 @@ nfsrc_freecache(struct nfsrvcache *rp) LIST_REMOVE(rp, rc_hash); if (rp->rc_flag & RC_UDP) { - TAILQ_REMOVE(&nfsrvudplru, rp, rc_lru); - nfsrc_udpcachesize--; + TAILQ_REMOVE(&NFSD_VNET(nfsrvudplru), rp, rc_lru); + NFSD_VNET(nfsrc_udpcachesize)--; } else if (rp->rc_acked != RC_NO_SEQ) { hbp = NFSRCAHASH(rp->rc_sockref); mtx_lock(&hbp->mtx); @@ -798,10 +808,10 @@ nfsrc_freecache(struct nfsrvcache *rp) if (rp->rc_flag & RC_REPMBUF) { m_freem(rp->rc_reply); if (!(rp->rc_flag & RC_UDP)) - atomic_add_int(&nfsrc_tcpsavedreplies, -1); + atomic_add_int(&NFSD_VNET(nfsrc_tcpsavedreplies), -1); } free(rp, M_NFSRVCACHE); - atomic_add_int(&nfsstatsv1.srvcache_size, -1); + atomic_add_int(&nfsstatsv1_p->srvcache_size, -1); } /* @@ -814,20 +824,22 @@ nfsrvd_cleancache(void) int i; for (i = 0; i < NFSRVCACHE_HASHSIZE; i++) { - mtx_lock(&nfsrchash_table[i].mtx); - LIST_FOREACH_SAFE(rp, &nfsrchash_table[i].tbl, rc_hash, nextrp) + mtx_lock(&NFSD_VNET(nfsrchash_table)[i].mtx); + LIST_FOREACH_SAFE(rp, &NFSD_VNET(nfsrchash_table)[i].tbl, + rc_hash, nextrp) nfsrc_freecache(rp); - mtx_unlock(&nfsrchash_table[i].mtx); + mtx_unlock(&NFSD_VNET(nfsrchash_table)[i].mtx); } mtx_lock(&nfsrc_udpmtx); for (i = 0; i < NFSRVCACHE_HASHSIZE; i++) { - LIST_FOREACH_SAFE(rp, &nfsrvudphashtbl[i], rc_hash, nextrp) { + LIST_FOREACH_SAFE(rp, &NFSD_VNET(nfsrvudphashtbl)[i], rc_hash, + nextrp) { nfsrc_freecache(rp); } } - nfsstatsv1.srvcache_size = 0; + nfsstatsv1_p->srvcache_size = 0; mtx_unlock(&nfsrc_udpmtx); - nfsrc_tcpsavedreplies = 0; + NFSD_VNET(nfsrc_tcpsavedreplies) = 0; } #define HISTSIZE 16 @@ -864,25 +876,28 @@ nfsrc_trimcache(u_int64_t sockref, uint32_t snd_una, int final) if (atomic_cmpset_acq_int(&onethread, 0, 1) == 0) return; if (NFSD_MONOSEC != udp_lasttrim || - nfsrc_udpcachesize >= (nfsrc_udphighwater + + NFSD_VNET(nfsrc_udpcachesize) >= (nfsrc_udphighwater + nfsrc_udphighwater / 2)) { mtx_lock(&nfsrc_udpmtx); udp_lasttrim = NFSD_MONOSEC; - TAILQ_FOREACH_SAFE(rp, &nfsrvudplru, rc_lru, nextrp) { + TAILQ_FOREACH_SAFE(rp, &NFSD_VNET(nfsrvudplru), rc_lru, + nextrp) { if (!(rp->rc_flag & (RC_INPROG|RC_LOCKED|RC_WANTED)) && rp->rc_refcnt == 0 && ((rp->rc_flag & RC_REFCNT) || udp_lasttrim > rp->rc_timestamp || - nfsrc_udpcachesize > nfsrc_udphighwater)) + NFSD_VNET(nfsrc_udpcachesize) > + nfsrc_udphighwater)) nfsrc_freecache(rp); } mtx_unlock(&nfsrc_udpmtx); } if (NFSD_MONOSEC != tcp_lasttrim || - nfsrc_tcpsavedreplies >= nfsrc_tcphighwater) { + NFSD_VNET(nfsrc_tcpsavedreplies) >= nfsrc_tcphighwater) { force = nfsrc_tcphighwater / 4; if (force > 0 && - nfsrc_tcpsavedreplies + force >= nfsrc_tcphighwater) { + NFSD_VNET(nfsrc_tcpsavedreplies) + force >= + nfsrc_tcphighwater) { for (i = 0; i < HISTSIZE; i++) time_histo[i] = 0; i = 0; @@ -901,8 +916,9 @@ nfsrc_trimcache(u_int64_t sockref, uint32_t snd_una, int final) tto = nfsrc_tcptimeout; tcp_lasttrim = NFSD_MONOSEC; for (; i <= lastslot; i++) { - mtx_lock(&nfsrchash_table[i].mtx); - LIST_FOREACH_SAFE(rp, &nfsrchash_table[i].tbl, rc_hash, + mtx_lock(&NFSD_VNET(nfsrchash_table)[i].mtx); + LIST_FOREACH_SAFE(rp, + &NFSD_VNET(nfsrchash_table)[i].tbl, rc_hash, nextrp) { if (!(rp->rc_flag & (RC_INPROG|RC_LOCKED|RC_WANTED)) @@ -932,7 +948,7 @@ nfsrc_trimcache(u_int64_t sockref, uint32_t snd_una, int final) time_histo[j]++; } } - mtx_unlock(&nfsrchash_table[i].mtx); + mtx_unlock(&NFSD_VNET(nfsrchash_table)[i].mtx); } if (force) { /* @@ -951,8 +967,9 @@ nfsrc_trimcache(u_int64_t sockref, uint32_t snd_una, int final) k = 1; thisstamp = tcp_lasttrim + k; for (i = 0; i < NFSRVCACHE_HASHSIZE; i++) { - mtx_lock(&nfsrchash_table[i].mtx); - LIST_FOREACH_SAFE(rp, &nfsrchash_table[i].tbl, + mtx_lock(&NFSD_VNET(nfsrchash_table)[i].mtx); + LIST_FOREACH_SAFE(rp, + &NFSD_VNET(nfsrchash_table)[i].tbl, rc_hash, nextrp) { if (!(rp->rc_flag & (RC_INPROG|RC_LOCKED|RC_WANTED)) @@ -962,7 +979,7 @@ nfsrc_trimcache(u_int64_t sockref, uint32_t snd_una, int final) rp->rc_acked == RC_ACK)) nfsrc_freecache(rp); } - mtx_unlock(&nfsrchash_table[i].mtx); + mtx_unlock(&NFSD_VNET(nfsrchash_table)[i].mtx); } } } diff --git a/sys/fs/nfsserver/nfs_nfsdkrpc.c b/sys/fs/nfsserver/nfs_nfsdkrpc.c index d2ba7887b8c2..696af8a0e409 100644 --- a/sys/fs/nfsserver/nfs_nfsdkrpc.c +++ b/sys/fs/nfsserver/nfs_nfsdkrpc.c @@ -52,7 +52,6 @@ __FBSDID("$FreeBSD$"); NFSDLOCKMUTEX; NFSV4ROOTLOCKMUTEX; -struct nfsv4lock nfsd_suspend_lock; char *nfsrv_zeropnfsdat = NULL; /* @@ -85,32 +84,39 @@ int newnfs_nfsv3_procid[NFS_V3NPROCS] = { SYSCTL_DECL(_vfs_nfsd); -SVCPOOL *nfsrvd_pool; - -static int nfs_privport = 0; -SYSCTL_INT(_vfs_nfsd, OID_AUTO, nfs_privport, CTLFLAG_RWTUN, - &nfs_privport, 0, +NFSD_VNET_DEFINE_STATIC(int, nfs_privport) = 0; +SYSCTL_INT(_vfs_nfsd, OID_AUTO, nfs_privport, CTLFLAG_NFSD_VNET | CTLFLAG_RWTUN, + &NFSD_VNET_NAME(nfs_privport), 0, "Only allow clients using a privileged port for NFSv2, 3 and 4"); -static int nfs_minvers = NFS_VER2; -SYSCTL_INT(_vfs_nfsd, OID_AUTO, server_min_nfsvers, CTLFLAG_RWTUN, - &nfs_minvers, 0, "The lowest version of NFS handled by the server"); +NFSD_VNET_DEFINE_STATIC(int, nfs_minvers) = NFS_VER2; +SYSCTL_INT(_vfs_nfsd, OID_AUTO, server_min_nfsvers, + CTLFLAG_NFSD_VNET | CTLFLAG_RWTUN, &NFSD_VNET_NAME(nfs_minvers), 0, + "The lowest version of NFS handled by the server"); -static int nfs_maxvers = NFS_VER4; -SYSCTL_INT(_vfs_nfsd, OID_AUTO, server_max_nfsvers, CTLFLAG_RWTUN, - &nfs_maxvers, 0, "The highest version of NFS handled by the server"); +NFSD_VNET_DEFINE_STATIC(int, nfs_maxvers) = NFS_VER4; +SYSCTL_INT(_vfs_nfsd, OID_AUTO, server_max_nfsvers, + CTLFLAG_NFSD_VNET | CTLFLAG_RWTUN, &NFSD_VNET_NAME(nfs_maxvers), 0, + "The highest version of NFS handled by the server"); static int nfs_proc(struct nfsrv_descript *, u_int32_t, SVCXPRT *xprt, struct nfsrvcache **); extern u_long sb_max_adj; extern int newnfs_numnfsd; -extern struct proc *nfsd_master_proc; extern time_t nfsdev_time; extern int nfsrv_writerpc[NFS_NPROCS]; extern volatile int nfsrv_devidcnt; extern struct nfsv4_opflag nfsv4_opflag[NFSV42_NOPS]; +NFSD_VNET_DECLARE(struct proc *, nfsd_master_proc); + +NFSD_VNET_DEFINE(SVCPOOL *, nfsrvd_pool); +NFSD_VNET_DEFINE(int, nfsrv_numnfsd) = 0; +NFSD_VNET_DEFINE(struct nfsv4lock, nfsd_suspend_lock); + +NFSD_VNET_DEFINE_STATIC(bool, nfsrvd_inited) = false; + /* * NFS server system calls */ @@ -125,6 +131,7 @@ nfssvc_program(struct svc_req *rqst, SVCXPRT *xprt) u_int maxlen; #endif + NFSD_CURVNET_SET_QUIET(NFSD_TD_TO_VNET(curthread)); memset(&nd, 0, sizeof(nd)); if (rqst->rq_vers == NFS_VER2) { if (rqst->rq_proc > NFSV2PROC_STATFS || @@ -169,7 +176,7 @@ nfssvc_program(struct svc_req *rqst, SVCXPRT *xprt) nd.nd_mreq = NULL; nd.nd_cred = NULL; - if (nfs_privport != 0) { + if (NFSD_VNET(nfs_privport) != 0) { /* Check if source port is privileged */ u_short port; struct sockaddr *nam = nd.nd_nam; @@ -261,17 +268,17 @@ nfssvc_program(struct svc_req *rqst, SVCXPRT *xprt) * nfsv4root exports by nfsvno_v4rootexport(). */ NFSLOCKV4ROOTMUTEX(); - nfsv4_lock(&nfsd_suspend_lock, 0, NULL, NFSV4ROOTLOCKMUTEXPTR, - NULL); - nfsv4_getref(&nfsd_suspend_lock, NULL, NFSV4ROOTLOCKMUTEXPTR, - NULL); + nfsv4_lock(&NFSD_VNET(nfsd_suspend_lock), 0, NULL, + NFSV4ROOTLOCKMUTEXPTR, NULL); + nfsv4_getref(&NFSD_VNET(nfsd_suspend_lock), NULL, + NFSV4ROOTLOCKMUTEXPTR, NULL); NFSUNLOCKV4ROOTMUTEX(); if ((nd.nd_flag & ND_NFSV4) != 0) { nd.nd_repstat = nfsvno_v4rootexport(&nd); if (nd.nd_repstat != 0) { NFSLOCKV4ROOTMUTEX(); - nfsv4_relref(&nfsd_suspend_lock); + nfsv4_relref(&NFSD_VNET(nfsd_suspend_lock)); NFSUNLOCKV4ROOTMUTEX(); svcerr_weakauth(rqst); svc_freereq(rqst); @@ -287,7 +294,7 @@ nfssvc_program(struct svc_req *rqst, SVCXPRT *xprt) #endif cacherep = nfs_proc(&nd, rqst->rq_xid, xprt, &rp); NFSLOCKV4ROOTMUTEX(); - nfsv4_relref(&nfsd_suspend_lock); + nfsv4_relref(&NFSD_VNET(nfsd_suspend_lock)); NFSUNLOCKV4ROOTMUTEX(); } else { NFSMGET(nd.nd_mreq); @@ -327,6 +334,7 @@ nfssvc_program(struct svc_req *rqst, SVCXPRT *xprt) svc_freereq(rqst); out: + NFSD_CURVNET_RESTORE(); ast_kclear(curthread); NFSEXITCODE(0); } @@ -440,7 +448,9 @@ nfssvc_loss(SVCXPRT *xprt) ack = 0; SVC_ACK(xprt, &ack); + NFSD_CURVNET_SET(NFSD_TD_TO_VNET(curthread)); nfsrc_trimcache(xprt->xp_sockref, ack, 1); + NFSD_CURVNET_RESTORE(); } /* @@ -467,26 +477,28 @@ nfsrvd_addsock(struct file *fp) * unexpectedly. */ if (so->so_type == SOCK_DGRAM) - xprt = svc_dg_create(nfsrvd_pool, so, 0, 0); + xprt = svc_dg_create(NFSD_VNET(nfsrvd_pool), so, 0, 0); else - xprt = svc_vc_create(nfsrvd_pool, so, 0, 0); + xprt = svc_vc_create(NFSD_VNET(nfsrvd_pool), so, 0, 0); if (xprt) { fp->f_ops = &badfileops; fp->f_data = NULL; xprt->xp_sockref = ++sockref; - if (nfs_minvers == NFS_VER2) + if (NFSD_VNET(nfs_minvers) == NFS_VER2) svc_reg(xprt, NFS_PROG, NFS_VER2, nfssvc_program, NULL); - if (nfs_minvers <= NFS_VER3 && nfs_maxvers >= NFS_VER3) + if (NFSD_VNET(nfs_minvers) <= NFS_VER3 && + NFSD_VNET(nfs_maxvers) >= NFS_VER3) svc_reg(xprt, NFS_PROG, NFS_VER3, nfssvc_program, NULL); - if (nfs_maxvers >= NFS_VER4) + if (NFSD_VNET(nfs_maxvers) >= NFS_VER4) svc_reg(xprt, NFS_PROG, NFS_VER4, nfssvc_program, NULL); if (so->so_type == SOCK_STREAM) svc_loss_reg(xprt, nfssvc_loss); SVC_RELEASE(xprt); - } + } else + error = EPERM; out: NFSEXITCODE(error); @@ -518,13 +530,15 @@ nfsrvd_nfsd(struct thread *td, struct nfsd_nfsd_args *args) * use. */ NFSD_LOCK(); - if (newnfs_numnfsd == 0) { + if (NFSD_VNET(nfsrv_numnfsd) == 0) { + nfsrvd_init(0); nfsdev_time = time_second; p = td->td_proc; PROC_LOCK(p); p->p_flag2 |= P2_AST_SU; PROC_UNLOCK(p); - newnfs_numnfsd++; + newnfs_numnfsd++; /* Total num for all vnets. */ + NFSD_VNET(nfsrv_numnfsd)++; /* Num for this vnet. */ NFSD_UNLOCK(); error = nfsrv_createdevids(args, td); @@ -542,12 +556,15 @@ nfsrvd_nfsd(struct thread *td, struct nfsd_nfsd_args *args) NFS_VER4); if (!ret2 || !ret3 || !ret4) - printf( - "nfsd: can't register svc name\n"); + printf("nfsd: can't register svc " + "name %s jid:%d\n", principal, + td->td_ucred->cr_prison->pr_id); } - nfsrvd_pool->sp_minthreads = args->minthreads; - nfsrvd_pool->sp_maxthreads = args->maxthreads; + NFSD_VNET(nfsrvd_pool)->sp_minthreads = + args->minthreads; + NFSD_VNET(nfsrvd_pool)->sp_maxthreads = + args->maxthreads; /* * If this is a pNFS service, make Getattr do a @@ -558,7 +575,7 @@ nfsrvd_nfsd(struct thread *td, struct nfsd_nfsd_args *args) nfsv4_opflag[NFSV4OP_GETATTR].modifyfs = 1; } - svc_run(nfsrvd_pool); + svc_run(NFSD_VNET(nfsrvd_pool)); /* Reset Getattr to not do a vn_start_write(). */ nfsrv_writerpc[NFSPROC_GETATTR] = 0; @@ -572,6 +589,7 @@ nfsrvd_nfsd(struct thread *td, struct nfsd_nfsd_args *args) } NFSD_LOCK(); newnfs_numnfsd--; + NFSD_VNET(nfsrv_numnfsd)--; nfsrvd_init(1); PROC_LOCK(p); p->p_flag2 &= ~P2_AST_SU; @@ -596,21 +614,25 @@ nfsrvd_init(int terminating) NFSD_LOCK_ASSERT(); if (terminating) { - nfsd_master_proc = NULL; + NFSD_VNET(nfsd_master_proc) = NULL; NFSD_UNLOCK(); nfsrv_freealllayoutsanddevids(); nfsrv_freeallbackchannel_xprts(); - svcpool_close(nfsrvd_pool); + svcpool_close(NFSD_VNET(nfsrvd_pool)); free(nfsrv_zeropnfsdat, M_TEMP); nfsrv_zeropnfsdat = NULL; NFSD_LOCK(); } else { + /* Initialize per-vnet globals once per vnet. */ + if (NFSD_VNET(nfsrvd_inited)) + return; + NFSD_VNET(nfsrvd_inited) = true; NFSD_UNLOCK(); - nfsrvd_pool = svcpool_create("nfsd", + NFSD_VNET(nfsrvd_pool) = svcpool_create("nfsd", SYSCTL_STATIC_CHILDREN(_vfs_nfsd)); - nfsrvd_pool->sp_rcache = NULL; - nfsrvd_pool->sp_assign = fhanew_assign; - nfsrvd_pool->sp_done = fhanew_nd_complete; + NFSD_VNET(nfsrvd_pool)->sp_rcache = NULL; + NFSD_VNET(nfsrvd_pool)->sp_assign = fhanew_assign; + NFSD_VNET(nfsrvd_pool)->sp_done = fhanew_nd_complete; NFSD_LOCK(); } } diff --git a/sys/fs/nfsserver/nfs_nfsdport.c b/sys/fs/nfsserver/nfs_nfsdport.c index 9cd7f9320bd5..af5327bd5a2d 100644 --- a/sys/fs/nfsserver/nfs_nfsdport.c +++ b/sys/fs/nfsserver/nfs_nfsdport.c @@ -50,6 +50,7 @@ __FBSDID("$FreeBSD$"); #include <sys/callout.h> #include <sys/filio.h> #include <sys/hash.h> +#include <sys/osd.h> #include <sys/sysctl.h> #include <nlm/nlm_prot.h> #include <nlm/nlm.h> @@ -59,45 +60,57 @@ FEATURE(nfsd, "NFSv4 server"); extern u_int32_t newnfs_true, newnfs_false, newnfs_xdrneg1; extern int nfsrv_useacl; extern int newnfs_numnfsd; -extern struct mount nfsv4root_mnt; -extern struct nfsrv_stablefirst nfsrv_stablefirst; -extern SVCPOOL *nfsrvd_pool; -extern struct nfsv4lock nfsd_suspend_lock; -extern struct nfsclienthashhead *nfsclienthash; -extern struct nfslockhashhead *nfslockhash; -extern struct nfssessionhash *nfssessionhash; extern int nfsrv_sessionhashsize; extern struct nfsstatsv1 nfsstatsv1; extern struct nfslayouthash *nfslayouthash; extern int nfsrv_layouthashsize; extern struct mtx nfsrv_dslock_mtx; extern int nfs_pnfsiothreads; -extern struct nfsdontlisthead nfsrv_dontlisthead; -extern volatile int nfsrv_dontlistlen; extern volatile int nfsrv_devidcnt; extern int nfsrv_maxpnfsmirror; extern uint32_t nfs_srvmaxio; extern int nfs_bufpackets; extern u_long sb_max_adj; -struct vfsoptlist nfsv4root_opt, nfsv4root_newopt; + +NFSD_VNET_DECLARE(int, nfsrv_numnfsd); +NFSD_VNET_DECLARE(struct nfsrv_stablefirst, nfsrv_stablefirst); +NFSD_VNET_DECLARE(SVCPOOL *, nfsrvd_pool); +NFSD_VNET_DECLARE(struct nfsclienthashhead *, nfsclienthash); +NFSD_VNET_DECLARE(struct nfslockhashhead *, nfslockhash); +NFSD_VNET_DECLARE(struct nfssessionhash *, nfssessionhash); +NFSD_VNET_DECLARE(struct nfsv4lock, nfsd_suspend_lock); + NFSDLOCKMUTEX; NFSSTATESPINLOCK; -struct nfsrchash_bucket nfsrchash_table[NFSRVCACHE_HASHSIZE]; -struct nfsrchash_bucket nfsrcahash_table[NFSRVCACHE_HASHSIZE]; struct mtx nfsrc_udpmtx; struct mtx nfs_v4root_mutex; struct mtx nfsrv_dontlistlock_mtx; struct mtx nfsrv_recalllock_mtx; -struct nfsrvfh nfs_rootfh, nfs_pubfh; -int nfs_pubfhset = 0, nfs_rootfhset = 0; -struct proc *nfsd_master_proc = NULL; +struct nfsrvfh nfs_pubfh; +int nfs_pubfhset = 0; int nfsd_debuglevel = 0; static pid_t nfsd_master_pid = (pid_t)-1; static char nfsd_master_comm[MAXCOMLEN + 1]; static struct timeval nfsd_master_start; static uint32_t nfsv4_sysid = 0; static fhandle_t zerofh; -struct callout nfsd_callout; +static int nfsrv_osd_jail_slot; + +NFSD_VNET_DEFINE(struct proc *, nfsd_master_proc) = NULL; +NFSD_VNET_DEFINE(struct nfsrvhashhead *, nfsrvudphashtbl); +NFSD_VNET_DEFINE(struct nfsrchash_bucket *, nfsrchash_table); +NFSD_VNET_DEFINE(struct nfsrchash_bucket *, nfsrcahash_table); +NFSD_VNET_DEFINE(struct nfsrvfh, nfs_rootfh); +NFSD_VNET_DEFINE(int, nfs_rootfhset) = 0; +NFSD_VNET_DEFINE(struct callout, nfsd_callout); +NFSD_VNET_DEFINE(struct nfsstatsv1 *, nfsstatsv1_p); +NFSD_VNET_DEFINE_STATIC(struct mount *, nfsv4root_mnt); +NFSD_VNET_DEFINE_STATIC(struct vfsoptlist, nfsv4root_opt); +NFSD_VNET_DEFINE_STATIC(struct vfsoptlist, nfsv4root_newopt); +NFSD_VNET_DEFINE_STATIC(bool, nfsrv_suspend_nfsd) = false; +NFSD_VNET_DEFINE_STATIC(bool, nfsrv_mntinited) = false; + +static void nfsrv_cleanup(struct prison *); static int nfssvc_srvcall(struct thread *, struct nfssvc_args *, struct ucred *); @@ -108,7 +121,6 @@ static int nfs_commit_blks; static int nfs_commit_miss; extern int nfsrv_issuedelegs; extern int nfsrv_dolocallocks; -extern int nfsd_enable_stringtouid; extern struct nfsdevicehead nfsrv_devidhead; static int nfsrv_createiovec(int, struct mbuf **, struct mbuf **, @@ -170,8 +182,10 @@ SYSCTL_INT(_vfs_nfsd, OID_AUTO, enable_locallocks, CTLFLAG_RW, &nfsrv_dolocallocks, 0, "Enable nfsd to acquire local locks on files"); SYSCTL_INT(_vfs_nfsd, OID_AUTO, debuglevel, CTLFLAG_RW, &nfsd_debuglevel, 0, "Debug level for NFS server"); -SYSCTL_INT(_vfs_nfsd, OID_AUTO, enable_stringtouid, CTLFLAG_RW, - &nfsd_enable_stringtouid, 0, "Enable nfsd to accept numeric owner_names"); +NFSD_VNET_DECLARE(int, nfsd_enable_stringtouid); +SYSCTL_INT(_vfs_nfsd, OID_AUTO, enable_stringtouid, + CTLFLAG_NFSD_VNET | CTLFLAG_RW, &NFSD_VNET_NAME(nfsd_enable_stringtouid), + 0, "Enable nfsd to accept numeric owner_names"); static int nfsrv_pnfsgetdsattr = 1; SYSCTL_INT(_vfs_nfsd, OID_AUTO, pnfsgetdsattr, CTLFLAG_RW, &nfsrv_pnfsgetdsattr, 0, "When set getattr gets DS attributes via RPC"); @@ -1022,7 +1036,7 @@ nfsvno_read(struct vnode *vp, off_t off, int cnt, struct ucred *cred, nh = nfsrv_sequential_heuristic(uiop, vp); ioflag |= nh->nh_seqcount << IO_SEQSHIFT; /* XXX KDM make this more systematic? */ - nfsstatsv1.srvbytes[NFSV4OP_READ] += uiop->uio_resid; + nfsstatsv1_p->srvbytes[NFSV4OP_READ] += uiop->uio_resid; error = VOP_READ(vp, uiop, IO_NODELOCKED | ioflag, cred); free(iv, M_TEMP); if (error) { @@ -1147,7 +1161,7 @@ nfsvno_write(struct vnode *vp, off_t off, int retlen, int *stable, nh = nfsrv_sequential_heuristic(uiop, vp); ioflags |= nh->nh_seqcount << IO_SEQSHIFT; /* XXX KDM make this more systematic? */ - nfsstatsv1.srvbytes[NFSV4OP_WRITE] += uiop->uio_resid; + nfsstatsv1_p->srvbytes[NFSV4OP_WRITE] += uiop->uio_resid; error = VOP_WRITE(vp, uiop, ioflags, cred); if (error == 0) nh->nh_nextoff = uiop->uio_offset; @@ -3252,7 +3266,7 @@ nfsvno_checkexp(struct mount *mp, struct sockaddr *nam, struct nfsexstuff *exp, error = VFS_CHECKEXP(mp, nam, &exp->nes_exflag, credp, &exp->nes_numsecflavor, exp->nes_secflavors); if (error) { - if (nfs_rootfhset) { + if (NFSD_VNET(nfs_rootfhset)) { exp->nes_exflag = 0; exp->nes_numsecflavor = 0; error = 0; @@ -3287,7 +3301,7 @@ nfsvno_fhtovp(struct mount *mp, fhandle_t *fhp, struct sockaddr *nam, error = VFS_CHECKEXP(mp, nam, &exp->nes_exflag, credp, &exp->nes_numsecflavor, exp->nes_secflavors); if (error) { - if (nfs_rootfhset) { + if (NFSD_VNET(nfs_rootfhset)) { exp->nes_exflag = 0; exp->nes_numsecflavor = 0; error = 0; @@ -3455,9 +3469,9 @@ nfsrv_v4rootexport(void *argp, struct ucred *cred, struct thread *p) struct nameidata nd; fhandle_t fh; - error = vfs_export(&nfsv4root_mnt, &nfsexargp->export); + error = vfs_export(NFSD_VNET(nfsv4root_mnt), &nfsexargp->export); if ((nfsexargp->export.ex_flags & MNT_DELEXPORT) != 0) - nfs_rootfhset = 0; + NFSD_VNET(nfs_rootfhset) = 0; else if (error == 0) { if (nfsexargp->fspec == NULL) { error = EPERM; @@ -3472,11 +3486,11 @@ nfsrv_v4rootexport(void *argp, struct ucred *cred, struct thread *p) error = nfsvno_getfh(nd.ni_vp, &fh, p); vrele(nd.ni_vp); if (!error) { - nfs_rootfh.nfsrvfh_len = NFSX_MYFH; + NFSD_VNET(nfs_rootfh).nfsrvfh_len = NFSX_MYFH; NFSBCOPY((caddr_t)&fh, - nfs_rootfh.nfsrvfh_data, + NFSD_VNET(nfs_rootfh).nfsrvfh_data, sizeof (fhandle_t)); - nfs_rootfhset = 1; + NFSD_VNET(nfs_rootfhset) = 1; } } @@ -3512,29 +3526,53 @@ nfsrv_mallocmget_limit(void) void nfsd_mntinit(void) { - static int inited = 0; - if (inited) + NFSD_LOCK(); + if (NFSD_VNET(nfsrv_mntinited)) { + NFSD_UNLOCK(); return; - inited = 1; - nfsv4root_mnt.mnt_flag = (MNT_RDONLY | MNT_EXPORTED); - TAILQ_INIT(&nfsv4root_mnt.mnt_nvnodelist); - TAILQ_INIT(&nfsv4root_mnt.mnt_lazyvnodelist); - nfsv4root_mnt.mnt_export = NULL; - TAILQ_INIT(&nfsv4root_opt); - TAILQ_INIT(&nfsv4root_newopt); - nfsv4root_mnt.mnt_opt = &nfsv4root_opt; - nfsv4root_mnt.mnt_optnew = &nfsv4root_newopt; - nfsv4root_mnt.mnt_nvnodelistsize = 0; - nfsv4root_mnt.mnt_lazyvnodelistsize = 0; + } + NFSD_VNET(nfsrv_mntinited) = true; + NFSD_UNLOCK(); + + if (curthread->td_ucred->cr_prison == &prison0) + NFSD_VNET(nfsstatsv1_p) = &nfsstatsv1; + else + NFSD_VNET(nfsstatsv1_p) = malloc(sizeof(struct nfsstatsv1), + M_TEMP, M_WAITOK | M_ZERO); + nfsstatsv1_p->srvcache_tcppeak = 0; + nfsstatsv1_p->srvcache_size = 0; + NFSD_VNET(nfsv4root_mnt) = malloc(sizeof(struct mount), M_TEMP, + M_WAITOK | M_ZERO); + NFSD_VNET(nfsv4root_mnt)->mnt_flag = (MNT_RDONLY | MNT_EXPORTED); + mtx_init(&NFSD_VNET(nfsv4root_mnt)->mnt_mtx, "nfs4mnt", NULL, MTX_DEF); + lockinit(&NFSD_VNET(nfsv4root_mnt)->mnt_explock, PVFS, "explock", 0, 0); + TAILQ_INIT(&NFSD_VNET(nfsv4root_mnt)->mnt_nvnodelist); + TAILQ_INIT(&NFSD_VNET(nfsv4root_mnt)->mnt_lazyvnodelist); + NFSD_VNET(nfsv4root_mnt)->mnt_export = NULL; + TAILQ_INIT(&NFSD_VNET(nfsv4root_opt)); + TAILQ_INIT(&NFSD_VNET(nfsv4root_newopt)); + NFSD_VNET(nfsv4root_mnt)->mnt_opt = &NFSD_VNET(nfsv4root_opt); + NFSD_VNET(nfsv4root_mnt)->mnt_optnew = &NFSD_VNET(nfsv4root_newopt); + NFSD_VNET(nfsv4root_mnt)->mnt_nvnodelistsize = 0; + NFSD_VNET(nfsv4root_mnt)->mnt_lazyvnodelistsize = 0; + callout_init(&NFSD_VNET(nfsd_callout), 1); + + nfsrvd_initcache(); + nfsd_init(); } static void nfsd_timer(void *arg) { - - nfsrv_servertimer(); - callout_reset_sbt(&nfsd_callout, SBT_1S, SBT_1S, nfsd_timer, NULL, 0); + struct vnet *vnetp; + + vnetp = (struct vnet *)arg; + NFSD_CURVNET_SET_QUIET(vnetp); + nfsrv_servertimer(vnetp); + callout_reset_sbt(&NFSD_VNET(nfsd_callout), SBT_1S, SBT_1S, nfsd_timer, + arg, 0); + NFSD_CURVNET_RESTORE(); } /* @@ -3616,7 +3654,7 @@ nfsvno_v4rootexport(struct nfsrv_descript *nd) int error = 0, numsecflavor, secflavors[MAXSECFLAVORS], i; uint64_t exflags; - error = vfs_stdcheckexp(&nfsv4root_mnt, nd->nd_nam, &exflags, + error = vfs_stdcheckexp(NFSD_VNET(nfsv4root_mnt), nd->nd_nam, &exflags, &credanon, &numsecflavor, secflavors); if (error) { error = NFSERR_PROGUNAVAIL; @@ -3649,6 +3687,18 @@ out: *** 1213 LINES SKIPPED ***