1df8bae1dSRodney W. Grimes /* 2df8bae1dSRodney W. Grimes * Copyright (c) 1989, 1993 3df8bae1dSRodney W. Grimes * The Regents of the University of California. All rights reserved. 4df8bae1dSRodney W. Grimes * 5df8bae1dSRodney W. Grimes * This code is derived from software contributed 6df8bae1dSRodney W. Grimes * to Berkeley by John Heidemann of the UCLA Ficus project. 7df8bae1dSRodney W. Grimes * 8df8bae1dSRodney W. Grimes * Source: * @(#)i405_init.c 2.10 92/04/27 UCLA Ficus project 9df8bae1dSRodney W. Grimes * 10df8bae1dSRodney W. Grimes * Redistribution and use in source and binary forms, with or without 11df8bae1dSRodney W. Grimes * modification, are permitted provided that the following conditions 12df8bae1dSRodney W. Grimes * are met: 13df8bae1dSRodney W. Grimes * 1. Redistributions of source code must retain the above copyright 14df8bae1dSRodney W. Grimes * notice, this list of conditions and the following disclaimer. 15df8bae1dSRodney W. Grimes * 2. Redistributions in binary form must reproduce the above copyright 16df8bae1dSRodney W. Grimes * notice, this list of conditions and the following disclaimer in the 17df8bae1dSRodney W. Grimes * documentation and/or other materials provided with the distribution. 18df8bae1dSRodney W. Grimes * 3. All advertising materials mentioning features or use of this software 19df8bae1dSRodney W. Grimes * must display the following acknowledgement: 20df8bae1dSRodney W. Grimes * This product includes software developed by the University of 21df8bae1dSRodney W. Grimes * California, Berkeley and its contributors. 22df8bae1dSRodney W. Grimes * 4. Neither the name of the University nor the names of its contributors 23df8bae1dSRodney W. Grimes * may be used to endorse or promote products derived from this software 24df8bae1dSRodney W. Grimes * without specific prior written permission. 25df8bae1dSRodney W. Grimes * 26df8bae1dSRodney W. Grimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 27df8bae1dSRodney W. Grimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28df8bae1dSRodney W. Grimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29df8bae1dSRodney W. Grimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 30df8bae1dSRodney W. Grimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31df8bae1dSRodney W. Grimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32df8bae1dSRodney W. Grimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33df8bae1dSRodney W. Grimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34df8bae1dSRodney W. Grimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35df8bae1dSRodney W. Grimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36df8bae1dSRodney W. Grimes * SUCH DAMAGE. 37df8bae1dSRodney W. Grimes * 38df8bae1dSRodney W. Grimes * @(#)vfs_init.c 8.3 (Berkeley) 1/4/94 39aa855a59SPeter Wemm * $Id: vfs_init.c,v 1.34 1998/10/05 11:10:55 obrien Exp $ 40df8bae1dSRodney W. Grimes */ 41df8bae1dSRodney W. Grimes 42df8bae1dSRodney W. Grimes 43df8bae1dSRodney W. Grimes #include <sys/param.h> 44f23b4c91SGarrett Wollman #include <sys/systm.h> 45c901836cSGarrett Wollman #include <sys/kernel.h> 46df8bae1dSRodney W. Grimes #include <sys/mount.h> 47e99ea9ecSBruce Evans #include <sys/sysctl.h> 48df8bae1dSRodney W. Grimes #include <sys/vnode.h> 49df8bae1dSRodney W. Grimes #include <sys/malloc.h> 5099448ed1SJohn Dyson #include <vm/vm_zone.h> 51df8bae1dSRodney W. Grimes 5227a0b398SPoul-Henning Kamp static void vfs_op_init __P((void)); 5398d93822SBruce Evans 544590fd3aSDavid Greenman static void vfsinit __P((void *)); 552b14f991SJulian Elischer SYSINIT(vfs, SI_SUB_VFS, SI_ORDER_FIRST, vfsinit, NULL) 562b14f991SJulian Elischer 57a1c995b6SPoul-Henning Kamp MALLOC_DEFINE(M_VNODE, "vnodes", "Dynamically allocated vnodes"); 58a1c995b6SPoul-Henning Kamp 592b14f991SJulian Elischer /* 60df8bae1dSRodney W. Grimes * Sigh, such primitive tools are these... 61df8bae1dSRodney W. Grimes */ 62df8bae1dSRodney W. Grimes #if 0 63df8bae1dSRodney W. Grimes #define DODEBUG(A) A 64df8bae1dSRodney W. Grimes #else 65df8bae1dSRodney W. Grimes #define DODEBUG(A) 66df8bae1dSRodney W. Grimes #endif 67df8bae1dSRodney W. Grimes 68303b270bSEivind Eklund static struct vfsconf void_vfsconf; 69c901836cSGarrett Wollman 70aa855a59SPeter Wemm #ifdef unused 71c901836cSGarrett Wollman extern struct linker_set vfs_opv_descs_; 72c901836cSGarrett Wollman #define vfs_opv_descs ((struct vnodeopv_desc **)vfs_opv_descs_.ls_items) 73aa855a59SPeter Wemm #endif 74c901836cSGarrett Wollman 75df8bae1dSRodney W. Grimes extern struct vnodeop_desc *vfs_op_descs[]; 76df8bae1dSRodney W. Grimes /* and the operations they perform */ 77df8bae1dSRodney W. Grimes 78df8bae1dSRodney W. Grimes /* 79aa855a59SPeter Wemm * XXX this bloat just exands the sysctl__vfs linker set a little so that 80aa855a59SPeter Wemm * we can attach sysctls for VFS modules without expanding the linker set. 81aa855a59SPeter Wemm * Currently (1998/09/06), only one VFS uses sysctls, so 2 extra linker 82aa855a59SPeter Wemm * set slots are more than sufficient. 83aa855a59SPeter Wemm */ 84aa855a59SPeter Wemm extern struct linker_set sysctl__vfs; 85aa855a59SPeter Wemm static int mod_xx; 86aa855a59SPeter Wemm SYSCTL_INT(_vfs, OID_AUTO, mod0, CTLFLAG_RD, &mod_xx, 0, ""); 87aa855a59SPeter Wemm SYSCTL_INT(_vfs, OID_AUTO, mod1, CTLFLAG_RD, &mod_xx, 0, ""); 88aa855a59SPeter Wemm 89aa855a59SPeter Wemm /* 9099448ed1SJohn Dyson * Zone for namei 9199448ed1SJohn Dyson */ 9299448ed1SJohn Dyson struct vm_zone *namei_zone; 9399448ed1SJohn Dyson 9499448ed1SJohn Dyson /* 95df8bae1dSRodney W. Grimes * vfs_init.c 96df8bae1dSRodney W. Grimes * 97df8bae1dSRodney W. Grimes * Allocate and fill in operations vectors. 98df8bae1dSRodney W. Grimes * 99df8bae1dSRodney W. Grimes * An undocumented feature of this approach to defining operations is that 100df8bae1dSRodney W. Grimes * there can be multiple entries in vfs_opv_descs for the same operations 101df8bae1dSRodney W. Grimes * vector. This allows third parties to extend the set of operations 102df8bae1dSRodney W. Grimes * supported by another layer in a binary compatibile way. For example, 103df8bae1dSRodney W. Grimes * assume that NFS needed to be modified to support Ficus. NFS has an entry 104df8bae1dSRodney W. Grimes * (probably nfs_vnopdeop_decls) declaring all the operations NFS supports by 105df8bae1dSRodney W. Grimes * default. Ficus could add another entry (ficus_nfs_vnodeop_decl_entensions) 106df8bae1dSRodney W. Grimes * listing those new operations Ficus adds to NFS, all without modifying the 107df8bae1dSRodney W. Grimes * NFS code. (Of couse, the OTW NFS protocol still needs to be munged, but 108df8bae1dSRodney W. Grimes * that is a(whole)nother story.) This is a feature. 109bf1d104aSPoul-Henning Kamp * 110bf1d104aSPoul-Henning Kamp * Without an explicit reserve area, however, you must replace vnode_if.c 111bf1d104aSPoul-Henning Kamp * and vnode_if.h when you do this, or you will be derefrencing of the 112bf1d104aSPoul-Henning Kamp * end of vfs_op_descs[]. This is a flaw in the use of a structure 113bf1d104aSPoul-Henning Kamp * pointer array rather than an agregate to define vfs_op_descs. So 114bf1d104aSPoul-Henning Kamp * it's not a very dynamic "feature". 115df8bae1dSRodney W. Grimes */ 116df8bae1dSRodney W. Grimes void 117aa855a59SPeter Wemm vfs_opv_init(struct vnodeopv_desc *opv) 118df8bae1dSRodney W. Grimes { 119aa855a59SPeter Wemm int j, k; 120f57e6547SBruce Evans vop_t ***opv_desc_vector_p; 121f57e6547SBruce Evans vop_t **opv_desc_vector; 122df8bae1dSRodney W. Grimes struct vnodeopv_entry_desc *opve_descp; 123df8bae1dSRodney W. Grimes 124df8bae1dSRodney W. Grimes /* 125df8bae1dSRodney W. Grimes * Allocate the dynamic vectors and fill them in. 126df8bae1dSRodney W. Grimes */ 127aa855a59SPeter Wemm opv_desc_vector_p = opv->opv_desc_vector_p; 128df8bae1dSRodney W. Grimes /* 129df8bae1dSRodney W. Grimes * Allocate and init the vector, if it needs it. 130df8bae1dSRodney W. Grimes * Also handle backwards compatibility. 131df8bae1dSRodney W. Grimes */ 132df8bae1dSRodney W. Grimes if (*opv_desc_vector_p == NULL) { 133df8bae1dSRodney W. Grimes /* XXX - shouldn't be M_VNODE */ 134f57e6547SBruce Evans MALLOC(*opv_desc_vector_p, vop_t **, 135f57e6547SBruce Evans vfs_opv_numops * sizeof(vop_t *), M_VNODE, 136f57e6547SBruce Evans M_WAITOK); 137f57e6547SBruce Evans bzero(*opv_desc_vector_p, 138f57e6547SBruce Evans vfs_opv_numops * sizeof(vop_t *)); 139df8bae1dSRodney W. Grimes DODEBUG(printf("vector at %x allocated\n", 140df8bae1dSRodney W. Grimes opv_desc_vector_p)); 141df8bae1dSRodney W. Grimes } 142df8bae1dSRodney W. Grimes opv_desc_vector = *opv_desc_vector_p; 143aa855a59SPeter Wemm for (j = 0; opv->opv_desc_ops[j].opve_op; j++) { 144aa855a59SPeter Wemm opve_descp = &(opv->opv_desc_ops[j]); 145df8bae1dSRodney W. Grimes 146df8bae1dSRodney W. Grimes /* 147df8bae1dSRodney W. Grimes * Sanity check: is this operation listed 148df8bae1dSRodney W. Grimes * in the list of operations? We check this 149df8bae1dSRodney W. Grimes * by seeing if its offest is zero. Since 150df8bae1dSRodney W. Grimes * the default routine should always be listed 151df8bae1dSRodney W. Grimes * first, it should be the only one with a zero 152df8bae1dSRodney W. Grimes * offset. Any other operation with a zero 153df8bae1dSRodney W. Grimes * offset is probably not listed in 154df8bae1dSRodney W. Grimes * vfs_op_descs, and so is probably an error. 155df8bae1dSRodney W. Grimes * 156df8bae1dSRodney W. Grimes * A panic here means the layer programmer 157df8bae1dSRodney W. Grimes * has committed the all-too common bug 158df8bae1dSRodney W. Grimes * of adding a new operation to the layer's 159df8bae1dSRodney W. Grimes * list of vnode operations but 160df8bae1dSRodney W. Grimes * not adding the operation to the system-wide 161df8bae1dSRodney W. Grimes * list of supported operations. 162df8bae1dSRodney W. Grimes */ 163df8bae1dSRodney W. Grimes if (opve_descp->opve_op->vdesc_offset == 0 && 164df8bae1dSRodney W. Grimes opve_descp->opve_op->vdesc_offset != 165df8bae1dSRodney W. Grimes VOFFSET(vop_default)) { 166df8bae1dSRodney W. Grimes printf("operation %s not listed in %s.\n", 167df8bae1dSRodney W. Grimes opve_descp->opve_op->vdesc_name, 168df8bae1dSRodney W. Grimes "vfs_op_descs"); 169df8bae1dSRodney W. Grimes panic ("vfs_opv_init: bad operation"); 170df8bae1dSRodney W. Grimes } 171df8bae1dSRodney W. Grimes /* 172df8bae1dSRodney W. Grimes * Fill in this entry. 173df8bae1dSRodney W. Grimes */ 174df8bae1dSRodney W. Grimes opv_desc_vector[opve_descp->opve_op->vdesc_offset] = 175df8bae1dSRodney W. Grimes opve_descp->opve_impl; 176df8bae1dSRodney W. Grimes } 177df8bae1dSRodney W. Grimes /* 178df8bae1dSRodney W. Grimes * Finally, go back and replace unfilled routines 179df8bae1dSRodney W. Grimes * with their default. (Sigh, an O(n^3) algorithm. I 180df8bae1dSRodney W. Grimes * could make it better, but that'd be work, and n is small.) 181df8bae1dSRodney W. Grimes */ 182aa855a59SPeter Wemm opv_desc_vector = *(opv->opv_desc_vector_p); 183df8bae1dSRodney W. Grimes /* 184df8bae1dSRodney W. Grimes * Force every operations vector to have a default routine. 185df8bae1dSRodney W. Grimes */ 186df8bae1dSRodney W. Grimes if (opv_desc_vector[VOFFSET(vop_default)]==NULL) { 187df8bae1dSRodney W. Grimes panic("vfs_opv_init: operation vector without default routine."); 188df8bae1dSRodney W. Grimes } 189df8bae1dSRodney W. Grimes for (k = 0; k<vfs_opv_numops; k++) 190df8bae1dSRodney W. Grimes if (opv_desc_vector[k] == NULL) 191df8bae1dSRodney W. Grimes opv_desc_vector[k] = 192df8bae1dSRodney W. Grimes opv_desc_vector[VOFFSET(vop_default)]; 193df8bae1dSRodney W. Grimes } 194df8bae1dSRodney W. Grimes 195df8bae1dSRodney W. Grimes /* 196df8bae1dSRodney W. Grimes * Initialize known vnode operations vectors. 197df8bae1dSRodney W. Grimes */ 19827a0b398SPoul-Henning Kamp static void 199df8bae1dSRodney W. Grimes vfs_op_init() 200df8bae1dSRodney W. Grimes { 201df8bae1dSRodney W. Grimes int i; 202df8bae1dSRodney W. Grimes 203df8bae1dSRodney W. Grimes DODEBUG(printf("Vnode_interface_init.\n")); 204bf1d104aSPoul-Henning Kamp DODEBUG(printf ("vfs_opv_numops=%d\n", vfs_opv_numops)); 205aa855a59SPeter Wemm #ifdef unused 206df8bae1dSRodney W. Grimes /* 207df8bae1dSRodney W. Grimes * Set all vnode vectors to a well known value. 208df8bae1dSRodney W. Grimes */ 209df8bae1dSRodney W. Grimes for (i = 0; vfs_opv_descs[i]; i++) 210df8bae1dSRodney W. Grimes *(vfs_opv_descs[i]->opv_desc_vector_p) = NULL; 211aa855a59SPeter Wemm #endif 212df8bae1dSRodney W. Grimes /* 213bf1d104aSPoul-Henning Kamp * assign each op to its offset 214bf1d104aSPoul-Henning Kamp * 215bf1d104aSPoul-Henning Kamp * XXX This should not be needed, but is because the per 216bf1d104aSPoul-Henning Kamp * XXX FS ops tables are not sorted according to the 217bf1d104aSPoul-Henning Kamp * XXX vnodeop_desc's offset in vfs_op_descs. This 218bf1d104aSPoul-Henning Kamp * XXX is the same reason we have to take the hit for 219bf1d104aSPoul-Henning Kamp * XXX the static inline function calls instead of using 220bf1d104aSPoul-Henning Kamp * XXX simple macro references. 221df8bae1dSRodney W. Grimes */ 222bf1d104aSPoul-Henning Kamp for (i = 0; i < vfs_opv_numops; i++) 223bf1d104aSPoul-Henning Kamp vfs_op_descs[i]->vdesc_offset = i; 224aa855a59SPeter Wemm #ifdef unused 225aa855a59SPeter Wemm /* Finish the job */ 226aa855a59SPeter Wemm for (i = 0; vfs_opv_descs[i]; i++) 227aa855a59SPeter Wemm vfs_opv_init(vfs_opv_descs[i]); 228aa855a59SPeter Wemm #endif 229df8bae1dSRodney W. Grimes } 230df8bae1dSRodney W. Grimes 231df8bae1dSRodney W. Grimes /* 232df8bae1dSRodney W. Grimes * Routines having to do with the management of the vnode table. 233df8bae1dSRodney W. Grimes */ 234df8bae1dSRodney W. Grimes extern struct vnodeops dead_vnodeops; 235df8bae1dSRodney W. Grimes extern struct vnodeops spec_vnodeops; 236df8bae1dSRodney W. Grimes struct vattr va_null; 237df8bae1dSRodney W. Grimes 238df8bae1dSRodney W. Grimes /* 239df8bae1dSRodney W. Grimes * Initialize the vnode structures and initialize each file system type. 240df8bae1dSRodney W. Grimes */ 2412b14f991SJulian Elischer /* ARGSUSED*/ 2422b14f991SJulian Elischer static void 243d841aaa7SBruce Evans vfsinit(dummy) 244d841aaa7SBruce Evans void *dummy; 245df8bae1dSRodney W. Grimes { 246e99ea9ecSBruce Evans struct vfsconf **vfc, *vfsp; 247996c772fSJohn Dyson int maxtypenum; 248df8bae1dSRodney W. Grimes 24999448ed1SJohn Dyson namei_zone = zinit("NAMEI", MAXPATHLEN, 0, 0, 2); 25099448ed1SJohn Dyson 251df8bae1dSRodney W. Grimes /* 252df8bae1dSRodney W. Grimes * Initialize the vnode table 253df8bae1dSRodney W. Grimes */ 254df8bae1dSRodney W. Grimes vntblinit(); 255df8bae1dSRodney W. Grimes /* 256df8bae1dSRodney W. Grimes * Initialize the vnode name cache 257df8bae1dSRodney W. Grimes */ 258df8bae1dSRodney W. Grimes nchinit(); 259df8bae1dSRodney W. Grimes /* 260df8bae1dSRodney W. Grimes * Build vnode operation vectors. 261df8bae1dSRodney W. Grimes */ 262df8bae1dSRodney W. Grimes vfs_op_init(); 263df8bae1dSRodney W. Grimes /* 264df8bae1dSRodney W. Grimes * Initialize each file system type. 265efcddb8eSDavid E. O'Brien * Vfs type numbers must be distinct from VFS_GENERIC (and VFS_VFSCONF). 266df8bae1dSRodney W. Grimes */ 267df8bae1dSRodney W. Grimes vattr_null(&va_null); 268aa855a59SPeter Wemm maxvfsconf = VFS_GENERIC + 1; 269df8bae1dSRodney W. Grimes } 270c901836cSGarrett Wollman 271aa855a59SPeter Wemm int 272aa855a59SPeter Wemm vfs_register(vfc) 273aa855a59SPeter Wemm struct vfsconf *vfc; 274aa855a59SPeter Wemm { 275aa855a59SPeter Wemm struct linker_set *l; 276aa855a59SPeter Wemm struct sysctl_oid **oidpp; 277aa855a59SPeter Wemm struct vfsconf *vfsp; 278aa855a59SPeter Wemm int error, i, maxtypenum, exists; 279aa855a59SPeter Wemm 280aa855a59SPeter Wemm vfsp = NULL; 281aa855a59SPeter Wemm exists = 0; 282aa855a59SPeter Wemm l = &sysctl__vfs; 283aa855a59SPeter Wemm if (vfsconf) 284aa855a59SPeter Wemm for (vfsp = vfsconf; vfsp->vfc_next; vfsp = vfsp->vfc_next) 285aa855a59SPeter Wemm if (!strcmp(vfc->vfc_name, vfsp->vfc_name)) 286aa855a59SPeter Wemm return EEXIST; 287aa855a59SPeter Wemm 288aa855a59SPeter Wemm vfc->vfc_typenum = maxvfsconf++; 289aa855a59SPeter Wemm if (vfc->vfc_vfsops->vfs_oid != NULL) { 290aa855a59SPeter Wemm oidpp = (struct sysctl_oid **)l->ls_items; 291aa855a59SPeter Wemm for (i = l->ls_length; i-- && !exists; oidpp++) 292aa855a59SPeter Wemm if (*oidpp == vfc->vfc_vfsops->vfs_oid) 293aa855a59SPeter Wemm exists = 1; 294aa855a59SPeter Wemm } 295aa855a59SPeter Wemm if (exists == 0 && vfc->vfc_vfsops->vfs_oid != NULL) { 296aa855a59SPeter Wemm oidpp = (struct sysctl_oid **)l->ls_items; 297aa855a59SPeter Wemm for (i = l->ls_length; i--; oidpp++) { 298aa855a59SPeter Wemm if (*oidpp == NULL || 299aa855a59SPeter Wemm *oidpp == &sysctl___vfs_mod0 || 300aa855a59SPeter Wemm *oidpp == &sysctl___vfs_mod1) { 301aa855a59SPeter Wemm *oidpp = vfc->vfc_vfsops->vfs_oid; 302aa855a59SPeter Wemm (*oidpp)->oid_number = vfc->vfc_typenum; 303aa855a59SPeter Wemm sysctl_order_all(); 304aa855a59SPeter Wemm break; 305aa855a59SPeter Wemm } 306aa855a59SPeter Wemm } 307aa855a59SPeter Wemm } 308aa855a59SPeter Wemm if (vfsp) 309aa855a59SPeter Wemm vfsp->vfc_next = vfc; 310aa855a59SPeter Wemm else 311aa855a59SPeter Wemm vfsconf = vfc; 312aa855a59SPeter Wemm vfc->vfc_next = NULL; 313aa855a59SPeter Wemm 314aa855a59SPeter Wemm /* 315aa855a59SPeter Wemm * Call init function for this VFS... 316aa855a59SPeter Wemm */ 317aa855a59SPeter Wemm (*(vfc->vfc_vfsops->vfs_init))(vfc); 318aa855a59SPeter Wemm 319aa855a59SPeter Wemm return 0; 320aa855a59SPeter Wemm } 321aa855a59SPeter Wemm 322aa855a59SPeter Wemm 323aa855a59SPeter Wemm /* 324aa855a59SPeter Wemm * To be called at SI_SUB_VFS, SECOND, for each VFS before any are registered. 325aa855a59SPeter Wemm */ 326aa855a59SPeter Wemm void 327aa855a59SPeter Wemm vfs_mod_opv_init(handle) 328aa855a59SPeter Wemm void *handle; 329aa855a59SPeter Wemm { 330aa855a59SPeter Wemm int i; 331aa855a59SPeter Wemm struct vnodeopv_desc *opv; 332aa855a59SPeter Wemm 333aa855a59SPeter Wemm opv = (struct vnodeopv_desc *)handle; 334aa855a59SPeter Wemm *(opv->opv_desc_vector_p) = NULL; 335aa855a59SPeter Wemm vfs_opv_init(opv); 336aa855a59SPeter Wemm } 337aa855a59SPeter Wemm 338aa855a59SPeter Wemm int 339aa855a59SPeter Wemm vfs_unregister(vfc) 340aa855a59SPeter Wemm struct vfsconf *vfc; 341aa855a59SPeter Wemm { 342aa855a59SPeter Wemm struct linker_set *l; 343aa855a59SPeter Wemm struct sysctl_oid **oidpp; 344aa855a59SPeter Wemm struct vfsconf *vfsp, *prev_vfsp; 345aa855a59SPeter Wemm int error, i, maxtypenum; 346aa855a59SPeter Wemm 347aa855a59SPeter Wemm i = vfc->vfc_typenum; 348aa855a59SPeter Wemm 349aa855a59SPeter Wemm prev_vfsp = NULL; 350aa855a59SPeter Wemm for (vfsp = vfsconf; vfsp; 351aa855a59SPeter Wemm prev_vfsp = vfsp, vfsp = vfsp->vfc_next) { 352aa855a59SPeter Wemm if (!strcmp(vfc->vfc_name, vfsp->vfc_name)) 353aa855a59SPeter Wemm break; 354aa855a59SPeter Wemm } 355aa855a59SPeter Wemm if (vfsp == NULL) 356aa855a59SPeter Wemm return EINVAL; 357aa855a59SPeter Wemm if (vfsp->vfc_refcount) 358aa855a59SPeter Wemm return EBUSY; 359aa855a59SPeter Wemm if (vfc->vfc_vfsops->vfs_uninit != NULL) { 360aa855a59SPeter Wemm error = (*vfc->vfc_vfsops->vfs_uninit)(vfsp); 361aa855a59SPeter Wemm if (error) 362aa855a59SPeter Wemm return (error); 363aa855a59SPeter Wemm } 364aa855a59SPeter Wemm if (prev_vfsp) 365aa855a59SPeter Wemm prev_vfsp->vfc_next = vfsp->vfc_next; 366aa855a59SPeter Wemm else 367aa855a59SPeter Wemm vfsconf = vfsp->vfc_next; 368aa855a59SPeter Wemm if (vfsp->vfc_vfsops->vfs_oid != NULL) { 369aa855a59SPeter Wemm l = &sysctl__vfs; 370aa855a59SPeter Wemm for (i = l->ls_length, 371aa855a59SPeter Wemm oidpp = (struct sysctl_oid **)l->ls_items; 372aa855a59SPeter Wemm i--; oidpp++) { 373aa855a59SPeter Wemm if (*oidpp == vfsp->vfc_vfsops->vfs_oid) { 374aa855a59SPeter Wemm *oidpp = NULL; 375aa855a59SPeter Wemm sysctl_order_all(); 376aa855a59SPeter Wemm break; 377aa855a59SPeter Wemm } 378aa855a59SPeter Wemm } 379aa855a59SPeter Wemm } 380aa855a59SPeter Wemm maxtypenum = VFS_GENERIC; 381aa855a59SPeter Wemm for (vfsp = vfsconf; vfsp != NULL; vfsp = vfsp->vfc_next) 382aa855a59SPeter Wemm if (maxtypenum < vfsp->vfc_typenum) 383aa855a59SPeter Wemm maxtypenum = vfsp->vfc_typenum; 384aa855a59SPeter Wemm maxvfsconf = maxtypenum + 1; 385aa855a59SPeter Wemm return 0; 386aa855a59SPeter Wemm } 387