X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/de355530ae67247cbd0da700edb3a2a1dae884c2..cc9f6e38162d3c1bf6ca97536c2477f476c8e01b:/bsd/vfs/vfs_init.c diff --git a/bsd/vfs/vfs_init.c b/bsd/vfs/vfs_init.c index 536623adc..4c4aabb22 100644 --- a/bsd/vfs/vfs_init.c +++ b/bsd/vfs/vfs_init.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -62,14 +62,13 @@ #include -#include +#include #include #include -#include +#include #include #include #include -#include #include #include @@ -106,7 +105,7 @@ int vn_default_error() { - return (EOPNOTSUPP); + return (ENOTSUP); } /* @@ -143,9 +142,8 @@ vfs_opv_init() * Also handle backwards compatibility. */ if (*opv_desc_vector_p == NULL) { - /* XXX - shouldn't be M_VNODE */ MALLOC(*opv_desc_vector_p, PFI*, - vfs_opv_numops*sizeof(PFI), M_VNODE, M_WAITOK); + vfs_opv_numops*sizeof(PFI), M_TEMP, M_WAITOK); bzero (*opv_desc_vector_p, vfs_opv_numops*sizeof(PFI)); DODEBUG(printf("vector at %x allocated\n", opv_desc_vector_p)); @@ -173,7 +171,7 @@ vfs_opv_init() */ if (opve_descp->opve_op->vdesc_offset == 0 && opve_descp->opve_op->vdesc_offset != - VOFFSET(vop_default)) { + VOFFSET(vnop_default)) { printf("operation %s not listed in %s.\n", opve_descp->opve_op->vdesc_name, "vfs_op_descs"); @@ -196,13 +194,13 @@ vfs_opv_init() /* * Force every operations vector to have a default routine. */ - if (opv_desc_vector[VOFFSET(vop_default)]==NULL) { + if (opv_desc_vector[VOFFSET(vnop_default)]==NULL) { panic("vfs_opv_init: operation vector without default routine."); } for (k = 0; kvfs_vfsops is encountered. */ - vattr_null(&va_null); numused_vfsslots = maxtypenum = 0; for (vfsp = vfsconf, i = 0; i < maxvfsconf; i++, vfsp++) { if (vfsp->vfc_vfsops == (struct vfsops *)0) @@ -276,63 +382,213 @@ vfsinit() if (maxtypenum <= vfsp->vfc_typenum) maxtypenum = vfsp->vfc_typenum + 1; (*vfsp->vfc_vfsops->vfs_init)(vfsp); + + lck_mtx_init(&vfsp->vfc_lock, fsconf_lck_grp, fsconf_lck_attr); + numused_vfsslots++; } /* next vfc_typenum to be used */ maxvfsconf = maxtypenum; + + /* + * Initialize the vnop authorization scope. + */ + vnode_authorize_init(); + + /* + * create a mount point for dead vnodes + */ + MALLOC_ZONE(mp, struct mount *, (u_long)sizeof(struct mount), + M_MOUNT, M_WAITOK); + bzero((char *)mp, (u_long)sizeof(struct mount)); + /* Initialize the default IO constraints */ + mp->mnt_maxreadcnt = mp->mnt_maxwritecnt = MAXPHYS; + mp->mnt_segreadcnt = mp->mnt_segwritecnt = 32; + mp->mnt_maxsegreadsize = mp->mnt_maxreadcnt; + mp->mnt_maxsegwritesize = mp->mnt_maxwritecnt; + mp->mnt_devblocksize = DEV_BSIZE; + + TAILQ_INIT(&mp->mnt_vnodelist); + TAILQ_INIT(&mp->mnt_workerqueue); + TAILQ_INIT(&mp->mnt_newvnodes); + mp->mnt_flag = MNT_LOCAL; + mp->mnt_lflag = MNT_LDEAD; + mount_lock_init(mp); + dead_mountp = mp; } -int -vfsconf_add(struct vfsconf *nvfsp) +void +vnode_list_lock() +{ + lck_mtx_lock(vnode_list_mtx_lock); +} + +void +vnode_list_unlock() { - struct vfsconf *vfsp; + lck_mtx_unlock(vnode_list_mtx_lock); +} - if ((numused_vfsslots >= maxvfsslots) || (nvfsp == (struct vfsconf *)0)) - return (-1); - bcopy(nvfsp, &vfsconf[numused_vfsslots], sizeof(struct vfsconf)); - vfsconf[numused_vfsslots-1].vfc_next = &vfsconf[numused_vfsslots]; - - if (nvfsp->vfc_typenum <= maxvfsconf ) - maxvfsconf = nvfsp->vfc_typenum + 1; +void +mount_list_lock() +{ + lck_mtx_lock(mnt_list_mtx_lock); +} + +void +mount_list_unlock() +{ + lck_mtx_unlock(mnt_list_mtx_lock); +} + +void +mount_lock_init(mount_t mp) +{ + lck_mtx_init(&mp->mnt_mlock, 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); +} + +void +mount_lock_destroy(mount_t mp) +{ + lck_mtx_destroy(&mp->mnt_mlock, mnt_lck_grp); + lck_mtx_destroy(&mp->mnt_renamelock, mnt_lck_grp); + lck_rw_destroy(&mp->mnt_rwlock, mnt_lck_grp); +} + + +/* + * Name: vfstable_add + * + * Description: Add a filesystem to the vfsconf list at the first + * unused slot. If no slots are available, return an + * error. + * + * Parameter: nvfsp vfsconf for VFS to add + * + * Returns: 0 Success + * -1 Failure + * + * Notes: The vfsconf should be treated as a linked list by + * all external references, as the implementation is + * expected to change in the future. The linkage is + * through ->vfc_next, and the list is NULL terminated. + * + * Warning: This code assumes that vfsconf[0] is non-empty. + */ +struct vfstable * +vfstable_add(struct vfstable *nvfsp) +{ + int slot; + struct vfstable *slotp; + + /* + * Find the next empty slot; we recognize an empty slot by a + * NULL-valued ->vfc_vfsops, so if we delete a VFS, we must + * ensure we set the entry back to NULL. + */ + for (slot = 0; slot < maxvfsslots; slot++) { + if (vfsconf[slot].vfc_vfsops == NULL) + break; + } + if (slot == maxvfsslots) { + /* out of static slots; allocate one instead */ + MALLOC(slotp, struct vfstable *, sizeof(struct vfstable), + M_TEMP, M_WAITOK); + } else { + slotp = &vfsconf[slot]; + } + + /* + * Replace the contents of the next empty slot with the contents + * of the provided nvfsp. + * + * Note; Takes advantage of the fact that 'slot' was left + * with the value of 'maxvfslots' in the allocation case. + */ + bcopy(nvfsp, slotp, sizeof(struct vfstable)); + lck_mtx_init(&slotp->vfc_lock, fsconf_lck_grp, fsconf_lck_attr); + if (slot != 0) { + slotp->vfc_next = vfsconf[slot - 1].vfc_next; + vfsconf[slot - 1].vfc_next = slotp; + } else { + slotp->vfc_next = NULL; + } numused_vfsslots++; - if (nvfsp->vfc_vfsops->vfs_init) - (*nvfsp->vfc_vfsops->vfs_init)(nvfsp); - return(0); + + return(slotp); } +/* + * Name: vfstable_del + * + * Description: Remove a filesystem from the vfsconf list by name. + * If no such filesystem exists, return an error. + * + * Parameter: fs_name name of VFS to remove + * + * Returns: 0 Success + * -1 Failure + * + * Notes: Hopefully all filesystems have unique names. + */ int -vfsconf_del(char * fs_name) +vfstable_del(struct vfstable * vtbl) { - int entriesRemaining; - struct vfsconf *vfsconflistentry; - struct vfsconf *prevconf = NULL; - struct vfsconf *targetconf = NULL; - - prevconf = vfsconflistentry = vfsconf; - for (entriesRemaining = maxvfsslots; - (entriesRemaining > 0) && (vfsconflistentry != NULL); - --entriesRemaining) { - if ((vfsconflistentry->vfc_vfsops != NULL) && (strcmp(vfsconflistentry->vfc_name, fs_name) == 0)) { - targetconf = vfsconflistentry; + struct vfstable **vcpp; + struct vfstable *vcdelp; + + /* + * Traverse the list looking for vtbl; if found, *vcpp + * will contain the address of the pointer to the entry to + * be removed. + */ + for( vcpp = &vfsconf; *vcpp; vcpp = &(*vcpp)->vfc_next) { + if (*vcpp == vtbl) break; - }; - prevconf = vfsconflistentry; - vfsconflistentry = vfsconflistentry->vfc_next; - }; - - if (targetconf != NULL) { - if (prevconf != NULL) { - /* Unlink the target entry from the list: - and decrement our count */ - prevconf->vfc_next = targetconf->vfc_next; - numused_vfsslots--; - } else { - /* XXX need real error code for no previous entry in list */ - return(-1); } - } else { - /* XXX need real error code for entry not found */ - return(-1); - }; + + if (*vcpp == NULL) + return(ESRCH); /* vtbl not on vfsconf list */ + + /* Unlink entry */ + vcdelp = *vcpp; + *vcpp = (*vcpp)->vfc_next; + + lck_mtx_destroy(&vcdelp->vfc_lock, fsconf_lck_grp); + + /* + * Is this an entry from our static table? We find out by + * 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 */ + /* Mark as empty for vfscon_add() */ + bzero(vcdelp, sizeof(struct vfstable)); + numused_vfsslots--; + } else { /* N */ + /* + * This entry was dynamically allocated; we must free it; + * we would prefer to have just linked the caller's + * vfsconf onto our list, but it may not be persistent + * because of the previous (copying) implementation. + */ + FREE(vcdelp, M_TEMP); + } + return(0); } + +void +SPECHASH_LOCK(void) +{ + lck_mtx_lock(spechash_mtx_lock); +} + +void +SPECHASH_UNLOCK(void) +{ + lck_mtx_unlock(spechash_mtx_lock); +} +