|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights ! 7: * Reserved. This file contains Original Code and/or Modifications of ! 8: * Original Code as defined in and that are subject to the Apple Public ! 9: * Source License Version 1.1 (the "License"). You may not use this file ! 10: * except in compliance with the License. Please obtain a copy of the ! 11: * License at http://www.apple.com/publicsource and read it before using ! 12: * this file. ! 13: * ! 14: * The Original Code and all software distributed under the License are ! 15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ! 19: * License for the specific language governing rights and limitations ! 20: * under the License. ! 21: * ! 22: * @APPLE_LICENSE_HEADER_END@ ! 23: */ ! 24: ! 25: /* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */ ! 26: /* ! 27: * Copyright (c) 1989, 1993 ! 28: * The Regents of the University of California. All rights reserved. ! 29: * ! 30: * This code is derived from software contributed ! 31: * to Berkeley by John Heidemann of the UCLA Ficus project. ! 32: * ! 33: * Source: * @(#)i405_init.c 2.10 92/04/27 UCLA Ficus project ! 34: * ! 35: * Redistribution and use in source and binary forms, with or without ! 36: * modification, are permitted provided that the following conditions ! 37: * are met: ! 38: * 1. Redistributions of source code must retain the above copyright ! 39: * notice, this list of conditions and the following disclaimer. ! 40: * 2. Redistributions in binary form must reproduce the above copyright ! 41: * notice, this list of conditions and the following disclaimer in the ! 42: * documentation and/or other materials provided with the distribution. ! 43: * 3. All advertising materials mentioning features or use of this software ! 44: * must display the following acknowledgement: ! 45: * This product includes software developed by the University of ! 46: * California, Berkeley and its contributors. ! 47: * 4. Neither the name of the University nor the names of its contributors ! 48: * may be used to endorse or promote products derived from this software ! 49: * without specific prior written permission. ! 50: * ! 51: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ! 52: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ! 53: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ! 54: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE ! 55: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ! 56: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ! 57: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ! 58: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ! 59: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ! 60: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ! 61: * SUCH DAMAGE. ! 62: * ! 63: * @(#)vfs_init.c 8.5 (Berkeley) 5/11/95 ! 64: */ ! 65: ! 66: ! 67: #include <sys/param.h> ! 68: #include <sys/mount.h> ! 69: #include <sys/time.h> ! 70: #include <sys/vm.h> ! 71: #include <sys/vnode.h> ! 72: #include <sys/stat.h> ! 73: #include <sys/namei.h> ! 74: #include <sys/ucred.h> ! 75: #include <sys/buf.h> ! 76: #include <sys/errno.h> ! 77: #include <sys/malloc.h> ! 78: ! 79: ! 80: /* ! 81: * Sigh, such primitive tools are these... ! 82: */ ! 83: #if 0 ! 84: #define DODEBUG(A) A ! 85: #else ! 86: #define DODEBUG(A) ! 87: #endif ! 88: ! 89: extern struct vnodeopv_desc *vfs_opv_descs[]; ! 90: /* a list of lists of vnodeops defns */ ! 91: extern struct vnodeop_desc *vfs_op_descs[]; ! 92: /* and the operations they perform */ ! 93: /* ! 94: * This code doesn't work if the defn is **vnodop_defns with cc. ! 95: * The problem is because of the compiler sometimes putting in an ! 96: * extra level of indirection for arrays. It's an interesting ! 97: * "feature" of C. ! 98: */ ! 99: int vfs_opv_numops; ! 100: ! 101: typedef (*PFI)(); /* the standard Pointer to a Function returning an Int */ ! 102: ! 103: /* ! 104: * A miscellaneous routine. ! 105: * A generic "default" routine that just returns an error. ! 106: */ ! 107: int ! 108: vn_default_error() ! 109: { ! 110: ! 111: return (EOPNOTSUPP); ! 112: } ! 113: ! 114: /* ! 115: * vfs_init.c ! 116: * ! 117: * Allocate and fill in operations vectors. ! 118: * ! 119: * An undocumented feature of this approach to defining operations is that ! 120: * there can be multiple entries in vfs_opv_descs for the same operations ! 121: * vector. This allows third parties to extend the set of operations ! 122: * supported by another layer in a binary compatibile way. For example, ! 123: * assume that NFS needed to be modified to support Ficus. NFS has an entry ! 124: * (probably nfs_vnopdeop_decls) declaring all the operations NFS supports by ! 125: * default. Ficus could add another entry (ficus_nfs_vnodeop_decl_entensions) ! 126: * listing those new operations Ficus adds to NFS, all without modifying the ! 127: * NFS code. (Of couse, the OTW NFS protocol still needs to be munged, but ! 128: * that is a(whole)nother story.) This is a feature. ! 129: */ ! 130: void ! 131: vfs_opv_init() ! 132: { ! 133: int i, j, k; ! 134: int (***opv_desc_vector_p)(); ! 135: int (**opv_desc_vector)(); ! 136: struct vnodeopv_entry_desc *opve_descp; ! 137: ! 138: /* ! 139: * Allocate the dynamic vectors and fill them in. ! 140: */ ! 141: for (i=0; vfs_opv_descs[i]; i++) { ! 142: opv_desc_vector_p = vfs_opv_descs[i]->opv_desc_vector_p; ! 143: /* ! 144: * Allocate and init the vector, if it needs it. ! 145: * Also handle backwards compatibility. ! 146: */ ! 147: if (*opv_desc_vector_p == NULL) { ! 148: /* XXX - shouldn't be M_VNODE */ ! 149: MALLOC(*opv_desc_vector_p, PFI*, ! 150: vfs_opv_numops*sizeof(PFI), M_VNODE, M_WAITOK); ! 151: bzero (*opv_desc_vector_p, vfs_opv_numops*sizeof(PFI)); ! 152: DODEBUG(printf("vector at %x allocated\n", ! 153: opv_desc_vector_p)); ! 154: } ! 155: opv_desc_vector = *opv_desc_vector_p; ! 156: for (j=0; vfs_opv_descs[i]->opv_desc_ops[j].opve_op; j++) { ! 157: opve_descp = &(vfs_opv_descs[i]->opv_desc_ops[j]); ! 158: ! 159: /* ! 160: * Sanity check: is this operation listed ! 161: * in the list of operations? We check this ! 162: * by seeing if its offest is zero. Since ! 163: * the default routine should always be listed ! 164: * first, it should be the only one with a zero ! 165: * offset. Any other operation with a zero ! 166: * offset is probably not listed in ! 167: * vfs_op_descs, and so is probably an error. ! 168: * ! 169: * A panic here means the layer programmer ! 170: * has committed the all-too common bug ! 171: * of adding a new operation to the layer's ! 172: * list of vnode operations but ! 173: * not adding the operation to the system-wide ! 174: * list of supported operations. ! 175: */ ! 176: if (opve_descp->opve_op->vdesc_offset == 0 && ! 177: opve_descp->opve_op->vdesc_offset != ! 178: VOFFSET(vop_default)) { ! 179: printf("operation %s not listed in %s.\n", ! 180: opve_descp->opve_op->vdesc_name, ! 181: "vfs_op_descs"); ! 182: panic ("vfs_opv_init: bad operation"); ! 183: } ! 184: /* ! 185: * Fill in this entry. ! 186: */ ! 187: opv_desc_vector[opve_descp->opve_op->vdesc_offset] = ! 188: opve_descp->opve_impl; ! 189: } ! 190: } ! 191: /* ! 192: * Finally, go back and replace unfilled routines ! 193: * with their default. (Sigh, an O(n^3) algorithm. I ! 194: * could make it better, but that'd be work, and n is small.) ! 195: */ ! 196: for (i = 0; vfs_opv_descs[i]; i++) { ! 197: opv_desc_vector = *(vfs_opv_descs[i]->opv_desc_vector_p); ! 198: /* ! 199: * Force every operations vector to have a default routine. ! 200: */ ! 201: if (opv_desc_vector[VOFFSET(vop_default)]==NULL) { ! 202: panic("vfs_opv_init: operation vector without default routine."); ! 203: } ! 204: for (k = 0; k<vfs_opv_numops; k++) ! 205: if (opv_desc_vector[k] == NULL) ! 206: opv_desc_vector[k] = ! 207: opv_desc_vector[VOFFSET(vop_default)]; ! 208: } ! 209: } ! 210: ! 211: /* ! 212: * Initialize known vnode operations vectors. ! 213: */ ! 214: void ! 215: vfs_op_init() ! 216: { ! 217: int i; ! 218: ! 219: DODEBUG(printf("Vnode_interface_init.\n")); ! 220: /* ! 221: * Set all vnode vectors to a well known value. ! 222: */ ! 223: for (i = 0; vfs_opv_descs[i]; i++) ! 224: *(vfs_opv_descs[i]->opv_desc_vector_p) = NULL; ! 225: /* ! 226: * Figure out how many ops there are by counting the table, ! 227: * and assign each its offset. ! 228: */ ! 229: for (vfs_opv_numops = 0, i = 0; vfs_op_descs[i]; i++) { ! 230: vfs_op_descs[i]->vdesc_offset = vfs_opv_numops; ! 231: vfs_opv_numops++; ! 232: } ! 233: DODEBUG(printf ("vfs_opv_numops=%d\n", vfs_opv_numops)); ! 234: } ! 235: ! 236: /* ! 237: * Routines having to do with the management of the vnode table. ! 238: */ ! 239: extern struct vnodeops dead_vnodeops; ! 240: extern struct vnodeops spec_vnodeops; ! 241: struct vattr va_null; ! 242: ! 243: /* ! 244: * Initialize the vnode structures and initialize each file system type. ! 245: */ ! 246: vfsinit() ! 247: { ! 248: struct vfsconf *vfsp; ! 249: int i, maxtypenum; ! 250: ! 251: /* ! 252: * Initialize the vnode table ! 253: */ ! 254: vntblinit(); ! 255: /* ! 256: * Initialize the vnode name cache ! 257: */ ! 258: nchinit(); ! 259: /* ! 260: * Build vnode operation vectors. ! 261: */ ! 262: vfs_op_init(); ! 263: vfs_opv_init(); /* finish the job */ ! 264: /* ! 265: * Initialize each file system type. ! 266: */ ! 267: vattr_null(&va_null); ! 268: numused_vfsslots = maxtypenum = 0; ! 269: for (vfsp = vfsconf, i = 0; i < maxvfsconf; i++, vfsp++) { ! 270: if (vfsp->vfc_vfsops == (struct vfsops *)0) ! 271: break; ! 272: if (i) vfsconf[i-1].vfc_next = vfsp; ! 273: if (maxtypenum <= vfsp->vfc_typenum) ! 274: maxtypenum = vfsp->vfc_typenum + 1; ! 275: (*vfsp->vfc_vfsops->vfs_init)(vfsp); ! 276: numused_vfsslots++; ! 277: } ! 278: /* next vfc_typenum to be used */ ! 279: maxvfsconf = maxtypenum; ! 280: } ! 281: ! 282: int vfsconf_add(struct vfsconf *nvfsp) ! 283: { ! 284: struct vfsconf *vfsp; ! 285: ! 286: if ((numused_vfsslots >= maxvfsslots) || (nvfsp == (struct vfsconf *)0)) ! 287: return (-1); ! 288: bcopy(nvfsp, vfsconf[numused_vfsslots], sizeof(struct vfsconf)); ! 289: vfsconf[numused_vfsslots-1].vfc_next = &vfsconf[numused_vfsslots]; ! 290: ! 291: if (nvfsp->vfc_typenum <= maxvfsconf ) ! 292: maxvfsconf = nvfsp->vfc_typenum + 1; ! 293: numused_vfsslots++; ! 294: if (nvfsp->vfc_vfsops->vfs_init) ! 295: (*nvfsp->vfc_vfsops->vfs_init)(nvfsp); ! 296: return(0); ! 297: } ! 298: ! 299: int vfsconf_del(char * fs_name) ! 300: { ! 301: return(-1); ! 302: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.