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} |
|