Annotation of kernel/bsd/vfs/vfs_init.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.