summaryrefslogtreecommitdiff
path: root/sys/nfs/nfs_srvcache.c
diff options
context:
space:
mode:
authorThordur I. Bjornsson <thib@cvs.openbsd.org>2009-06-04 18:36:44 +0000
committerThordur I. Bjornsson <thib@cvs.openbsd.org>2009-06-04 18:36:44 +0000
commit55553aa18b9ed4f2816efde311ab87566fe65dd7 (patch)
tree8941bab962fa1f527ec5f8ec28331efcd4991f5c /sys/nfs/nfs_srvcache.c
parent54bcc9c37bd9a36606c2378c63dbb1436f34752c (diff)
Plug mbuf leaks in the DRC, when we reuse entries we didn't
free the mbufs the entry has (socket name, reply). Found with dlg@'s amazing mbuf debug diff, fix is based on the same thing in NetBSD (by yamt@netbsd.org). OK blambert@
Diffstat (limited to 'sys/nfs/nfs_srvcache.c')
-rw-r--r--sys/nfs/nfs_srvcache.c26
1 files changed, 17 insertions, 9 deletions
diff --git a/sys/nfs/nfs_srvcache.c b/sys/nfs/nfs_srvcache.c
index 14d78f9497b..c8d336b2479 100644
--- a/sys/nfs/nfs_srvcache.c
+++ b/sys/nfs/nfs_srvcache.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: nfs_srvcache.c,v 1.22 2009/05/30 17:20:29 thib Exp $ */
+/* $OpenBSD: nfs_srvcache.c,v 1.23 2009/06/04 18:36:43 thib Exp $ */
/* $NetBSD: nfs_srvcache.c,v 1.12 1996/02/18 11:53:49 fvdl Exp $ */
/*
@@ -62,6 +62,7 @@ extern int nfsv2_procid[NFS_NPROCS];
long numnfsrvcache, desirednfsrvcache = NFSRVCACHESIZ;
struct nfsrvcache *nfsrv_lookupcache(struct nfsrv_descript *);
+void nfsrv_cleanentry(struct nfsrvcache *);
#define NFSRCHASH(xid) \
(&nfsrvhashtbl[((xid) + ((xid) >> 24)) & nfsrvhash])
@@ -86,6 +87,18 @@ int nfsv2_repstat[NFS_NPROCS] = {
0, 0
};
+void
+nfsrv_cleanentry(struct nfsrvcache *rp)
+{
+ if ((rp->rc_flag & RC_REPMBUF) != 0)
+ m_freem(rp->rc_reply);
+
+ if ((rp->rc_flag & RC_NAM) != 0)
+ m_free(rp->rc_nam);
+
+ rp->rc_flag &= ~(RC_REPSTATUS|RC_REPMBUF);
+}
+
/* Initialize the server request cache list */
void
nfsrv_initcache(void)
@@ -173,10 +186,7 @@ nfsrv_getcache(struct nfsrv_descript *nd, struct nfssvc_sock *slp,
rp->rc_flag |= RC_LOCKED;
LIST_REMOVE(rp, rc_hash);
TAILQ_REMOVE(&nfsrvlruhead, rp, rc_lru);
- if (rp->rc_flag & RC_REPMBUF)
- m_freem(rp->rc_reply);
- if (rp->rc_flag & RC_NAM)
- m_freem(rp->rc_nam);
+ nfsrv_cleanentry(rp);
rp->rc_flag &= (RC_LOCKED | RC_WANTED);
}
TAILQ_INSERT_TAIL(&nfsrvlruhead, rp, rc_lru);
@@ -215,6 +225,7 @@ nfsrv_updatecache(struct nfsrv_descript *nd, int repvalid,
rp = nfsrv_lookupcache(nd);
if (rp) {
+ nfsrv_cleanentry(rp);
rp->rc_state = RC_DONE;
/*
* If we have a valid reply update status and save
@@ -250,10 +261,7 @@ nfsrv_cleancache(void)
nextrp = TAILQ_NEXT(rp, rc_lru);
LIST_REMOVE(rp, rc_hash);
TAILQ_REMOVE(&nfsrvlruhead, rp, rc_lru);
- if (rp->rc_flag & RC_REPMBUF)
- m_freem(rp->rc_reply);
- if (rp->rc_flag & RC_NAM)
- m_freem(rp->rc_nam);
+ nfsrv_cleanentry(rp);
free(rp, M_NFSD);
}
numnfsrvcache = 0;