Don't use vfssw[], it's gone; use vfs_list instead.

Implement vfs_attach() and vfs_detach(), which add and remove file systems
from the kernel.
This commit is contained in:
thorpej 1998-02-18 07:16:41 +00:00
parent 6c57a3c322
commit d1f0dbf1b1
1 changed files with 114 additions and 21 deletions

View File

@ -1,7 +1,7 @@
/* $NetBSD: vfs_subr.c,v 1.78 1998/02/10 14:09:52 mrg Exp $ */
/* $NetBSD: vfs_subr.c,v 1.79 1998/02/18 07:16:41 thorpej Exp $ */
/*-
* Copyright (c) 1997 The NetBSD Foundation, Inc.
* Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
@ -136,9 +136,18 @@ TAILQ_HEAD(freelst, vnode) vnode_free_list = /* vnode free list */
struct mntlist mountlist = /* mounted filesystem list */
CIRCLEQ_HEAD_INITIALIZER(mountlist);
struct device *root_device; /* root device */
struct vfs_list_head vfs_list = /* vfs list */
LIST_HEAD_INITIALIZER(vfs_list);
struct nfs_public nfs_pub; /* publicly exported FS */
/*
* These define the root filesystem and device.
*/
struct mount *rootfs;
struct vnode *rootvnode;
struct device *root_device;
int vfs_lock __P((struct mount *));
void vfs_unlock __P((struct mount *));
struct mount *getvfs __P((fsid_t *));
@ -1823,7 +1832,7 @@ int
vfs_mountroot()
{
extern int (*mountroot) __P((void));
int i;
struct vfsops *v;
if (root_device == NULL)
panic("vfs_mountroot: root device unknown");
@ -1854,24 +1863,26 @@ vfs_mountroot()
/*
* Try each file system currently configured into the kernel.
*/
for (i = 0; i < nvfssw; i++) {
if (vfssw[i] == NULL || vfssw[i]->vfs_mountroot == NULL)
for (v = LIST_FIRST(&vfs_list); v != NULL; v = LIST_NEXT(v, vfs_list)) {
if (v->vfs_mountroot == NULL)
continue;
#ifdef DEBUG
printf("mountroot: trying %s...\n", vfssw[i]->vfs_name);
printf("mountroot: trying %s...\n", v->vfs_name);
#endif
if ((*vfssw[i]->vfs_mountroot)() == 0) {
printf("root file system type: %s\n",
vfssw[i]->vfs_name);
return (0);
if ((*v->vfs_mountroot)() == 0) {
printf("root file system type: %s\n", v->vfs_name);
break;
}
}
printf("no file system for %s", root_device->dv_xname);
if (root_device->dv_class == DV_DISK)
printf(" (dev 0x%x)", rootdev);
printf("\n");
return (EFTYPE);
if (v == NULL) {
printf("no file system for %s", root_device->dv_xname);
if (root_device->dv_class == DV_DISK)
printf(" (dev 0x%x)", rootdev);
printf("\n");
return (EFTYPE);
}
return (0);
}
/*
@ -1883,10 +1894,92 @@ struct vfsops *
vfs_getopsbyname(name)
const char *name;
{
int i;
struct vfsops *v;
for (i = 0; i < nvfssw; i++)
if (vfssw[i] != NULL && strcmp(vfssw[i]->vfs_name, name) == 0)
return (vfssw[i]);
return (NULL);
for (v = LIST_FIRST(&vfs_list); v != NULL; v = LIST_NEXT(v, vfs_list)) {
if (strcmp(v->vfs_name, name) == 0)
break;
}
return (v);
}
/*
* Establish a file system and initialize it.
*/
int
vfs_attach(vfs)
struct vfsops *vfs;
{
struct vfsops *v;
int error = 0;
/*
* Make sure this file system doesn't already exist.
*/
for (v = LIST_FIRST(&vfs_list); v != NULL; v = LIST_NEXT(v, vfs_list)) {
if (strcmp(vfs->vfs_name, v->vfs_name) == 0) {
error = EEXIST;
goto out;
}
}
/*
* Initialize the vnode operations for this file system.
*/
vfs_opv_init(vfs->vfs_opv_descs);
/*
* Now initialize the file system itself.
*/
(*vfs->vfs_init)();
/*
* ...and link it into the kernel's list.
*/
LIST_INSERT_HEAD(&vfs_list, vfs, vfs_list);
/*
* Sanity: make sure the reference count is 0.
*/
vfs->vfs_refcount = 0;
out:
return (error);
}
/*
* Remove a file system from the kernel.
*/
int
vfs_detach(vfs)
struct vfsops *vfs;
{
struct vfsops *v;
/*
* Make sure no one is using the filesystem.
*/
if (vfs->vfs_refcount != 0)
return (EBUSY);
/*
* ...and remove it from the kernel's list.
*/
for (v = LIST_FIRST(&vfs_list); v != NULL; v = LIST_NEXT(v, vfs_list)) {
if (v == vfs) {
LIST_REMOVE(v, vfs_list);
break;
}
}
if (v == NULL)
return (ESRCH);
/*
* Free the vnode operations vector.
*/
vfs_opv_free(vfs->vfs_opv_descs);
return (0);
}