Subject: Re: VFS LKM & pool_init() panic
To: None <tech-kern@netbsd.org>
From: Jaromir Dolecek <dolecek@ics.muni.cz>
List: tech-kern
Date: 03/15/2000 13:00:08
Hi,
here are the changes I've made to add the VFS op. I also
added a new function - hashdone(), for freeing memory
returned from hashinit(). I think it's good to have
it as a functions instead of hardcoding free() on all
the respecive places. But as it's just a wrapper around free(),
it's probably not necessary. Opinions are welcome.

I also changed ufs_init() to keep the count it was called
in external variable and added ufs_done(), which lowers
the variable and calls appropriate cleanups if in reaches
zero. Might be significant in improbable case that also
ffs is dynamically loaded/unloaded.

I added similar thing to ffs_init()/ffs_done() and add a call in
mfs_init()/mfs_done(), so that the ffs resources are initialized
if it's not been done by ffs itself.  This may not be actually
needed, since mfs needs ffs already loaded, what means that ffs is
already initialized and hence next call to ffs_init() doesn't do
anything. But should probably be good to clearly show semantics of
the code. If it's not necessary, it won't go in.

The code has not been tested yet (it will be before going in tree,
of course).

XXXXX
Index: sys/mount.h
===================================================================
RCS file: /cvsroot/syssrc/sys/sys/mount.h,v
retrieving revision 1.81
diff -u -p -r1.81 mount.h
--- mount.h	2000/03/13 18:52:06	1.81
+++ mount.h	2000/03/15 11:49:55
@@ -296,7 +296,7 @@ struct vnodeopv_desc;
 #endif
 
 struct vfsops {
-	char	*vfs_name;
+	const char *vfs_name;
 	int	(*vfs_mount)	__P((struct mount *mp, const char *path,
 				    void *data, struct nameidata *ndp,
 				    struct proc *p));
@@ -317,6 +317,7 @@ struct vfsops {
 				    struct vnode **vpp));
 	int	(*vfs_vptofh)	__P((struct vnode *vp, struct fid *fhp));
 	void	(*vfs_init)	__P((void));
+	void	(*vfs_done)	__P((void));
 	int	(*vfs_sysctl)	__P((int *, u_int, void *, size_t *, void *,
 				    size_t, struct proc *));
 	int	(*vfs_mountroot) __P((void));
Index: kern/kern_subr.c
===================================================================
RCS file: /cvsroot/syssrc/sys/kern/kern_subr.c,v
retrieving revision 1.60
diff -u -p -r1.60 kern_subr.c
--- kern_subr.c	2000/03/01 03:51:29	1.60
+++ kern_subr.c	2000/03/15 11:29:47
@@ -237,6 +237,18 @@ hashinit(elements, type, flags, hashmask
 }
 
 /*
+ * Free memory from hash table previosly allocated via hashinit().
+ */
+int
+hashdone(hashtbl, type, hashmask)
+	void *hashtbl;
+	int type;
+	u_long hashmask;
+{
+	free(hashtbl, type);
+}
+
+/*
  * "Shutdown hook" types, functions, and variables.
  */
 
Index: sys/systm.h
===================================================================
RCS file: /cvsroot/syssrc/sys/sys/systm.h,v
retrieving revision 1.103
diff -u -p -r1.103 systm.h
--- systm.h	2000/02/20 19:32:28	1.103
+++ systm.h	2000/03/15 11:29:50
@@ -160,6 +160,7 @@ int	lkmenodev __P((void));
 
 int	seltrue __P((dev_t dev, int events, struct proc *p));
 void	*hashinit __P((int count, int type, int flags, u_long *hashmask));
+int	hashdone __P((void *hashtbl, int type));
 int	sys_nosys __P((struct proc *, void *, register_t *));
 
 
Index: adosfs/advfsops.c
===================================================================
RCS file: /cvsroot/syssrc/sys/adosfs/advfsops.c,v
retrieving revision 1.41
diff -u -p -r1.41 advfsops.c
--- advfsops.c	1999/11/15 20:55:48	1.41
+++ advfsops.c	2000/03/15 11:29:52
@@ -53,6 +53,7 @@
 #include <adosfs/adosfs.h>
 
 void adosfs_init __P((void));
+void adosfs_done __P((void));
 int adosfs_mount __P((struct mount *, const char *, void *, struct nameidata *,
 		      struct proc *));
 int adosfs_start __P((struct mount *, int, struct proc *));
@@ -794,6 +795,12 @@ adosfs_init()
 	    M_ANODE);
 }
 
+void
+adosfs_done()
+{
+	pool_destroy(&adosfs_node_pool);
+}
+
 int
 adosfs_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
 	int *name;
@@ -831,6 +838,7 @@ struct vfsops adosfs_vfsops = {
 	adosfs_fhtovp,                  
 	adosfs_vptofh,                  
 	adosfs_init,                    
+	adosfs_done,
 	adosfs_sysctl,
 	NULL,				/* vfs_mountroot */
 	adosfs_checkexp,
Index: coda/coda_vfsops.c
===================================================================
RCS file: /cvsroot/syssrc/sys/coda/coda_vfsops.c,v
retrieving revision 1.8
diff -u -p -r1.8 coda_vfsops.c
--- coda_vfsops.c	1999/10/17 23:39:16	1.8
+++ coda_vfsops.c	2000/03/15 11:29:56
@@ -109,6 +109,9 @@ struct vfsops coda_vfsops = {
 	eopnotsupp,
     (int (*) (struct vnode *, struct fid *)) eopnotsupp,
     coda_init,
+#ifdef __NetBSD__
+    coda_done,
+#endif
     coda_sysctl,
     (int (*)(void)) eopnotsupp,
     (int (*)(struct mount *, struct mbuf *, int *, struct ucred **))
@@ -534,6 +537,14 @@ coda_init(void)
 {
     ENTRY;
 }
+
+#ifdef __NetBSD__
+void
+coda_done(void)
+{
+    ENTRY;
+}
+#endif
 
 int
 coda_sysctl(name, namelen, oldp, oldlp, newp, newl, p)
Index: filecorefs/filecore_extern.h
===================================================================
RCS file: /cvsroot/syssrc/sys/filecorefs/filecore_extern.h,v
retrieving revision 1.5
diff -u -p -r1.5 filecore_extern.h
--- filecore_extern.h	1999/02/26 23:44:44	1.5
+++ filecore_extern.h	2000/03/15 11:29:56
@@ -86,6 +86,7 @@ int filecore_checkexp __P((struct mount 
 	    struct ucred **));
 int filecore_vptofh __P((struct vnode *, struct fid *));
 void filecore_init __P((void));
+void filecore_done __P((void));
 int filecore_sysctl __P((int *, u_int, void *, size_t *, void *, size_t,
 			struct proc *));
 
Index: filecorefs/filecore_node.c
===================================================================
RCS file: /cvsroot/syssrc/sys/filecorefs/filecore_node.c,v
retrieving revision 1.4
diff -u -p -r1.4 filecore_node.c
--- filecore_node.c	1999/07/08 01:06:00	1.4
+++ filecore_node.c	2000/03/15 11:29:57
@@ -73,13 +73,22 @@ int prtactive;	/* 1 => print out reclaim
 void
 filecore_init()
 {
-
 	filecorehashtbl = hashinit(desiredvnodes, M_FILECOREMNT, M_WAITOK,
 	    &filecorehash);
 	simple_lock_init(&filecore_ihash_slock);
 	pool_init(&filecore_node_pool, sizeof(struct filecore_node),
 	    0, 0, 0, "filecrnopl", 0, pool_page_alloc_nointr,
 	    pool_page_free_nointr, M_FILECORENODE);
+}
+
+/*
+ * Destroy node pool and hash table.
+ */
+void
+filecore_done()
+{
+	pool_destroy(&filecore_node_pool);
+	hashdone(filecorehashtbl, M_FILECOREMNT);
 }
 
 /*
Index: filecorefs/filecore_vfsops.c
===================================================================
RCS file: /cvsroot/syssrc/sys/filecorefs/filecore_vfsops.c,v
retrieving revision 1.10
diff -u -p -r1.10 filecore_vfsops.c
--- filecore_vfsops.c	1999/11/15 18:49:08	1.10
+++ filecore_vfsops.c	2000/03/15 11:29:59
@@ -79,6 +79,7 @@ struct vfsops filecore_vfsops = {
 	filecore_fhtovp,
 	filecore_vptofh,
 	filecore_init,
+	filecore_done,
 	filecore_sysctl,
 	NULL,				/* filecore_mountroot */
 	filecore_checkexp,
Index: isofs/cd9660/cd9660_extern.h
===================================================================
RCS file: /cvsroot/syssrc/sys/isofs/cd9660/cd9660_extern.h,v
retrieving revision 1.7
diff -u -p -r1.7 cd9660_extern.h
--- cd9660_extern.h	1999/07/13 11:12:05	1.7
+++ cd9660_extern.h	2000/03/15 11:29:59
@@ -98,6 +98,7 @@ int cd9660_check_export __P((struct moun
 	    struct ucred **));
 int cd9660_vptofh __P((struct vnode *, struct fid *));
 void cd9660_init __P((void));
+void cd9660_done __P((void));
 int cd9660_sysctl __P((int *, u_int, void *, size_t *, void *, size_t,
 			struct proc *));
 
Index: isofs/cd9660/cd9660_node.c
===================================================================
RCS file: /cvsroot/syssrc/sys/isofs/cd9660/cd9660_node.c,v
retrieving revision 1.21
diff -u -p -r1.21 cd9660_node.c
--- cd9660_node.c	1999/07/08 01:06:00	1.21
+++ cd9660_node.c	2000/03/15 11:30:01
@@ -85,7 +85,6 @@ static u_int cd9660_chars2ui __P((u_char
 void
 cd9660_init()
 {
-
 	isohashtbl = hashinit(desiredvnodes, M_ISOFSMNT, M_WAITOK, &isohash);
 	simple_lock_init(&cd9660_ihash_slock);
 #ifdef ISODEVMAP
@@ -95,6 +94,19 @@ cd9660_init()
 	pool_init(&cd9660_node_pool, sizeof(struct iso_node), 0, 0, 0,
 	    "cd9660nopl", 0, pool_page_alloc_nointr, pool_page_free_nointr,
 	    M_ISOFSNODE);
+}
+
+/*
+ * Destroy node pool and hash table.
+ */
+void
+cd9660_done()
+{
+	hashdone(isohashtbl, M_ISOFSMNT);
+#ifdef ISODEVMAP
+	hashdone(idvhashtbl, M_ISOFSMNT);
+#endif
+	pool_destroy(&cd9660_node_pool);
 }
 
 #ifdef ISODEVMAP
Index: miscfs/fdesc/fdesc.h
===================================================================
RCS file: /cvsroot/syssrc/sys/miscfs/fdesc/fdesc.h,v
retrieving revision 1.10
diff -u -p -r1.10 fdesc.h
--- fdesc.h	1998/03/01 02:21:08	1.10
+++ fdesc.h	2000/03/15 11:30:02
@@ -76,6 +76,7 @@ struct fdescnode {
 
 extern dev_t devctty;
 extern void fdesc_init __P((void));
+extern void fdesc_done __P((void));
 extern int fdesc_root __P((struct mount *, struct vnode **));
 extern int fdesc_allocvp __P((fdntype, int, struct mount *, struct vnode **));
 extern int (**fdesc_vnodeop_p) __P((void *));
Index: miscfs/fdesc/fdesc_vnops.c
===================================================================
RCS file: /cvsroot/syssrc/sys/miscfs/fdesc/fdesc_vnops.c,v
retrieving revision 1.53
diff -u -p -r1.53 fdesc_vnops.c
--- fdesc_vnops.c	1999/08/25 14:42:35	1.53
+++ fdesc_vnops.c	2000/03/15 11:30:07
@@ -199,6 +199,15 @@ fdesc_init()
 }
 
 /*
+ * Free hash table.
+ */
+void
+fdesc_done()
+{
+	hashdone(fdhashtbl, M_CACHE);
+}
+
+/*
  * Return a locked vnode of the correct type.
  */
 int
Index: miscfs/genfs/layer_extern.h
===================================================================
RCS file: /cvsroot/syssrc/sys/miscfs/genfs/layer_extern.h,v
retrieving revision 1.2
diff -u -p -r1.2 layer_extern.h
--- layer_extern.h	2000/03/13 23:52:40	1.2
+++ layer_extern.h	2000/03/15 11:30:07
@@ -75,6 +75,7 @@
 
 /* misc routines in layer_subr.c */
 void	layerfs_init __P((void));
+void	layerfs_done __P((void));
 int	layer_node_alloc __P((struct mount *, struct vnode *, struct vnode **));
 int	layer_node_create __P((struct mount *, struct vnode *, struct vnode **));
 struct vnode *
Index: miscfs/genfs/layer_subr.c
===================================================================
RCS file: /cvsroot/syssrc/sys/miscfs/genfs/layer_subr.c,v
retrieving revision 1.5
diff -u -p -r1.5 layer_subr.c
--- layer_subr.c	2000/03/13 23:52:40	1.5
+++ layer_subr.c	2000/03/15 11:30:09
@@ -100,9 +100,19 @@
 void
 layerfs_init()
 {
-
 #ifdef LAYERFS_DIAGNOSTIC
 	printf("layerfs_init\n");		/* printed during system boot */
+#endif
+}
+
+/*
+ * Free global resources of layerfs.
+ */
+void
+layerfs_done()
+{
+#ifdef LAYERFS_DIAGNOSTIC
+	printf("layerfs_done\n");		/* printed on layerfs detach */
 #endif
 }
 
Index: miscfs/kernfs/kernfs_vfsops.c
===================================================================
RCS file: /cvsroot/syssrc/sys/miscfs/kernfs/kernfs_vfsops.c,v
retrieving revision 1.35
diff -u -p -r1.35 kernfs_vfsops.c
--- kernfs_vfsops.c	1999/02/26 23:44:45	1.35
+++ kernfs_vfsops.c	2000/03/15 11:30:09
@@ -62,6 +62,7 @@
 dev_t rrootdev = NODEV;
 
 void	kernfs_init __P((void));
+void	kernfs_done __P((void));
 void	kernfs_get_rrootdev __P((void));
 int	kernfs_mount __P((struct mount *, const char *, void *,
 	    struct nameidata *, struct proc *));
@@ -86,6 +87,11 @@ kernfs_init()
 }
 
 void
+kernfs_done()
+{
+}
+
+void
 kernfs_get_rrootdev()
 {
 	static int tried = 0;
@@ -375,6 +381,7 @@ struct vfsops kernfs_vfsops = {
 	kernfs_fhtovp,
 	kernfs_vptofh,
 	kernfs_init,
+	kernfs_done,
 	kernfs_sysctl,
 	NULL,				/* vfs_mountroot */
 	kernfs_checkexp,
Index: miscfs/nullfs/null_vfsops.c
===================================================================
RCS file: /cvsroot/syssrc/sys/miscfs/nullfs/null_vfsops.c,v
retrieving revision 1.25
diff -u -p -r1.25 null_vfsops.c
--- null_vfsops.c	2000/03/13 23:52:41	1.25
+++ null_vfsops.c	2000/03/15 11:30:11
@@ -289,6 +289,7 @@ struct vfsops nullfs_vfsops = {
 	layerfs_fhtovp,
 	layerfs_vptofh,
 	layerfs_init,
+	layerfs_done,
 	layerfs_sysctl,
 	NULL,				/* vfs_mountroot */
 	layerfs_checkexp,
Index: miscfs/overlay/overlay_vfsops.c
===================================================================
RCS file: /cvsroot/syssrc/sys/miscfs/overlay/overlay_vfsops.c,v
retrieving revision 1.2
diff -u -p -r1.2 overlay_vfsops.c
--- overlay_vfsops.c	2000/03/13 23:52:41	1.2
+++ overlay_vfsops.c	2000/03/15 11:30:12
@@ -280,6 +280,7 @@ struct vfsops overlay_vfsops = {
 	layerfs_fhtovp,
 	layerfs_vptofh,
 	layerfs_init,
+	layerfs_done,
 	layerfs_sysctl,
 	NULL,				/* vfs_mountroot */
 	layerfs_checkexp,
Index: miscfs/portal/portal_vfsops.c
===================================================================
RCS file: /cvsroot/syssrc/sys/miscfs/portal/portal_vfsops.c,v
retrieving revision 1.22
diff -u -p -r1.22 portal_vfsops.c
--- portal_vfsops.c	1999/05/05 20:01:11	1.22
+++ portal_vfsops.c	2000/03/15 11:30:16
@@ -67,6 +67,7 @@
 #include <miscfs/portal/portal.h>
 
 void	portal_init __P((void));
+void	portal_done __P((void));
 int	portal_mount __P((struct mount *, const char *, void *,
 			  struct nameidata *, struct proc *));
 int	portal_start __P((struct mount *, int, struct proc *));
@@ -89,6 +90,11 @@ portal_init()
 {
 }
 
+void
+portal_done()
+{
+}
+
 /*
  * Mount the per-process file descriptors (/dev/fd)
  */
@@ -361,6 +367,7 @@ struct vfsops portal_vfsops = {
 	portal_fhtovp,
 	portal_vptofh,
 	portal_init,
+	portal_done,
 	portal_sysctl,
 	NULL,				/* vfs_mountroot */
 	portal_checkexp,
Index: miscfs/procfs/procfs.h
===================================================================
RCS file: /cvsroot/syssrc/sys/miscfs/procfs/procfs.h,v
retrieving revision 1.28
diff -u -p -r1.28 procfs.h
--- procfs.h	2000/01/25 21:52:04	1.28
+++ procfs.h	2000/03/15 11:30:16
@@ -137,6 +137,7 @@ int procfs_docmdline __P((struct proc *,
 int procfs_checkioperm __P((struct proc *, struct proc *));
 void procfs_revoke_vnodes __P((struct proc *, void *));
 void procfs_hashinit __P((void));
+void procfs_hashdone __P((void));
 
 /* functions to check whether or not files should be displayed */
 int procfs_validfile __P((struct proc *));
Index: miscfs/procfs/procfs_subr.c
===================================================================
RCS file: /cvsroot/syssrc/sys/miscfs/procfs/procfs_subr.c,v
retrieving revision 1.30
diff -u -p -r1.30 procfs_subr.c
--- procfs_subr.c	2000/02/25 22:33:43	1.30
+++ procfs_subr.c	2000/03/15 11:30:18
@@ -321,6 +321,15 @@ procfs_hashinit()
 	simple_lock_init(&pfs_hash_slock);
 }
 
+/*
+ * Free pfsnode hash table.
+ */
+void
+procfs_hashdone()
+{
+	hashdone(pfs_hashtbl, M_UFSMNT);
+}
+
 struct vnode *
 procfs_hashget(pid, type, mp)
 	pid_t pid;
Index: miscfs/procfs/procfs_vfsops.c
===================================================================
RCS file: /cvsroot/syssrc/sys/miscfs/procfs/procfs_vfsops.c,v
retrieving revision 1.32
diff -u -p -r1.32 procfs_vfsops.c
--- procfs_vfsops.c	2000/01/25 21:52:04	1.32
+++ procfs_vfsops.c	2000/03/15 11:30:19
@@ -62,6 +62,7 @@
 #include <vm/vm.h>			/* for PAGE_SIZE */
 
 void	procfs_init __P((void));
+void	procfs_done __P((void));
 int	procfs_mount __P((struct mount *, const char *, void *,
 			  struct nameidata *, struct proc *));
 int	procfs_start __P((struct mount *, int, struct proc *));
@@ -272,6 +273,12 @@ procfs_init()
 	procfs_hashinit();
 }
 
+void
+procfs_done()
+{
+	procfs_hashdone();
+}
+
 int
 procfs_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
 	int *name;
@@ -305,6 +312,7 @@ struct vfsops procfs_vfsops = {
 	procfs_fhtovp,
 	procfs_vptofh,
 	procfs_init,
+	procfs_done,
 	procfs_sysctl,
 	NULL,				/* vfs_mountroot */
 	procfs_checkexp,
Index: miscfs/umapfs/umap_vfsops.c
===================================================================
RCS file: /cvsroot/syssrc/sys/miscfs/umapfs/umap_vfsops.c,v
retrieving revision 1.23
diff -u -p -r1.23 umap_vfsops.c
--- umap_vfsops.c	1999/07/08 01:19:07	1.23
+++ umap_vfsops.c	2000/03/15 11:30:21
@@ -302,6 +302,7 @@ struct vfsops umapfs_vfsops = {
 	layerfs_fhtovp,
 	layerfs_vptofh,
 	layerfs_init,
+	layerfs_done,
 	layerfs_sysctl,
 	NULL,				/* vfs_mountroot */
 	layerfs_checkexp,
Index: miscfs/union/union.h
===================================================================
RCS file: /cvsroot/syssrc/sys/miscfs/union/union.h,v
retrieving revision 1.11
diff -u -p -r1.11 union.h
--- union.h	1999/08/01 00:00:57	1.11
+++ union.h	2000/03/15 11:30:21
@@ -131,6 +131,7 @@ extern int (**union_vnodeop_p) __P((void
 extern struct vfsops union_vfsops;
 
 void union_init __P((void));
+void union_done __P((void));
 int union_freevp __P((struct vnode *));
 
 #endif /* _KERNEL */
Index: miscfs/union/union_subr.c
===================================================================
RCS file: /cvsroot/syssrc/sys/miscfs/union/union_subr.c,v
retrieving revision 1.36
diff -u -p -r1.36 union_subr.c
--- union_subr.c	1999/10/16 23:53:28	1.36
+++ union_subr.c	2000/03/15 11:30:25
@@ -93,6 +93,14 @@ union_init()
 	memset((caddr_t) unvplock, 0, sizeof(unvplock));
 }
 
+/*
+ * Free global unionfs resources.
+ */
+void
+union_done()
+{
+}
+
 static int
 union_list_lock(ix)
 	int ix;
Index: miscfs/union/union_vfsops.c
===================================================================
RCS file: /cvsroot/syssrc/sys/miscfs/union/union_vfsops.c,v
retrieving revision 1.23
diff -u -p -r1.23 union_vfsops.c
--- union_vfsops.c	1999/07/31 23:56:15	1.23
+++ union_vfsops.c	2000/03/15 11:30:31
@@ -580,6 +580,7 @@ struct vfsops union_vfsops = {
 	union_fhtovp,
 	union_vptofh,
 	union_init,
+	union_done,
 	union_sysctl,
 	NULL,				/* vfs_mountroot */
 	union_checkexp,
Index: msdosfs/msdosfs_denode.c
===================================================================
RCS file: /cvsroot/syssrc/sys/msdosfs/msdosfs_denode.c,v
retrieving revision 1.39
diff -u -p -r1.39 msdosfs_denode.c
--- msdosfs_denode.c	2000/02/26 17:25:17	1.39
+++ msdosfs_denode.c	2000/03/15 11:30:58
@@ -92,6 +92,13 @@ msdosfs_init()
 	    M_MSDOSFSNODE);
 }
 
+void
+msdosfs_done()
+{
+	hashdone(dehashtbl, M_MSDOSFSMNT, dehash);
+	pool_destroy(&msdosfs_denode_pool);
+}
+
 static struct denode *
 msdosfs_hashget(dev, dirclust, diroff)
 	dev_t dev;
Index: msdosfs/msdosfs_vfsops.c
===================================================================
RCS file: /cvsroot/syssrc/sys/msdosfs/msdosfs_vfsops.c,v
retrieving revision 1.66
diff -u -p -r1.66 msdosfs_vfsops.c
--- msdosfs_vfsops.c	2000/02/01 10:33:19	1.66
+++ msdosfs_vfsops.c	2000/03/15 11:31:58
@@ -120,6 +120,7 @@ struct vfsops msdosfs_vfsops = {
 	msdosfs_fhtovp,
 	msdosfs_vptofh,
 	msdosfs_init,
+	msdosfs_done,
 	msdosfs_sysctl,
 	msdosfs_mountroot,
 	msdosfs_checkexp,
Index: msdosfs/msdosfsmount.h
===================================================================
RCS file: /cvsroot/syssrc/sys/msdosfs/msdosfsmount.h,v
retrieving revision 1.19
diff -u -p -r1.19 msdosfsmount.h
--- msdosfsmount.h	1999/02/26 23:44:47	1.19
+++ msdosfsmount.h	2000/03/15 11:31:59
@@ -218,5 +218,6 @@ int msdosfs_fhtovp __P((struct mount *, 
 int msdosfs_checkexp __P((struct mount *, struct mbuf *, int *, struct ucred **));
 int msdosfs_vptofh __P((struct vnode *, struct fid *));
 void msdosfs_init __P((void));
+void msdosfs_done __P((void));
 
 #endif /* _KERNEL */
Index: nfs/nfs_node.c
===================================================================
RCS file: /cvsroot/syssrc/sys/nfs/nfs_node.c,v
retrieving revision 1.30
diff -u -p -r1.30 nfs_node.c
--- nfs_node.c	1999/11/29 23:34:00	1.30
+++ nfs_node.c	2000/03/15 11:32:00
@@ -86,6 +86,17 @@ nfs_nhinit()
 }
 
 /*
+ * Free resources previoslu allocated in nfs_nhinit().
+ */
+void
+nfs_nhdone()
+{
+	hashdone(nfsnodehashtbl, M_NFSNODE);
+	pool_destroy(&nfs_node_pool);
+	pool_destroy(&nfs_vattr_pool);
+}
+
+/*
  * Compute an entry in the NFS hash table structure
  */
 u_long
Index: nfs/nfs_subs.c
===================================================================
RCS file: /cvsroot/syssrc/sys/nfs/nfs_subs.c,v
retrieving revision 1.72
diff -u -p -r1.72 nfs_subs.c
--- nfs_subs.c	1999/11/01 21:32:41	1.72
+++ nfs_subs.c	2000/03/15 11:32:42
@@ -1477,6 +1477,12 @@ nfs_vfs_init()
 	nfs_nhinit();			/* Init the nfsnode table */
 }
 
+void
+nfs_vfs_done()
+{
+	nfs_nhdone();
+}
+
 /*
  * Attribute cache routines.
  * nfs_loadattrcache() - loads or updates the cache contents from attributes
Index: nfs/nfs_var.h
===================================================================
RCS file: /cvsroot/syssrc/sys/nfs/nfs_var.h,v
retrieving revision 1.15
diff -u -p -r1.15 nfs_var.h
--- nfs_var.h	1998/09/05 14:29:52	1.15
+++ nfs_var.h	2000/03/15 11:32:43
@@ -82,6 +82,7 @@ int nfs_doio __P((struct buf *, struct u
 
 /* nfs_node.c */
 void nfs_nhinit __P((void));
+void nfs_nhdone __P((void));
 u_long nfs_hash __P((nfsfh_t *, int));
 int nfs_nget __P((struct mount *, nfsfh_t *, int, struct nfsnode **));
 
Index: nfs/nfs_vfsops.c
===================================================================
RCS file: /cvsroot/syssrc/sys/nfs/nfs_vfsops.c,v
retrieving revision 1.85
diff -u -p -r1.85 nfs_vfsops.c
--- nfs_vfsops.c	1999/11/15 18:49:11	1.85
+++ nfs_vfsops.c	2000/03/15 11:32:49
@@ -107,6 +107,7 @@ struct vfsops nfs_vfsops = {
 	nfs_fhtovp,
 	nfs_vptofh,
 	nfs_vfs_init,
+	nfs_vfs_done,
 	nfs_sysctl,
 	nfs_mountroot,
 	nfs_checkexp,
Index: nfs/nfsmount.h
===================================================================
RCS file: /cvsroot/syssrc/sys/nfs/nfsmount.h,v
retrieving revision 1.18
diff -u -p -r1.18 nfsmount.h
--- nfsmount.h	1999/07/04 19:56:00	1.18
+++ nfsmount.h	2000/03/15 11:32:50
@@ -192,6 +192,7 @@ int	nfs_vptofh __P((struct vnode *vp, st
 int	nfs_fsinfo __P((struct nfsmount *, struct vnode *, struct ucred *,
 			struct proc *));
 void	nfs_vfs_init __P((void));
+void	nfs_vfs_done __P((void));
 
 /*
  * Prototypes for miscellaneous exported NFS functions.
Index: ntfs/ntfs_ihash.c
===================================================================
RCS file: /cvsroot/syssrc/sys/ntfs/ntfs_ihash.c,v
retrieving revision 1.5
diff -u -p -r1.5 ntfs_ihash.c
--- ntfs_ihash.c	1999/09/30 16:56:40	1.5
+++ ntfs_ihash.c	2000/03/15 11:32:50
@@ -74,6 +74,18 @@ ntfs_nthashinit()
 	simple_lock_init(&ntfs_nthash_slock);
 }
 
+#ifdef __NetBSD__
+/*
+ * Free the inode hash table. Called from ntfs_done(), only needed
+ * on NetBSD.
+ */
+void
+ntfs_nthashdone()
+{
+	hashdone(ntfs_nthashtbl, M_NTFSNTHASH);
+}
+#endif
+
 /*
  * Use the device/inum pair to find the incore inode, and return a pointer
  * to it. If it is in core, return it, even if it is locked.
Index: ntfs/ntfs_ihash.h
===================================================================
RCS file: /cvsroot/syssrc/sys/ntfs/ntfs_ihash.h,v
retrieving revision 1.4
diff -u -p -r1.4 ntfs_ihash.h
--- ntfs_ihash.h	1999/09/30 16:56:40	1.4
+++ ntfs_ihash.h	2000/03/15 11:32:50
@@ -30,6 +30,7 @@
 
 extern struct lock ntfs_hashlock;
 void ntfs_nthashinit __P((void));
+void ntfs_nthashdone __P((void));
 struct ntnode   *ntfs_nthashlookup __P((dev_t, ino_t));
 struct ntnode   *ntfs_nthashget __P((dev_t, ino_t));
 void ntfs_nthashins __P((struct ntnode *));
Index: ntfs/ntfs_vfsops.c
===================================================================
RCS file: /cvsroot/syssrc/sys/ntfs/ntfs_vfsops.c,v
retrieving revision 1.24
diff -u -p -r1.24 ntfs_vfsops.c
--- ntfs_vfsops.c	2000/02/08 16:17:59	1.24
+++ ntfs_vfsops.c	2000/03/15 11:32:56
@@ -96,6 +96,7 @@ static int	ntfs_fhtovp __P((struct mount
 				 int *, struct ucred **));
 #elif defined(__NetBSD__)
 static void	ntfs_init __P((void));
+static void	ntfs_done __P((void));
 static int	ntfs_fhtovp __P((struct mount *, struct fid *,
 				 struct vnode **));
 static int	ntfs_checkexp __P((struct mount *, struct mbuf *,
@@ -196,12 +197,18 @@ ntfs_mountroot()
 }
 
 static void
-ntfs_init ()
+ntfs_init()
 {
 	ntfs_nthashinit();
 	ntfs_toupper_init();
 }
 
+static void
+ntfs_done()
+{
+	ntfs_nthashdone();
+}
+
 #elif defined(__FreeBSD__)
 
 static int
@@ -1031,26 +1038,12 @@ struct vfsops ntfs_vfsops = {
 	ntfs_fhtovp,
 	ntfs_vptofh,
 	ntfs_init,
+	ntfs_done,
 	ntfs_sysctl,
 	ntfs_mountroot,
 	ntfs_checkexp,
 	ntfs_vnodeopv_descs,
 };
-#else /* !NetBSD && !FreeBSD */
-static struct vfsops ntfs_vfsops = {
-	ntfs_mount,
-	ntfs_start,
-	ntfs_unmount,
-	ntfs_root,
-	ntfs_quotactl,
-	ntfs_statfs,
-	ntfs_sync,
-	ntfs_vget,
-	ntfs_fhtovp,
-	ntfs_vptofh,
-	ntfs_init,
-};
-VFS_SET(ntfs_vfsops, ntfs, MOUNT_NTFS, 0);
 #endif
 
 
Index: ufs/ext2fs/ext2fs_extern.h
===================================================================
RCS file: /cvsroot/syssrc/sys/ufs/ext2fs/ext2fs_extern.h,v
retrieving revision 1.7
diff -u -p -r1.7 ext2fs_extern.h
--- ext2fs_extern.h	1999/02/26 23:44:48	1.7
+++ ext2fs_extern.h	2000/03/15 11:33:01
@@ -76,7 +76,6 @@ int ext2fs_balloc __P((struct inode *, u
 int ext2fs_bmap __P((void *));
 
 /* ext2fs_inode.c */
-void ext2fs_init __P((void));
 int ext2fs_update __P((void *));
 int ext2fs_truncate __P((void *));
 int ext2fs_inactive __P((void *));
@@ -100,6 +99,8 @@ void	ext2fs_checkoverlap __P((struct buf
 #endif
 
 /* ext2fs_vfsops.c */
+void ext2fs_init __P((void));
+void ext2fs_done __P((void));
 int ext2fs_mountroot __P((void));
 int ext2fs_mount __P((struct mount *, const char *, void *, struct nameidata *,
 		   struct proc *));
Index: ufs/ext2fs/ext2fs_vfsops.c
===================================================================
RCS file: /cvsroot/syssrc/sys/ufs/ext2fs/ext2fs_vfsops.c,v
retrieving revision 1.33
diff -u -p -r1.33 ext2fs_vfsops.c
--- ext2fs_vfsops.c	2000/01/31 11:34:55	1.33
+++ ext2fs_vfsops.c	2000/03/15 11:33:09
@@ -100,6 +100,7 @@ struct vfsops ext2fs_vfsops = {
 	ext2fs_fhtovp,
 	ext2fs_vptofh,
 	ext2fs_init,
+	ext2fs_done,
 	ext2fs_sysctl,
 	ext2fs_mountroot,
 	ufs_check_export,
@@ -123,6 +124,12 @@ ext2fs_init()
 	    M_EXT2FSNODE);
 }
 
+void
+ext2fs_done()
+{
+	ufs_done();
+	pool_destroy(&ext2fs_inode_pool);
+}
 
 /*
  * Called by main() when ext2fs is going to be mounted as root.
Index: ufs/ffs/ffs_extern.h
===================================================================
RCS file: /cvsroot/syssrc/sys/ufs/ffs/ffs_extern.h,v
retrieving revision 1.14
diff -u -p -r1.14 ffs_extern.h
--- ffs_extern.h	2000/02/14 22:00:22	1.14
+++ ffs_extern.h	2000/03/15 11:33:09
@@ -94,7 +94,6 @@ void ffs_dinode_swap __P((struct dinode 
 void ffs_csum_swap __P((struct csum *, struct csum *, int));
 
 /* ffs_inode.c */
-void ffs_init __P((void));
 int ffs_update __P((void *));
 int ffs_truncate __P((void *));
 
@@ -111,6 +110,8 @@ void ffs_clrblock __P((struct fs *, u_ch
 void ffs_setblock __P((struct fs *, unsigned char *, ufs_daddr_t));
 
 /* ffs_vfsops.c */
+void ffs_init __P((void));
+void ffs_done __P((void));
 int ffs_mountroot __P((void));
 int ffs_mount __P((struct mount *, const char *, void *, struct nameidata *,
 		   struct proc *));
Index: ufs/ffs/ffs_vfsops.c
===================================================================
RCS file: /cvsroot/syssrc/sys/ufs/ffs/ffs_vfsops.c,v
retrieving revision 1.57
diff -u -p -r1.57 ffs_vfsops.c
--- ffs_vfsops.c	2000/02/14 22:00:23	1.57
+++ ffs_vfsops.c	2000/03/15 11:33:20
@@ -74,6 +74,9 @@
 #include <ufs/ffs/fs.h>
 #include <ufs/ffs/ffs_extern.h>
 
+/* how many times ffs_init() was called */
+int ffs_initcount = 0;
+
 extern struct lock ufs_hashlock;
 
 int ffs_sbupdate __P((struct ufsmount *, int));
@@ -102,6 +105,7 @@ struct vfsops ffs_vfsops = {
 	ffs_fhtovp,
 	ffs_vptofh,
 	ffs_init,
+	ffs_done,
 	ffs_sysctl,
 	ffs_mountroot,
 	ufs_check_export,
@@ -1103,11 +1107,25 @@ ffs_vptofh(vp, fhp)
 void
 ffs_init()
 {
+	if (ffs_initcount++ > 0)
+		return;
+
 	softdep_initialize();
 	ufs_init();
 
 	pool_init(&ffs_inode_pool, sizeof(struct inode), 0, 0, 0, "ffsinopl",
 	    0, pool_page_alloc_nointr, pool_page_free_nointr, M_FFSNODE);
+}
+
+void
+ffs_done()
+{
+	if (--ffs_initcount > 0)
+		return;
+
+	/* XXX softdep cleanup ? */
+	ufs_done();
+	pool_destroy(&ffs_inode_pool);
 }
 
 int
Index: ufs/lfs/lfs_extern.h
===================================================================
RCS file: /cvsroot/syssrc/sys/ufs/lfs/lfs_extern.h,v
retrieving revision 1.16
diff -u -p -r1.16 lfs_extern.h
--- lfs_extern.h	2000/01/19 00:03:04	1.16
+++ lfs_extern.h	2000/03/15 11:33:22
@@ -129,7 +129,6 @@ void lfs_check_segsum __P((struct lfs *,
 #endif /* DEBUG */
 
 /* lfs_inode.c */
-void lfs_init __P((void));
 struct dinode *lfs_ifind __P((struct lfs *, ino_t, struct buf *));
 
 /* lfs_segment.c */
@@ -167,6 +166,8 @@ int lfs_fastvget __P((struct mount *, in
 struct buf *lfs_fakebuf __P((struct vnode *, int, size_t, caddr_t));
 
 /* lfs_vfsops.c */
+void lfs_init __P((void));
+void lfs_done __P((void));
 int lfs_mountroot __P((void));
 int lfs_mount __P((struct mount *, const char *, void *, struct nameidata *, struct proc *));
 int lfs_mountfs __P((struct vnode *, struct mount *, struct proc *));
Index: ufs/lfs/lfs_vfsops.c
===================================================================
RCS file: /cvsroot/syssrc/sys/ufs/lfs/lfs_vfsops.c,v
retrieving revision 1.46
diff -u -p -r1.46 lfs_vfsops.c
--- lfs_vfsops.c	2000/01/19 00:03:05	1.46
+++ lfs_vfsops.c	2000/03/15 11:33:26
@@ -130,6 +130,7 @@ struct vfsops lfs_vfsops = {
 	lfs_fhtovp,
 	lfs_vptofh,
 	lfs_init,
+	lfs_done,
 	lfs_sysctl,
 	lfs_mountroot,
 	ufs_check_export,
@@ -152,6 +153,13 @@ lfs_init()
 	pool_init(&lfs_inode_pool, sizeof(struct inode), 0, 0, 0,
 		  "lfsinopl", 0, pool_page_alloc_nointr, pool_page_free_nointr,
 		  M_LFSNODE);
+}
+
+void
+lfs_done()
+{
+	ufs_done();
+	pool_destroy(&lfs_inode_pool);
 }
 
 /*
Index: ufs/mfs/mfs_extern.h
===================================================================
RCS file: /cvsroot/syssrc/sys/ufs/mfs/mfs_extern.h,v
retrieving revision 1.8
diff -u -p -r1.8 mfs_extern.h
--- mfs_extern.h	1998/08/10 08:11:13	1.8
+++ mfs_extern.h	2000/03/15 11:33:27
@@ -57,6 +57,7 @@ int	mfs_sysctl	__P((int *, u_int, void *
 			     struct proc *));
 
 void	mfs_init	__P((void));
+void	mfs_done	__P((void));
 
 /* mfs_vnops.c */
 int	mfs_open	__P((void *));
Index: ufs/mfs/mfs_vfsops.c
===================================================================
RCS file: /cvsroot/syssrc/sys/ufs/mfs/mfs_vfsops.c,v
retrieving revision 1.22
diff -u -p -r1.22 mfs_vfsops.c
--- mfs_vfsops.c	2000/01/21 23:43:10	1.22
+++ mfs_vfsops.c	2000/03/15 11:33:29
@@ -92,6 +92,7 @@ struct vfsops mfs_vfsops = {
 	ffs_fhtovp,
 	ffs_vptofh,
 	mfs_init,
+	mfs_done,
 	ffs_sysctl,
 	NULL,
 	ufs_check_export,
@@ -104,8 +105,22 @@ struct vfsops mfs_vfsops = {
 void
 mfs_init()
 {
+	/*
+	 * ffs_init() ensures to initialize necessary resources
+	 * only once.
+	 */
+	ffs_init();
 }
 
+void
+mfs_done()
+{
+	/*
+	 * ffs_done() ensures to free necessary resources
+	 * only once, when it's no more needed.
+	 */
+	ffs_done();
+}
 
 /*
  * Called by main() when mfs is going to be mounted as root.
Index: ufs/ufs/quota.h
===================================================================
RCS file: /cvsroot/syssrc/sys/ufs/ufs/quota.h,v
retrieving revision 1.7
diff -u -p -r1.7 quota.h
--- quota.h	1996/09/28 19:07:06	1.7
+++ quota.h	2000/03/15 11:33:31
@@ -190,6 +190,7 @@ void	dqflush __P((struct vnode *));
 int	dqget __P((struct vnode *,
 	    u_long, struct ufsmount *, int, struct dquot **));
 void	dqinit __P((void));
+void	dqdone __P((void));
 void	dqref __P((struct dquot *));
 void	dqrele __P((struct vnode *, struct dquot *));
 int	dqsync __P((struct vnode *, struct dquot *));
Index: ufs/ufs/ufs_extern.h
===================================================================
RCS file: /cvsroot/syssrc/sys/ufs/ufs/ufs_extern.h,v
retrieving revision 1.22
diff -u -p -r1.22 ufs_extern.h
--- ufs_extern.h	2000/02/14 22:00:23	1.22
+++ ufs_extern.h	2000/03/15 11:33:33
@@ -105,13 +105,13 @@ int ufs_getlbns __P((struct vnode *, ufs
 
 /* ufs_ihash.c */
 void ufs_ihashinit __P((void));
+void ufs_ihashdone __P((void));
 struct vnode *ufs_ihashlookup __P((dev_t, ino_t));
 struct vnode *ufs_ihashget __P((dev_t, ino_t, int));
 void ufs_ihashins __P((struct inode *));
 void ufs_ihashrem __P((struct inode *));
 
 /* ufs_inode.c */
-void ufs_init __P((void));
 int ufs_reclaim __P((struct vnode *, struct proc *));
 
 /* ufs_lookup.c */
@@ -147,6 +147,8 @@ int dqsync __P((struct vnode *, struct d
 void dqflush __P((struct vnode *));
 
 /* ufs_vfsops.c */
+void ufs_init __P((void));
+void ufs_done __P((void));
 int ufs_start __P((struct mount *, int, struct proc *));
 int ufs_root __P((struct mount *, struct vnode **));
 int ufs_quotactl __P((struct mount *, int, uid_t, caddr_t, struct proc *));
Index: ufs/ufs/ufs_ihash.c
===================================================================
RCS file: /cvsroot/syssrc/sys/ufs/ufs/ufs_ihash.c,v
retrieving revision 1.9
diff -u -p -r1.9 ufs_ihash.c
--- ufs_ihash.c	1999/11/15 18:49:15	1.9
+++ ufs_ihash.c	2000/03/15 11:33:33
@@ -68,6 +68,15 @@ ufs_ihashinit()
 }
 
 /*
+ * Free inode hash table.
+ */
+void
+ufs_ihashdone()
+{
+	hashdone(ihashtbl, M_UFSMNT);
+}
+
+/*
  * Use the device/inum pair to find the incore inode, and return a pointer
  * to it. If it is in core, return it, even if it is locked.
  */
Index: ufs/ufs/ufs_quota.c
===================================================================
RCS file: /cvsroot/syssrc/sys/ufs/ufs/ufs_quota.c,v
retrieving revision 1.13
diff -u -p -r1.13 ufs_quota.c
--- ufs_quota.c	1999/11/15 18:49:15	1.13
+++ ufs_quota.c	2000/03/15 11:33:37
@@ -684,9 +684,17 @@ long numdquot, desireddquot = DQUOTINC;
 void
 dqinit()
 {
-
 	dqhashtbl = hashinit(desiredvnodes, M_DQUOT, M_WAITOK, &dqhash);
 	TAILQ_INIT(&dqfreelist);
+}
+
+/*
+ * Free resources held by quota system.
+ */
+void
+dqdone()
+{
+	hashdone(dqhashtbl, M_DQUOT);
 }
 
 /*
Index: ufs/ufs/ufs_vfsops.c
===================================================================
RCS file: /cvsroot/syssrc/sys/ufs/ufs/ufs_vfsops.c,v
retrieving revision 1.9
diff -u -p -r1.9 ufs_vfsops.c
--- ufs_vfsops.c	1999/02/26 23:44:50	1.9
+++ ufs_vfsops.c	2000/03/15 11:33:39
@@ -57,6 +57,9 @@
 #include <ufs/ufs/ufsmount.h>
 #include <ufs/ufs/ufs_extern.h>
 
+/* how many times ufs_init() was called */
+int ufs_initcount = 0;
+
 /*
  * Make a filesystem operational.
  * Nothing to do at the moment.
@@ -219,17 +222,29 @@ ufs_fhtovp(mp, ufhp, vpp)
 /*
  * Initialize UFS filesystems, done only once.
  */
-
 void
 ufs_init()
 {
-	static int done = 0;
-
-	if (done)
+	if (ufs_initcount++ > 0)
 		return;
-	done = 1;
+
 	ufs_ihashinit();
 #ifdef QUOTA
 	dqinit();
+#endif
+}
+
+/*
+ * Free UFS filesystem resources, done only once.
+ */
+void
+ufs_done()
+{
+	if (--ufs_initcount > 0)
+		return;
+
+	ufs_ihashdone();
+#ifdef QUOTA
+	dqdone();
 #endif
 }
XXXXX
-- 
Jaromir Dolecek <jdolecek@NetBSD.org>      http://www.ics.muni.cz/~dolecek/
@@@@  Wanna a real operating system ? Go and get NetBSD, damn!  @@@@