Fixed loading of vfs's. The Lite2 merge added unnecessary compatibility
cruft and resulted in loading usually following a null pointer. Use something closer to the pre-Lite2 code, including not making a copy of the new filesystem's config info. Not making a copy also fixes a race for loading and a memory leak for unloading. Fixed unloading of vfs's. maxvfsconf wasn't maintained. Look up the vfs to unload by name instead of by number. The numbers should go away as soon as all mount utilities are converted.
This commit is contained in:
parent
b98afd0d00
commit
886ee0aa9f
@ -30,7 +30,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id$
|
||||
* $Id: kern_lkm.c,v 1.36 1997/02/22 09:39:06 peter Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -604,11 +604,9 @@ _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;
|
||||
struct vfsconf *vfsp, *prev_vfsp;
|
||||
int i, maxtypenum;
|
||||
int err = 0;
|
||||
char fstypename[MFSNAMELEN];
|
||||
int neednamesearch = 1;
|
||||
|
||||
switch(cmd) {
|
||||
case LKM_E_LOAD:
|
||||
@ -616,26 +614,9 @@ _lkm_vfs(lkmtp, cmd)
|
||||
if (lkmexists(lkmtp))
|
||||
return(EEXIST);
|
||||
|
||||
/* 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;
|
||||
}
|
||||
for (vfsp = vfsconf; vfsp->vfc_next; vfsp = vfsp->vfc_next) {
|
||||
if (!strcmp(vfc->vfc_name, vfsp->vfc_name)) {
|
||||
return EEXIST;
|
||||
}
|
||||
}
|
||||
|
||||
@ -645,21 +626,10 @@ _lkm_vfs(lkmtp, cmd)
|
||||
}
|
||||
args->lkm_offset = vfc->vfc_typenum = i;
|
||||
|
||||
if (maxvfsconf <= vfsp->vfc_typenum)
|
||||
maxvfsconf = vfsp->vfc_typenum + 1;
|
||||
if (maxvfsconf <= i)
|
||||
maxvfsconf = i + 1;
|
||||
|
||||
/* find vfsconf tail */
|
||||
for (lastvfsp = vfsconf; lastvfsp->vfc_next;
|
||||
lastvfsp = lastvfsp->vfc_next) ;
|
||||
|
||||
/* 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;
|
||||
vfsp->vfc_next = vfc;
|
||||
vfc->vfc_next = NULL;
|
||||
|
||||
/* like in vfs_op_init */
|
||||
@ -673,7 +643,7 @@ _lkm_vfs(lkmtp, cmd)
|
||||
/*
|
||||
* Call init function for this VFS...
|
||||
*/
|
||||
(*(vfsp->vfc_vfsops->vfs_init))(vfsp);
|
||||
(*(vfc->vfc_vfsops->vfs_init))(vfc);
|
||||
|
||||
/* done! */
|
||||
break;
|
||||
@ -685,7 +655,7 @@ _lkm_vfs(lkmtp, cmd)
|
||||
prev_vfsp = NULL;
|
||||
for (vfsp = vfsconf; vfsp;
|
||||
prev_vfsp = vfsp, vfsp = vfsp->vfc_next) {
|
||||
if (vfsp->vfc_typenum == vfc->vfc_typenum)
|
||||
if (!strcmp(vfc->vfc_name, vfsp->vfc_name))
|
||||
break;
|
||||
}
|
||||
if (vfsp == NULL) {
|
||||
@ -700,6 +670,15 @@ _lkm_vfs(lkmtp, cmd)
|
||||
|
||||
prev_vfsp->vfc_next = vfsp->vfc_next;
|
||||
|
||||
/*
|
||||
* Maintain maxvfsconf.
|
||||
*/
|
||||
maxtypenum = 0;
|
||||
for (vfsp = vfsconf; vfsp != NULL; vfsp = vfsp->vfc_next)
|
||||
if (maxtypenum < vfsp->vfc_typenum)
|
||||
maxtypenum = vfsp->vfc_typenum;
|
||||
maxvfsconf = maxtypenum + 1;
|
||||
|
||||
break;
|
||||
|
||||
case LKM_E_STAT: /* no special handling... */
|
||||
|
Loading…
Reference in New Issue
Block a user