Index: sys/sys/mount.h =================================================================== RCS file: /home/ncvs/src/sys/sys/mount.h,v retrieving revision 1.48 diff -c -r1.48 mount.h *** mount.h 1997/10/12 20:26:02 1.48 --- mount.h 1997/10/24 08:18:40 *************** *** 383,397 **** lkmtp, cmd, ver, lkm_nullcmd, lkm_nullcmd, lkm_nullcmd); } #else #define VFS_SET(vfsops, fsname, index, flags) \ static struct vfsconf _fs_vfsconf = { \ &vfsops, \ #fsname, \ index, \ 0, \ ! flags | VFCF_STATIC, \ }; \ ! DATA_SET(vfs_set,_fs_vfsconf) #endif /* VFS_LKM */ #endif /* KERNEL */ --- 383,403 ---- lkmtp, cmd, ver, lkm_nullcmd, lkm_nullcmd, lkm_nullcmd); } #else + #include #define VFS_SET(vfsops, fsname, index, flags) \ static struct vfsconf _fs_vfsconf = { \ &vfsops, \ #fsname, \ index, \ 0, \ ! flags, \ }; \ ! static moduledata_t _fs_vfs_module = { \ ! #fsname, \ ! vfs_mod_handler, \ ! &_fs_vfsconf}; \ ! DECLARE_MODULE(fsname, _fs_vfs_module, \ ! SI_SUB_VFS, SI_ORDER_MIDDLE+index); #endif /* VFS_LKM */ #endif /* KERNEL */ *************** *** 435,440 **** --- 441,447 ---- __P((struct mount *, struct netexport *, struct sockaddr *)); void vfs_getnewfsid __P((struct mount *)); struct mount *vfs_getvfs __P((fsid_t *)); /* return vfs given fsid */ + int vfs_mod_handler __P((module_t, modeventtype_t, void *)); int vfs_mountedon __P((struct vnode *)); /* is a vfs mounted on vp */ int vfs_mountrootfs __P((char *)); int vfs_rootmountalloc __P((char *, char *, struct mount **)); Index: sys/sys/vnode.h =================================================================== RCS file: /home/ncvs/src/sys/sys/vnode.h,v retrieving revision 1.53 diff -c -r1.53 vnode.h *** vnode.h 1997/10/17 12:36:18 1.53 --- vnode.h 1997/10/24 08:57:05 *************** *** 241,247 **** #ifdef VFS_LKM #define VNODEOP_SET(f) DATA_SET(MODVNOPS,f) #else ! #define VNODEOP_SET(f) DATA_SET(vfs_opv_descs_,f) #endif /* --- 241,249 ---- #ifdef VFS_LKM #define VNODEOP_SET(f) DATA_SET(MODVNOPS,f) #else ! #define VNODEOP_SET(f) \ ! DATA_SET(vfs_opv_descs_,f); \ ! SYSINIT(f,SI_SUB_VFS, SI_ORDER_ANY,vfs_opv_init,&f) #endif /* *************** *** 479,485 **** void vdrop __P((struct vnode *)); int vfinddev __P((dev_t dev, enum vtype type, struct vnode **vpp)); void vfree __P((struct vnode *)); ! void vfs_opv_init __P((struct vnodeopv_desc **them)); int vflush __P((struct mount *mp, struct vnode *skipvp, int flags)); int vget __P((struct vnode *vp, int lockflag, struct proc *p)); void vgone __P((struct vnode *vp)); --- 481,487 ---- void vdrop __P((struct vnode *)); int vfinddev __P((dev_t dev, enum vtype type, struct vnode **vpp)); void vfree __P((struct vnode *)); ! void vfs_opv_init __P((struct vnodeopv_desc *them)); int vflush __P((struct mount *mp, struct vnode *skipvp, int flags)); int vget __P((struct vnode *vp, int lockflag, struct proc *p)); void vgone __P((struct vnode *vp)); Index: sys/sys/kern/kern_lkm.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_lkm.c,v retrieving revision 1.43 diff -c -r1.43 kern_lkm.c *** kern_lkm.c 1997/10/11 13:11:32 1.43 --- kern_lkm.c 1997/10/24 08:40:48 *************** *** 633,639 **** args->lkm_vnodeops->ls_items[i]; *(opv->opv_desc_vector_p) = NULL; } ! vfs_opv_init((struct vnodeopv_desc **)args->lkm_vnodeops->ls_items); /* * Call init function for this VFS... --- 633,641 ---- args->lkm_vnodeops->ls_items[i]; *(opv->opv_desc_vector_p) = NULL; } ! for (i = 0; args->lkm_vnodeops->ls_items[i] != NULL; i++) ! vfs_opv_init((struct vnodeopv_desc *) ! args->lkm_vnodeops->ls_items[i]); /* * Call init function for this VFS... Index: sys/sys/kern/vfs_init.c =================================================================== RCS file: /home/ncvs/src/sys/kern/vfs_init.c,v retrieving revision 1.30 diff -c -r1.30 vfs_init.c *** vfs_init.c 1997/10/16 10:47:57 1.30 --- vfs_init.c 1997/10/24 00:56:35 *************** *** 102,187 **** * it's not a very dynamic "feature". */ void ! vfs_opv_init(struct vnodeopv_desc **them) { ! int i, j, k; vop_t ***opv_desc_vector_p; vop_t **opv_desc_vector; struct vnodeopv_entry_desc *opve_descp; /* ! * Allocate the dynamic vectors and fill them in. */ ! for (i=0; them[i]; i++) { ! opv_desc_vector_p = them[i]->opv_desc_vector_p; /* ! * Allocate and init the vector, if it needs it. ! * Also handle backwards compatibility. */ ! if (*opv_desc_vector_p == NULL) { ! /* XXX - shouldn't be M_VNODE */ ! MALLOC(*opv_desc_vector_p, vop_t **, ! vfs_opv_numops * sizeof(vop_t *), M_VNODE, ! M_WAITOK); ! bzero(*opv_desc_vector_p, ! vfs_opv_numops * sizeof(vop_t *)); ! DODEBUG(printf("vector at %x allocated\n", ! opv_desc_vector_p)); ! } ! opv_desc_vector = *opv_desc_vector_p; ! for (j=0; them[i]->opv_desc_ops[j].opve_op; j++) { ! opve_descp = &(them[i]->opv_desc_ops[j]); ! ! /* ! * Sanity check: is this operation listed ! * in the list of operations? We check this ! * by seeing if its offest is zero. Since ! * the default routine should always be listed ! * first, it should be the only one with a zero ! * offset. Any other operation with a zero ! * offset is probably not listed in ! * vfs_op_descs, and so is probably an error. ! * ! * A panic here means the layer programmer ! * has committed the all-too common bug ! * of adding a new operation to the layer's ! * list of vnode operations but ! * not adding the operation to the system-wide ! * list of supported operations. ! */ ! if (opve_descp->opve_op->vdesc_offset == 0 && ! opve_descp->opve_op->vdesc_offset != ! VOFFSET(vop_default)) { ! printf("operation %s not listed in %s.\n", ! opve_descp->opve_op->vdesc_name, ! "vfs_op_descs"); ! panic ("vfs_opv_init: bad operation"); ! } ! /* ! * Fill in this entry. ! */ ! opv_desc_vector[opve_descp->opve_op->vdesc_offset] = ! opve_descp->opve_impl; } } /* * Finally, go back and replace unfilled routines * with their default. (Sigh, an O(n^3) algorithm. I * could make it better, but that'd be work, and n is small.) */ ! for (i = 0; them[i]; i++) { ! opv_desc_vector = *(them[i]->opv_desc_vector_p); ! /* ! * Force every operations vector to have a default routine. ! */ ! if (opv_desc_vector[VOFFSET(vop_default)]==NULL) { ! panic("vfs_opv_init: operation vector without default routine."); ! } ! for (k = 0; kopv_desc_vector_p = NULL; + opv_desc_vector_p = them->opv_desc_vector_p; /* ! * Allocate and init the vector, if it needs it. ! * Also handle backwards compatibility. */ ! if (*opv_desc_vector_p == NULL) { ! /* XXX - shouldn't be M_VNODE */ ! MALLOC(*opv_desc_vector_p, vop_t **, ! vfs_opv_numops * sizeof(vop_t *), M_VNODE, ! M_WAITOK); ! bzero(*opv_desc_vector_p, ! vfs_opv_numops * sizeof(vop_t *)); ! DODEBUG(printf("vector at %x allocated\n", ! opv_desc_vector_p)); ! } ! opv_desc_vector = *opv_desc_vector_p; ! for (j=0; them->opv_desc_ops[j].opve_op; j++) { ! opve_descp = &(them->opv_desc_ops[j]); ! /* ! * Sanity check: is this operation listed ! * in the list of operations? We check this ! * by seeing if its offest is zero. Since ! * the default routine should always be listed ! * first, it should be the only one with a zero ! * offset. Any other operation with a zero ! * offset is probably not listed in ! * vfs_op_descs, and so is probably an error. ! * ! * A panic here means the layer programmer ! * has committed the all-too common bug ! * of adding a new operation to the layer's ! * list of vnode operations but ! * not adding the operation to the system-wide ! * list of supported operations. */ ! if (opve_descp->opve_op->vdesc_offset == 0 && ! opve_descp->opve_op->vdesc_offset != ! VOFFSET(vop_default)) { ! printf("operation %s not listed in %s.\n", ! opve_descp->opve_op->vdesc_name, ! "vfs_op_descs"); ! panic ("vfs_opv_init: bad operation"); } + /* + * Fill in this entry. + */ + opv_desc_vector[opve_descp->opve_op->vdesc_offset] = + opve_descp->opve_impl; } + /* * Finally, go back and replace unfilled routines * with their default. (Sigh, an O(n^3) algorithm. I * could make it better, but that'd be work, and n is small.) */ ! opv_desc_vector = *(them->opv_desc_vector_p); ! /* ! * Force every operations vector to have a default routine. ! */ ! if (opv_desc_vector[VOFFSET(vop_default)]==NULL) { ! panic("vfs_opv_init: operation vector without default routine."); } + for (k = 0; kopv_desc_vector_p) = NULL; - /* * assign each op to its offset * * XXX This should not be needed, but is because the per --- 190,195 ---- *************** *** 228,236 **** vfsinit(dummy) void *dummy; { - struct vfsconf **vfc; - int maxtypenum; - namei_zone = zinit("NAMEI", MAXPATHLEN, 0, 0, 2); /* --- 218,223 ---- *************** *** 242,269 **** */ nchinit(); /* ! * Build vnode operation vectors. */ vfs_op_init(); - vfs_opv_init(vfs_opv_descs); /* finish the job */ /* * Initialize each file system type. */ vattr_null(&va_null); ! maxtypenum = 0; ! vfc = (struct vfsconf **)vfs_set.ls_items; ! vfsconf = *vfc; /* simulate Lite2 vfsconf array */ ! while (*vfc) { ! struct vfsconf *vfsp = *vfc; ! ! vfc++; ! vfsp->vfc_next = *vfc; ! if (maxtypenum <= vfsp->vfc_typenum) ! maxtypenum = vfsp->vfc_typenum + 1; ! (*vfsp->vfc_vfsops->vfs_init)(vfsp); } ! /* next vfc_typenum to be used */ ! maxvfsconf = maxtypenum; } /* --- 229,313 ---- */ nchinit(); /* ! * Build vnode operations tables. */ vfs_op_init(); /* * Initialize each file system type. */ vattr_null(&va_null); ! } ! ! int ! vfs_mod_handler(mod, what, arg) ! module_t mod; ! modeventtype_t what; ! void *arg; ! { ! int maxtypenum; ! struct vfsconf *vfc; ! struct vfsconf *vfsp, *prev_vfsp; ! ! vfc = (struct vfsconf *)arg; ! ! switch (what) { ! case MOD_LOAD: ! for (vfsp = vfsconf; vfsconf && vfsp->vfc_next; ! vfsp = vfsp->vfc_next) ! if (!strcmp(vfc->vfc_name, vfsp->vfc_name)) ! return EEXIST; ! ! if (vfc->vfc_typenum < 0) ! vfc->vfc_typenum = maxvfsconf; ! ! if (maxvfsconf <= vfc->vfc_typenum) ! maxvfsconf = vfc->vfc_typenum + 1; ! ! if (vfsp == NULL) ! vfsconf = vfc; ! else ! vfsp->vfc_next = vfc; ! ! vfc->vfc_next = NULL; ! ! (*(vfc->vfc_vfsops->vfs_init))(vfc); ! break; ! ! case MOD_UNLOAD: ! prev_vfsp = NULL; ! for (vfsp = vfsconf; vfsp; prev_vfsp = vfsp, ! vfsp = vfsp->vfc_next) ! if (!strcmp(vfc->vfc_name, vfsp->vfc_name)) ! break; ! if (vfsp == NULL) ! return EINVAL; ! ! if (vfsp->vfc_refcount) ! return EBUSY; ! ! prev_vfsp->vfc_next = vfsp->vfc_next; ! ! if (vfsp->vfc_typenum + 1 == maxvfsconf) { ! for (maxtypenum = maxvfsconf, vfsp = vfsconf; ! vfsp != NULL; vfsp = vfsp->vfc_next) ! if (vfsp->vfc_typenum > maxtypenum) ! maxtypenum = vfsp->vfc_typenum + 1; ! maxvfsconf = maxtypenum; ! } ! ! /* ! * We still need to handle the vnodeop table by deallocating ! * the space. We probably need to create a similar handler ! * for the vnodeop table too. This would make another module ! * which we could depend upon. ! */ ! break; ! ! case MOD_SHUTDOWN: ! break; } ! ! return 0; } /*