Deleted Added
full compact
vfs_init.c (39975) vfs_init.c (40435)
1/*
2 * Copyright (c) 1989, 1993
3 * The Regents of the University of California. 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

--- 22 unchanged lines hidden (view full) ---

31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * SUCH DAMAGE.
37 *
38 * @(#)vfs_init.c 8.3 (Berkeley) 1/4/94
1/*
2 * Copyright (c) 1989, 1993
3 * The Regents of the University of California. 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

--- 22 unchanged lines hidden (view full) ---

31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * SUCH DAMAGE.
37 *
38 * @(#)vfs_init.c 8.3 (Berkeley) 1/4/94
39 * $Id: vfs_init.c,v 1.33 1998/09/05 17:13:27 bde Exp $
39 * $Id: vfs_init.c,v 1.34 1998/10/05 11:10:55 obrien Exp $
40 */
41
42
43#include <sys/param.h>
44#include <sys/systm.h>
45#include <sys/kernel.h>
46#include <sys/mount.h>
47#include <sys/sysctl.h>

--- 14 unchanged lines hidden (view full) ---

62#if 0
63#define DODEBUG(A) A
64#else
65#define DODEBUG(A)
66#endif
67
68static struct vfsconf void_vfsconf;
69
40 */
41
42
43#include <sys/param.h>
44#include <sys/systm.h>
45#include <sys/kernel.h>
46#include <sys/mount.h>
47#include <sys/sysctl.h>

--- 14 unchanged lines hidden (view full) ---

62#if 0
63#define DODEBUG(A) A
64#else
65#define DODEBUG(A)
66#endif
67
68static struct vfsconf void_vfsconf;
69
70#ifdef unused
70extern struct linker_set vfs_opv_descs_;
71#define vfs_opv_descs ((struct vnodeopv_desc **)vfs_opv_descs_.ls_items)
71extern struct linker_set vfs_opv_descs_;
72#define vfs_opv_descs ((struct vnodeopv_desc **)vfs_opv_descs_.ls_items)
73#endif
72
74
73extern struct linker_set vfs_set;
74
75extern struct vnodeop_desc *vfs_op_descs[];
76 /* and the operations they perform */
77
78/*
75extern struct vnodeop_desc *vfs_op_descs[];
76 /* and the operations they perform */
77
78/*
79 * XXX this bloat just exands the sysctl__vfs linker set a little so that
80 * we can attach sysctls for VFS modules without expanding the linker set.
81 * Currently (1998/09/06), only one VFS uses sysctls, so 2 extra linker
82 * set slots are more than sufficient.
83 */
84extern struct linker_set sysctl__vfs;
85static int mod_xx;
86SYSCTL_INT(_vfs, OID_AUTO, mod0, CTLFLAG_RD, &mod_xx, 0, "");
87SYSCTL_INT(_vfs, OID_AUTO, mod1, CTLFLAG_RD, &mod_xx, 0, "");
88
89/*
79 * Zone for namei
80 */
81struct vm_zone *namei_zone;
82
83/*
84 * vfs_init.c
85 *
86 * Allocate and fill in operations vectors.

--- 11 unchanged lines hidden (view full) ---

98 *
99 * Without an explicit reserve area, however, you must replace vnode_if.c
100 * and vnode_if.h when you do this, or you will be derefrencing of the
101 * end of vfs_op_descs[]. This is a flaw in the use of a structure
102 * pointer array rather than an agregate to define vfs_op_descs. So
103 * it's not a very dynamic "feature".
104 */
105void
90 * Zone for namei
91 */
92struct vm_zone *namei_zone;
93
94/*
95 * vfs_init.c
96 *
97 * Allocate and fill in operations vectors.

--- 11 unchanged lines hidden (view full) ---

109 *
110 * Without an explicit reserve area, however, you must replace vnode_if.c
111 * and vnode_if.h when you do this, or you will be derefrencing of the
112 * end of vfs_op_descs[]. This is a flaw in the use of a structure
113 * pointer array rather than an agregate to define vfs_op_descs. So
114 * it's not a very dynamic "feature".
115 */
116void
106vfs_opv_init(struct vnodeopv_desc **them)
117vfs_opv_init(struct vnodeopv_desc *opv)
107{
118{
108 int i, j, k;
119 int j, k;
109 vop_t ***opv_desc_vector_p;
110 vop_t **opv_desc_vector;
111 struct vnodeopv_entry_desc *opve_descp;
112
113 /*
114 * Allocate the dynamic vectors and fill them in.
115 */
120 vop_t ***opv_desc_vector_p;
121 vop_t **opv_desc_vector;
122 struct vnodeopv_entry_desc *opve_descp;
123
124 /*
125 * Allocate the dynamic vectors and fill them in.
126 */
116 for (i=0; them[i]; i++) {
117 opv_desc_vector_p = them[i]->opv_desc_vector_p;
127 opv_desc_vector_p = opv->opv_desc_vector_p;
128 /*
129 * Allocate and init the vector, if it needs it.
130 * Also handle backwards compatibility.
131 */
132 if (*opv_desc_vector_p == NULL) {
133 /* XXX - shouldn't be M_VNODE */
134 MALLOC(*opv_desc_vector_p, vop_t **,
135 vfs_opv_numops * sizeof(vop_t *), M_VNODE,
136 M_WAITOK);
137 bzero(*opv_desc_vector_p,
138 vfs_opv_numops * sizeof(vop_t *));
139 DODEBUG(printf("vector at %x allocated\n",
140 opv_desc_vector_p));
141 }
142 opv_desc_vector = *opv_desc_vector_p;
143 for (j = 0; opv->opv_desc_ops[j].opve_op; j++) {
144 opve_descp = &(opv->opv_desc_ops[j]);
145
118 /*
146 /*
119 * Allocate and init the vector, if it needs it.
120 * Also handle backwards compatibility.
147 * Sanity check: is this operation listed
148 * in the list of operations? We check this
149 * by seeing if its offest is zero. Since
150 * the default routine should always be listed
151 * first, it should be the only one with a zero
152 * offset. Any other operation with a zero
153 * offset is probably not listed in
154 * vfs_op_descs, and so is probably an error.
155 *
156 * A panic here means the layer programmer
157 * has committed the all-too common bug
158 * of adding a new operation to the layer's
159 * list of vnode operations but
160 * not adding the operation to the system-wide
161 * list of supported operations.
121 */
162 */
122 if (*opv_desc_vector_p == NULL) {
123 /* XXX - shouldn't be M_VNODE */
124 MALLOC(*opv_desc_vector_p, vop_t **,
125 vfs_opv_numops * sizeof(vop_t *), M_VNODE,
126 M_WAITOK);
127 bzero(*opv_desc_vector_p,
128 vfs_opv_numops * sizeof(vop_t *));
129 DODEBUG(printf("vector at %x allocated\n",
130 opv_desc_vector_p));
163 if (opve_descp->opve_op->vdesc_offset == 0 &&
164 opve_descp->opve_op->vdesc_offset !=
165 VOFFSET(vop_default)) {
166 printf("operation %s not listed in %s.\n",
167 opve_descp->opve_op->vdesc_name,
168 "vfs_op_descs");
169 panic ("vfs_opv_init: bad operation");
131 }
170 }
132 opv_desc_vector = *opv_desc_vector_p;
133 for (j=0; them[i]->opv_desc_ops[j].opve_op; j++) {
134 opve_descp = &(them[i]->opv_desc_ops[j]);
135
136 /*
137 * Sanity check: is this operation listed
138 * in the list of operations? We check this
139 * by seeing if its offest is zero. Since
140 * the default routine should always be listed
141 * first, it should be the only one with a zero
142 * offset. Any other operation with a zero
143 * offset is probably not listed in
144 * vfs_op_descs, and so is probably an error.
145 *
146 * A panic here means the layer programmer
147 * has committed the all-too common bug
148 * of adding a new operation to the layer's
149 * list of vnode operations but
150 * not adding the operation to the system-wide
151 * list of supported operations.
152 */
153 if (opve_descp->opve_op->vdesc_offset == 0 &&
154 opve_descp->opve_op->vdesc_offset !=
155 VOFFSET(vop_default)) {
156 printf("operation %s not listed in %s.\n",
157 opve_descp->opve_op->vdesc_name,
158 "vfs_op_descs");
159 panic ("vfs_opv_init: bad operation");
160 }
161 /*
162 * Fill in this entry.
163 */
164 opv_desc_vector[opve_descp->opve_op->vdesc_offset] =
165 opve_descp->opve_impl;
166 }
171 /*
172 * Fill in this entry.
173 */
174 opv_desc_vector[opve_descp->opve_op->vdesc_offset] =
175 opve_descp->opve_impl;
167 }
168 /*
169 * Finally, go back and replace unfilled routines
170 * with their default. (Sigh, an O(n^3) algorithm. I
171 * could make it better, but that'd be work, and n is small.)
172 */
176 }
177 /*
178 * Finally, go back and replace unfilled routines
179 * with their default. (Sigh, an O(n^3) algorithm. I
180 * could make it better, but that'd be work, and n is small.)
181 */
173 for (i = 0; them[i]; i++) {
174 opv_desc_vector = *(them[i]->opv_desc_vector_p);
175 /*
176 * Force every operations vector to have a default routine.
177 */
178 if (opv_desc_vector[VOFFSET(vop_default)]==NULL) {
179 panic("vfs_opv_init: operation vector without default routine.");
180 }
181 for (k = 0; k<vfs_opv_numops; k++)
182 if (opv_desc_vector[k] == NULL)
183 opv_desc_vector[k] =
184 opv_desc_vector[VOFFSET(vop_default)];
182 opv_desc_vector = *(opv->opv_desc_vector_p);
183 /*
184 * Force every operations vector to have a default routine.
185 */
186 if (opv_desc_vector[VOFFSET(vop_default)]==NULL) {
187 panic("vfs_opv_init: operation vector without default routine.");
185 }
188 }
189 for (k = 0; k<vfs_opv_numops; k++)
190 if (opv_desc_vector[k] == NULL)
191 opv_desc_vector[k] =
192 opv_desc_vector[VOFFSET(vop_default)];
186}
187
188/*
189 * Initialize known vnode operations vectors.
190 */
191static void
192vfs_op_init()
193{
194 int i;
195
196 DODEBUG(printf("Vnode_interface_init.\n"));
197 DODEBUG(printf ("vfs_opv_numops=%d\n", vfs_opv_numops));
193}
194
195/*
196 * Initialize known vnode operations vectors.
197 */
198static void
199vfs_op_init()
200{
201 int i;
202
203 DODEBUG(printf("Vnode_interface_init.\n"));
204 DODEBUG(printf ("vfs_opv_numops=%d\n", vfs_opv_numops));
205#ifdef unused
198 /*
199 * Set all vnode vectors to a well known value.
200 */
201 for (i = 0; vfs_opv_descs[i]; i++)
202 *(vfs_opv_descs[i]->opv_desc_vector_p) = NULL;
206 /*
207 * Set all vnode vectors to a well known value.
208 */
209 for (i = 0; vfs_opv_descs[i]; i++)
210 *(vfs_opv_descs[i]->opv_desc_vector_p) = NULL;
211#endif
203 /*
204 * assign each op to its offset
205 *
206 * XXX This should not be needed, but is because the per
207 * XXX FS ops tables are not sorted according to the
208 * XXX vnodeop_desc's offset in vfs_op_descs. This
209 * XXX is the same reason we have to take the hit for
210 * XXX the static inline function calls instead of using
211 * XXX simple macro references.
212 */
213 for (i = 0; i < vfs_opv_numops; i++)
214 vfs_op_descs[i]->vdesc_offset = i;
212 /*
213 * assign each op to its offset
214 *
215 * XXX This should not be needed, but is because the per
216 * XXX FS ops tables are not sorted according to the
217 * XXX vnodeop_desc's offset in vfs_op_descs. This
218 * XXX is the same reason we have to take the hit for
219 * XXX the static inline function calls instead of using
220 * XXX simple macro references.
221 */
222 for (i = 0; i < vfs_opv_numops; i++)
223 vfs_op_descs[i]->vdesc_offset = i;
224#ifdef unused
225 /* Finish the job */
226 for (i = 0; vfs_opv_descs[i]; i++)
227 vfs_opv_init(vfs_opv_descs[i]);
228#endif
215}
216
217/*
218 * Routines having to do with the management of the vnode table.
219 */
220extern struct vnodeops dead_vnodeops;
221extern struct vnodeops spec_vnodeops;
222struct vattr va_null;

--- 18 unchanged lines hidden (view full) ---

241 /*
242 * Initialize the vnode name cache
243 */
244 nchinit();
245 /*
246 * Build vnode operation vectors.
247 */
248 vfs_op_init();
229}
230
231/*
232 * Routines having to do with the management of the vnode table.
233 */
234extern struct vnodeops dead_vnodeops;
235extern struct vnodeops spec_vnodeops;
236struct vattr va_null;

--- 18 unchanged lines hidden (view full) ---

255 /*
256 * Initialize the vnode name cache
257 */
258 nchinit();
259 /*
260 * Build vnode operation vectors.
261 */
262 vfs_op_init();
249 vfs_opv_init(vfs_opv_descs); /* finish the job */
250 /*
251 * Initialize each file system type.
252 * Vfs type numbers must be distinct from VFS_GENERIC (and VFS_VFSCONF).
253 */
254 vattr_null(&va_null);
263 /*
264 * Initialize each file system type.
265 * Vfs type numbers must be distinct from VFS_GENERIC (and VFS_VFSCONF).
266 */
267 vattr_null(&va_null);
255 maxtypenum = VFS_GENERIC + 1;
256 vfc = (struct vfsconf **)vfs_set.ls_items;
257 vfsconf = *vfc;
258 for (; *vfc != NULL; maxtypenum++, vfc++) {
259 vfsp = *vfc;
260 vfsp->vfc_next = *(vfc + 1);
261 vfsp->vfc_typenum = maxtypenum;
262 if (vfsp->vfc_vfsops->vfs_oid != NULL) {
263 vfsp->vfc_vfsops->vfs_oid->oid_number = maxtypenum;
264 sysctl_order_all();
268 maxvfsconf = VFS_GENERIC + 1;
269}
270
271int
272vfs_register(vfc)
273 struct vfsconf *vfc;
274{
275 struct linker_set *l;
276 struct sysctl_oid **oidpp;
277 struct vfsconf *vfsp;
278 int error, i, maxtypenum, exists;
279
280 vfsp = NULL;
281 exists = 0;
282 l = &sysctl__vfs;
283 if (vfsconf)
284 for (vfsp = vfsconf; vfsp->vfc_next; vfsp = vfsp->vfc_next)
285 if (!strcmp(vfc->vfc_name, vfsp->vfc_name))
286 return EEXIST;
287
288 vfc->vfc_typenum = maxvfsconf++;
289 if (vfc->vfc_vfsops->vfs_oid != NULL) {
290 oidpp = (struct sysctl_oid **)l->ls_items;
291 for (i = l->ls_length; i-- && !exists; oidpp++)
292 if (*oidpp == vfc->vfc_vfsops->vfs_oid)
293 exists = 1;
294 }
295 if (exists == 0 && vfc->vfc_vfsops->vfs_oid != NULL) {
296 oidpp = (struct sysctl_oid **)l->ls_items;
297 for (i = l->ls_length; i--; oidpp++) {
298 if (*oidpp == NULL ||
299 *oidpp == &sysctl___vfs_mod0 ||
300 *oidpp == &sysctl___vfs_mod1) {
301 *oidpp = vfc->vfc_vfsops->vfs_oid;
302 (*oidpp)->oid_number = vfc->vfc_typenum;
303 sysctl_order_all();
304 break;
305 }
265 }
306 }
266 (*vfsp->vfc_vfsops->vfs_init)(vfsp);
267 }
307 }
268 /* next vfc_typenum to be used */
269 maxvfsconf = maxtypenum;
308 if (vfsp)
309 vfsp->vfc_next = vfc;
310 else
311 vfsconf = vfc;
312 vfc->vfc_next = NULL;
313
314 /*
315 * Call init function for this VFS...
316 */
317 (*(vfc->vfc_vfsops->vfs_init))(vfc);
318
319 return 0;
270}
271
320}
321
322
323/*
324 * To be called at SI_SUB_VFS, SECOND, for each VFS before any are registered.
325 */
326void
327vfs_mod_opv_init(handle)
328 void *handle;
329{
330 int i;
331 struct vnodeopv_desc *opv;
332
333 opv = (struct vnodeopv_desc *)handle;
334 *(opv->opv_desc_vector_p) = NULL;
335 vfs_opv_init(opv);
336}
337
338int
339vfs_unregister(vfc)
340 struct vfsconf *vfc;
341{
342 struct linker_set *l;
343 struct sysctl_oid **oidpp;
344 struct vfsconf *vfsp, *prev_vfsp;
345 int error, i, maxtypenum;
346
347 i = vfc->vfc_typenum;
348
349 prev_vfsp = NULL;
350 for (vfsp = vfsconf; vfsp;
351 prev_vfsp = vfsp, vfsp = vfsp->vfc_next) {
352 if (!strcmp(vfc->vfc_name, vfsp->vfc_name))
353 break;
354 }
355 if (vfsp == NULL)
356 return EINVAL;
357 if (vfsp->vfc_refcount)
358 return EBUSY;
359 if (vfc->vfc_vfsops->vfs_uninit != NULL) {
360 error = (*vfc->vfc_vfsops->vfs_uninit)(vfsp);
361 if (error)
362 return (error);
363 }
364 if (prev_vfsp)
365 prev_vfsp->vfc_next = vfsp->vfc_next;
366 else
367 vfsconf = vfsp->vfc_next;
368 if (vfsp->vfc_vfsops->vfs_oid != NULL) {
369 l = &sysctl__vfs;
370 for (i = l->ls_length,
371 oidpp = (struct sysctl_oid **)l->ls_items;
372 i--; oidpp++) {
373 if (*oidpp == vfsp->vfc_vfsops->vfs_oid) {
374 *oidpp = NULL;
375 sysctl_order_all();
376 break;
377 }
378 }
379 }
380 maxtypenum = VFS_GENERIC;
381 for (vfsp = vfsconf; vfsp != NULL; vfsp = vfsp->vfc_next)
382 if (maxtypenum < vfsp->vfc_typenum)
383 maxtypenum = vfsp->vfc_typenum;
384 maxvfsconf = maxtypenum + 1;
385 return 0;
386}