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