check for negative bytes in seguse update; increment version number
[unix-history] / usr / src / sys / kern / vfs_init.c
CommitLineData
81461cae
KM
1/*
2 * Copyright (c) 1989 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed
6 * to Berkeley by John Heidemann of the UCLA Ficus project.
7 *
8 * Source: * @(#)i405_init.c 2.10 92/04/27 UCLA Ficus project
9 *
10 * %sccs.include.redist.c%
11 *
6c5694d2 12 * @(#)vfs_init.c 7.4 (Berkeley) %G%
81461cae
KM
13 */
14
15
16#include <sys/param.h>
17#include <sys/mount.h>
18#include <sys/time.h>
19#include <sys/vnode.h>
20#include <sys/stat.h>
81461cae
KM
21#include <sys/namei.h>
22#include <sys/ucred.h>
23#include <sys/buf.h>
24#include <sys/errno.h>
25#include <sys/malloc.h>
26
226cc7ed
KM
27/*
28 * Sigh, such primitive tools are these...
29 */
81461cae
KM
30#if 0
31#define DODEBUG(A) A
32#else
33#define DODEBUG(A)
34#endif
35
81461cae
KM
36extern struct vnodeopv_desc *vfs_opv_descs[];
37 /* a list of lists of vnodeops defns */
38extern struct vnodeop_desc *vfs_op_descs[];
39 /* and the operations they perform */
40/*
41 * This code doesn't work if the defn is **vnodop_defns with cc.
42 * The problem is because of the compiler sometimes putting in an
43 * extra level of indirection for arrays. It's an interesting
44 * "feature" of C.
45 */
46int vfs_opv_numops;
47
48typedef (*PFI)(); /* the standard Pointer to a Function returning an Int */
49
81461cae
KM
50/*
51 * A miscellaneous routine.
52 * A generic "default" routine that just returns an error.
53 */
54int
55vn_default_error()
56{
81461cae 57
226cc7ed
KM
58 return (EOPNOTSUPP);
59}
81461cae
KM
60
61/*
62 * vfs_init.c
63 *
64 * Allocate and fill in operations vectors.
65 *
226cc7ed
KM
66 * An undocumented feature of this approach to defining operations is that
67 * there can be multiple entries in vfs_opv_descs for the same operations
68 * vector. This allows third parties to extend the set of operations
69 * supported by another layer in a binary compatibile way. For example,
70 * assume that NFS needed to be modified to support Ficus. NFS has an entry
71 * (probably nfs_vnopdeop_decls) declaring all the operations NFS supports by
72 * default. Ficus could add another entry (ficus_nfs_vnodeop_decl_entensions)
73 * listing those new operations Ficus adds to NFS, all without modifying the
74 * NFS code. (Of couse, the OTW NFS protocol still needs to be munged, but
75 * that is a(whole)nother story.) This is a feature.
81461cae 76 */
81461cae
KM
77void
78vfs_opv_init()
79{
80 int i, j, k;
81 struct vnodeop_defn *defnp;
82 int (***opv_desc_vector_p)();
83 int (**opv_desc_vector)();
84 struct vnodeopv_entry_desc *opve_descp;
85
86 /*
87 * Allocate the dynamic vectors and fill them in.
88 */
89 for (i=0; vfs_opv_descs[i]; i++) {
90 opv_desc_vector_p = vfs_opv_descs[i]->opv_desc_vector_p;
91 /*
92 * Allocate and init the vector, if it needs it.
93 * Also handle backwards compatibility.
94 */
95 if (*opv_desc_vector_p == NULL) {
96 /* XXX - shouldn't be M_VNODE */
97 MALLOC(*opv_desc_vector_p, PFI*,
98 vfs_opv_numops*sizeof(PFI), M_VNODE, M_WAITOK);
99 bzero (*opv_desc_vector_p, vfs_opv_numops*sizeof(PFI));
226cc7ed
KM
100 DODEBUG(printf("vector at %x allocated\n",
101 opv_desc_vector_p));
102 }
81461cae
KM
103 opv_desc_vector = *opv_desc_vector_p;
104 for (j=0; vfs_opv_descs[i]->opv_desc_ops[j].opve_op; j++) {
105 opve_descp = &(vfs_opv_descs[i]->opv_desc_ops[j]);
106
107 /*
108 * Sanity check: is this operation listed
109 * in the list of operations? We check this
110 * by seeing if its offest is zero. Since
111 * the default routine should always be listed
112 * first, it should be the only one with a zero
113 * offset. Any other operation with a zero
114 * offset is probably not listed in
226cc7ed 115 * vfs_op_descs, and so is probably an error.
81461cae
KM
116 *
117 * A panic here means the layer programmer
118 * has committed the all-too common bug
119 * of adding a new operation to the layer's
120 * list of vnode operations but
121 * not adding the operation to the system-wide
122 * list of supported operations.
123 */
124 if (opve_descp->opve_op->vdesc_offset == 0 &&
125 opve_descp->opve_op->vdesc_offset !=
126 VOFFSET(vop_default)) {
226cc7ed
KM
127 printf("operation %s not listed in %s.\n",
128 opve_descp->opve_op->vdesc_name,
129 "vfs_op_descs");
81461cae 130 panic ("vfs_opv_init: bad operation");
226cc7ed 131 }
81461cae
KM
132 /*
133 * Fill in this entry.
134 */
226cc7ed 135 opv_desc_vector[opve_descp->opve_op->vdesc_offset] =
81461cae 136 opve_descp->opve_impl;
226cc7ed
KM
137 }
138 }
81461cae
KM
139 /*
140 * Finally, go back and replace unfilled routines
141 * with their default. (Sigh, an O(n^3) algorithm. I
142 * could make it better, but that'd be work, and n is small.)
143 */
226cc7ed 144 for (i = 0; vfs_opv_descs[i]; i++) {
81461cae
KM
145 opv_desc_vector = *(vfs_opv_descs[i]->opv_desc_vector_p);
146 /*
147 * Force every operations vector to have a default routine.
148 */
149 if (opv_desc_vector[VOFFSET(vop_default)]==NULL) {
150 panic("vfs_opv_init: operation vector without default routine.");
226cc7ed
KM
151 }
152 for (k = 0; k<vfs_opv_numops; k++)
81461cae
KM
153 if (opv_desc_vector[k] == NULL)
154 opv_desc_vector[k] =
155 opv_desc_vector[VOFFSET(vop_default)];
226cc7ed 156 }
81461cae
KM
157}
158
226cc7ed
KM
159/*
160 * Initialize known vnode operations vectors.
161 */
81461cae
KM
162void
163vfs_op_init()
164{
165 int i, j;
166
226cc7ed 167 DODEBUG(printf("Vnode_interface_init.\n"));
81461cae
KM
168 /*
169 * Set all vnode vectors to a well known value.
170 */
226cc7ed 171 for (i = 0; vfs_opv_descs[i]; i++)
81461cae 172 *(vfs_opv_descs[i]->opv_desc_vector_p) = NULL;
81461cae
KM
173 /*
174 * Figure out how many ops there are by counting the table,
175 * and assign each its offset.
176 */
226cc7ed 177 for (vfs_opv_numops = 0, i = 0; vfs_op_descs[i]; i++) {
81461cae
KM
178 vfs_op_descs[i]->vdesc_offset = vfs_opv_numops;
179 vfs_opv_numops++;
226cc7ed 180 }
81461cae
KM
181 DODEBUG(printf ("vfs_opv_numops=%d\n", vfs_opv_numops));
182}
183
81461cae
KM
184/*
185 * Routines having to do with the management of the vnode table.
186 */
81461cae
KM
187extern struct vnodeops dead_vnodeops;
188extern struct vnodeops spec_vnodeops;
189extern void vclean();
190struct vattr va_null;
191
192/*
193 * Initialize the vnode structures and initialize each file system type.
194 */
195vfsinit()
196{
197 struct vfsops **vfsp;
198
199 /*
200 * Initialize the vnode name cache
201 */
202 nchinit();
203 /*
204 * Build vnode operation vectors.
205 */
206 vfs_op_init();
207 vfs_opv_init(); /* finish the job */
208 /*
209 * Initialize each file system type.
210 */
211 vattr_null(&va_null);
212 for (vfsp = &vfssw[0]; vfsp <= &vfssw[MOUNT_MAXTYPE]; vfsp++) {
213 if (*vfsp == NULL)
214 continue;
215 (*(*vfsp)->vfs_init)();
216 }
217}