vfs_init.c revision 12569
190792Sgshapiro/* 294334Sgshapiro * Copyright (c) 1989, 1993 390792Sgshapiro * The Regents of the University of California. All rights reserved. 490792Sgshapiro * 590792Sgshapiro * This code is derived from software contributed 690792Sgshapiro * to Berkeley by John Heidemann of the UCLA Ficus project. 790792Sgshapiro * 890792Sgshapiro * Source: * @(#)i405_init.c 2.10 92/04/27 UCLA Ficus project 990792Sgshapiro * 1090792Sgshapiro * Redistribution and use in source and binary forms, with or without 1194334Sgshapiro * modification, are permitted provided that the following conditions 12168515Sgshapiro * are met: 1394334Sgshapiro * 1. Redistributions of source code must retain the above copyright 1490792Sgshapiro * notice, this list of conditions and the following disclaimer. 1590792Sgshapiro * 2. Redistributions in binary form must reproduce the above copyright 1690792Sgshapiro * notice, this list of conditions and the following disclaimer in the 1790792Sgshapiro * documentation and/or other materials provided with the distribution. 1890792Sgshapiro * 3. All advertising materials mentioning features or use of this software 1990792Sgshapiro * must display the following acknowledgement: 2090792Sgshapiro * This product includes software developed by the University of 2190792Sgshapiro * California, Berkeley and its contributors. 2290792Sgshapiro * 4. Neither the name of the University nor the names of its contributors 2390792Sgshapiro * may be used to endorse or promote products derived from this software 2490792Sgshapiro * without specific prior written permission. 2590792Sgshapiro * 2690792Sgshapiro * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 27243747Sume * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28243747Sume * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29243747Sume * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 30243747Sume * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31243747Sume * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32243747Sume * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33243747Sume * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34243747Sume * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35243747Sume * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3690792Sgshapiro * SUCH DAMAGE. 3790792Sgshapiro * 3890792Sgshapiro * @(#)vfs_init.c 8.3 (Berkeley) 1/4/94 3998121Sgshapiro * $Id: vfs_init.c,v 1.14 1995/11/20 12:42:09 phk Exp $ 4090792Sgshapiro */ 4190792Sgshapiro 4290792Sgshapiro 4390792Sgshapiro#include <sys/param.h> 4490792Sgshapiro#include <sys/systm.h> 4590792Sgshapiro#include <sys/kernel.h> 4690792Sgshapiro#include <sys/mount.h> 4790792Sgshapiro#include <sys/time.h> 4890792Sgshapiro#include <sys/vnode.h> 4990792Sgshapiro#include <sys/stat.h> 5090792Sgshapiro#include <sys/namei.h> 5190792Sgshapiro#include <sys/ucred.h> 5290792Sgshapiro#include <sys/buf.h> 5390792Sgshapiro#include <sys/errno.h> 5490792Sgshapiro#include <sys/malloc.h> 5590792Sgshapiro#include <sys/proc.h> 5690792Sgshapiro#include <vm/vm.h> 5790792Sgshapiro#include <sys/sysctl.h> 5890792Sgshapiro 59243747Sumestatic void vfsinit __P((void *)); 6090792SgshapiroSYSINIT(vfs, SI_SUB_VFS, SI_ORDER_FIRST, vfsinit, NULL) 6190792Sgshapiro 6290792Sgshapirovoid vfs_op_init __P((void)); 6390792Sgshapiro 6490792Sgshapiro/* 6590792Sgshapiro * Sigh, such primitive tools are these... 6690792Sgshapiro */ 6790792Sgshapiro#if 0 6890792Sgshapiro#define DODEBUG(A) A 6990792Sgshapiro#else 7090792Sgshapiro#define DODEBUG(A) 7190792Sgshapiro#endif 7290792Sgshapiro 7390792Sgshapirostruct vfsconf void_vfsconf; 7490792Sgshapiro 7590792Sgshapiroextern struct linker_set vfs_opv_descs_; 7690792Sgshapiro#define vfs_opv_descs ((struct vnodeopv_desc **)vfs_opv_descs_.ls_items) 7790792Sgshapiro 7890792Sgshapiroextern struct linker_set vfs_set; 7990792Sgshapirostruct vfsops *vfssw[MOUNT_MAXTYPE + 1]; 80243747Sumestruct vfsconf *vfsconf[MOUNT_MAXTYPE + 1]; 81243747Sume 8290792Sgshapiroextern struct vnodeop_desc *vfs_op_descs[]; 8390792Sgshapiro /* and the operations they perform */ 8490792Sgshapiro/* 8590792Sgshapiro * This code doesn't work if the defn is **vnodop_defns with cc. 8690792Sgshapiro * The problem is because of the compiler sometimes putting in an 8790792Sgshapiro * extra level of indirection for arrays. It's an interesting 8890792Sgshapiro * "feature" of C. 8990792Sgshapiro */ 9090792Sgshapiroint vfs_opv_numops; 9190792Sgshapiro 9290792Sgshapiro/* 9390792Sgshapiro * A miscellaneous routine. 9490792Sgshapiro * A generic "default" routine that just returns an error. 9590792Sgshapiro */ 9690792Sgshapiroint 9790792Sgshapirovn_default_error() 9890792Sgshapiro{ 9990792Sgshapiro 10090792Sgshapiro return (EOPNOTSUPP); 10190792Sgshapiro} 10290792Sgshapiro 10390792Sgshapiro/* 10490792Sgshapiro * vfs_init.c 10590792Sgshapiro * 10690792Sgshapiro * Allocate and fill in operations vectors. 10790792Sgshapiro * 108243747Sume * An undocumented feature of this approach to defining operations is that 10990792Sgshapiro * there can be multiple entries in vfs_opv_descs for the same operations 11090792Sgshapiro * vector. This allows third parties to extend the set of operations 11190792Sgshapiro * supported by another layer in a binary compatibile way. For example, 11290792Sgshapiro * assume that NFS needed to be modified to support Ficus. NFS has an entry 11390792Sgshapiro * (probably nfs_vnopdeop_decls) declaring all the operations NFS supports by 11490792Sgshapiro * default. Ficus could add another entry (ficus_nfs_vnodeop_decl_entensions) 11590792Sgshapiro * listing those new operations Ficus adds to NFS, all without modifying the 11690792Sgshapiro * NFS code. (Of couse, the OTW NFS protocol still needs to be munged, but 11790792Sgshapiro * that is a(whole)nother story.) This is a feature. 11890792Sgshapiro */ 11990792Sgshapirovoid 12090792Sgshapirovfs_opv_init(struct vnodeopv_desc **them) 12190792Sgshapiro{ 12290792Sgshapiro int i, j, k; 12390792Sgshapiro vop_t ***opv_desc_vector_p; 12490792Sgshapiro vop_t **opv_desc_vector; 12590792Sgshapiro struct vnodeopv_entry_desc *opve_descp; 12690792Sgshapiro 12790792Sgshapiro /* 12890792Sgshapiro * Allocate the dynamic vectors and fill them in. 12990792Sgshapiro */ 13090792Sgshapiro for (i=0; them[i]; i++) { 13190792Sgshapiro opv_desc_vector_p = them[i]->opv_desc_vector_p; 13290792Sgshapiro /* 13390792Sgshapiro * Allocate and init the vector, if it needs it. 13490792Sgshapiro * Also handle backwards compatibility. 13590792Sgshapiro */ 13690792Sgshapiro if (*opv_desc_vector_p == NULL) { 13790792Sgshapiro /* XXX - shouldn't be M_VNODE */ 13890792Sgshapiro MALLOC(*opv_desc_vector_p, vop_t **, 13990792Sgshapiro vfs_opv_numops * sizeof(vop_t *), M_VNODE, 14090792Sgshapiro M_WAITOK); 14190792Sgshapiro bzero(*opv_desc_vector_p, 14290792Sgshapiro vfs_opv_numops * sizeof(vop_t *)); 14390792Sgshapiro DODEBUG(printf("vector at %x allocated\n", 14490792Sgshapiro opv_desc_vector_p)); 14590792Sgshapiro } 14690792Sgshapiro opv_desc_vector = *opv_desc_vector_p; 14790792Sgshapiro for (j=0; them[i]->opv_desc_ops[j].opve_op; j++) { 14890792Sgshapiro opve_descp = &(them[i]->opv_desc_ops[j]); 14990792Sgshapiro 15090792Sgshapiro /* 15190792Sgshapiro * Sanity check: is this operation listed 15290792Sgshapiro * in the list of operations? We check this 15390792Sgshapiro * by seeing if its offest is zero. Since 15490792Sgshapiro * the default routine should always be listed 15590792Sgshapiro * first, it should be the only one with a zero 15690792Sgshapiro * offset. Any other operation with a zero 15790792Sgshapiro * offset is probably not listed in 15890792Sgshapiro * vfs_op_descs, and so is probably an error. 15990792Sgshapiro * 16090792Sgshapiro * A panic here means the layer programmer 16190792Sgshapiro * has committed the all-too common bug 16290792Sgshapiro * of adding a new operation to the layer's 16390792Sgshapiro * list of vnode operations but 16490792Sgshapiro * not adding the operation to the system-wide 16590792Sgshapiro * list of supported operations. 16690792Sgshapiro */ 16790792Sgshapiro if (opve_descp->opve_op->vdesc_offset == 0 && 16890792Sgshapiro opve_descp->opve_op->vdesc_offset != 16990792Sgshapiro VOFFSET(vop_default)) { 17090792Sgshapiro printf("operation %s not listed in %s.\n", 17190792Sgshapiro opve_descp->opve_op->vdesc_name, 17290792Sgshapiro "vfs_op_descs"); 17390792Sgshapiro panic ("vfs_opv_init: bad operation"); 17490792Sgshapiro } 17590792Sgshapiro /* 17690792Sgshapiro * Fill in this entry. 17790792Sgshapiro */ 17890792Sgshapiro opv_desc_vector[opve_descp->opve_op->vdesc_offset] = 17990792Sgshapiro opve_descp->opve_impl; 18090792Sgshapiro } 18190792Sgshapiro } 18290792Sgshapiro /* 18390792Sgshapiro * Finally, go back and replace unfilled routines 18490792Sgshapiro * with their default. (Sigh, an O(n^3) algorithm. I 18590792Sgshapiro * could make it better, but that'd be work, and n is small.) 18690792Sgshapiro */ 18790792Sgshapiro for (i = 0; them[i]; i++) { 18890792Sgshapiro opv_desc_vector = *(them[i]->opv_desc_vector_p); 18990792Sgshapiro /* 19090792Sgshapiro * Force every operations vector to have a default routine. 19190792Sgshapiro */ 19290792Sgshapiro if (opv_desc_vector[VOFFSET(vop_default)]==NULL) { 19390792Sgshapiro panic("vfs_opv_init: operation vector without default routine."); 19490792Sgshapiro } 19590792Sgshapiro for (k = 0; k<vfs_opv_numops; k++) 19690792Sgshapiro if (opv_desc_vector[k] == NULL) 19790792Sgshapiro opv_desc_vector[k] = 19890792Sgshapiro opv_desc_vector[VOFFSET(vop_default)]; 19990792Sgshapiro } 20090792Sgshapiro} 20190792Sgshapiro 20290792Sgshapiro/* 20390792Sgshapiro * Initialize known vnode operations vectors. 20490792Sgshapiro */ 20590792Sgshapirovoid 20690792Sgshapirovfs_op_init() 20790792Sgshapiro{ 20890792Sgshapiro int i; 20990792Sgshapiro 21090792Sgshapiro DODEBUG(printf("Vnode_interface_init.\n")); 21190792Sgshapiro /* 21290792Sgshapiro * Set all vnode vectors to a well known value. 21390792Sgshapiro */ 21498121Sgshapiro for (i = 0; vfs_opv_descs[i]; i++) 21598121Sgshapiro *(vfs_opv_descs[i]->opv_desc_vector_p) = NULL; 21698121Sgshapiro /* 217132943Sgshapiro * Figure out how many ops there are by counting the table, 21898121Sgshapiro * and assign each its offset. 21998121Sgshapiro */ 22098121Sgshapiro for (vfs_opv_numops = 0, i = 0; vfs_op_descs[i]; i++) { 22198121Sgshapiro vfs_op_descs[i]->vdesc_offset = vfs_opv_numops; 22298121Sgshapiro vfs_opv_numops++; 22398121Sgshapiro } 22498121Sgshapiro DODEBUG(printf ("vfs_opv_numops=%d\n", vfs_opv_numops)); 22598121Sgshapiro} 22698121Sgshapiro 22798121Sgshapiro/* 22898121Sgshapiro * Routines having to do with the management of the vnode table. 22998121Sgshapiro */ 23098121Sgshapiroextern struct vnodeops dead_vnodeops; 23198121Sgshapiroextern struct vnodeops spec_vnodeops; 23298121Sgshapiroextern void vclean(); 23398121Sgshapirostruct vattr va_null; 23498121Sgshapiro 23598121Sgshapiro/* 23698121Sgshapiro * Initialize the vnode structures and initialize each file system type. 23798121Sgshapiro */ 23898121Sgshapiro/* ARGSUSED*/ 23998121Sgshapirostatic void 24098121Sgshapirovfsinit(dummy) 24198121Sgshapiro void *dummy; 24298121Sgshapiro{ 24398121Sgshapiro struct vfsops **vfsp; 24498121Sgshapiro struct vfsconf **vfc; 24598121Sgshapiro int i; 24698121Sgshapiro 24798121Sgshapiro /* 24898121Sgshapiro * Initialize the VFS switch table 24998121Sgshapiro */ 250141858Sgshapiro for(i = 0; i < MOUNT_MAXTYPE + 1; i++) { 251141858Sgshapiro vfsconf[i] = &void_vfsconf; 252141858Sgshapiro } 25398121Sgshapiro 25498121Sgshapiro vfc = (struct vfsconf **)vfs_set.ls_items; 25598121Sgshapiro while(*vfc) { 25698121Sgshapiro vfssw[(**vfc).vfc_index] = (**vfc).vfc_vfsops; 25798121Sgshapiro vfsconf[(**vfc).vfc_index] = *vfc; 25898121Sgshapiro vfc++; 25998121Sgshapiro } 26098121Sgshapiro 261141858Sgshapiro /* 262141858Sgshapiro * Initialize the vnode table 263141858Sgshapiro */ 264141858Sgshapiro vntblinit(); 265141858Sgshapiro /* 26698121Sgshapiro * Initialize the vnode name cache 267168515Sgshapiro */ 26898121Sgshapiro nchinit(); 26998121Sgshapiro /* 27098121Sgshapiro * Build vnode operation vectors. 27198121Sgshapiro */ 27298121Sgshapiro vfs_op_init(); 27398121Sgshapiro vfs_opv_init(vfs_opv_descs); /* finish the job */ 27498121Sgshapiro /* 27598841Sgshapiro * Initialize each file system type. 27698841Sgshapiro */ 27798121Sgshapiro vattr_null(&va_null); 27898841Sgshapiro for (vfsp = &vfssw[0]; vfsp <= &vfssw[MOUNT_MAXTYPE]; vfsp++) { 27998121Sgshapiro if (*vfsp == NULL) 28098121Sgshapiro continue; 281168515Sgshapiro (*(*vfsp)->vfs_init)(); 28298121Sgshapiro } 28398121Sgshapiro} 28498121Sgshapiro 28598121Sgshapiro/* 28698121Sgshapiro * kernel related system variables. 28798121Sgshapiro */ 28898121Sgshapiro 28998121Sgshapirostatic int 29098121Sgshapirosysctl_fs_vfsconf SYSCTL_HANDLER_ARGS 29198121Sgshapiro{ 29298121Sgshapiro int i, error; 29390792Sgshapiro 294 if (req->newptr) 295 return EINVAL; 296 for(i = 0; i < MOUNT_MAXTYPE + 1; i++) { 297 error = SYSCTL_OUT(req, vfsconf[i], sizeof *vfsconf[i]); 298 if(error) 299 return error; 300 } 301 return (error); 302 303} 304 305SYSCTL_PROC(_fs, FS_VFSCONF, vfsconf, CTLTYPE_OPAQUE|CTLFLAG_RD, 306 0, 0, sysctl_fs_vfsconf, ""); 307 308/* 309 * This goop is here to support a loadable NFS module... grumble... 310 */ 311void (*lease_check) __P((struct vnode *, struct proc *, struct ucred *, int)) 312 = 0; 313void (*lease_updatetime) __P((int)) 314 = 0; 315 316