aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/fs/nfs/nfs_var.h1
-rw-r--r--sys/fs/nfsserver/nfs_nfsdport.c8
-rw-r--r--sys/fs/nfsserver/nfs_nfsdstate.c34
3 files changed, 43 insertions, 0 deletions
diff --git a/sys/fs/nfs/nfs_var.h b/sys/fs/nfs/nfs_var.h
index 03365fc628de6..b767cbfacbb91 100644
--- a/sys/fs/nfs/nfs_var.h
+++ b/sys/fs/nfs/nfs_var.h
@@ -124,6 +124,7 @@ int nfsrv_checkgetattr(struct nfsrv_descript *, vnode_t,
struct nfsvattr *, nfsattrbit_t *, struct ucred *, NFSPROC_T *);
int nfsrv_nfsuserdport(u_short, NFSPROC_T *);
void nfsrv_nfsuserddelport(void);
+void nfsrv_throwawayallstate(NFSPROC_T *);
/* nfs_nfsdserv.c */
int nfsrvd_access(struct nfsrv_descript *, int,
diff --git a/sys/fs/nfsserver/nfs_nfsdport.c b/sys/fs/nfsserver/nfs_nfsdport.c
index 81bccb6012d37..8f5f3cdf03c84 100644
--- a/sys/fs/nfsserver/nfs_nfsdport.c
+++ b/sys/fs/nfsserver/nfs_nfsdport.c
@@ -54,6 +54,7 @@ extern int newnfs_numnfsd;
extern struct mount nfsv4root_mnt;
extern struct nfsrv_stablefirst nfsrv_stablefirst;
extern void (*nfsd_call_servertimer)(void);
+extern SVCPOOL *nfsrvd_pool;
struct vfsoptlist nfsv4root_opt, nfsv4root_newopt;
NFSDLOCKMUTEX;
struct mtx nfs_cache_mutex;
@@ -3125,9 +3126,16 @@ nfsd_modevent(module_t mod, int type, void *data)
nfsd_call_servertimer = NULL;
nfsd_call_nfsd = NULL;
+ /* Clean out all NFSv4 state. */
+ nfsrv_throwawayallstate(curthread);
+
/* Clean the NFS server reply cache */
nfsrvd_cleancache();
+ /* Free up the krpc server pool. */
+ if (nfsrvd_pool != NULL)
+ svcpool_destroy(nfsrvd_pool);
+
/* and get rid of the locks */
mtx_destroy(&nfs_cache_mutex);
mtx_destroy(&nfs_v4root_mutex);
diff --git a/sys/fs/nfsserver/nfs_nfsdstate.c b/sys/fs/nfsserver/nfs_nfsdstate.c
index a480c8e9a7494..ab94f0e88fcb7 100644
--- a/sys/fs/nfsserver/nfs_nfsdstate.c
+++ b/sys/fs/nfsserver/nfs_nfsdstate.c
@@ -5194,3 +5194,37 @@ nfsrv_unlocklf(struct nfslockfile *lfp)
nfsv4_unlock(&lfp->lf_locallock_lck, 0);
}
+/*
+ * Clear out all state for the NFSv4 server.
+ * Must be called by a thread that can sleep when no nfsds are running.
+ */
+void
+nfsrv_throwawayallstate(NFSPROC_T *p)
+{
+ struct nfsclient *clp, *nclp;
+ struct nfslockfile *lfp, *nlfp;
+ int i;
+
+ /*
+ * For each client, clean out the state and then free the structure.
+ */
+ for (i = 0; i < NFSCLIENTHASHSIZE; i++) {
+ LIST_FOREACH_SAFE(clp, &nfsclienthash[i], lc_hash, nclp) {
+ nfsrv_cleanclient(clp, p);
+ nfsrv_freedeleglist(&clp->lc_deleg);
+ nfsrv_freedeleglist(&clp->lc_olddeleg);
+ free(clp, M_NFSDCLIENT);
+ }
+ }
+
+ /*
+ * Also, free up any remaining lock file structures.
+ */
+ for (i = 0; i < NFSLOCKHASHSIZE; i++) {
+ LIST_FOREACH_SAFE(lfp, &nfslockhash[i], lf_hash, nlfp) {
+ printf("nfsd unload: fnd a lock file struct\n");
+ nfsrv_freenfslockfile(lfp);
+ }
+ }
+}
+