On Thu, Jun 06, 2013 at 15:39, Sylvestre Gallon wrote: > If you look at sys/kern/vfs_init.c MOUNT_FUSEFS use the biggest typenum : 18. > So when the function vfsinit in sbin/sysctl.c gets VFS_MAXTYPENUM it gets > 18, but this value will never be reached in the for statement...
The diff below doesn't fix this issue, but since I was looking at the code... We don't need to support loadable filesystems via lkm. Particularly now that fuse is here. Removing such support allows a great deal of simplification because the supported list is static. (Yes, I am sending a "make the dynamic structure static" diff the day after I sent a "make the static structure dynamic" diff.) Index: kern/kern_lkm.c =================================================================== RCS file: /cvs/src/sys/kern/kern_lkm.c,v retrieving revision 1.46 diff -u -p -r1.46 kern_lkm.c --- kern/kern_lkm.c 14 Jan 2010 23:12:11 -0000 1.46 +++ kern/kern_lkm.c 6 Jun 2013 21:37:01 -0000 @@ -91,7 +91,6 @@ static void lkmfree(struct lkm_table *); static struct lkm_table *lkmlookup(int, char *, int *); static void lkmunreserve(void); static int _lkm_syscall(struct lkm_table *, int); -static int _lkm_vfs(struct lkm_table *, int); static int _lkm_dev(struct lkm_table *, int); static int _lkm_exec(struct lkm_table *, int); @@ -657,35 +656,6 @@ _lkm_syscall(struct lkm_table *lkmtp, in } /* - * For the loadable virtual file system described by the structure pointed - * to by lkmtp, load/unload/stat it depending on the cmd requested. - */ -static int -_lkm_vfs(struct lkm_table *lkmtp, int cmd) -{ - int error = 0; - struct lkm_vfs *args = lkmtp->private.lkm_vfs; - - switch (cmd) { - case LKM_E_LOAD: - /* don't load twice! */ - if (lkmexists(lkmtp)) - return (EEXIST); - error = vfs_register(args->lkm_vfsconf); - break; - - case LKM_E_UNLOAD: - error = vfs_unregister(args->lkm_vfsconf); - break; - - case LKM_E_STAT: /* no special handling... */ - break; - } - - return (error); -} - -/* * For the loadable device driver described by the structure pointed to * by lkmtp, load/unload/stat it depending on the cmd requested. */ @@ -893,10 +863,6 @@ lkmdispatch(struct lkm_table *lkmtp, int switch (lkmtp->private.lkm_any->lkm_type) { case LM_SYSCALL: error = _lkm_syscall(lkmtp, cmd); - break; - - case LM_VFS: - error = _lkm_vfs(lkmtp, cmd); break; case LM_DEV: Index: kern/vfs_init.c =================================================================== RCS file: /cvs/src/sys/kern/vfs_init.c,v retrieving revision 1.32 diff -u -p -r1.32 vfs_init.c --- kern/vfs_init.c 3 Jun 2013 15:54:48 -0000 1.32 +++ kern/vfs_init.c 6 Jun 2013 22:02:17 -0000 @@ -91,63 +91,59 @@ extern const struct vfsops fusefs_vfsops #endif /* Set up the filesystem operations for vnodes. */ -static struct vfsconf vfsconflist[] = { +struct vfsconf vfsconf[] = { #ifdef FFS - { &ffs_vfsops, MOUNT_FFS, 1, 0, MNT_LOCAL, NULL }, + { &ffs_vfsops, MOUNT_FFS, 0, MNT_LOCAL }, #endif #ifdef MFS - { &mfs_vfsops, MOUNT_MFS, 3, 0, MNT_LOCAL, NULL }, + { &mfs_vfsops, MOUNT_MFS, 0, MNT_LOCAL }, #endif #ifdef EXT2FS - { &ext2fs_vfsops, MOUNT_EXT2FS, 17, 0, MNT_LOCAL, NULL }, + { &ext2fs_vfsops, MOUNT_EXT2FS, 0, MNT_LOCAL }, #endif #ifdef CD9660 - { &cd9660_vfsops, MOUNT_CD9660, 14, 0, MNT_LOCAL, NULL }, + { &cd9660_vfsops, MOUNT_CD9660, 0, MNT_LOCAL }, #endif #ifdef MSDOSFS - { &msdosfs_vfsops, MOUNT_MSDOS, 4, 0, MNT_LOCAL, NULL }, + { &msdosfs_vfsops, MOUNT_MSDOS, 0, MNT_LOCAL }, #endif #ifdef NFSCLIENT - { &nfs_vfsops, MOUNT_NFS, 2, 0, 0, NULL }, + { &nfs_vfsops, MOUNT_NFS, 0, 0 }, #endif #ifdef PROCFS - { &procfs_vfsops, MOUNT_PROCFS, 12, 0, 0, NULL }, + { &procfs_vfsops, MOUNT_PROCFS, 0, 0 }, #endif #ifdef NTFS - { &ntfs_vfsops, MOUNT_NTFS, 6, 0, MNT_LOCAL, NULL }, + { &ntfs_vfsops, MOUNT_NTFS, 0, MNT_LOCAL }, #endif #ifdef UDF - { &udf_vfsops, MOUNT_UDF, 13, 0, MNT_LOCAL, NULL }, + { &udf_vfsops, MOUNT_UDF, 0, MNT_LOCAL }, #endif #ifdef FUSE - { &fusefs_vfsops, MOUNT_FUSEFS, 18, 0, MNT_LOCAL, NULL }, + { &fusefs_vfsops, MOUNT_FUSEFS, 0, MNT_LOCAL }, #endif }; /* - * Initially the size of the list, vfsinit will set maxvfsconf - * to the highest defined type number. + * The number of elements in the above array */ -int maxvfsconf = sizeof(vfsconflist) / sizeof(struct vfsconf); -struct vfsconf *vfsconf = vfsconflist; +int maxvfsconf = nitems(vfsconf); /* Initialize the vnode structures and initialize each file system type. */ void vfsinit(void) { int i; - struct vfsconf *vfsconflist; - int vfsconflistlen; pool_init(&namei_pool, MAXPATHLEN, 0, 0, 0, "namei", &pool_allocator_nointr); @@ -158,15 +154,10 @@ vfsinit(void) /* Initialize the vnode name cache. */ nchinit(); - /* - * Stop using vfsconf and maxvfsconf as a temporary storage, - * set them to their correct values now. - */ - vfsconflist = vfsconf; - vfsconflistlen = maxvfsconf; - vfsconf = NULL; - maxvfsconf = 0; - - for (i = 0; i < vfsconflistlen; i++) - vfs_register(&vfsconflist[i]); + for (i = 0; i < nitems(vfsconf); i++) { + struct vfsconf *vfs = &vfsconf[i]; + vfs->vfc_typenum = i + 1; + if (vfs->vfc_vfsops->vfs_init) + vfs->vfc_vfsops->vfs_init(vfs); + } } Index: kern/vfs_subr.c =================================================================== RCS file: /cvs/src/sys/kern/vfs_subr.c,v retrieving revision 1.203 diff -u -p -r1.203 vfs_subr.c --- kern/vfs_subr.c 15 Apr 2013 15:32:19 -0000 1.203 +++ kern/vfs_subr.c 6 Jun 2013 21:48:47 -0000 @@ -207,11 +207,14 @@ vfs_rootmountalloc(char *fstypename, cha { struct vfsconf *vfsp; struct mount *mp; + int i; - for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next) + for (i = 0; i < maxvfsconf; i++) { + vfsp = &vfsconf[i]; if (!strcmp(vfsp->vfc_name, fstypename)) break; - if (vfsp == NULL) + } + if (i == maxvfsconf) return (ENODEV); mp = malloc(sizeof(struct mount), M_MOUNT, M_WAITOK|M_ZERO); (void)vfs_busy(mp, VB_READ|VB_NOWAIT); @@ -1240,18 +1243,19 @@ vfs_sysctl(int *name, u_int namelen, voi size_t newlen, struct proc *p) { struct vfsconf *vfsp, *tmpvfsp; - int ret; + int i, ret; /* all sysctl names at this level are at least name and field */ if (namelen < 2) return (ENOTDIR); /* overloaded */ if (name[0] != VFS_GENERIC) { - for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next) + for (i = 0; i < maxvfsconf; i++) { + vfsp = &vfsconf[i]; if (vfsp->vfc_typenum == name[0]) break; - - if (vfsp == NULL) + } + if (i == maxvfsconf) return (EOPNOTSUPP); return ((*vfsp->vfc_vfsops->vfs_sysctl)(&name[1], namelen - 1, @@ -1266,18 +1270,18 @@ vfs_sysctl(int *name, u_int namelen, voi if (namelen < 3) return (ENOTDIR); /* overloaded */ - for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next) + for (i = 0; i < maxvfsconf; i++) { + vfsp = &vfsconf[i]; if (vfsp->vfc_typenum == name[2]) break; - - if (vfsp == NULL) + } + if (i == maxvfsconf) return (EOPNOTSUPP); /* Make a copy, clear out kernel pointers */ tmpvfsp = malloc(sizeof(*tmpvfsp), M_TEMP, M_WAITOK); bcopy(vfsp, tmpvfsp, sizeof(*tmpvfsp)); tmpvfsp->vfc_vfsops = NULL; - tmpvfsp->vfc_next = NULL; ret = sysctl_rdstruct(oldp, oldlenp, newp, tmpvfsp, sizeof(struct vfsconf)); @@ -2065,72 +2069,6 @@ reassignbuf(struct buf *bp) } } bufinsvn(bp, listheadp); -} - -int -vfs_register(struct vfsconf *vfs) -{ - struct vfsconf *vfsp; - struct vfsconf **vfspp; - -#ifdef DIAGNOSTIC - /* Paranoia? */ - if (vfs->vfc_refcount != 0) - printf("vfs_register called with vfc_refcount > 0\n"); -#endif - - /* Check if filesystem already known */ - for (vfspp = &vfsconf, vfsp = vfsconf; vfsp; - vfspp = &vfsp->vfc_next, vfsp = vfsp->vfc_next) - if (strcmp(vfsp->vfc_name, vfs->vfc_name) == 0) - return (EEXIST); - - if (vfs->vfc_typenum > maxvfsconf) - maxvfsconf = vfs->vfc_typenum; - - vfs->vfc_next = NULL; - - /* Add to the end of the list */ - *vfspp = vfs; - - /* Call vfs_init() */ - if (vfs->vfc_vfsops->vfs_init) - (*(vfs->vfc_vfsops->vfs_init))(vfs); - - return 0; -} - -int -vfs_unregister(struct vfsconf *vfs) -{ - struct vfsconf *vfsp; - struct vfsconf **vfspp; - int maxtypenum; - - /* Find our vfsconf struct */ - for (vfspp = &vfsconf, vfsp = vfsconf; vfsp; - vfspp = &vfsp->vfc_next, vfsp = vfsp->vfc_next) { - if (strcmp(vfsp->vfc_name, vfs->vfc_name) == 0) - break; - } - - if (!vfsp) /* Not found */ - return (ENOENT); - - if (vfsp->vfc_refcount) /* In use */ - return (EBUSY); - - /* Remove from list and free */ - *vfspp = vfsp->vfc_next; - - maxtypenum = 0; - - for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next) - if (vfsp->vfc_typenum > maxtypenum) - maxtypenum = vfsp->vfc_typenum; - - maxvfsconf = maxtypenum; - return 0; } /* Index: kern/vfs_syscalls.c =================================================================== RCS file: /cvs/src/sys/kern/vfs_syscalls.c,v retrieving revision 1.193 diff -u -p -r1.193 vfs_syscalls.c --- kern/vfs_syscalls.c 5 Jun 2013 01:26:00 -0000 1.193 +++ kern/vfs_syscalls.c 6 Jun 2013 21:49:53 -0000 @@ -118,7 +118,7 @@ sys_mount(struct proc *p, void *v, regis } */ *uap = v; struct vnode *vp; struct mount *mp; - int error, mntflag = 0; + int i, error, mntflag = 0; char fstypename[MFSNAMELEN]; char fspath[MNAMELEN]; struct vattr va; @@ -228,12 +228,12 @@ sys_mount(struct proc *p, void *v, regis vput(vp); return (error); } - for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next) { + for (i = 0; i < maxvfsconf; i++) { + vfsp = &vfsconf[i]; if (!strcmp(vfsp->vfc_name, fstypename)) break; } - - if (vfsp == NULL) { + if (i == maxvfsconf) { vput(vp); return (EOPNOTSUPP); } Index: sys/lkm.h =================================================================== RCS file: /cvs/src/sys/sys/lkm.h,v retrieving revision 1.13 diff -u -p -r1.13 lkm.h --- sys/lkm.h 7 Nov 2008 02:23:04 -0000 1.13 +++ sys/lkm.h 6 Jun 2013 21:37:56 -0000 @@ -49,7 +49,7 @@ */ typedef enum loadmod { LM_SYSCALL, - LM_VFS, + LM_WAS_VFS, LM_DEV, LM_EXEC, LM_MISC @@ -77,17 +77,6 @@ struct lkm_syscall { }; /* - * Loadable file system - */ -struct lkm_vfs { - MODTYPE lkm_type; - int lkm_ver; - char *lkm_name; - u_long lkm_offset; - struct vfsconf *lkm_vfsconf; -}; - -/* * Supported device module types */ typedef enum devtype { @@ -155,7 +144,6 @@ struct lkm_any { union lkm_generic { struct lkm_any *lkm_any; struct lkm_syscall *lkm_syscall; - struct lkm_vfs *lkm_vfs; struct lkm_dev *lkm_dev; struct lkm_exec *lkm_exec; struct lkm_misc *lkm_misc; @@ -201,15 +189,6 @@ struct lkm_table { name, \ callslot, \ sysentp \ - }; - -#define MOD_VFS(name,vfsslot,vfsconf) \ - static struct lkm_vfs _module = { \ - LM_VFS, \ - LKM_VERSION, \ - name, \ - vfsslot, \ - vfsconf \ }; #define MOD_DEV(name,devtype,devslot,devp) \ Index: sys/mount.h =================================================================== RCS file: /cvs/src/sys/sys/mount.h,v retrieving revision 1.111 diff -u -p -r1.111 mount.h --- sys/mount.h 3 Jun 2013 15:56:01 -0000 1.111 +++ sys/mount.h 6 Jun 2013 21:55:58 -0000 @@ -496,10 +496,9 @@ typedef struct fhandle fhandle_t; struct vfsconf { const struct vfsops *vfc_vfsops; /* filesystem operations vector */ char vfc_name[MFSNAMELEN]; /* filesystem type name */ - int vfc_typenum; /* historic filesystem type number */ int vfc_refcount; /* number mounted of this type */ int vfc_flags; /* permanent flags */ - struct vfsconf *vfc_next; /* next in list */ + int vfc_typenum; /* historic filesystem type number */ }; /* buffer cache statistics */ @@ -538,8 +537,8 @@ extern int bufbackoff(struct uvm_constra struct nameidata; struct mbuf; -extern int maxvfsconf; /* highest defined filesystem type */ -extern struct vfsconf *vfsconf; /* head of list of filesystem types */ +extern struct vfsconf vfsconf[]; /* head of list of filesystem types */ +extern int maxvfsconf; /* size of vfsconf[] */ struct vfsops { int (*vfs_mount)(struct mount *mp, const char *path,