Annotation of sys/kern/vfs_init.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: vfs_init.c,v 1.19 2007/05/29 16:25:07 thib Exp $ */
! 2: /* $NetBSD: vfs_init.c,v 1.6 1996/02/09 19:00:58 christos Exp $ */
! 3:
! 4: /*
! 5: * Copyright (c) 1989, 1993
! 6: * The Regents of the University of California. All rights reserved.
! 7: *
! 8: * This code is derived from software contributed
! 9: * to Berkeley by John Heidemann of the UCLA Ficus project.
! 10: *
! 11: * Source: * @(#)i405_init.c 2.10 92/04/27 UCLA Ficus project
! 12: *
! 13: * Redistribution and use in source and binary forms, with or without
! 14: * modification, are permitted provided that the following conditions
! 15: * are met:
! 16: * 1. Redistributions of source code must retain the above copyright
! 17: * notice, this list of conditions and the following disclaimer.
! 18: * 2. Redistributions in binary form must reproduce the above copyright
! 19: * notice, this list of conditions and the following disclaimer in the
! 20: * documentation and/or other materials provided with the distribution.
! 21: * 3. Neither the name of the University nor the names of its contributors
! 22: * may be used to endorse or promote products derived from this software
! 23: * without specific prior written permission.
! 24: *
! 25: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
! 26: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
! 27: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
! 28: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
! 29: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
! 30: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
! 31: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 32: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
! 33: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
! 34: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
! 35: * SUCH DAMAGE.
! 36: *
! 37: * @(#)vfs_init.c 8.3 (Berkeley) 1/4/94
! 38: */
! 39:
! 40: #include <sys/param.h>
! 41: #include <sys/mount.h>
! 42: #include <sys/time.h>
! 43: #include <sys/vnode.h>
! 44: #include <sys/stat.h>
! 45: #include <sys/namei.h>
! 46: #include <sys/ucred.h>
! 47: #include <sys/buf.h>
! 48: #include <sys/errno.h>
! 49: #include <sys/malloc.h>
! 50: #include <sys/pool.h>
! 51: #include <sys/systm.h>
! 52:
! 53: /*
! 54: * Sigh, such primitive tools are these...
! 55: */
! 56: #if 0
! 57: #define DODEBUG(A) A
! 58: #else
! 59: #define DODEBUG(A)
! 60: #endif
! 61:
! 62: extern struct vnodeopv_desc *vfs_opv_descs[];
! 63: /* a list of lists of vnodeops defns */
! 64: extern struct vnodeop_desc *vfs_op_descs[];
! 65: /* and the operations they perform */
! 66: /*
! 67: * This code doesn't work if the defn is **vnodop_defns with cc.
! 68: * The problem is because of the compiler sometimes putting in an
! 69: * extra level of indirection for arrays. It's an interesting
! 70: * "feature" of C.
! 71: */
! 72: int vfs_opv_numops;
! 73:
! 74: typedef int (*PFI)(void *);
! 75:
! 76: /*
! 77: * A miscellaneous routine.
! 78: * A generic "default" routine that just returns an error.
! 79: */
! 80: /*ARGSUSED*/
! 81: int
! 82: vn_default_error(void *v)
! 83: {
! 84:
! 85: return (EOPNOTSUPP);
! 86: }
! 87:
! 88: /*
! 89: * vfs_init.c
! 90: *
! 91: * Allocate and fill in operations vectors.
! 92: *
! 93: * An undocumented feature of this approach to defining operations is that
! 94: * there can be multiple entries in vfs_opv_descs for the same operations
! 95: * vector. This allows third parties to extend the set of operations
! 96: * supported by another layer in a binary compatibile way. For example,
! 97: * assume that NFS needed to be modified to support Ficus. NFS has an entry
! 98: * (probably nfs_vnopdeop_decls) declaring all the operations NFS supports by
! 99: * default. Ficus could add another entry (ficus_nfs_vnodeop_decl_entensions)
! 100: * listing those new operations Ficus adds to NFS, all without modifying the
! 101: * NFS code. (Of couse, the OTW NFS protocol still needs to be munged, but
! 102: * that is a(whole)nother story.) This is a feature.
! 103: */
! 104:
! 105: /*
! 106: * Allocate and init the vector, if it needs it.
! 107: * Also handle backwards compatibility.
! 108: */
! 109: void
! 110: vfs_opv_init_explicit(struct vnodeopv_desc *vfs_opv_desc)
! 111: {
! 112: int (**opv_desc_vector)(void *);
! 113: struct vnodeopv_entry_desc *opve_descp;
! 114:
! 115: opv_desc_vector = *(vfs_opv_desc->opv_desc_vector_p);
! 116:
! 117: if (opv_desc_vector == NULL) {
! 118: /* XXX - shouldn't be M_VNODE */
! 119: opv_desc_vector = malloc(vfs_opv_numops * sizeof(PFI),
! 120: M_VNODE, M_WAITOK);
! 121: bzero(opv_desc_vector, vfs_opv_numops * sizeof(PFI));
! 122: *(vfs_opv_desc->opv_desc_vector_p) = opv_desc_vector;
! 123: DODEBUG(printf("vector at %p allocated\n",
! 124: opv_desc_vector));
! 125: }
! 126:
! 127: for (opve_descp = vfs_opv_desc->opv_desc_ops;
! 128: opve_descp->opve_op; opve_descp++) {
! 129: /*
! 130: * Sanity check: is this operation listed
! 131: * in the list of operations? We check this
! 132: * by seeing if its offset is zero. Since
! 133: * the default routine should always be listed
! 134: * first, it should be the only one with a zero
! 135: * offset. Any other operation with a zero
! 136: * offset is probably not listed in
! 137: * vfs_op_descs, and so is probably an error.
! 138: *
! 139: * A panic here means the layer programmer
! 140: * has committed the all-too common bug
! 141: * of adding a new operation to the layer's
! 142: * list of vnode operations but
! 143: * not adding the operation to the system-wide
! 144: * list of supported operations.
! 145: */
! 146: if (opve_descp->opve_op->vdesc_offset == 0 &&
! 147: opve_descp->opve_op->vdesc_offset != VOFFSET(vop_default)) {
! 148: printf("operation %s not listed in %s.\n",
! 149: opve_descp->opve_op->vdesc_name, "vfs_op_descs");
! 150: panic ("vfs_opv_init: bad operation");
! 151: }
! 152:
! 153: /*
! 154: * Fill in this entry.
! 155: */
! 156: opv_desc_vector[opve_descp->opve_op->vdesc_offset] =
! 157: opve_descp->opve_impl;
! 158: }
! 159: }
! 160:
! 161: void
! 162: vfs_opv_init_default(struct vnodeopv_desc *vfs_opv_desc)
! 163: {
! 164: int j;
! 165: int (**opv_desc_vector)(void *);
! 166:
! 167: opv_desc_vector = *(vfs_opv_desc->opv_desc_vector_p);
! 168:
! 169: /*
! 170: * Force every operations vector to have a default routine.
! 171: */
! 172: if (opv_desc_vector[VOFFSET(vop_default)] == NULL)
! 173: panic("vfs_opv_init: operation vector without default routine.");
! 174:
! 175: for (j = 0; j < vfs_opv_numops; j++)
! 176: if (opv_desc_vector[j] == NULL)
! 177: opv_desc_vector[j] =
! 178: opv_desc_vector[VOFFSET(vop_default)];
! 179: }
! 180:
! 181: void
! 182: vfs_opv_init(void)
! 183: {
! 184: int i;
! 185:
! 186: /*
! 187: * Allocate the dynamic vectors and fill them in.
! 188: */
! 189: for (i = 0; vfs_opv_descs[i]; i++)
! 190: vfs_opv_init_explicit(vfs_opv_descs[i]);
! 191:
! 192: /*
! 193: * Finally, go back and replace unfilled routines
! 194: * with their default.
! 195: */
! 196: for (i = 0; vfs_opv_descs[i]; i++)
! 197: vfs_opv_init_default(vfs_opv_descs[i]);
! 198: }
! 199:
! 200: /*
! 201: * Initialize known vnode operations vectors.
! 202: */
! 203: void
! 204: vfs_op_init(void)
! 205: {
! 206: int i;
! 207:
! 208: DODEBUG(printf("Vnode_interface_init.\n"));
! 209: /*
! 210: * Set all vnode vectors to a well known value.
! 211: */
! 212: for (i = 0; vfs_opv_descs[i]; i++)
! 213: *(vfs_opv_descs[i]->opv_desc_vector_p) = NULL;
! 214: /*
! 215: * Figure out how many ops there are by counting the table,
! 216: * and assign each its offset.
! 217: */
! 218: for (vfs_opv_numops = 0, i = 0; vfs_op_descs[i]; i++) {
! 219: vfs_op_descs[i]->vdesc_offset = vfs_opv_numops;
! 220: vfs_opv_numops++;
! 221: }
! 222: DODEBUG(printf ("vfs_opv_numops=%d\n", vfs_opv_numops));
! 223: }
! 224:
! 225: /*
! 226: * Routines having to do with the management of the vnode table.
! 227: */
! 228: struct pool namei_pool;
! 229:
! 230: /*
! 231: * Initialize the vnode structures and initialize each file system type.
! 232: */
! 233: void
! 234: vfsinit(void)
! 235: {
! 236: int i;
! 237: struct vfsconf *vfsconflist;
! 238: int vfsconflistlen;
! 239:
! 240: pool_init(&namei_pool, MAXPATHLEN, 0, 0, 0, "namei",
! 241: &pool_allocator_nointr);
! 242:
! 243: /*
! 244: * Initialize the vnode table
! 245: */
! 246: vntblinit();
! 247: /*
! 248: * Initialize the vnode name cache
! 249: */
! 250: nchinit();
! 251: /*
! 252: * Build vnode operation vectors.
! 253: */
! 254: vfs_op_init();
! 255: vfs_opv_init(); /* finish the job */
! 256:
! 257: /*
! 258: * Stop using vfsconf and maxvfsconf as a temporary storage,
! 259: * set them to their correct values now.
! 260: */
! 261: vfsconflist = vfsconf;
! 262: vfsconflistlen = maxvfsconf;
! 263: vfsconf = NULL;
! 264: maxvfsconf = 0;
! 265:
! 266: for (i = 0; i < vfsconflistlen; i++)
! 267: vfs_register(&vfsconflist[i]);
! 268: }
CVSweb