From nobody Mon May 15 23:42:18 2023 X-Original-To: dev-commits-src-branches@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4QKwrp6R72z4BFYl; Mon, 15 May 2023 23:42:18 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4QKwrp69jhz3LWr; Mon, 15 May 2023 23:42:18 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1684194138; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=z87ToFD+ttaj5jbCTP4dr6g0qbNEcbKn9MB+27QSd88=; b=SFI6ZlDSbxzDiY8L0ZrwVkCbsr3HpsNWHZJzo4+F9LPQxyoRo8OflOHCKj1agwP5n+yQOA Z6tUY1tU1AZE00BOWP8x1+Tkq5L5dUL50eRRO0LRGpDmKgU1AJ3H/1bwlR0TGz2ahjlOUj 4P5bCSPNGV16/a0EnzqWbhT94KBNwaulYdDUnACSAiF6CJ5ckQ+3Rx/TVCDE/JC1znHgU8 BcR0lQ5nSAlY7A/jZyJdZBuyG0EQ8iq07Nwe4mDvvthoZmlDkP8llqKRM4F7LxjhCwHWBT pTsngfHe+Dt/MzFkR+OVhnLmoQ0d7ajNjaIOFEo2b758jvBQF2Sapx/Zqv5QDA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1684194138; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=z87ToFD+ttaj5jbCTP4dr6g0qbNEcbKn9MB+27QSd88=; b=rBCLBQ2TtSrFvFBc5mlyEZpFdoEr+4aVycdGZ23oyKGBhJuBdBnaw3HSkZL7K+mdu80fyd kWELECbFTzc6TO/hLpQAZyZmnFVdh8itUAmyhbmOIC79JoVtSzRHfX1RiYKN8KDyrafjeL 9ONt/hHn9ueORYvJ2PUkEgHlpZRgJ7CvnpN/O/hgQIvc/codxFPVSpJaf9w11TJpIa9C6h csXmmrv7m1iw2znN5g1rFXXSxGNmaQWF9Nc6iqkhQc1/lOLaq8sBrxgIgGVZ2n1lQnBqo0 1XmgJR4deSXU4IGA4SVKwarUuRP1QT54cx+A3Tdz3BDQWYzScj9P2lz3ufb7JA== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1684194138; a=rsa-sha256; cv=none; b=Gt28XmsoMfo7Eu3NZiHe7GitpQZ2b9fkdkX2d5/2QzcIk22MzUt+SsWuOEpGglQv3G/LKo gC7wUEZdokowXw31qeNE+JbkcUpHA8jQQQNzr31GN8JgaGiDPkbs9vf0gzmCb7Ry9PDDKo 1ne/XczpwSHfeuLMWfIXd29rgSHhd5nOUzDbw4cP1wufhD2qbdj0F9asC9J9iEvIOB1wY5 VsKNkK/AuNtKhQR18d7YvQoBAwKzabp8tjGWBclPNcrSLI7tlgJ+/U6Jah/NA2xgd/8EqS xLDbfzUKHUj4CHGN53tl6SZhavYJMLY75OiMDEWNDxrV/sxnmkLblmt2kZxe5A== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4QKwrp5Cqcz10dB; Mon, 15 May 2023 23:42:18 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 34FNgIkD061450; Mon, 15 May 2023 23:42:18 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 34FNgI3s061449; Mon, 15 May 2023 23:42:18 GMT (envelope-from git) Date: Mon, 15 May 2023 23:42:18 GMT Message-Id: <202305152342.34FNgI3s061449@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Rick Macklem Subject: git: b4805d577787 - stable/13 - nfsd: Prepare the NFS server code to run in a vnet prison List-Id: Commits to the stable branches of the FreeBSD src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-branches List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-branches@freebsd.org X-BeenThere: dev-commits-src-branches@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: rmacklem X-Git-Repository: src X-Git-Refname: refs/heads/stable/13 X-Git-Reftype: branch X-Git-Commit: b4805d5777871ee62400737ceddec5e0e5e05941 Auto-Submitted: auto-generated X-ThisMailContainsUnwantedMimeParts: N The branch stable/13 has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=b4805d5777871ee62400737ceddec5e0e5e05941 commit b4805d5777871ee62400737ceddec5e0e5e05941 Author: Rick Macklem AuthorDate: 2023-02-11 23:51:19 +0000 Commit: Rick Macklem CommitDate: 2023-05-15 23:39:04 +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. (cherry picked from commit 7e44856e3a6deb194c2c376e886854b256360c40) --- 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 | 186 +++++++++++++----------- sys/fs/nfsserver/nfs_nfsdsubs.c | 45 +++--- 9 files changed, 522 insertions(+), 347 deletions(-) diff --git a/sys/fs/nfs/nfs_var.h b/sys/fs/nfs/nfs_var.h index 9dd3be3d5c42..ef7d0050e1a3 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 2955ae43de85..0a0e68787f65 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 -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 44f585ff0beb..7b0f84c397bc 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(); td_softdep_cleanup(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 407987aa767f..a58df7b69420 100644 --- a/sys/fs/nfsserver/nfs_nfsdport.c +++ b/sys/fs/nfsserver/nfs_nfsdport.c @@ -50,6 +50,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -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 **, @@ -168,8 +180,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"); @@ -1025,7 +1039,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) { @@ -1150,7 +1164,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; @@ -3263,7 +3277,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; @@ -3298,7 +3312,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; @@ -3466,9 +3480,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; @@ -3484,11 +3498,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; } } @@ -3524,29 +3538,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(); } /* @@ -3628,7 +3666,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; @@ -3661,6 +3699,18 @@ out: return (error); *** 1205 LINES SKIPPED ***