mfs is a bit off in the sense that mount(2) doesn't return since

mfs uses the mounting process for the backing store memory.  I
guess mfs could be fixed to just reference the process vmspace and
let it return, but that would probably cause wait() to return for
other worms.  So it's easier to dance according to mfs's tune: if
mounting mfs, create a thread for extra execution context.
This commit is contained in:
pooka 2010-03-08 12:38:14 +00:00
parent cc5a93f703
commit b405c8d23e
1 changed files with 68 additions and 5 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: ukfs.c,v 1.48 2010/03/05 18:49:30 pooka Exp $ */
/* $NetBSD: ukfs.c,v 1.49 2010/03/08 12:38:14 pooka Exp $ */
/*
* Copyright (c) 2007, 2008, 2009 Antti Kantee. All Rights Reserved.
@ -501,6 +501,30 @@ process_diskdevice(const char *devpath, struct ukfs_part *part, int rdonly,
return rv;
}
struct mountinfo {
const char *mi_vfsname;
const char *mi_mountpath;
int mi_mntflags;
void *mi_arg;
size_t mi_alen;
int *mi_error;
};
static void *
mfs_mounter(void *arg)
{
struct mountinfo *mi = arg;
int rv;
rv = rump_sys_mount(mi->mi_vfsname, mi->mi_mountpath, mi->mi_mntflags,
mi->mi_arg, mi->mi_alen);
if (rv) {
warn("mfs mount failed. fix me.");
abort(); /* XXX */
}
return NULL;
}
static struct ukfs *
doukfsmount(const char *vfsname, const char *devpath, struct ukfs_part *part,
const char *mountpath, int mntflags, void *arg, size_t alen)
@ -544,11 +568,50 @@ doukfsmount(const char *vfsname, const char *devpath, struct ukfs_part *part,
regged = 1;
}
rv = rump_sys_mount(vfsname, mountpath, mntflags, arg, alen);
if (rv) {
rv = errno;
goto out;
/*
* MFS is special since mount(2) doesn't return. Hence, we
* create a thread here. Could fix mfs to return, but there's
* too much history for me to bother.
*/
if (strcmp(vfsname, MOUNT_MFS) == 0) {
pthread_t pt;
struct mountinfo mi;
int i;
mi.mi_vfsname = vfsname;
mi.mi_mountpath = mountpath;
mi.mi_mntflags = mntflags;
mi.mi_arg = arg;
mi.mi_alen = alen;
if (pthread_create(&pt, NULL, mfs_mounter, &mi) == -1) {
rv = errno;
goto out;
}
for (i = 0;i < 100000; i++) {
struct statvfs svfsb;
rv = rump_sys_statvfs1(mountpath, &svfsb, ST_WAIT);
if (rv == -1) {
rv = errno;
goto out;
}
if (strcmp(svfsb.f_mntonname, mountpath) == 0 &&
strcmp(svfsb.f_fstypename, MOUNT_MFS) == 0) {
break;
}
usleep(1);
}
} else {
rv = rump_sys_mount(vfsname, mountpath, mntflags, arg, alen);
if (rv) {
rv = errno;
goto out;
}
}
mounted = 1;
rv = rump_pub_vfs_getmp(mountpath, &fs->ukfs_mp);
if (rv) {