X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/fe8ab488e9161c46dd9885d58fc52996dc0249ff..eb6b6ca394357805f2bdba989abae309f718b4d8:/bsd/vfs/vfs_init.c?ds=sidebyside diff --git a/bsd/vfs/vfs_init.c b/bsd/vfs/vfs_init.c index 54b6880fc..d17cb02bd 100644 --- a/bsd/vfs/vfs_init.c +++ b/bsd/vfs/vfs_init.c @@ -2,7 +2,7 @@ * Copyright (c) 2000-2010 Apple Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ - * + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -11,10 +11,10 @@ * unlawful or unlicensed copies of an Apple operating system, or to * circumvent, violate, or enable the circumvention or violation of, any * terms of an Apple operating system software license agreement. - * + * * Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this file. - * + * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, @@ -22,7 +22,7 @@ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. - * + * * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ */ /* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */ @@ -83,8 +83,8 @@ #include #include #include +#include -#include /* journal_init() */ #if CONFIG_MACF #include #include @@ -104,10 +104,10 @@ __private_extern__ void vntblinit(void); -extern struct vnodeopv_desc *vfs_opv_descs[]; - /* a list of lists of vnodeops defns */ +extern const 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 */ +/* 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 @@ -116,7 +116,7 @@ extern struct vnodeop_desc *vfs_op_descs[]; */ int vfs_opv_numops; -typedef int (*PFIvp)(void *); +typedef int (*PFIvp)(void *); /* * A miscellaneous routine. @@ -125,8 +125,7 @@ typedef int (*PFIvp)(void *); int vn_default_error(void) { - - return (ENOTSUP); + return ENOTSUP; } /* @@ -149,14 +148,14 @@ void vfs_opv_init(void) { int i, j, k; - int (***opv_desc_vector_p)(void *); - int (**opv_desc_vector)(void *); - struct vnodeopv_entry_desc *opve_descp; + int(***opv_desc_vector_p)(void *); + int(**opv_desc_vector)(void *); + const struct vnodeopv_entry_desc *opve_descp; /* * Allocate the dynamic vectors and fill them in. */ - for (i=0; vfs_opv_descs[i]; i++) { + for (i = 0; vfs_opv_descs[i]; i++) { opv_desc_vector_p = vfs_opv_descs[i]->opv_desc_vector_p; /* * Allocate and init the vector, if it needs it. @@ -164,15 +163,22 @@ vfs_opv_init(void) */ if (*opv_desc_vector_p == NULL) { MALLOC(*opv_desc_vector_p, PFIvp*, - vfs_opv_numops*sizeof(PFIvp), M_TEMP, M_WAITOK); - bzero (*opv_desc_vector_p, vfs_opv_numops*sizeof(PFIvp)); + vfs_opv_numops * sizeof(PFIvp), M_TEMP, M_WAITOK); + bzero(*opv_desc_vector_p, vfs_opv_numops * sizeof(PFIvp)); DODEBUG(printf("vector at %x allocated\n", opv_desc_vector_p)); } opv_desc_vector = *opv_desc_vector_p; - for (j=0; vfs_opv_descs[i]->opv_desc_ops[j].opve_op; j++) { + for (j = 0; vfs_opv_descs[i]->opv_desc_ops[j].opve_op; j++) { opve_descp = &(vfs_opv_descs[i]->opv_desc_ops[j]); + /* Silently skip known-disabled operations */ + if (opve_descp->opve_op->vdesc_flags & VDESC_DISABLED) { + printf("vfs_fsadd: Ignoring reference in %p to disabled operation %s.\n", + vfs_opv_descs[i], opve_descp->opve_op->vdesc_name); + continue; + } + /* * Sanity check: is this operation listed * in the list of operations? We check this @@ -191,18 +197,18 @@ vfs_opv_init(void) * list of supported operations. */ if (opve_descp->opve_op->vdesc_offset == 0 && - opve_descp->opve_op->vdesc_offset != - VOFFSET(vnop_default)) { + opve_descp->opve_op != + VDESC(vnop_default)) { printf("operation %s not listed in %s.\n", opve_descp->opve_op->vdesc_name, "vfs_op_descs"); - panic ("vfs_opv_init: bad operation"); + panic("vfs_opv_init: bad operation"); } /* * Fill in this entry. */ opv_desc_vector[opve_descp->opve_op->vdesc_offset] = - opve_descp->opve_impl; + opve_descp->opve_impl; } } /* @@ -215,13 +221,15 @@ vfs_opv_init(void) /* * Force every operations vector to have a default routine. */ - if (opv_desc_vector[VOFFSET(vnop_default)]==NULL) { + if (opv_desc_vector[VOFFSET(vnop_default)] == NULL) { panic("vfs_opv_init: operation vector without default routine."); } - for (k = 0; kopv_desc_vector_p) = NULL; + } /* * Figure out how many ops there are by counting the table, * and assign each its offset. */ for (vfs_opv_numops = 0, i = 0; vfs_op_descs[i]; i++) { + /* Silently skip known-disabled operations */ + if (vfs_op_descs[i]->vdesc_flags & VDESC_DISABLED) { + continue; + } vfs_op_descs[i]->vdesc_offset = vfs_opv_numops; vfs_opv_numops++; } - DODEBUG(printf ("vfs_opv_numops=%d\n", vfs_opv_numops)); + DODEBUG(printf("vfs_opv_numops=%d\n", vfs_opv_numops)); } /* @@ -306,8 +319,6 @@ lck_mtx_t *pkg_extensions_lck; struct mount * dead_mountp; -extern void nspace_handler_init(void); - /* * Initialize the vnode structures and initialize each file system type. */ @@ -317,12 +328,12 @@ vfsinit(void) struct vfstable *vfsp; int i, maxtypenum; struct mount * mp; - + /* Allocate vnode list lock group attribute and group */ vnode_list_lck_grp_attr = lck_grp_attr_alloc_init(); - vnode_list_lck_grp = lck_grp_alloc_init("vnode list", vnode_list_lck_grp_attr); - + vnode_list_lck_grp = lck_grp_alloc_init("vnode list", vnode_list_lck_grp_attr); + /* Allocate vnode list lock attribute */ vnode_list_lck_attr = lck_attr_alloc_init(); @@ -336,9 +347,9 @@ vfsinit(void) pkg_extensions_lck = lck_mtx_alloc_init(vnode_list_lck_grp, vnode_list_lck_attr); /* allocate vnode lock group attribute and group */ - vnode_lck_grp_attr= lck_grp_attr_alloc_init(); + vnode_lck_grp_attr = lck_grp_attr_alloc_init(); - vnode_lck_grp = lck_grp_alloc_init("vnode", vnode_lck_grp_attr); + vnode_lck_grp = lck_grp_alloc_init("vnode", vnode_lck_grp_attr); /* Allocate vnode lock attribute */ vnode_lck_attr = lck_attr_alloc_init(); @@ -354,20 +365,20 @@ vfsinit(void) fd_vn_lck_attr = lck_attr_alloc_init(); /* Allocate fs config lock group attribute and group */ - fsconf_lck_grp_attr= lck_grp_attr_alloc_init(); + fsconf_lck_grp_attr = lck_grp_attr_alloc_init(); + + fsconf_lck_grp = lck_grp_alloc_init("fs conf", fsconf_lck_grp_attr); - fsconf_lck_grp = lck_grp_alloc_init("fs conf", fsconf_lck_grp_attr); - /* Allocate fs config lock attribute */ fsconf_lck_attr = lck_attr_alloc_init(); /* Allocate mount point related lock structures */ /* Allocate mount list lock group attribute and group */ - mnt_list_lck_grp_attr= lck_grp_attr_alloc_init(); + mnt_list_lck_grp_attr = lck_grp_attr_alloc_init(); + + mnt_list_lck_grp = lck_grp_alloc_init("mount list", mnt_list_lck_grp_attr); - mnt_list_lck_grp = lck_grp_alloc_init("mount list", mnt_list_lck_grp_attr); - /* Allocate mount list lock attribute */ mnt_list_lck_attr = lck_attr_alloc_init(); @@ -376,18 +387,18 @@ vfsinit(void) /* allocate mount lock group attribute and group */ - mnt_lck_grp_attr= lck_grp_attr_alloc_init(); + mnt_lck_grp_attr = lck_grp_attr_alloc_init(); - mnt_lck_grp = lck_grp_alloc_init("mount", mnt_lck_grp_attr); + mnt_lck_grp = lck_grp_alloc_init("mount", mnt_lck_grp_attr); /* Allocate mount lock attribute */ mnt_lck_attr = lck_attr_alloc_init(); /* Allocate sync lock */ - sync_mtx_lck_grp_attr = lck_grp_attr_alloc_init(); - sync_mtx_lck_grp = lck_grp_alloc_init("sync thread", sync_mtx_lck_grp_attr); - sync_mtx_lck_attr = lck_attr_alloc_init(); - sync_mtx_lck = lck_mtx_alloc_init(sync_mtx_lck_grp, sync_mtx_lck_attr); + sync_mtx_lck_grp_attr = lck_grp_attr_alloc_init(); + sync_mtx_lck_grp = lck_grp_alloc_init("sync thread", sync_mtx_lck_grp_attr); + sync_mtx_lck_attr = lck_attr_alloc_init(); + sync_mtx_lck = lck_mtx_alloc_init(sync_mtx_lck_grp, sync_mtx_lck_attr); /* * Initialize the vnode table @@ -402,14 +413,6 @@ vfsinit(void) */ nchinit(); -#if JOURNALING - /* - * Initialize the journaling locks - */ - journal_init(); -#endif - nspace_handler_init(); - /* * Build vnode operation vectors. */ @@ -422,12 +425,16 @@ vfsinit(void) maxtypenum = VT_NON; for (vfsp = vfsconf, i = 0; i < maxvfsslots; i++, vfsp++) { struct vfsconf vfsc; - if (vfsp->vfc_vfsops == (struct vfsops *)0) + if (vfsp->vfc_vfsops == (struct vfsops *)0) { break; - if (i) vfsconf[i-1].vfc_next = vfsp; - if (maxtypenum <= vfsp->vfc_typenum) + } + if (i) { + vfsconf[i - 1].vfc_next = vfsp; + } + if (maxtypenum <= vfsp->vfc_typenum) { maxtypenum = vfsp->vfc_typenum + 1; - + } + bzero(&vfsc, sizeof(struct vfsconf)); vfsc.vfc_reserved1 = 0; bcopy(vfsp->vfc_name, vfsc.vfc_name, sizeof(vfsc.vfc_name)); @@ -440,16 +447,16 @@ vfsinit(void) if (vfsp->vfc_vfsops->vfs_sysctl) { struct sysctl_oid *oidp = NULL; struct sysctl_oid oid = SYSCTL_STRUCT_INIT(_vfs, vfsp->vfc_typenum, , CTLTYPE_NODE | CTLFLAG_KERN | CTLFLAG_RW | CTLFLAG_LOCKED, NULL, 0, vfs_sysctl_node, "-", ""); - + MALLOC(oidp, struct sysctl_oid *, sizeof(struct sysctl_oid), M_TEMP, M_WAITOK); *oidp = oid; - + /* Memory for VFS oid held by vfsentry forever */ vfsp->vfc_sysctl = oidp; oidp->oid_name = vfsp->vfc_name; sysctl_register_oid(vfsp->vfc_sysctl); } - + (*vfsp->vfc_vfsops->vfs_init)(&vfsc); numused_vfsslots++; @@ -469,12 +476,12 @@ vfsinit(void) #if QUOTA dqinit(); #endif - - /* + + /* * create a mount point for dead vnodes */ MALLOC_ZONE(mp, struct mount *, sizeof(struct mount), - M_MOUNT, M_WAITOK); + M_MOUNT, M_WAITOK); bzero((char *)mp, sizeof(struct mount)); /* Initialize the default IO constraints */ mp->mnt_maxreadcnt = mp->mnt_maxwritecnt = MAXPHYS; @@ -488,7 +495,7 @@ vfsinit(void) mp->mnt_ioflags = 0; mp->mnt_realrootvp = NULLVP; mp->mnt_authcache_ttl = CACHED_LOOKUP_RIGHT_TTL; - + TAILQ_INIT(&mp->mnt_vnodelist); TAILQ_INIT(&mp->mnt_workerqueue); TAILQ_INIT(&mp->mnt_newvnodes); @@ -501,12 +508,18 @@ vfsinit(void) mac_mount_label_associate(vfs_context_kernel(), mp); #endif dead_mountp = mp; + +#if FS_COMPRESSION + decmpfs_init(); +#endif + + nspace_resolver_init(); } void vnode_list_lock(void) { - lck_spin_lock(vnode_list_spin_lock); + lck_spin_lock_grp(vnode_list_spin_lock, vnode_list_lck_grp); } void @@ -531,6 +544,7 @@ void mount_lock_init(mount_t mp) { lck_mtx_init(&mp->mnt_mlock, mnt_lck_grp, mnt_lck_attr); + lck_mtx_init(&mp->mnt_iter_lock, mnt_lck_grp, mnt_lck_attr); lck_mtx_init(&mp->mnt_renamelock, mnt_lck_grp, mnt_lck_attr); lck_rw_init(&mp->mnt_rwlock, mnt_lck_grp, mnt_lck_attr); } @@ -539,6 +553,7 @@ void mount_lock_destroy(mount_t mp) { lck_mtx_destroy(&mp->mnt_mlock, mnt_lck_grp); + lck_mtx_destroy(&mp->mnt_iter_lock, mnt_lck_grp); lck_mtx_destroy(&mp->mnt_renamelock, mnt_lck_grp); lck_rw_destroy(&mp->mnt_rwlock, mnt_lck_grp); } @@ -570,14 +585,14 @@ vfstable_add(struct vfstable *nvfsp) struct vfstable *slotp, *allocated = NULL; struct sysctl_oid *oidp = NULL; - + if (nvfsp->vfc_vfsops->vfs_sysctl) { struct sysctl_oid oid = SYSCTL_STRUCT_INIT(_vfs, nvfsp->vfc_typenum, , CTLTYPE_NODE | CTLFLAG_KERN | CTLFLAG_RW | CTLFLAG_LOCKED, NULL, 0, vfs_sysctl_node, "-", ""); - + MALLOC(oidp, struct sysctl_oid *, sizeof(struct sysctl_oid), M_TEMP, M_WAITOK); *oidp = oid; } - + /* * Find the next empty slot; we recognize an empty slot by a * NULL-valued ->vfc_vfsops, so if we delete a VFS, we must @@ -586,15 +601,16 @@ vfstable_add(struct vfstable *nvfsp) findslot: mount_list_lock(); for (slot = 0; slot < maxvfsslots; slot++) { - if (vfsconf[slot].vfc_vfsops == NULL) + if (vfsconf[slot].vfc_vfsops == NULL) { break; + } } if (slot == maxvfsslots) { if (allocated == NULL) { mount_list_unlock(); /* out of static slots; allocate one instead */ MALLOC(allocated, struct vfstable *, sizeof(struct vfstable), - M_TEMP, M_WAITOK); + M_TEMP, M_WAITOK); goto findslot; } else { slotp = allocated; @@ -632,13 +648,13 @@ findslot: } mount_list_unlock(); - + if (allocated && allocated != slotp) { /* did allocation, but ended up using static slot */ FREE(allocated, M_TEMP); } - return(slotp); + return slotp; } /* @@ -669,14 +685,15 @@ vfstable_del(struct vfstable * vtbl) * will contain the address of the pointer to the entry to * be removed. */ - for( vcpp = &vfsconf; *vcpp; vcpp = &(*vcpp)->vfc_next) { - if (*vcpp == vtbl) + for (vcpp = &vfsconf; *vcpp; vcpp = &(*vcpp)->vfc_next) { + if (*vcpp == vtbl) { break; + } } - if (*vcpp == NULL) - return(ESRCH); /* vtbl not on vfsconf list */ - + if (*vcpp == NULL) { + return ESRCH; /* vtbl not on vfsconf list */ + } if ((*vcpp)->vfc_sysctl) { sysctl_unregister_oid((*vcpp)->vfc_sysctl); (*vcpp)->vfc_sysctl->oid_name = NULL; @@ -693,12 +710,12 @@ vfstable_del(struct vfstable * vtbl) * seeing if the pointer to the object to be deleted places * the object in the address space containing the table (or not). */ - if (vcdelp >= vfsconf && vcdelp < (vfsconf + maxvfsslots)) { /* Y */ + if (vcdelp >= vfsconf && vcdelp < (vfsconf + maxvfsslots)) { /* Y */ /* Mark as empty for vfscon_add() */ bzero(vcdelp, sizeof(struct vfstable)); numregistered_fses--; numused_vfsslots--; - } else { /* N */ + } else { /* N */ /* * This entry was dynamically allocated; we must free it; * we would prefer to have just linked the caller's @@ -715,7 +732,7 @@ vfstable_del(struct vfstable * vtbl) lck_mtx_assert(mnt_list_mtx_lock, LCK_MTX_ASSERT_OWNED); #endif /* DEBUG */ - return(0); + return 0; } void @@ -729,4 +746,3 @@ SPECHASH_UNLOCK(void) { lck_mtx_unlock(spechash_mtx_lock); } -