summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>1998-11-10 09:04:09 +0000
committerpeter <peter@FreeBSD.org>1998-11-10 09:04:09 +0000
commite2cbb31311dcb5aad532570f7dffd777a8408ff1 (patch)
tree6100304ba9db8f31f528cba0b8c097a47549fe8f
parentb8784ef1750330bf06be7cd66106d137faba55b7 (diff)
downloadFreeBSD-src-e2cbb31311dcb5aad532570f7dffd777a8408ff1.zip
FreeBSD-src-e2cbb31311dcb5aad532570f7dffd777a8408ff1.tar.gz
Make the vnode opv vector construction fully dynamic. Previously we
leaked memory on each unload and were limited to items referenced in the kernel copy of vnode_if.c. Now a kernel module is free to create it's own VOP_FOO() routines and the rest of the system will happily deal with it, including passthrough layers like union/umap/etc. Have VFS_SET() call a common vfs_modevent() handler rather than inline duplicating the common code all over the place. Have VNODEOP_SET() have the vnodeops removed at unload time (assuming a module) so that the vop_t ** vector is reclaimed. Slightly adjust the vop_t ** vectors so that calling slot 0 is a panic rather than a page fault. This could happen if VOP_something() was called without *any* handlers being present anywhere (including in vfs_default.c). slot 1 becomes the default vector for the vnodeop table. TODO: reclaim zones on unload (eg: nfs code)
-rw-r--r--sys/kern/vfs_default.c7
-rw-r--r--sys/kern/vfs_init.c348
-rw-r--r--sys/kern/vnode_if.pl40
-rw-r--r--sys/kern/vnode_if.sh40
-rw-r--r--sys/sys/mount.h52
-rw-r--r--sys/sys/vnode.h10
-rw-r--r--sys/tools/vnode_if.awk40
7 files changed, 257 insertions, 280 deletions
diff --git a/sys/kern/vfs_default.c b/sys/kern/vfs_default.c
index 538cbc0..47545c3 100644
--- a/sys/kern/vfs_default.c
+++ b/sys/kern/vfs_default.c
@@ -130,6 +130,13 @@ vop_defaultop(struct vop_generic_args *ap)
return (VOCALL(default_vnodeop_p, ap->a_desc->vdesc_offset, ap));
}
+int
+vop_panic(struct vop_generic_args *ap)
+{
+
+ panic("illegal vnode op called");
+}
+
static int
vop_nostrategy (struct vop_strategy_args *ap)
{
diff --git a/sys/kern/vfs_init.c b/sys/kern/vfs_init.c
index 10d8d82..3314274 100644
--- a/sys/kern/vfs_init.c
+++ b/sys/kern/vfs_init.c
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)vfs_init.c 8.3 (Berkeley) 1/4/94
- * $Id: vfs_init.c,v 1.37 1998/10/25 17:44:52 phk Exp $
+ * $Id: vfs_init.c,v 1.38 1998/11/04 03:18:10 peter Exp $
*/
@@ -49,26 +49,10 @@
#include <sys/malloc.h>
#include <vm/vm_zone.h>
-static void vfs_op_init __P((void));
-
-static void vfsinit __P((void *));
-SYSINIT(vfs, SI_SUB_VFS, SI_ORDER_FIRST, vfsinit, NULL)
MALLOC_DEFINE(M_VNODE, "vnodes", "Dynamically allocated vnodes");
/*
- * Sigh, such primitive tools are these...
- */
-#if 0
-#define DODEBUG(A) A
-#else
-#define DODEBUG(A)
-#endif
-
-extern struct vnodeop_desc *vfs_op_descs[];
- /* and the operations they perform */
-
-/*
* XXX this bloat just exands the sysctl__vfs linker set a little so that
* we can attach sysctls for VFS modules without expanding the linker set.
* Currently (1998/09/06), only one VFS uses sysctls, so 2 extra linker
@@ -99,113 +83,223 @@ struct vm_zone *namei_zone;
* listing those new operations Ficus adds to NFS, all without modifying the
* NFS code. (Of couse, the OTW NFS protocol still needs to be munged, but
* that is a(whole)nother story.) This is a feature.
- *
- * Without an explicit reserve area, however, you must replace vnode_if.c
- * and vnode_if.h when you do this, or you will be derefrencing of the
- * end of vfs_op_descs[]. This is a flaw in the use of a structure
- * pointer array rather than an agregate to define vfs_op_descs. So
- * it's not a very dynamic "feature".
*/
-void
-vfs_opv_init(struct vnodeopv_desc *opv)
+
+/* Table of known vnodeop vectors (list of VFS vnode vectors) */
+static struct vnodeopv_desc **vnodeopv_descs;
+static int vnodeopv_num;
+
+/* Table of known descs (list of vnode op handlers "vop_access_desc") */
+static struct vnodeop_desc **vfs_op_descs;
+static int *vfs_op_desc_refs; /* reference counts */
+static int num_op_descs;
+static int vfs_opv_numops;
+
+static void
+vfs_opv_recalc(void)
{
- int j;
+ int i, j;
vop_t ***opv_desc_vector_p;
vop_t **opv_desc_vector;
struct vnodeopv_entry_desc *opve_descp;
- int default_vector;
+ struct vnodeopv_desc *opv;
+
+ if (vfs_op_descs == NULL)
+ panic("vfs_opv_recalc called with null vfs_op_descs");
- default_vector = VOFFSET(vop_default);
/*
- * Allocate the dynamic vectors and fill them in.
+ * Run through and make sure all known descs have an offset
+ *
+ * vop_default_desc is hardwired at offset 1, and offset 0
+ * is a panic sanity check.
*/
- opv_desc_vector_p = opv->opv_desc_vector_p;
+ vfs_opv_numops = 0;
+ for (i = 0; i < num_op_descs; i++)
+ if (vfs_opv_numops < (vfs_op_descs[i]->vdesc_offset + 1))
+ vfs_opv_numops = vfs_op_descs[i]->vdesc_offset + 1;
+ for (i = 0; i < num_op_descs; i++)
+ if (vfs_op_descs[i]->vdesc_offset == 0)
+ vfs_op_descs[i]->vdesc_offset = vfs_opv_numops++;
/*
- * Allocate and init the vector, if it needs it.
- * Also handle backwards compatibility.
+ * Allocate and fill in the vectors
*/
- if (*opv_desc_vector_p == NULL) {
- /* XXX - shouldn't be M_VNODE */
+ for (i = 0; i < vnodeopv_num; i++) {
+ opv = vnodeopv_descs[i];
+ opv_desc_vector_p = opv->opv_desc_vector_p;
+ if (*opv_desc_vector_p)
+ FREE(*opv_desc_vector_p, M_VNODE);
MALLOC(*opv_desc_vector_p, vop_t **,
vfs_opv_numops * sizeof(vop_t *), M_VNODE, M_WAITOK);
- bzero(*opv_desc_vector_p,
- vfs_opv_numops * sizeof(vop_t *));
- DODEBUG(printf("vector at %x allocated\n",
- opv_desc_vector_p));
- }
- opv_desc_vector = *opv_desc_vector_p;
- for (j = 0; opv->opv_desc_ops[j].opve_op; j++) {
- opve_descp = &(opv->opv_desc_ops[j]);
+ if (*opv_desc_vector_p == NULL)
+ panic("no memory for vop_t ** vector");
+ bzero(*opv_desc_vector_p, vfs_opv_numops * sizeof(vop_t *));
- /*
- * Sanity check: is this operation listed
- * in the list of operations? We check this
- * by seeing if its offest is zero. Since
- * the default routine should always be listed
- * first, it should be the only one with a zero
- * offset. Any other operation with a zero
- * offset is probably not listed in
- * vfs_op_descs, and so is probably an error.
- *
- * A panic here means the layer programmer
- * has committed the all-too common bug
- * of adding a new operation to the layer's
- * list of vnode operations but
- * not adding the operation to the system-wide
- * list of supported operations.
- */
- if (opve_descp->opve_op->vdesc_offset == 0 &&
- opve_descp->opve_op->vdesc_offset != default_vector) {
- printf("operation %s not listed in vfs_op_descs[].\n",
- opve_descp->opve_op->vdesc_name);
- panic ("vfs_opv_init: bad operation");
- }
- /*
- * Fill in this entry.
- */
- opv_desc_vector[opve_descp->opve_op->vdesc_offset] =
+ /* Fill in, with slot 0 being panic */
+ opv_desc_vector = *opv_desc_vector_p;
+ opv_desc_vector[0] = (vop_t *)vop_panic;
+ for (j = 0; opv->opv_desc_ops[j].opve_op; j++) {
+ opve_descp = &(opv->opv_desc_ops[j]);
+ opv_desc_vector[opve_descp->opve_op->vdesc_offset] =
opve_descp->opve_impl;
+ }
+
+ /* Replace unfilled routines with their default (slot 1). */
+ opv_desc_vector = *(opv->opv_desc_vector_p);
+ if (opv_desc_vector[1] == NULL)
+ panic("vfs_opv_recalc: vector without a default.");
+ for (j = 0; j < vfs_opv_numops; j++)
+ if (opv_desc_vector[j] == NULL)
+ opv_desc_vector[j] = opv_desc_vector[1];
}
- /*
- * Finally, go back and replace unfilled routines with their default.
- */
+}
+
+void
+vfs_add_vnodeops(void *data)
+{
+ struct vnodeopv_desc *opv;
+ struct vnodeopv_desc **newopv;
+ struct vnodeop_desc **newop;
+ int *newref;
+ vop_t **opv_desc_vector;
+ struct vnodeop_desc *desc;
+ struct vnodeopv_entry_desc *opve_descp;
+ int i, j, k;
+
+ opv = (struct vnodeopv_desc *)data;
+ MALLOC(newopv, struct vnodeopv_desc **,
+ (vnodeopv_num + 1) * sizeof(*newopv), M_VNODE, M_WAITOK);
+ if (newopv == NULL)
+ panic("vfs_add_vnodeops: no memory");
+ if (vnodeopv_descs) {
+ bcopy(vnodeopv_descs, newopv, vnodeopv_num * sizeof(*newopv));
+ FREE(vnodeopv_descs, M_VNODE);
+ }
+ newopv[vnodeopv_num] = opv;
+ vnodeopv_descs = newopv;
+ vnodeopv_num++;
+
+ /* See if we have turned up a new vnode op desc */
opv_desc_vector = *(opv->opv_desc_vector_p);
- if (opv_desc_vector[default_vector] == NULL)
- panic("vfs_opv_init: operation vector without a default.");
- for (j = 0; j < vfs_opv_numops; j++)
- if (opv_desc_vector[j] == NULL)
- opv_desc_vector[j] = opv_desc_vector[default_vector];
+ for (i = 0; (desc = opv->opv_desc_ops[i].opve_op); i++) {
+ for (j = 0; j < num_op_descs; j++) {
+ if (desc == vfs_op_descs[j]) {
+ /* found it, increase reference count */
+ vfs_op_desc_refs[j]++;
+ break;
+ }
+ }
+ if (j == num_op_descs) {
+ /* not found, new entry */
+ MALLOC(newop, struct vnodeop_desc **,
+ (num_op_descs + 1) * sizeof(*newop),
+ M_VNODE, M_WAITOK);
+ if (newop == NULL)
+ panic("vfs_add_vnodeops: no memory for desc");
+ /* new reference count (for unload) */
+ MALLOC(newref, int *,
+ (num_op_descs + 1) * sizeof(*newref),
+ M_VNODE, M_WAITOK);
+ if (newref == NULL)
+ panic("vfs_add_vnodeops: no memory for refs");
+ if (vfs_op_descs) {
+ bcopy(vfs_op_descs, newop,
+ num_op_descs * sizeof(*newop));
+ FREE(vfs_op_descs, M_VNODE);
+ }
+ if (vfs_op_desc_refs) {
+ bcopy(vfs_op_desc_refs, newref,
+ num_op_descs * sizeof(*newref));
+ FREE(vfs_op_desc_refs, M_VNODE);
+ }
+ newop[num_op_descs] = desc;
+ newref[num_op_descs] = 1;
+ vfs_op_descs = newop;
+ vfs_op_desc_refs = newref;
+ num_op_descs++;
+ }
+ }
+ vfs_opv_recalc();
}
-/*
- * Initialize known vnode operations vectors.
- */
-static void
-vfs_op_init()
+void
+vfs_rm_vnodeops(void *data)
{
- int i;
+ struct vnodeopv_desc *opv;
+ struct vnodeopv_desc **newopv;
+ struct vnodeop_desc **newop;
+ int *newref;
+ vop_t **opv_desc_vector;
+ struct vnodeop_desc *desc;
+ struct vnodeopv_entry_desc *opve_descp;
+ int i, j, k;
- DODEBUG(printf("Vnode_interface_init.\n"));
- DODEBUG(printf ("vfs_opv_numops=%d\n", vfs_opv_numops));
- /*
- * assign each op to its offset
- *
- * XXX This should not be needed, but is because the per
- * XXX FS ops tables are not sorted according to the
- * XXX vnodeop_desc's offset in vfs_op_descs. This
- * XXX is the same reason we have to take the hit for
- * XXX the static inline function calls instead of using
- * XXX simple macro references.
- */
- for (i = 0; i < vfs_opv_numops; i++)
- vfs_op_descs[i]->vdesc_offset = i;
+ opv = (struct vnodeopv_desc *)data;
+ /* Lower ref counts on descs in the table and release if zero */
+ opv_desc_vector = *(opv->opv_desc_vector_p);
+ for (i = 0; (desc = opv->opv_desc_ops[i].opve_op); i++) {
+ for (j = 0; j < num_op_descs; j++) {
+ if (desc == vfs_op_descs[j]) {
+ /* found it, decrease reference count */
+ vfs_op_desc_refs[j]--;
+ break;
+ }
+ }
+ for (j = 0; j < num_op_descs; j++) {
+ if (vfs_op_desc_refs[j] > 0)
+ continue;
+ if (vfs_op_desc_refs[j] < 0)
+ panic("vfs_remove_vnodeops: negative refcnt");
+ MALLOC(newop, struct vnodeop_desc **,
+ (num_op_descs - 1) * sizeof(*newop),
+ M_VNODE, M_WAITOK);
+ if (newop == NULL)
+ panic("vfs_remove_vnodeops: no memory for desc");
+ /* new reference count (for unload) */
+ MALLOC(newref, int *,
+ (num_op_descs - 1) * sizeof(*newref),
+ M_VNODE, M_WAITOK);
+ if (newref == NULL)
+ panic("vfs_remove_vnodeops: no memory for refs");
+ for (k = j; k < (num_op_descs - 1); k++) {
+ vfs_op_descs[k] = vfs_op_descs[k + 1];
+ vfs_op_desc_refs[k] = vfs_op_desc_refs[k + 1];
+ }
+ bcopy(vfs_op_descs, newop,
+ (num_op_descs - 1) * sizeof(*newop));
+ bcopy(vfs_op_desc_refs, newref,
+ (num_op_descs - 1) * sizeof(*newref));
+ FREE(vfs_op_descs, M_VNODE);
+ FREE(vfs_op_desc_refs, M_VNODE);
+ vfs_op_descs = newop;
+ vfs_op_desc_refs = newref;
+ num_op_descs--;
+ }
+ }
+
+ for (i = 0; i < vnodeopv_num; i++) {
+ if (vnodeopv_descs[i] == opv) {
+ for (j = i; j < (vnodeopv_num - 1); j++)
+ vnodeopv_descs[j] = vnodeopv_descs[j + 1];
+ break;
+ }
+ }
+ if (i == vnodeopv_num)
+ panic("vfs_remove_vnodeops: opv not found");
+ MALLOC(newopv, struct vnodeopv_desc **,
+ (vnodeopv_num - 1) * sizeof(*newopv), M_VNODE, M_WAITOK);
+ if (newopv == NULL)
+ panic("vfs_remove_vnodeops: no memory");
+ bcopy(vnodeopv_descs, newopv, (vnodeopv_num - 1) * sizeof(*newopv));
+ FREE(vnodeopv_descs, M_VNODE);
+ vnodeopv_descs = newopv;
+ vnodeopv_num--;
+
+ vfs_opv_recalc();
}
/*
* Routines having to do with the management of the vnode table.
*/
-extern struct vnodeops dead_vnodeops;
-extern struct vnodeops spec_vnodeops;
struct vattr va_null;
/*
@@ -213,8 +307,7 @@ struct vattr va_null;
*/
/* ARGSUSED*/
static void
-vfsinit(dummy)
- void *dummy;
+vfsinit(void *dummy)
{
namei_zone = zinit("NAMEI", MAXPATHLEN, 0, 0, 2);
@@ -228,20 +321,16 @@ vfsinit(dummy)
*/
nchinit();
/*
- * Build vnode operation vectors.
- */
- vfs_op_init();
- /*
* Initialize each file system type.
* Vfs type numbers must be distinct from VFS_GENERIC (and VFS_VFSCONF).
*/
vattr_null(&va_null);
maxvfsconf = VFS_GENERIC + 1;
}
+SYSINIT(vfs, SI_SUB_VFS, SI_ORDER_FIRST, vfsinit, NULL)
int
-vfs_register(vfc)
- struct vfsconf *vfc;
+vfs_register(struct vfsconf *vfc)
{
struct linker_set *l;
struct sysctl_oid **oidpp;
@@ -300,25 +389,8 @@ vfs_register(vfc)
}
-/*
- * To be called at SI_SUB_VFS, SECOND, for each VFS before any are registered.
- */
-void
-vfs_mod_opv_init(handle)
- void *handle;
-{
- struct vnodeopv_desc *opv;
-
- opv = (struct vnodeopv_desc *)handle;
- *(opv->opv_desc_vector_p) = NULL;
-
- /* XXX there is a memory leak on unload here */
- vfs_opv_init(opv);
-}
-
int
-vfs_unregister(vfc)
- struct vfsconf *vfc;
+vfs_unregister(struct vfsconf *vfc)
{
struct linker_set *l;
struct sysctl_oid **oidpp;
@@ -365,3 +437,29 @@ vfs_unregister(vfc)
maxvfsconf = maxtypenum + 1;
return 0;
}
+
+int
+vfs_modevent(module_t mod, modeventtype_t type, void *data)
+{
+ struct vfsconf *vfc;
+ struct vnodeopv_desc *opv;
+ int i;
+ int error = 0;
+
+ vfc = (struct vfsconf *)data;
+
+ switch (type) {
+ case MOD_LOAD:
+ if (vfc)
+ error = vfs_register(vfc);
+ break;
+
+ case MOD_UNLOAD:
+ if (vfc)
+ error = vfs_unregister(vfc);
+ break;
+ default: /* including MOD_SHUTDOWN */
+ break;
+ }
+ return (error);
+}
diff --git a/sys/kern/vnode_if.pl b/sys/kern/vnode_if.pl
index d289c35..8193edb 100644
--- a/sys/kern/vnode_if.pl
+++ b/sys/kern/vnode_if.pl
@@ -32,7 +32,7 @@
# SUCH DAMAGE.
#
# @(#)vnode_if.sh 8.1 (Berkeley) 6/10/93
-# $Id: vnode_if.sh,v 1.14 1997/12/19 23:25:16 bde Exp $
+# $Id: vnode_if.sh,v 1.15 1998/07/04 20:45:32 julian Exp $
#
# Script to produce VFS front-end sugar.
@@ -188,7 +188,7 @@ cat << END_OF_LEADING_COMMENT > $CFILE
#include <sys/vnode.h>
struct vnodeop_desc vop_default_desc = {
- 0,
+ 1, /* special case, vop_default => 1 */
"default",
0,
NULL,
@@ -400,39 +400,3 @@ struct vnodeop_desc vop_bwrite_desc = {
NULL,
};
END_OF_SPECIAL_CASES
-
-# Add the vfs_op_descs array to the C file.
-$AWK '
- BEGIN {
- printf("\nstruct vnodeop_desc *vfs_op_descs[] = {\n");
- printf("\t&vop_default_desc, /* MUST BE FIRST */\n");
- printf("\t&vop_strategy_desc, /* XXX: SPECIAL CASE */\n");
- printf("\t&vop_bwrite_desc, /* XXX: SPECIAL CASE */\n");
- }
- END {
- printf("\tNULL\n};\n");
- }
- NF == 0 || $0 ~ "^#" {
- next;
- }
- {
- # Get the function name.
- printf("\t&%s_desc,\n", $1);
-
- # Skip the function arguments.
- for (;;) {
- if (getline <= 0)
- exit
- if ($0 ~ "^};")
- break;
- }
- }' < $SRC >> $CFILE
-
-cat << END_OF_NUMOPS_CODE >> $CFILE
-
-/*
- * the -1 is to account for the NULL
- * XXX is the NULL still necessary? I don't think so...
- */
-int vfs_opv_numops = (sizeof(vfs_op_descs)/sizeof(struct vnodeop_desc *)) - 1;
-END_OF_NUMOPS_CODE
diff --git a/sys/kern/vnode_if.sh b/sys/kern/vnode_if.sh
index d289c35..8193edb 100644
--- a/sys/kern/vnode_if.sh
+++ b/sys/kern/vnode_if.sh
@@ -32,7 +32,7 @@
# SUCH DAMAGE.
#
# @(#)vnode_if.sh 8.1 (Berkeley) 6/10/93
-# $Id: vnode_if.sh,v 1.14 1997/12/19 23:25:16 bde Exp $
+# $Id: vnode_if.sh,v 1.15 1998/07/04 20:45:32 julian Exp $
#
# Script to produce VFS front-end sugar.
@@ -188,7 +188,7 @@ cat << END_OF_LEADING_COMMENT > $CFILE
#include <sys/vnode.h>
struct vnodeop_desc vop_default_desc = {
- 0,
+ 1, /* special case, vop_default => 1 */
"default",
0,
NULL,
@@ -400,39 +400,3 @@ struct vnodeop_desc vop_bwrite_desc = {
NULL,
};
END_OF_SPECIAL_CASES
-
-# Add the vfs_op_descs array to the C file.
-$AWK '
- BEGIN {
- printf("\nstruct vnodeop_desc *vfs_op_descs[] = {\n");
- printf("\t&vop_default_desc, /* MUST BE FIRST */\n");
- printf("\t&vop_strategy_desc, /* XXX: SPECIAL CASE */\n");
- printf("\t&vop_bwrite_desc, /* XXX: SPECIAL CASE */\n");
- }
- END {
- printf("\tNULL\n};\n");
- }
- NF == 0 || $0 ~ "^#" {
- next;
- }
- {
- # Get the function name.
- printf("\t&%s_desc,\n", $1);
-
- # Skip the function arguments.
- for (;;) {
- if (getline <= 0)
- exit
- if ($0 ~ "^};")
- break;
- }
- }' < $SRC >> $CFILE
-
-cat << END_OF_NUMOPS_CODE >> $CFILE
-
-/*
- * the -1 is to account for the NULL
- * XXX is the NULL still necessary? I don't think so...
- */
-int vfs_opv_numops = (sizeof(vfs_op_descs)/sizeof(struct vnodeop_desc *)) - 1;
-END_OF_NUMOPS_CODE
diff --git a/sys/sys/mount.h b/sys/sys/mount.h
index 3775e09..25a336c 100644
--- a/sys/sys/mount.h
+++ b/sys/sys/mount.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)mount.h 8.21 (Berkeley) 5/20/95
- * $Id: mount.h,v 1.70 1998/11/06 16:36:31 peter Exp $
+ * $Id: mount.h,v 1.71 1998/11/07 04:51:36 peter Exp $
*/
#ifndef _SYS_MOUNT_H_
@@ -351,47 +351,24 @@ struct vfsops {
#else
#include <sys/module.h>
+
#define VFS_SET(vfsops, fsname, flags) \
- static struct vfsconf fsname ## _vfsconf = { \
- &vfsops, \
- #fsname, \
- -1, \
- 0, \
- flags | VFCF_STATIC, \
- }; \
- static int fsname ## _modevent(module_t mod, modeventtype_t type, \
- void *data) \
- { \
- struct vfsconf *vfc = (struct vfsconf *)data; \
- int error = 0; \
- switch (type) { \
- case MOD_LOAD: \
- /* printf(#fsname " module load\n"); */ \
- error = vfs_register(vfc); \
- if (error) \
- printf(#fsname " register failed\n"); \
- break; \
- case MOD_UNLOAD: \
- /* printf(#fsname " module unload\n"); */ \
- error = vfs_unregister(vfc); \
- if (error) \
- printf(#fsname " register failed\n"); \
- break; \
- } \
- return error; \
- } \
- static moduledata_t fsname ## _mod = { \
- #fsname, \
- fsname ## _modevent, \
- & fsname ## _vfsconf \
- }; \
+ static struct vfsconf fsname ## _vfsconf = { \
+ &vfsops, \
+ #fsname, \
+ -1, \
+ 0, \
+ flags \
+ }; \
+ static moduledata_t fsname ## _mod = { \
+ #fsname, \
+ vfs_modevent, \
+ & fsname ## _vfsconf \
+ }; \
DECLARE_MODULE(fsname, fsname ## _mod, SI_SUB_VFS, SI_ORDER_MIDDLE)
#endif /* VFS_LKM */
-#endif /* KERNEL */
-
-#ifdef KERNEL
#include <net/radix.h>
#define AF_MAX 31 /* XXX */
@@ -438,6 +415,7 @@ void vfs_unbusy __P((struct mount *, struct proc *));
void vfs_unmountall __P((void));
int vfs_register __P((struct vfsconf *));
int vfs_unregister __P((struct vfsconf *));
+int vfs_modevent __P((module_t, modeventtype_t, void *));
extern CIRCLEQ_HEAD(mntlist, mount) mountlist; /* mounted filesystem list */
extern struct simplelock mountlist_slock;
extern struct nfs_public nfs_pub;
diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h
index b1c33e7..730dce2 100644
--- a/sys/sys/vnode.h
+++ b/sys/sys/vnode.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)vnode.h 8.7 (Berkeley) 2/4/94
- * $Id: vnode.h,v 1.76 1998/10/29 09:51:28 peter Exp $
+ * $Id: vnode.h,v 1.77 1998/10/31 14:05:11 peter Exp $
*/
#ifndef _SYS_VNODE_H_
@@ -259,7 +259,8 @@ extern int vttoif_tab[];
#define VNODEOP_SET(f) DATA_SET(MODVNOPS,f)
#else
#define VNODEOP_SET(f) \
- SYSINIT(f##init, SI_SUB_VFS, SI_ORDER_SECOND, vfs_mod_opv_init, &f);
+ SYSINIT(f##init, SI_SUB_VFS, SI_ORDER_SECOND, vfs_add_vnodeops, &f); \
+ SYSUNINIT(f##uninit, SI_SUB_VFS, SI_ORDER_SECOND, vfs_rm_vnodeops, &f);
#endif
/*
@@ -487,8 +488,8 @@ void vattr_null __P((struct vattr *vap));
int vcount __P((struct vnode *vp));
void vdrop __P((struct vnode *));
int vfinddev __P((dev_t dev, enum vtype type, struct vnode **vpp));
-void vfs_opv_init __P((struct vnodeopv_desc *opv));
-void vfs_mod_opv_init __P((void *handle));
+void vfs_add_vnodeops __P((void *));
+void vfs_rm_vnodeops __P((void *));
int vflush __P((struct mount *mp, struct vnode *skipvp, int flags));
int vget __P((struct vnode *vp, int lockflag, struct proc *p));
void vgone __P((struct vnode *vp));
@@ -535,6 +536,7 @@ int vop_einval __P((struct vop_generic_args *ap));
int vop_enotty __P((struct vop_generic_args *ap));
int vop_defaultop __P((struct vop_generic_args *ap));
int vop_null __P((struct vop_generic_args *ap));
+int vop_panic __P((struct vop_generic_args *ap));
struct vnode *
checkalias __P((struct vnode *vp, dev_t nvp_rdev, struct mount *mp));
diff --git a/sys/tools/vnode_if.awk b/sys/tools/vnode_if.awk
index d289c35..8193edb 100644
--- a/sys/tools/vnode_if.awk
+++ b/sys/tools/vnode_if.awk
@@ -32,7 +32,7 @@
# SUCH DAMAGE.
#
# @(#)vnode_if.sh 8.1 (Berkeley) 6/10/93
-# $Id: vnode_if.sh,v 1.14 1997/12/19 23:25:16 bde Exp $
+# $Id: vnode_if.sh,v 1.15 1998/07/04 20:45:32 julian Exp $
#
# Script to produce VFS front-end sugar.
@@ -188,7 +188,7 @@ cat << END_OF_LEADING_COMMENT > $CFILE
#include <sys/vnode.h>
struct vnodeop_desc vop_default_desc = {
- 0,
+ 1, /* special case, vop_default => 1 */
"default",
0,
NULL,
@@ -400,39 +400,3 @@ struct vnodeop_desc vop_bwrite_desc = {
NULL,
};
END_OF_SPECIAL_CASES
-
-# Add the vfs_op_descs array to the C file.
-$AWK '
- BEGIN {
- printf("\nstruct vnodeop_desc *vfs_op_descs[] = {\n");
- printf("\t&vop_default_desc, /* MUST BE FIRST */\n");
- printf("\t&vop_strategy_desc, /* XXX: SPECIAL CASE */\n");
- printf("\t&vop_bwrite_desc, /* XXX: SPECIAL CASE */\n");
- }
- END {
- printf("\tNULL\n};\n");
- }
- NF == 0 || $0 ~ "^#" {
- next;
- }
- {
- # Get the function name.
- printf("\t&%s_desc,\n", $1);
-
- # Skip the function arguments.
- for (;;) {
- if (getline <= 0)
- exit
- if ($0 ~ "^};")
- break;
- }
- }' < $SRC >> $CFILE
-
-cat << END_OF_NUMOPS_CODE >> $CFILE
-
-/*
- * the -1 is to account for the NULL
- * XXX is the NULL still necessary? I don't think so...
- */
-int vfs_opv_numops = (sizeof(vfs_op_descs)/sizeof(struct vnodeop_desc *)) - 1;
-END_OF_NUMOPS_CODE
OpenPOWER on IntegriCloud