Subject: The death of vfs_conf.c
To: None <tech-kern@NetBSD.ORG>
From: Jason Thorpe <thorpej@nas.nasa.gov>
List: tech-kern
Date: 02/16/1998 23:10:20
Hi folks...

So, today I sat down and finally finished some work I started over a year
ago to nuke vfs_conf.c.  Basically, the round of changes to config(8)
that added the "file-system" keyword were geared towards making the list
of statically-included file systems generated by config(8), with no need
for icky #ifdef's.

The changes attached below basically do:

	(1) Remove vfssw[] and vfs_opv_descs[].  vfssw[] has been replaced
	    with vfs_list, and a generated table vfs_list_initial[] which
	    vfsinit() uses to build vfs_list a boot time.

	(2) In support of (1), struct vfsops now has a LIST_ENTRY and
	    a pointer to a NULL-terminated array of struct vnodeopv_desc *'s.

	(3) vfs_init.c has been modified to make the 2nd part of (2) possible,
	    and also to build the initial vfs_list.

	(4) vfs_establish() and vfs_disestablish() - new functions for adding
	    and removing file systems from the kernel's vfs_list.  Used by
	    LKM code and vfsinit().

	(5) All places that referenced vfssw[] have been cleaned up to
	    use the most appropriate interface for that situation.

	(6) LKMs have been cleaned up, and fixed.  (Previously, file systems
	    which supported FIFOs or special files had broken LKMs.)

	(7) [ Not shown ]  Delete vfs_conf.c

If there are no objections, I'll commit these as soon as I've had a chance to
test all of the LKMs (probably Tuesday evening, PST).

Jason R. Thorpe                                       thorpej@nas.nasa.gov
NASA Ames Research Center                            Home: +1 408 866 1912
NAS: M/S 258-5                                       Work: +1 650 604 0935
Moffett Field, CA 94035                             Pager: +1 415 428 6939

Index: usr.sbin/config/mkioconf.c
===================================================================
RCS file: /cvsroot/src/usr.sbin/config/mkioconf.c,v
retrieving revision 1.47
diff -c -r1.47 mkioconf.c
*** mkioconf.c	1998/02/16 22:05:36	1.47
--- mkioconf.c	1998/02/17 06:53:57
***************
*** 64,69 ****
--- 64,70 ----
  static int emitpseudo __P((FILE *));
  static int emitpv __P((FILE *));
  static int emitroots __P((FILE *));
+ static int emitvfslist __P((FILE *));
  
  #define	SEP(pos, max)	(((u_int)(pos) % (max)) == 0 ? "\n\t" : " ")
  
***************
*** 87,93 ****
  	}
  	v = emithdr(fp);
  	if (v != 0 || emitcfdrivers(fp) || emitexterns(fp) || emitloc(fp) ||
! 	    emitpv(fp) || emitcfdata(fp) || emitroots(fp) || emitpseudo(fp)) {
  		if (v >= 0)
  			(void)fprintf(stderr,
  			    "config: error writing ioconf.c: %s\n",
--- 88,95 ----
  	}
  	v = emithdr(fp);
  	if (v != 0 || emitcfdrivers(fp) || emitexterns(fp) || emitloc(fp) ||
! 	    emitpv(fp) || emitcfdata(fp) || emitroots(fp) || emitpseudo(fp) ||
! 	    emitvfslist(fp)) {
  		if (v >= 0)
  			(void)fprintf(stderr,
  			    "config: error writing ioconf.c: %s\n",
***************
*** 141,147 ****
  	} else {
  		if (fputs("\
  #include <sys/param.h>\n\
! #include <sys/device.h>\n", ofp) < 0)
  			return (1);
  	}
  	return (0);
--- 143,150 ----
  	} else {
  		if (fputs("\
  #include <sys/param.h>\n\
! #include <sys/device.h>\n\
! #include <sys/mount.h>\n", ofp) < 0)
  			return (1);
  	}
  	return (0);
***************
*** 372,375 ****
--- 375,416 ----
  			return (1);
  	}
  	return (fputs("\t{ 0, 0 }\n};\n", fp) < 0);
+ }
+ 
+ /*
+  * Emit the initial VFS list.
+  */
+ static int
+ emitvfslist(fp)
+ 	FILE *fp;
+ {
+ 	struct nvlist *nv;
+ 
+ 	if (fputs("\n/* file systems */\n", fp) < 0)
+ 		return (1);
+ 
+ 	/*
+ 	 * Walk the list twice, once to emit the externs,
+ 	 * and again to actually emit the vfs_list_initial[]
+ 	 * array.
+ 	 */
+ 
+ 	for (nv = fsoptions; nv != NULL; nv = nv->nv_next) {
+ 		if (fprintf(fp, "extern struct vfsops %s_vfsops;\n",
+ 		    nv->nv_name) < 0)
+ 			return (1);
+ 	}
+ 
+ 	if (fputs("\nstruct vfsops *vfs_list_initial[] = {\n", fp) < 0)
+ 		return (1);
+ 
+ 	for (nv = fsoptions; nv != NULL; nv = nv->nv_next) {
+ 		if (fprintf(fp, "\t&%s_vfsops,\n", nv->nv_name) < 0)
+ 			return (1);
+ 	}
+ 
+ 	if (fputs("\tNULL,\n};\n", fp) < 0)
+ 		return (1);
+ 
+ 	return (0);
  }
Index: sys/adosfs/advfsops.c
===================================================================
RCS file: /cvsroot/src/sys/adosfs/advfsops.c,v
retrieving revision 1.26
diff -c -r1.26 advfsops.c
*** advfsops.c	1997/07/08 09:11:29	1.26
--- advfsops.c	1998/02/17 06:54:08
***************
*** 748,753 ****
--- 748,761 ----
  /*
   * vfs generic function call table
   */
+ 
+ extern struct vnodeopv_desc adosfs_vnodeop_opv_desc; 
+ 
+ struct vnodeopv_desc *adosfs_vnodeopv_descs[] = {
+ 	&adosfs_vnodeop_opv_desc,
+ 	NULL,
+ };
+ 
  struct vfsops adosfs_vfsops = {
  	MOUNT_ADOSFS,
  	adosfs_mount,
***************
*** 761,764 ****
  	adosfs_fhtovp,                  
  	adosfs_vptofh,                  
  	adosfs_init,                    
! };           
--- 769,774 ----
  	adosfs_fhtovp,                  
  	adosfs_vptofh,                  
  	adosfs_init,                    
! 	NULL,				/* vfs_mountroot */
! 	adosfs_vnodeopv_descs,
! };
Index: sys/isofs/cd9660/cd9660_vfsops.c
===================================================================
RCS file: /cvsroot/src/sys/isofs/cd9660/cd9660_vfsops.c,v
retrieving revision 1.26
diff -c -r1.26 cd9660_vfsops.c
*** cd9660_vfsops.c	1997/06/13 15:38:58	1.26
--- cd9660_vfsops.c	1998/02/17 06:54:15
***************
*** 62,67 ****
--- 62,82 ----
  #include <isofs/cd9660/iso_rrip.h>
  #include <isofs/cd9660/cd9660_node.h>
  
+ extern struct vnodeopv_desc cd9660_vnodeop_opv_desc;
+ extern struct vnodeopv_desc cd9660_specop_opv_desc;
+ #ifdef FIFO
+ extern struct vnodeopv_desc cd9660_fifoop_opv_desc;
+ #endif
+ 
+ struct vnodeopv_desc *cd9660_vnodeopv_descs[] = {
+ 	&cd9660_vnodeop_opv_desc,
+ 	&cd9660_specop_opv_desc,
+ #ifdef FIFO
+ 	&cd9660_fifoop_opv_desc,
+ #endif
+ 	NULL,
+ };
+ 
  struct vfsops cd9660_vfsops = {
  	MOUNT_CD9660,
  	cd9660_mount,
***************
*** 76,81 ****
--- 91,97 ----
  	cd9660_vptofh,
  	cd9660_init,
  	cd9660_mountroot,
+ 	cd9660_vnodeopv_descs,
  };
  
  /*
Index: sys/kern/kern_lkm.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_lkm.c,v
retrieving revision 1.42
diff -c -r1.42 kern_lkm.c
*** kern_lkm.c	1998/02/10 14:09:32	1.42
--- kern_lkm.c	1998/02/17 06:54:30
***************
*** 643,649 ****
  	int cmd;
  {
  	struct lkm_vfs *args = lkmtp->private.lkm_vfs;
- 	int i;
  	int error = 0;
  
  	switch(cmd) {
--- 643,648 ----
***************
*** 652,694 ****
  		if (lkmexists(lkmtp))
  			return (EEXIST);
  
! 		/* make sure there's no VFS in the table with this name */
! 		if (vfs_getopsbyname(args->lkm_vfsops->vfs_name) != NULL)
! 			return (EEXIST);
! 
! 		/* pick the last available empty slot */
! 		for (i = nvfssw - 1; i >= 0; i--)
! 			if (vfssw[i] == (struct vfsops *)0)
! 				break;
! 		if (i == -1) {		/* or if none, punt */
! 			error = EINVAL;
! 			break;
! 		}
! 
! 		/*
! 		 * Set up file system
! 		 */
! 		vfssw[i] = args->lkm_vfsops;
! 		vfssw[i]->vfs_refcount = 0;
! 
! 		/*
! 		 * Call init function for this VFS...
! 		 */
! 	 	(*(vfssw[i]->vfs_init))();
  
  		/* done! */
- 		args->lkm_offset = i;	/* slot in vfssw[] */
  		break;
  
  	case LKM_E_UNLOAD:
! 		/* current slot... */
! 		i = args->lkm_offset;
! 
! 		if (vfssw[i]->vfs_refcount != 0)
! 			return (EBUSY);
! 
! 		/* replace current slot contents with old contents */
! 		vfssw[i] = (struct vfsops *)0;
  		break;
  
  	case LKM_E_STAT:	/* no special handling... */
--- 651,667 ----
  		if (lkmexists(lkmtp))
  			return (EEXIST);
  
! 		/* Establish the file system. */
! 		if ((error = vfs_establish(args->lkm_vfsops)) != 0)
! 			return (error);
  
  		/* done! */
  		break;
  
  	case LKM_E_UNLOAD:
! 		/* Disestablish the file system. */
! 		if ((error = vfs_disestablish(args->lkm_vfsops)) != 0)
! 			return (error);
  		break;
  
  	case LKM_E_STAT:	/* no special handling... */
Index: sys/kern/kern_subr.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_subr.c,v
retrieving revision 1.35
diff -c -r1.35 kern_subr.c
*** kern_subr.c	1998/02/13 17:36:41	1.35
--- kern_subr.c	1998/02/17 06:54:30
***************
*** 1,7 ****
  /*	$NetBSD: kern_subr.c,v 1.35 1998/02/13 17:36:41 tls Exp $	*/
  
  /*-
!  * Copyright (c) 1997 The NetBSD Foundation, Inc.
   * All rights reserved.
   *
   * This code is derived from software contributed to The NetBSD Foundation
--- 1,7 ----
  /*	$NetBSD: kern_subr.c,v 1.35 1998/02/13 17:36:41 tls Exp $	*/
  
  /*-
!  * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
   * All rights reserved.
   *
   * This code is derived from software contributed to The NetBSD Foundation
***************
*** 415,421 ****
  	struct devnametobdevmaj *nam2blk;
  {
  	struct device *dv;
! 	int len, i, print_newline = 0;
  	dev_t nrootdev;
  	dev_t ndumpdev = NODEV;
  	char buf[128];
--- 415,421 ----
  	struct devnametobdevmaj *nam2blk;
  {
  	struct device *dv;
! 	int len, print_newline = 0;
  	dev_t nrootdev;
  	dev_t ndumpdev = NODEV;
  	char buf[128];
***************
*** 569,585 ****
  		rootdev = nrootdev;
  		dumpdev = ndumpdev;
  
! 		for (i = 0; i < nvfssw; i++) {
! 			if (vfssw[i] != NULL &&
! 			    vfssw[i]->vfs_mountroot != NULL &&
! 			    vfssw[i]->vfs_mountroot == mountroot)
  				break;
  		}
! 		if (i >= nvfssw) {
  			mountroot = NULL;
  			deffsname = "generic";
  		} else
! 			deffsname = vfssw[i]->vfs_name;
  		for (;;) {
  			printf("file system (default %s): ", deffsname);
  			len = getstr(buf, sizeof(buf));
--- 569,587 ----
  		rootdev = nrootdev;
  		dumpdev = ndumpdev;
  
! 		for (vops = LIST_FIRST(&vfs_list); vops != NULL;
! 		     vops = LIST_NEXT(vops, vfs_list)) {
! 			if (vops->vfs_mountroot != NULL &&
! 			    vops->vfs_mountroot == mountroot)
  				break;
  		}
! 
! 		if (vops == NULL) {
  			mountroot = NULL;
  			deffsname = "generic";
  		} else
! 			deffsname = vops->vfs_name;
! 
  		for (;;) {
  			printf("file system (default %s): ", deffsname);
  			len = getstr(buf, sizeof(buf));
***************
*** 594,604 ****
  			vops = vfs_getopsbyname(buf);
  			if (vops == NULL || vops->vfs_mountroot == NULL) {
  				printf("use one of: generic");
! 				for (i = 0; i < nvfssw; i++)
! 					if (vfssw[i] != NULL &&
! 					    vfssw[i]->vfs_mountroot != NULL)
! 						printf(" %s",
! 						    vfssw[i]->vfs_name);
  				printf(" halt\n");
  			} else {
  				mountroot = vops->vfs_mountroot;
--- 596,607 ----
  			vops = vfs_getopsbyname(buf);
  			if (vops == NULL || vops->vfs_mountroot == NULL) {
  				printf("use one of: generic");
! 				for (vops = LIST_FIRST(&vfs_list);
! 				     vops != NULL;
! 				     vops = LIST_NEXT(vops, vfs_list)) {
! 					if (vops->vfs_mountroot != NULL)
! 						printf(" %s", vops->vfs_name);
! 				}
  				printf(" halt\n");
  			} else {
  				mountroot = vops->vfs_mountroot;
Index: sys/kern/vfs_init.c
===================================================================
RCS file: /cvsroot/src/sys/kern/vfs_init.c,v
retrieving revision 1.8
diff -c -r1.8 vfs_init.c
*** vfs_init.c	1996/10/13 02:32:50	1.8
--- vfs_init.c	1998/02/17 06:54:30
***************
*** 1,5 ****
--- 1,42 ----
  /*	$NetBSD: vfs_init.c,v 1.8 1996/10/13 02:32:50 christos Exp $	*/
  
+ /*-
+  * Copyright (c) 1998 The NetBSD Foundation, Inc.
+  * All rights reserved.
+  *
+  * This code is derived from software contributed to The NetBSD Foundation
+  * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
+  * NASA Ames Research Center.
+  *
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 3. All advertising materials mentioning features or use of this software
+  *    must display the following acknowledgement:
+  *	This product includes software developed by the NetBSD
+  *	Foundation, Inc. and its contributors.
+  * 4. Neither the name of The NetBSD Foundation nor the names of its
+  *    contributors may be used to endorse or promote products derived
+  *    from this software without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+  * POSSIBILITY OF SUCH DAMAGE.
+  */
+ 
  /*
   * Copyright (c) 1989, 1993
   *	The Regents of the University of California.  All rights reserved.
***************
*** 62,71 ****
  #define DODEBUG(A)
  #endif
  
! extern struct vnodeopv_desc *vfs_opv_descs[];
! 				/* a list of lists of vnodeops defns */
  extern struct vnodeop_desc *vfs_op_descs[];
! 				/* and the operations they perform */
  /*
   * This code doesn't work if the defn is **vnodop_defns with cc.
   * The problem is because of the compiler sometimes putting in an
--- 99,129 ----
  #define DODEBUG(A)
  #endif
  
! /*
!  * The global list of vnode operations.
!  */
  extern struct vnodeop_desc *vfs_op_descs[];
! 
! /*
!  * These vnodeopv_descs are listed here because they are not
!  * associated with any particular file system, and thus cannot
!  * be initialized by vfs_establish().
!  */
! extern struct vnodeopv_desc dead_vnodeop_opv_desc;
! #ifdef FIFO
! extern struct vnodeopv_desc fifo_vnodeop_opv_desc;
! #endif
! extern struct vnodeopv_desc spec_vnodeop_opv_desc;
! 
! struct vnodeopv_desc *vfs_special_vnodeopv_descs[] = {
! 	&dead_vnodeop_opv_desc,
! #ifdef FIFO
! 	&fifo_vnodeop_opv_desc,
! #endif
! 	&spec_vnodeop_opv_desc,
! 	NULL,
! };
! 
  /*
   * This code doesn't work if the defn is **vnodop_defns with cc.
   * The problem is because of the compiler sometimes putting in an
***************
*** 76,82 ****
  
  typedef (*PFI) __P((void *));
  
- void vfs_opv_init __P((void));
  void vfs_opv_init_explicit __P((struct vnodeopv_desc *));
  void vfs_opv_init_default __P((struct vnodeopv_desc *));
  void vfs_op_init __P((void));
--- 134,139 ----
***************
*** 112,118 ****
   */
  
  /*
!  * Allocate and init the vector, if it needs it.
   * Also handle backwards compatibility.
   */
  void
--- 169,175 ----
   */
  
  /*
!  * Init the vector, if it needs it.
   * Also handle backwards compatibility.
   */
  void
***************
*** 124,139 ****
  
  	opv_desc_vector = *(vfs_opv_desc->opv_desc_vector_p);
  
- 	if (opv_desc_vector == NULL) {
- 		/* XXX - shouldn't be M_VNODE */
- 		MALLOC(opv_desc_vector, PFI *,
- 		    vfs_opv_numops * sizeof(PFI), M_VNODE, M_WAITOK);
- 		bzero(opv_desc_vector, vfs_opv_numops * sizeof(PFI));
- 		*(vfs_opv_desc->opv_desc_vector_p) = opv_desc_vector;
- 		DODEBUG(printf("vector at %p allocated\n",
- 		    opv_desc_vector_p));
- 	}
- 
  	for (opve_descp = vfs_opv_desc->opv_desc_ops;
  	     opve_descp->opve_op;
  	     opve_descp++) {
--- 181,186 ----
***************
*** 191,228 ****
  }
  
  void
! vfs_opv_init()
  {
  	int i;
  
  	/*
! 	 * Allocate the dynamic vectors and fill them in.
  	 */
! 	for (i = 0; vfs_opv_descs[i]; i++)
! 		vfs_opv_init_explicit(vfs_opv_descs[i]);
  
  	/*
  	 * Finally, go back and replace unfilled routines
  	 * with their default.
  	 */
! 	for (i = 0; vfs_opv_descs[i]; i++)
! 		vfs_opv_init_default(vfs_opv_descs[i]);
  }
  
- /*
-  * Initialize known vnode operations vectors.
-  */
  void
! vfs_op_init()
  {
  	int i;
  
- 	DODEBUG(printf("Vnode_interface_init.\n"));
  	/*
! 	 * Set all vnode vectors to a well known value.
  	 */
! 	for (i = 0; vfs_opv_descs[i]; i++)
! 		*(vfs_opv_descs[i]->opv_desc_vector_p) = NULL;
  	/*
  	 * Figure out how many ops there are by counting the table,
  	 * and assign each its offset.
--- 238,298 ----
  }
  
  void
! vfs_opv_init(vopvdpp)
! 	struct vnodeopv_desc **vopvdpp;
  {
+ 	int (**opv_desc_vector) __P((void *));
  	int i;
  
  	/*
! 	 * Allocate the vectors.
  	 */
! 	for (i = 0; vopvdpp[i] != NULL; i++) {
! 		/* XXX - shouldn't be M_VNODE */
! 		opv_desc_vector =
! 		    malloc(vfs_opv_numops * sizeof(PFI), M_VNODE, M_WAITOK);
! 		bzero(opv_desc_vector, vfs_opv_numops * sizeof(PFI));
! 		*(vopvdpp[i]->opv_desc_vector_p) = opv_desc_vector;
! 		DODEBUG(printf("vector at %p allocated\n",
! 		    opv_desc_vector_p));
! 	}
! 
! 	/*
! 	 * ...and fill them in.
! 	 */
! 	for (i = 0; vopvdpp[i] != NULL; i++)
! 		vfs_opv_init_explicit(vopvdpp[i]);
  
  	/*
  	 * Finally, go back and replace unfilled routines
  	 * with their default.
  	 */
! 	for (i = 0; vopvdpp[i] != NULL; i++)
! 		vfs_opv_init_default(vopvdpp[i]);
  }
  
  void
! vfs_opv_free(vopvdpp)
! 	struct vnodeopv_desc **vopvdpp;
  {
  	int i;
  
  	/*
! 	 * Free the vectors allocated in vfs_opv_init().
  	 */
! 	for (i = 0; vopvdpp[i] != NULL; i++) {
! 		/* XXX - shouldn't be M_VNODE */
! 		free(*(vopvdpp[i]->opv_desc_vector_p), M_VNODE);
! 		*(vopvdpp[i]->opv_desc_vector_p) = NULL;
! 	}
! }
! 
! void
! vfs_op_init()
! {
! 	int i;
! 
! 	DODEBUG(printf("Vnode_interface_init.\n"));
  	/*
  	 * Figure out how many ops there are by counting the table,
  	 * and assign each its offset.
***************
*** 237,244 ****
  /*
   * Routines having to do with the management of the vnode table.
   */
- extern struct vnodeops dead_vnodeops;
- extern struct vnodeops spec_vnodeops;
  struct vattr va_null;
  
  /*
--- 307,312 ----
***************
*** 247,274 ****
  void
  vfsinit()
  {
! 	struct vfsops **vfsp;
  
  	/*
  	 * Initialize the vnode table
  	 */
  	vntblinit();
  	/*
  	 * Initialize the vnode name cache
  	 */
  	nchinit();
  	/*
! 	 * Build vnode operation vectors.
  	 */
  	vfs_op_init();
! 	vfs_opv_init();   /* finish the job */
  	/*
! 	 * Initialize each file system type.
  	 */
  	vattr_null(&va_null);
! 	for (vfsp = &vfssw[0]; vfsp < &vfssw[nvfssw]; vfsp++) {
! 		if (*vfsp == NULL)
! 			continue;
! 		(*(*vfsp)->vfs_init)();
  	}
  }
--- 315,353 ----
  void
  vfsinit()
  {
! 	extern struct vfsops *vfs_list_initial[];
! 	int i;
  
  	/*
  	 * Initialize the vnode table
  	 */
  	vntblinit();
+ 
  	/*
  	 * Initialize the vnode name cache
  	 */
  	nchinit();
+ 
  	/*
! 	 * Initialize the list of vnode operations.
  	 */
  	vfs_op_init();
! 
  	/*
! 	 * Initialize the special vnode operations.
! 	 */
! 	vfs_opv_init(vfs_special_vnodeopv_descs);
! 
! 	/*
! 	 * Establish each file system which was statically
! 	 * included in the kernel.
  	 */
  	vattr_null(&va_null);
! 	for (i = 0; vfs_list_initial[i] != NULL; i++) {
! 		if (vfs_establish(vfs_list_initial[i])) {
! 			printf("multiple `%s' file systems",
! 			    vfs_list_initial[i]->vfs_name);
! 			panic("vfsinit");
! 		}
  	}
  }
Index: sys/kern/vfs_subr.c
===================================================================
RCS file: /cvsroot/src/sys/kern/vfs_subr.c,v
retrieving revision 1.78
diff -c -r1.78 vfs_subr.c
*** vfs_subr.c	1998/02/10 14:09:52	1.78
--- vfs_subr.c	1998/02/17 06:54:31
***************
*** 1,7 ****
  /*	$NetBSD: vfs_subr.c,v 1.78 1998/02/10 14:09:52 mrg Exp $	*/
  
  /*-
!  * Copyright (c) 1997 The NetBSD Foundation, Inc.
   * All rights reserved.
   *
   * This code is derived from software contributed to The NetBSD Foundation
--- 1,7 ----
  /*	$NetBSD: vfs_subr.c,v 1.78 1998/02/10 14:09:52 mrg Exp $	*/
  
  /*-
!  * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
   * All rights reserved.
   *
   * This code is derived from software contributed to The NetBSD Foundation
***************
*** 136,144 ****
  struct mntlist mountlist =			/* mounted filesystem list */
      CIRCLEQ_HEAD_INITIALIZER(mountlist);
  
! struct device *root_device;			/* root device */
  struct nfs_public nfs_pub;			/* publicly exported FS */
  
  int vfs_lock __P((struct mount *));
  void vfs_unlock __P((struct mount *));
  struct mount *getvfs __P((fsid_t *));
--- 136,153 ----
  struct mntlist mountlist =			/* mounted filesystem list */
      CIRCLEQ_HEAD_INITIALIZER(mountlist);
  
! struct vfs_list_head vfs_list =			/* vfs list */
!     LIST_HEAD_INITIALIZER(vfs_list);
! 
  struct nfs_public nfs_pub;			/* publicly exported FS */
  
+ /*
+  * These define the root filesystem and device.
+  */
+ struct mount *rootfs;
+ struct vnode *rootvnode;
+ struct device *root_device;
+ 
  int vfs_lock __P((struct mount *));
  void vfs_unlock __P((struct mount *));
  struct mount *getvfs __P((fsid_t *));
***************
*** 1823,1829 ****
  vfs_mountroot()
  {
  	extern int (*mountroot) __P((void));
! 	int i;
  
  	if (root_device == NULL)
  		panic("vfs_mountroot: root device unknown");
--- 1832,1838 ----
  vfs_mountroot()
  {
  	extern int (*mountroot) __P((void));
! 	struct vfsops *v;
  
  	if (root_device == NULL)
  		panic("vfs_mountroot: root device unknown");
***************
*** 1854,1877 ****
  	/*
  	 * Try each file system currently configured into the kernel.
  	 */
! 	for (i = 0; i < nvfssw; i++) {
! 		if (vfssw[i] == NULL || vfssw[i]->vfs_mountroot == NULL)
  			continue;
  #ifdef DEBUG
! 		printf("mountroot: trying %s...\n", vfssw[i]->vfs_name);
  #endif
! 		if ((*vfssw[i]->vfs_mountroot)() == 0) {
! 			printf("root file system type: %s\n",
! 			    vfssw[i]->vfs_name);
! 			return (0);
  		}
  	}
  
! 	printf("no file system for %s", root_device->dv_xname);
! 	if (root_device->dv_class == DV_DISK)
! 		printf(" (dev 0x%x)", rootdev);
! 	printf("\n");
! 	return (EFTYPE);
  }
  
  /*
--- 1863,1888 ----
  	/*
  	 * Try each file system currently configured into the kernel.
  	 */
! 	for (v = LIST_FIRST(&vfs_list); v != NULL; v = LIST_NEXT(v, vfs_list)) {
! 		if (v->vfs_mountroot == NULL)
  			continue;
  #ifdef DEBUG
! 		printf("mountroot: trying %s...\n", v->vfs_name);
  #endif
! 		if ((*v->vfs_mountroot)() == 0) {
! 			printf("root file system type: %s\n", v->vfs_name);
! 			break;
  		}
  	}
  
! 	if (v == NULL) {
! 		printf("no file system for %s", root_device->dv_xname);
! 		if (root_device->dv_class == DV_DISK)
! 			printf(" (dev 0x%x)", rootdev);
! 		printf("\n");
! 		return (EFTYPE);
! 	}
! 	return (0);
  }
  
  /*
***************
*** 1883,1892 ****
  vfs_getopsbyname(name)
  	const char *name;
  {
! 	int i;
  
! 	for (i = 0; i < nvfssw; i++)
! 		if (vfssw[i] != NULL && strcmp(vfssw[i]->vfs_name, name) == 0)
! 			return (vfssw[i]);
! 	return (NULL);
  }
--- 1894,1985 ----
  vfs_getopsbyname(name)
  	const char *name;
  {
! 	struct vfsops *v;
! 
! 	for (v = LIST_FIRST(&vfs_list); v != NULL; v = LIST_NEXT(v, vfs_list)) {
! 		if (strcmp(v->vfs_name, name) == 0)
! 			break;
! 	}
! 
! 	return (v);
! }
! 
! /*
!  * Establish a file system and initialize it.
!  */
! int
! vfs_establish(vfs)
! 	struct vfsops *vfs;
! {
! 	struct vfsops *v;
! 	int error = 0;
! 
  
! 	/*
! 	 * Make sure this file system doesn't already exist.
! 	 */
! 	for (v = LIST_FIRST(&vfs_list); v != NULL; v = LIST_NEXT(v, vfs_list)) {
! 		if (strcmp(vfs->vfs_name, v->vfs_name) == 0) {
! 			error = EEXIST;
! 			goto out;
! 		}
! 	}
! 
! 	/*
! 	 * Initialize the vnode operations for this file system.
! 	 */
! 	vfs_opv_init(vfs->vfs_opv_descs);
! 
! 	/*
! 	 * Now initialize the file system itself.
! 	 */
! 	(*vfs->vfs_init)();
! 
! 	/*
! 	 * ...and link it into the kernel's list.
! 	 */
! 	LIST_INSERT_HEAD(&vfs_list, vfs, vfs_list);
! 
! 	/*
! 	 * Sanity: make sure the reference count is 0.
! 	 */
! 	vfs->vfs_refcount = 0;
! 
!  out:
! 	return (error);
! }
! 
! /*
!  * Remove a file system from the kernel.
!  */
! int
! vfs_disestablish(vfs)
! 	struct vfsops *vfs;
! {
! 	struct vfsops *v;
! 
! 	/*
! 	 * Make sure no one is using the filesystem.
! 	 */
! 	if (vfs->vfs_refcount != 0)
! 		return (EBUSY);
! 
! 	/*
! 	 * ...and remove it from the kernel's list.
! 	 */
! 	for (v = LIST_FIRST(&vfs_list); v != NULL; v = LIST_NEXT(v, vfs_list)) {
! 		if (v == vfs) {
! 			LIST_REMOVE(v, vfs_list);
! 			break;
! 		}
! 	}
! 
! 	if (v == NULL)
! 		return (ESRCH);
! 
! 	/*
! 	 * Free the vnode operations vector.
! 	 */
! 	vfs_opv_free(vfs->vfs_opv_descs);
! 	return (0);
  }
Index: sys/lkm/vfs/adosfs/lkminit_vfs.c
===================================================================
RCS file: /cvsroot/src/sys/lkm/vfs/adosfs/lkminit_vfs.c,v
retrieving revision 1.1
diff -c -r1.1 lkminit_vfs.c
*** lkminit_vfs.c	1997/07/08 16:44:49	1.1
--- lkminit_vfs.c	1998/02/17 06:54:42
***************
*** 50,56 ****
   * This is the vfsops table for the file system in question
   */
  extern struct vfsops adosfs_vfsops;
- extern struct vnodeopv_desc adosfs_vnodeop_opv_desc;
  
  /*
   * declare the filesystem
--- 50,55 ----
***************
*** 66,78 ****
  	int cmd;
  	int ver;
  {
- 	/*
- 	 * This is normally done automatically at boot time if the
- 	 * opv_desc is listed in vfs_opv_descs[] in vfs_conf.c.  For
- 	 * loaded modules, we have to do it manually.
- 	 */
- 	vfs_opv_init_explicit(&adosfs_vnodeop_opv_desc);
- 	vfs_opv_init_default(&adosfs_vnodeop_opv_desc);
  
  	DISPATCH(lkmtp, cmd, ver, lkm_nofunc, lkm_nofunc, lkm_nofunc)
  }
--- 65,70 ----
Index: sys/lkm/vfs/isofs/cd9660/lkminit_vfs.c
===================================================================
RCS file: /cvsroot/src/sys/lkm/vfs/isofs/cd9660/lkminit_vfs.c,v
retrieving revision 1.2
diff -c -r1.2 lkminit_vfs.c
*** lkminit_vfs.c	1997/05/19 23:26:32	1.2
--- lkminit_vfs.c	1998/02/17 06:54:42
***************
*** 50,56 ****
   * This is the vfsops table for the file system in question
   */
  extern struct vfsops cd9660_vfsops;
- extern struct vnodeopv_desc cd9660_vnodeop_opv_desc;
  
  /*
   * declare the filesystem
--- 50,55 ----
***************
*** 66,78 ****
  	int cmd;
  	int ver;
  {
- 	/*
- 	 * This is normally done automatically at boot time if the
- 	 * opv_desc is listed in vfs_opv_descs[] in vfs_conf.c.  For
- 	 * loaded modules, we have to do it manually.
- 	 */
- 	vfs_opv_init_explicit(&cd9660_vnodeop_opv_desc);
- 	vfs_opv_init_default(&cd9660_vnodeop_opv_desc);
  
  	DISPATCH(lkmtp, cmd, ver, lkm_nofunc, lkm_nofunc, lkm_nofunc)
  }
--- 65,70 ----
Index: sys/lkm/vfs/miscfs/fdesc/lkminit_vfs.c
===================================================================
RCS file: /cvsroot/src/sys/lkm/vfs/miscfs/fdesc/lkminit_vfs.c,v
retrieving revision 1.2
diff -c -r1.2 lkminit_vfs.c
*** lkminit_vfs.c	1997/05/19 23:26:33	1.2
--- lkminit_vfs.c	1998/02/17 06:54:42
***************
*** 50,56 ****
   * This is the vfsops table for the file system in question
   */
  extern struct vfsops fdesc_vfsops;
- extern struct vnodeopv_desc fdesc_vnodeop_opv_desc;
  
  /*
   * declare the filesystem
--- 50,55 ----
***************
*** 66,78 ****
  	int cmd;
  	int ver;
  {
- 	/*
- 	 * This is normally done automatically at boot time if the
- 	 * opv_desc is listed in vfs_opv_descs[] in vfs_conf.c.  For
- 	 * loaded modules, we have to do it manually.
- 	 */
- 	vfs_opv_init_explicit(&fdesc_vnodeop_opv_desc);
- 	vfs_opv_init_default(&fdesc_vnodeop_opv_desc);
  
  	DISPATCH(lkmtp, cmd, ver, lkm_nofunc, lkm_nofunc, lkm_nofunc)
  }
--- 65,70 ----
Index: sys/lkm/vfs/miscfs/kernfs/lkminit_vfs.c
===================================================================
RCS file: /cvsroot/src/sys/lkm/vfs/miscfs/kernfs/lkminit_vfs.c,v
retrieving revision 1.2
diff -c -r1.2 lkminit_vfs.c
*** lkminit_vfs.c	1997/05/19 23:26:34	1.2
--- lkminit_vfs.c	1998/02/17 06:54:42
***************
*** 50,56 ****
   * This is the vfsops table for the file system in question
   */
  extern struct vfsops kernfs_vfsops;
- extern struct vnodeopv_desc kernfs_vnodeop_opv_desc;
  
  /*
   * declare the filesystem
--- 50,55 ----
***************
*** 66,78 ****
  	int cmd;
  	int ver;
  {
- 	/*
- 	 * This is normally done automatically at boot time if the
- 	 * opv_desc is listed in vfs_opv_descs[] in vfs_conf.c.  For
- 	 * loaded modules, we have to do it manually.
- 	 */
- 	vfs_opv_init_explicit(&kernfs_vnodeop_opv_desc);
- 	vfs_opv_init_default(&kernfs_vnodeop_opv_desc);
  
  	DISPATCH(lkmtp, cmd, ver, lkm_nofunc, lkm_nofunc, lkm_nofunc)
  }
--- 65,70 ----
Index: sys/lkm/vfs/miscfs/nullfs/lkminit_vfs.c
===================================================================
RCS file: /cvsroot/src/sys/lkm/vfs/miscfs/nullfs/lkminit_vfs.c,v
retrieving revision 1.3
diff -c -r1.3 lkminit_vfs.c
*** lkminit_vfs.c	1997/10/21 16:16:02	1.3
--- lkminit_vfs.c	1998/02/17 06:54:42
***************
*** 50,56 ****
   * This is the vfsops table for the file system in question
   */
  extern struct vfsops nullfs_vfsops;
- extern struct vnodeopv_desc nullfs_vnodeop_opv_desc;
  
  /*
   * declare the filesystem
--- 50,55 ----
***************
*** 66,78 ****
  	int cmd;
  	int ver;
  {
- 	/*
- 	 * This is normally done automatically at boot time if the
- 	 * opv_desc is listed in vfs_opv_descs[] in vfs_conf.c.  For
- 	 * loaded modules, we have to do it manually.
- 	 */
- 	vfs_opv_init_explicit(&nullfs_vnodeop_opv_desc);
- 	vfs_opv_init_default(&nullfs_vnodeop_opv_desc);
  
  	DISPATCH(lkmtp, cmd, ver, lkm_nofunc, lkm_nofunc, lkm_nofunc)
  }
--- 65,70 ----
Index: sys/lkm/vfs/miscfs/portal/lkminit_vfs.c
===================================================================
RCS file: /cvsroot/src/sys/lkm/vfs/miscfs/portal/lkminit_vfs.c,v
retrieving revision 1.2
diff -c -r1.2 lkminit_vfs.c
*** lkminit_vfs.c	1997/05/19 23:26:37	1.2
--- lkminit_vfs.c	1998/02/17 06:54:42
***************
*** 50,56 ****
   * This is the vfsops table for the file system in question
   */
  extern struct vfsops portal_vfsops;
- extern struct vnodeopv_desc portal_vnodeop_opv_desc;
  
  /*
   * declare the filesystem
--- 50,55 ----
***************
*** 66,78 ****
  	int cmd;
  	int ver;
  {
- 	/*
- 	 * This is normally done automatically at boot time if the
- 	 * opv_desc is listed in vfs_opv_descs[] in vfs_conf.c.  For
- 	 * loaded modules, we have to do it manually.
- 	 */
- 	vfs_opv_init_explicit(&portal_vnodeop_opv_desc);
- 	vfs_opv_init_default(&portal_vnodeop_opv_desc);
  
  	DISPATCH(lkmtp, cmd, ver, lkm_nofunc, lkm_nofunc, lkm_nofunc)
  }
--- 65,70 ----
Index: sys/lkm/vfs/miscfs/procfs/lkminit_vfs.c
===================================================================
RCS file: /cvsroot/src/sys/lkm/vfs/miscfs/procfs/lkminit_vfs.c,v
retrieving revision 1.2
diff -c -r1.2 lkminit_vfs.c
*** lkminit_vfs.c	1997/05/19 23:26:38	1.2
--- lkminit_vfs.c	1998/02/17 06:54:43
***************
*** 50,56 ****
   * This is the vfsops table for the file system in question
   */
  extern struct vfsops procfs_vfsops;
- extern struct vnodeopv_desc procfs_vnodeop_opv_desc;
  
  /*
   * declare the filesystem
--- 50,55 ----
***************
*** 66,78 ****
  	int cmd;
  	int ver;
  {
- 	/*
- 	 * This is normally done automatically at boot time if the
- 	 * opv_desc is listed in vfs_opv_descs[] in vfs_conf.c.  For
- 	 * loaded modules, we have to do it manually.
- 	 */
- 	vfs_opv_init_explicit(&procfs_vnodeop_opv_desc);
- 	vfs_opv_init_default(&procfs_vnodeop_opv_desc);
  
  	DISPATCH(lkmtp, cmd, ver, lkm_nofunc, lkm_nofunc, lkm_nofunc)
  }
--- 65,70 ----
Index: sys/lkm/vfs/miscfs/umapfs/lkminit_vfs.c
===================================================================
RCS file: /cvsroot/src/sys/lkm/vfs/miscfs/umapfs/lkminit_vfs.c,v
retrieving revision 1.3
diff -c -r1.3 lkminit_vfs.c
*** lkminit_vfs.c	1997/10/21 16:16:23	1.3
--- lkminit_vfs.c	1998/02/17 06:54:43
***************
*** 50,56 ****
   * This is the vfsops table for the file system in question
   */
  extern struct vfsops umapfs_vfsops;
- extern struct vnodeopv_desc umapfs_vnodeop_opv_desc;
  
  /*
   * declare the filesystem
--- 50,55 ----
***************
*** 66,78 ****
  	int cmd;
  	int ver;
  {
- 	/*
- 	 * This is normally done automatically at boot time if the
- 	 * opv_desc is listed in vfs_opv_descs[] in vfs_conf.c.  For
- 	 * loaded modules, we have to do it manually.
- 	 */
- 	vfs_opv_init_explicit(&umapfs_vnodeop_opv_desc);
- 	vfs_opv_init_default(&umapfs_vnodeop_opv_desc);
  
  	DISPATCH(lkmtp, cmd, ver, lkm_nofunc, lkm_nofunc, lkm_nofunc)
  }
--- 65,70 ----
Index: sys/lkm/vfs/miscfs/union/lkminit_vfs.c
===================================================================
RCS file: /cvsroot/src/sys/lkm/vfs/miscfs/union/lkminit_vfs.c,v
retrieving revision 1.2
diff -c -r1.2 lkminit_vfs.c
*** lkminit_vfs.c	1997/05/19 23:26:41	1.2
--- lkminit_vfs.c	1998/02/17 06:54:43
***************
*** 50,56 ****
   * This is the vfsops table for the file system in question
   */
  extern struct vfsops union_vfsops;
- extern struct vnodeopv_desc union_vnodeop_opv_desc;
  
  /*
   * declare the filesystem
--- 50,55 ----
***************
*** 66,78 ****
  	int cmd;
  	int ver;
  {
- 	/*
- 	 * This is normally done automatically at boot time if the
- 	 * opv_desc is listed in vfs_opv_descs[] in vfs_conf.c.  For
- 	 * loaded modules, we have to do it manually.
- 	 */
- 	vfs_opv_init_explicit(&union_vnodeop_opv_desc);
- 	vfs_opv_init_default(&union_vnodeop_opv_desc);
  
  	DISPATCH(lkmtp, cmd, ver, lkm_nofunc, lkm_nofunc, lkm_nofunc)
  }
--- 65,70 ----
Index: sys/lkm/vfs/msdosfs/lkminit_vfs.c
===================================================================
RCS file: /cvsroot/src/sys/lkm/vfs/msdosfs/lkminit_vfs.c,v
retrieving revision 1.2
diff -c -r1.2 lkminit_vfs.c
*** lkminit_vfs.c	1997/05/19 23:26:42	1.2
--- lkminit_vfs.c	1998/02/17 06:54:43
***************
*** 50,56 ****
   * This is the vfsops table for the file system in question
   */
  extern struct vfsops msdosfs_vfsops;
- extern struct vnodeopv_desc msdosfs_vnodeop_opv_desc;
  
  /*
   * declare the filesystem
--- 50,55 ----
***************
*** 66,78 ****
  	int cmd;
  	int ver;
  {
- 	/*
- 	 * This is normally done automatically at boot time if the
- 	 * opv_desc is listed in vfs_opv_descs[] in vfs_conf.c.  For
- 	 * loaded modules, we have to do it manually.
- 	 */
- 	vfs_opv_init_explicit(&msdosfs_vnodeop_opv_desc);
- 	vfs_opv_init_default(&msdosfs_vnodeop_opv_desc);
  
  	DISPATCH(lkmtp, cmd, ver, lkm_nofunc, lkm_nofunc, lkm_nofunc)
  }
--- 65,70 ----
Index: sys/lkm/vfs/ufs/ffs/lkminit_vfs.c
===================================================================
RCS file: /cvsroot/src/sys/lkm/vfs/ufs/ffs/lkminit_vfs.c,v
retrieving revision 1.2
diff -c -r1.2 lkminit_vfs.c
*** lkminit_vfs.c	1997/05/19 23:26:43	1.2
--- lkminit_vfs.c	1998/02/17 06:54:43
***************
*** 50,56 ****
   * This is the vfsops table for the file system in question
   */
  extern struct vfsops ffs_vfsops;
- extern struct vnodeopv_desc ffs_vnodeop_opv_desc;
  
  /*
   * declare the filesystem
--- 50,55 ----
***************
*** 66,78 ****
  	int cmd;
  	int ver;
  {
- 	/*
- 	 * This is normally done automatically at boot time if the
- 	 * opv_desc is listed in vfs_opv_descs[] in vfs_conf.c.  For
- 	 * loaded modules, we have to do it manually.
- 	 */
- 	vfs_opv_init_explicit(&ffs_vnodeop_opv_desc);
- 	vfs_opv_init_default(&ffs_vnodeop_opv_desc);
  
  	DISPATCH(lkmtp, cmd, ver, lkm_nofunc, lkm_nofunc, lkm_nofunc)
  }
--- 65,70 ----
Index: sys/lkm/vfs/ufs/lfs/lkminit_lfs.c
===================================================================
RCS file: /cvsroot/src/sys/lkm/vfs/ufs/lfs/lkminit_lfs.c,v
retrieving revision 1.2
diff -c -r1.2 lkminit_lfs.c
*** lkminit_lfs.c	1997/05/19 23:26:44	1.2
--- lkminit_lfs.c	1998/02/17 06:54:43
***************
*** 50,56 ****
   * This is the vfsops table for the file system in question
   */
  extern struct vfsops lfs_vfsops;
- extern struct vnodeopv_desc lfs_vnodeop_opv_desc;
  
  /*
   * declare the filesystem
--- 50,55 ----
***************
*** 66,78 ****
  	int cmd;
  	int ver;
  {
- 	/*
- 	 * This is normally done automatically at boot time if the
- 	 * opv_desc is listed in vfs_opv_descs[] in vfs_conf.c.  For
- 	 * loaded modules, we have to do it manually.
- 	 */
- 	vfs_opv_init_explicit(&lfs_vnodeop_opv_desc);
- 	vfs_opv_init_default(&lfs_vnodeop_opv_desc);
  
  	DISPATCH(lkmtp, cmd, ver, lkm_nofunc, lkm_nofunc, lkm_nofunc)
  }
--- 65,70 ----
Index: sys/lkm/vfs/ufs/mfs/lkminit_vfs.c
===================================================================
RCS file: /cvsroot/src/sys/lkm/vfs/ufs/mfs/lkminit_vfs.c,v
retrieving revision 1.2
diff -c -r1.2 lkminit_vfs.c
*** lkminit_vfs.c	1997/05/19 23:26:45	1.2
--- lkminit_vfs.c	1998/02/17 06:54:43
***************
*** 50,56 ****
   * This is the vfsops table for the file system in question
   */
  extern struct vfsops mfs_vfsops;
- extern struct vnodeopv_desc mfs_vnodeop_opv_desc;
  
  /*
   * declare the filesystem
--- 50,55 ----
***************
*** 66,78 ****
  	int cmd;
  	int ver;
  {
- 	/*
- 	 * This is normally done automatically at boot time if the
- 	 * opv_desc is listed in vfs_opv_descs[] in vfs_conf.c.  For
- 	 * loaded modules, we have to do it manually.
- 	 */
- 	vfs_opv_init_explicit(&mfs_vnodeop_opv_desc);
- 	vfs_opv_init_default(&mfs_vnodeop_opv_desc);
  
  	DISPATCH(lkmtp, cmd, ver, lkm_nofunc, lkm_nofunc, lkm_nofunc)
  }
--- 65,70 ----
Index: sys/miscfs/fdesc/fdesc_vfsops.c
===================================================================
RCS file: /cvsroot/src/sys/miscfs/fdesc/fdesc_vfsops.c,v
retrieving revision 1.22
diff -c -r1.22 fdesc_vfsops.c
*** fdesc_vfsops.c	1996/12/22 10:10:19	1.22
--- fdesc_vfsops.c	1998/02/17 06:55:05
***************
*** 300,305 ****
--- 300,312 ----
  	return (EOPNOTSUPP);
  }
  
+ extern struct vnodeopv_desc fdesc_vnodeop_opv_desc;
+ 
+ struct vnodeopv_desc *fdesc_vnodeopv_descs[] = {
+ 	&fdesc_vnodeop_opv_desc,
+ 	NULL,
+ };
+ 
  struct vfsops fdesc_vfsops = {
  	MOUNT_FDESC,
  	fdesc_mount,
***************
*** 313,316 ****
--- 320,325 ----
  	fdesc_fhtovp,
  	fdesc_vptofh,
  	fdesc_init,
+ 	NULL,				/* vfs_mountroot */
+ 	fdesc_vnodeopv_descs,
  };
Index: sys/miscfs/kernfs/kernfs_vfsops.c
===================================================================
RCS file: /cvsroot/src/sys/miscfs/kernfs/kernfs_vfsops.c,v
retrieving revision 1.30
diff -c -r1.30 kernfs_vfsops.c
*** kernfs_vfsops.c	1997/09/10 13:44:20	1.30
--- kernfs_vfsops.c	1998/02/17 06:55:06
***************
*** 332,337 ****
--- 332,344 ----
  	return (EOPNOTSUPP);
  }
  
+ extern struct vnodeopv_desc kernfs_vnodeop_opv_desc;
+ 
+ struct vnodeopv_desc *kernfs_vnodeopv_descs[] = {
+ 	&kernfs_vnodeop_opv_desc,
+ 	NULL,
+ };
+ 
  struct vfsops kernfs_vfsops = {
  	MOUNT_KERNFS,
  	kernfs_mount,
***************
*** 345,348 ****
--- 352,357 ----
  	kernfs_fhtovp,
  	kernfs_vptofh,
  	kernfs_init,
+ 	NULL,				/* vfs_mountroot */
+ 	kernfs_vnodeopv_descs,
  };
Index: sys/miscfs/nullfs/null_vfsops.c
===================================================================
RCS file: /cvsroot/src/sys/miscfs/nullfs/null_vfsops.c,v
retrieving revision 1.17
diff -c -r1.17 null_vfsops.c
*** null_vfsops.c	1997/10/06 09:32:33	1.17
--- null_vfsops.c	1998/02/17 06:55:06
***************
*** 367,372 ****
--- 367,379 ----
  	return (EOPNOTSUPP);
  }
  
+ extern struct vnodeopv_desc nullfs_vnodeop_opv_desc;
+ 
+ struct vnodeopv_desc *nullfs_vnodeopv_descs[] = {
+ 	&nullfs_vnodeop_opv_desc,
+ 	NULL,
+ };
+ 
  struct vfsops nullfs_vfsops = {
  	MOUNT_NULL,
  	nullfs_mount,
***************
*** 380,383 ****
--- 387,392 ----
  	nullfs_fhtovp,
  	nullfs_vptofh,
  	nullfs_init,
+ 	NULL,				/* vfs_mountroot */
+ 	nullfs_vnodeopv_descs,
  };
Index: sys/miscfs/portal/portal_vfsops.c
===================================================================
RCS file: /cvsroot/src/sys/miscfs/portal/portal_vfsops.c,v
retrieving revision 1.15
diff -c -r1.15 portal_vfsops.c
*** portal_vfsops.c	1996/12/22 10:10:25	1.15
--- portal_vfsops.c	1998/02/17 06:55:06
***************
*** 315,320 ****
--- 315,327 ----
  	return (EOPNOTSUPP);
  }
  
+ extern struct vnodeopv_desc portal_vnodeop_opv_desc;
+ 
+ struct vnodeopv_desc *portal_vnodeopv_descs[] = {
+ 	&portal_vnodeop_opv_desc,
+ 	NULL,
+ };
+ 
  struct vfsops portal_vfsops = {
  	MOUNT_PORTAL,
  	portal_mount,
***************
*** 328,331 ****
--- 335,340 ----
  	portal_fhtovp,
  	portal_vptofh,
  	portal_init,
+ 	NULL,				/* vfs_mountroot */
+ 	portal_vnodeopv_descs,
  };
Index: sys/miscfs/procfs/procfs_vfsops.c
===================================================================
RCS file: /cvsroot/src/sys/miscfs/procfs/procfs_vfsops.c,v
retrieving revision 1.26
diff -c -r1.26 procfs_vfsops.c
*** procfs_vfsops.c	1996/12/22 10:10:27	1.26
--- procfs_vfsops.c	1998/02/17 06:55:06
***************
*** 245,250 ****
--- 245,257 ----
  {
  }
  
+ extern struct vnodeopv_desc procfs_vnodeop_opv_desc;
+ 
+ struct vnodeopv_desc *procfs_vnodeopv_descs[] = {
+ 	&procfs_vnodeop_opv_desc,
+ 	NULL,
+ };
+ 
  struct vfsops procfs_vfsops = {
  	MOUNT_PROCFS,
  	procfs_mount,
***************
*** 258,261 ****
--- 265,270 ----
  	procfs_fhtovp,
  	procfs_vptofh,
  	procfs_init,
+ 	NULL,				/* vfs_mountroot */
+ 	procfs_vnodeopv_descs,
  };
Index: sys/miscfs/umapfs/umap_vfsops.c
===================================================================
RCS file: /cvsroot/src/sys/miscfs/umapfs/umap_vfsops.c,v
retrieving revision 1.16
diff -c -r1.16 umap_vfsops.c
*** umap_vfsops.c	1997/10/06 09:32:37	1.16
--- umap_vfsops.c	1998/02/17 06:55:07
***************
*** 409,414 ****
--- 409,421 ----
  	return (EOPNOTSUPP);
  }
  
+ extern struct vnodeopv_desc umapfs_vnodeop_opv_desc;
+ 
+ struct vnodeopv_desc *umapfs_vnodeopv_descs[] = {
+ 	&umapfs_vnodeop_opv_desc,
+ 	NULL,
+ };
+ 
  struct vfsops umapfs_vfsops = {
  	MOUNT_UMAP,
  	umapfs_mount,
***************
*** 422,425 ****
--- 429,434 ----
  	umapfs_fhtovp,
  	umapfs_vptofh,
  	umapfs_init,
+ 	NULL,				/* vfs_mountroot */
+ 	umapfs_vnodeopv_descs,
  };
Index: sys/miscfs/union/union_vfsops.c
===================================================================
RCS file: /cvsroot/src/sys/miscfs/union/union_vfsops.c,v
retrieving revision 1.17
diff -c -r1.17 union_vfsops.c
*** union_vfsops.c	1997/09/10 13:44:30	1.17
--- union_vfsops.c	1998/02/17 06:55:07
***************
*** 535,540 ****
--- 535,547 ----
  	return (EOPNOTSUPP);
  }
  
+ extern struct vnodeopv_desc union_vnodeop_opv_desc;
+ 
+ struct vnodeopv_desc *union_vnodeopv_descs[] = {
+ 	&union_vnodeop_opv_desc,
+ 	NULL,
+ };
+ 
  struct vfsops union_vfsops = {
  	MOUNT_UNION,
  	union_mount,
***************
*** 548,551 ****
--- 555,560 ----
  	union_fhtovp,
  	union_vptofh,
  	union_init,
+ 	NULL,				/* vfs_mountroot */
+ 	union_vnodeopv_descs,
  };
Index: sys/msdosfs/msdosfs_vfsops.c
===================================================================
RCS file: /cvsroot/src/sys/msdosfs/msdosfs_vfsops.c,v
retrieving revision 1.51
diff -c -r1.51 msdosfs_vfsops.c
*** msdosfs_vfsops.c	1997/11/17 15:36:58	1.51
--- msdosfs_vfsops.c	1998/02/17 06:55:18
***************
*** 92,97 ****
--- 92,104 ----
  
  #define ROOTNAME "root_device"
  
+ extern struct vnodeopv_desc msdosfs_vnodeop_opv_desc;
+ 
+ struct vnodeopv_desc *msdosfs_vnodeopv_descs[] = {
+ 	&msdosfs_vnodeop_opv_desc,
+ 	NULL,
+ };
+ 
  struct vfsops msdosfs_vfsops = {
  	MOUNT_MSDOS,
  	msdosfs_mount,
***************
*** 105,111 ****
  	msdosfs_fhtovp,
  	msdosfs_vptofh,
  	msdosfs_init,
! 	msdosfs_mountroot
  };
  
  static int
--- 112,119 ----
  	msdosfs_fhtovp,
  	msdosfs_vptofh,
  	msdosfs_init,
! 	msdosfs_mountroot,
! 	msdosfs_vnodeopv_descs,
  };
  
  static int
Index: sys/nfs/nfs_vfsops.c
===================================================================
RCS file: /cvsroot/src/sys/nfs/nfs_vfsops.c,v
retrieving revision 1.67
diff -c -r1.67 nfs_vfsops.c
*** nfs_vfsops.c	1998/01/30 22:44:15	1.67
--- nfs_vfsops.c	1998/02/17 06:55:38
***************
*** 80,85 ****
--- 80,101 ----
  /*
   * nfs vfs operations.
   */
+ 
+ extern struct vnodeopv_desc nfsv2_vnodeop_opv_desc;
+ extern struct vnodeopv_desc spec_nfsv2nodeop_opv_desc;
+ #ifdef FIFO
+ extern struct vnodeopv_desc fifo_nfsv2nodeop_opv_desc;
+ #endif
+ 
+ struct vnodeopv_desc *nfs_vnodeopv_descs[] = {
+ 	&nfsv2_vnodeop_opv_desc,
+ 	&spec_nfsv2nodeop_opv_desc,
+ #ifdef FIFO
+ 	&fifo_nfsv2nodeop_opv_desc,
+ #endif
+ 	NULL,
+ };
+ 
  struct vfsops nfs_vfsops = {
  	MOUNT_NFS,
  	nfs_mount,
***************
*** 94,99 ****
--- 110,116 ----
  	nfs_vptofh,
  	nfs_vfs_init,
  	nfs_mountroot,
+ 	nfs_vnodeopv_descs,
  #ifdef notyet
  	nfs_sysctl
  #endif
Index: sys/ufs/ext2fs/ext2fs_vfsops.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/ext2fs/ext2fs_vfsops.c,v
retrieving revision 1.6
diff -c -r1.6 ext2fs_vfsops.c
*** ext2fs_vfsops.c	1997/10/27 14:43:41	1.6
--- ext2fs_vfsops.c	1998/02/17 06:55:50
***************
*** 72,77 ****
--- 72,92 ----
  int ext2fs_check_export __P((struct mount *, struct ufid *, struct mbuf *,
  	struct vnode **, int *, struct ucred **));
  
+ extern struct vnodeopv_desc ext2fs_vnodeop_opv_desc;
+ extern struct vnodeopv_desc ext2fs_specop_opv_desc;
+ #ifdef FIFO
+ extern struct vnodeopv_desc ext2fs_fifoop_opv_desc;
+ #endif
+ 
+ struct vnodeopv_desc *ext2fs_vnodeopv_descs[] = {
+ 	&ext2fs_vnodeop_opv_desc,
+ 	&ext2fs_specop_opv_desc,
+ #ifdef FIFO
+ 	&ext2fs_fifoop_opv_desc,
+ #endif
+ 	NULL,
+ };
+ 
  struct vfsops ext2fs_vfsops = {
  	MOUNT_EXT2FS,
  	ext2fs_mount,
Index: sys/ufs/ffs/ffs_vfsops.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/ffs/ffs_vfsops.c,v
retrieving revision 1.31
diff -c -r1.31 ffs_vfsops.c
*** ffs_vfsops.c	1997/10/16 18:29:11	1.31
--- ffs_vfsops.c	1998/02/17 06:55:51
***************
*** 68,73 ****
--- 68,88 ----
  
  int ffs_sbupdate __P((struct ufsmount *, int));
  
+ extern struct vnodeopv_desc ffs_vnodeop_opv_desc;
+ extern struct vnodeopv_desc ffs_specop_opv_desc;
+ #ifdef FIFO
+ extern struct vnodeopv_desc ffs_fifoop_opv_desc;
+ #endif  
+ 
+ struct vnodeopv_desc *ffs_vnodeopv_descs[] = {
+ 	&ffs_vnodeop_opv_desc,
+ 	&ffs_specop_opv_desc,
+ #ifdef FIFO
+ 	&ffs_fifoop_opv_desc,
+ #endif
+ 	NULL,
+ };
+ 
  struct vfsops ffs_vfsops = {
  	MOUNT_FFS,
  	ffs_mount,
***************
*** 82,87 ****
--- 97,103 ----
  	ffs_vptofh,
  	ffs_init,
  	ffs_mountroot,
+ 	ffs_vnodeopv_descs,
  };
  
  /*
Index: sys/ufs/lfs/lfs_vfsops.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/lfs/lfs_vfsops.c,v
retrieving revision 1.14
diff -c -r1.14 lfs_vfsops.c
*** lfs_vfsops.c	1997/10/16 18:29:20	1.14
--- lfs_vfsops.c	1998/02/17 06:55:51
***************
*** 63,68 ****
--- 63,83 ----
  
  int lfs_mountfs __P((struct vnode *, struct mount *, struct proc *));
  
+ extern struct vnodeopv_desc lfs_vnodeop_opv_desc;
+ extern struct vnodeopv_desc lfs_specop_opv_desc;
+ #ifdef FIFO
+ extern struct vnodeopv_desc lfs_fifoop_opv_desc;
+ #endif  
+ 
+ struct vnodeopv_desc *lfs_vnodeopv_descs[] = {
+ 	&lfs_vnodeop_opv_desc,
+ 	&lfs_specop_opv_desc,
+ #ifdef FIFO
+ 	&lfs_fifoop_opv_desc,
+ #endif
+ 	NULL,
+ };
+ 
  struct vfsops lfs_vfsops = {
  	MOUNT_LFS,
  	lfs_mount,
***************
*** 76,81 ****
--- 91,98 ----
  	lfs_fhtovp,
  	lfs_vptofh,
  	lfs_init,
+ 	NULL,				/* vfs_mountroot */
+ 	lfs_vnodeopv_descs,
  };
  
  int
Index: sys/ufs/mfs/mfs_vfsops.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/mfs/mfs_vfsops.c,v
retrieving revision 1.13
diff -c -r1.13 mfs_vfsops.c
*** mfs_vfsops.c	1997/06/12 17:15:00	1.13
--- mfs_vfsops.c	1998/02/17 06:55:51
***************
*** 67,72 ****
--- 67,80 ----
  /*
   * mfs vfs operations.
   */
+ 
+ extern struct vnodeopv_desc mfs_vnodeop_opv_desc;  
+ 
+ struct vnodeopv_desc *mfs_vnodeopv_descs[] = {
+ 	&mfs_vnodeop_opv_desc,
+ 	NULL,
+ };
+ 
  struct vfsops mfs_vfsops = {
  	MOUNT_MFS,
  	mfs_mount,
***************
*** 80,85 ****
--- 88,95 ----
  	ffs_fhtovp,
  	ffs_vptofh,
  	mfs_init,
+ 	NULL,				/* vfs_mountroot */
+ 	mfs_vnodeopv_descs,
  };
  
  /*
Index: sys/sys/mount.h
===================================================================
RCS file: /cvsroot/src/sys/sys/mount.h,v
retrieving revision 1.62
diff -c -r1.62 mount.h
*** mount.h	1997/11/18 21:35:16	1.62
--- mount.h	1998/02/17 07:12:48
***************
*** 187,192 ****
--- 187,193 ----
  #ifdef __STDC__
  struct nameidata;
  struct mbuf;
+ struct vnodeopv_desc;
  #endif
  
  struct vfsops {
***************
*** 213,219 ****
--- 214,222 ----
  	int	(*vfs_vptofh)	__P((struct vnode *vp, struct fid *fhp));
  	void	(*vfs_init)	__P((void));
  	int	(*vfs_mountroot) __P((void));
+ 	struct vnodeopv_desc **vfs_opv_descs;
  	int	vfs_refcount;
+ 	LIST_ENTRY(vfsops) vfs_list;
  };
  
  #define VFS_MOUNT(MP, PATH, DATA, NDP, P) \
***************
*** 441,457 ****
  void	vfs_unmountall __P((void));	    /* unmount file systems */
  int 	vfs_busy __P((struct mount *));
  void	vfs_unbusy __P((struct mount *));
  struct vfsops *vfs_getopsbyname __P((const char *));
! extern	CIRCLEQ_HEAD(mntlist, mount) mountlist;	/* mounted filesystem list */
! extern	struct vfsops *vfssw[];		    /* filesystem type table */
! extern	int nvfssw;
! extern	struct nfs_public nfs_pub;
  long	makefstype __P((char *));
  int	dounmount __P((struct mount *, int, struct proc *));
  void	vfsinit __P((void));
  #ifdef DEBUG
  void	vfs_bufstats __P((void));
  #endif
  #else /* _KERNEL */
  
  #include <sys/cdefs.h>
--- 444,468 ----
  void	vfs_unmountall __P((void));	    /* unmount file systems */
  int 	vfs_busy __P((struct mount *));
  void	vfs_unbusy __P((struct mount *));
+ int	vfs_establish __P((struct vfsops *));
+ int	vfs_disestablish __P((struct vfsops *));
  struct vfsops *vfs_getopsbyname __P((const char *));
! 
  long	makefstype __P((char *));
  int	dounmount __P((struct mount *, int, struct proc *));
  void	vfsinit __P((void));
+ void	vfs_opv_init __P((struct vnodeopv_desc **));
+ void	vfs_opv_free __P((struct vnodeopv_desc **));
+ 
  #ifdef DEBUG
  void	vfs_bufstats __P((void));
  #endif
+ 
+ LIST_HEAD(vfs_list_head, vfsops);
+ extern struct vfs_list_head vfs_list;
+ 
+ extern	CIRCLEQ_HEAD(mntlist, mount) mountlist;	/* mounted filesystem list */
+ extern	struct nfs_public nfs_pub;
  #else /* _KERNEL */
  
  #include <sys/cdefs.h>