summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2006-08-01 16:27:14 +0000
committerjhb <jhb@FreeBSD.org>2006-08-01 16:27:14 +0000
commit4dc640e56e164af7bfa43acfe36b6a8037512f66 (patch)
tree37dd7fcc8f2e00c87c785f35c3c31843f7eb1b29
parentdcdaa35dc670769cb6106cbfd637c36bbb1422f3 (diff)
downloadFreeBSD-src-4dc640e56e164af7bfa43acfe36b6a8037512f66.zip
FreeBSD-src-4dc640e56e164af7bfa43acfe36b6a8037512f66.tar.gz
- Add a new function nfsrv_destroycache() to tear down the server request
cache when unloading the nfsserver module. This fixes a memory leak and a stale pointer. - Use callout_drain() rather than callout_stop() when unloading the nfsserver module. MFC after: 3 days
-rw-r--r--sys/nfsserver/nfs.h1
-rw-r--r--sys/nfsserver/nfs_srvcache.c16
-rw-r--r--sys/nfsserver/nfs_srvsubs.c3
3 files changed, 17 insertions, 3 deletions
diff --git a/sys/nfsserver/nfs.h b/sys/nfsserver/nfs.h
index 809df66..c3b231a 100644
--- a/sys/nfsserver/nfs.h
+++ b/sys/nfsserver/nfs.h
@@ -337,6 +337,7 @@ int nfs_namei(struct nameidata *, fhandle_t *, int,
void nfsm_adj(struct mbuf *, int, int);
int nfsm_mbuftouio(struct mbuf **, struct uio *, int, caddr_t *);
void nfsrv_initcache(void);
+void nfsrv_destroycache(void);
void nfsrv_timer(void *);
int nfsrv_dorec(struct nfssvc_sock *, struct nfsd *,
struct nfsrv_descript **);
diff --git a/sys/nfsserver/nfs_srvcache.c b/sys/nfsserver/nfs_srvcache.c
index 272534f..7d0c126 100644
--- a/sys/nfsserver/nfs_srvcache.c
+++ b/sys/nfsserver/nfs_srvcache.c
@@ -65,6 +65,7 @@ static long desirednfsrvcache;
static LIST_HEAD(nfsrvhash, nfsrvcache) *nfsrvhashtbl;
static TAILQ_HEAD(nfsrvlru, nfsrvcache) nfsrvlruhead;
static u_long nfsrvhash;
+static eventhandler_tag nfsrv_nmbclusters_tag;
#define TRUE 1
#define FALSE 0
@@ -147,8 +148,19 @@ nfsrv_initcache(void)
nfsrvcache_size_change(NULL);
nfsrvhashtbl = hashinit(desirednfsrvcache, M_NFSD, &nfsrvhash);
TAILQ_INIT(&nfsrvlruhead);
- EVENTHANDLER_REGISTER(nmbclusters_change, nfsrvcache_size_change, NULL,
- EVENTHANDLER_PRI_FIRST);
+ nfsrv_nmbclusters_tag = EVENTHANDLER_REGISTER(nmbclusters_change,
+ nfsrvcache_size_change, NULL, EVENTHANDLER_PRI_FIRST);
+}
+
+/*
+ * Teardown the server request cache list
+ */
+void
+nfsrv_destroycache(void)
+{
+ KASSERT(TAILQ_EMPTY(&nfsrvlruhead), ("%s: pending requests", __func__));
+ EVENTHANDLER_DEREGISTER(nmbclusters_change, nfsrv_nmbclusters_tag);
+ hashdestroy(nfsrvhashtbl, M_NFSD, nfsrvhash);
}
/*
diff --git a/sys/nfsserver/nfs_srvsubs.c b/sys/nfsserver/nfs_srvsubs.c
index de2b7af..a6bcb8ea 100644
--- a/sys/nfsserver/nfs_srvsubs.c
+++ b/sys/nfsserver/nfs_srvsubs.c
@@ -567,9 +567,10 @@ nfsrv_modevent(module_t mod, int type, void *data)
break;
}
- callout_stop(&nfsrv_callout);
+ callout_drain(&nfsrv_callout);
sysent[SYS_nfssvc].sy_narg = nfs_prev_nfssvc_sy_narg;
sysent[SYS_nfssvc].sy_call = nfs_prev_nfssvc_sy_call;
+ nfsrv_destroycache(); /* Free the server request cache */
mtx_destroy(&nfsd_mtx);
break;
default:
OpenPOWER on IntegriCloud