summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_lkm.c
diff options
context:
space:
mode:
authordyson <dyson@FreeBSD.org>1997-02-10 02:22:35 +0000
committerdyson <dyson@FreeBSD.org>1997-02-10 02:22:35 +0000
commit10f666af84d48e89e4e2960415c9b616fce4077f (patch)
tree88a944de263165091f0a18abeedbaaccec532407 /sys/kern/kern_lkm.c
parent0960d7e91af3428ffba89b42228d82d8afaa0389 (diff)
downloadFreeBSD-src-10f666af84d48e89e4e2960415c9b616fce4077f.zip
FreeBSD-src-10f666af84d48e89e4e2960415c9b616fce4077f.tar.gz
This is the kernel Lite/2 commit. There are some requisite userland
changes, so don't expect to be able to run the kernel as-is (very well) without the appropriate Lite/2 userland changes. The system boots and can mount UFS filesystems. Untested: ext2fs, msdosfs, NFS Known problems: Incorrect Berkeley ID strings in some files. Mount_std mounts will not work until the getfsent library routine is changed. Reviewed by: various people Submitted by: Jeffery Hsu <hsu@freebsd.org>
Diffstat (limited to 'sys/kern/kern_lkm.c')
-rw-r--r--sys/kern/kern_lkm.c76
1 files changed, 57 insertions, 19 deletions
diff --git a/sys/kern/kern_lkm.c b/sys/kern/kern_lkm.c
index c2dad16..33c5ef3 100644
--- a/sys/kern/kern_lkm.c
+++ b/sys/kern/kern_lkm.c
@@ -604,8 +604,11 @@ _lkm_vfs(lkmtp, cmd)
{
struct lkm_vfs *args = lkmtp->private.lkm_vfs;
struct vfsconf *vfc = args->lkm_vfsconf;
+ struct vfsconf *vfsp, *lastvfsp, *prev_vfsp, *new_vfc;
int i;
int err = 0;
+ char fstypename[MFSNAMELEN];
+ int neednamesearch = 1;
switch(cmd) {
case LKM_E_LOAD:
@@ -613,26 +616,51 @@ _lkm_vfs(lkmtp, cmd)
if (lkmexists(lkmtp))
return(EEXIST);
- for(i = 0; i < MOUNT_MAXTYPE; i++) {
- if(!strcmp(vfc->vfc_name, vfsconf[i]->vfc_name)) {
- return EEXIST;
- }
- }
-
- i = args->lkm_offset = vfc->vfc_index;
- if (i < 0) {
- for (i = MOUNT_MAXTYPE - 1; i >= 0; i--) {
- if(vfsconf[i] == &void_vfsconf)
+ /* check to see if filesystem already exists */
+ vfsp = NULL;
+#ifdef COMPAT_43 /* see vfs_syscalls.c:mount() */
+ if (vfc->vfc_typenum < maxvfsconf) {
+ neednamesearch = 0;
+ for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next)
+ if (vfsp->vfc_typenum == vfc->vfc_typenum)
break;
+ if (vfsp != NULL) {
+ neednamesearch = 1;
+ strncpy(fstypename, vfsp->vfc_name, MFSNAMELEN);
+ }
+ } else
+#endif /* COMPAT_43 */
+ if (neednamesearch) {
+ strncpy(fstypename, vfc->vfc_name, MFSNAMELEN);
+ for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next) {
+ if (!strcmp(vfsp->vfc_name, fstypename)) {
+ return EEXIST;
+ }
}
}
+
+ i = args->lkm_offset = vfc->vfc_typenum;
if (i < 0) {
- return EINVAL;
+ i = maxvfsconf;
}
- args->lkm_offset = vfc->vfc_index = i;
+ args->lkm_offset = vfc->vfc_typenum = i;
+
+ if (maxvfsconf <= vfsp->vfc_typenum)
+ maxvfsconf = vfsp->vfc_typenum + 1;
+
+ /* find vfsconf tail */
+ for (lastvfsp = vfsconf; lastvfsp->vfc_next;
+ lastvfsp = lastvfsp->vfc_next) ;
- vfsconf[i] = vfc;
- vfssw[i] = vfc->vfc_vfsops;
+ /* make copy */
+/* possible race condition if vfsconf changes while we wait XXX JH */
+ MALLOC(new_vfc, struct vfsconf *, sizeof(struct vfsconf),
+ M_VFSCONF, M_WAITOK);
+ *new_vfc = *vfc;
+ vfc = new_vfc;
+
+ lastvfsp->vfc_next = vfc;
+ vfc->vfc_next = NULL;
/* like in vfs_op_init */
for(i = 0; args->lkm_vnodeops->ls_items[i]; i++) {
@@ -645,7 +673,7 @@ _lkm_vfs(lkmtp, cmd)
/*
* Call init function for this VFS...
*/
- (*(vfssw[vfc->vfc_index]->vfs_init))();
+ (*(vfsp->vfc_vfsops->vfs_init))(vfsp);
/* done! */
break;
@@ -654,13 +682,23 @@ _lkm_vfs(lkmtp, cmd)
/* current slot... */
i = args->lkm_offset;
- if (vfsconf[i]->vfc_refcount) {
+ prev_vfsp = NULL;
+ for (vfsp = vfsconf; vfsp;
+ prev_vfsp = vfsp, vfsp = vfsp->vfc_next) {
+ if (vfsp->vfc_typenum == vfc->vfc_typenum)
+ break;
+ }
+ if (vfsp == NULL) {
+ return EINVAL;
+ }
+
+ if (vfsp->vfc_refcount) {
return EBUSY;
}
- /* replace current slot contents with old contents */
- vfssw[i] = (struct vfsops *)0;
- vfsconf[i] = &void_vfsconf;
+ FREE(vfsp, M_VFSCONF);
+
+ prev_vfsp->vfc_next = vfsp->vfc_next;
break;
OpenPOWER on IntegriCloud