#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/vnode.h>
#include <sys/lock.h>
#include <sys/disk.h>
#include <sys/mount.h>
#include <sys/namecache.h>
#include <sys/nlookup.h>
#include <sys/proc.h>
#include <sys/devfs.h>
struct mount *synth_mp;
struct vnode *synth_vp;
static int synth_inited = 0;
static int synth_synced = 0;
struct vnode *
getsynthvnode(const char *devname)
{
struct vnode *vp;
struct nchandle nch;
struct nlookupdata nd;
struct ucred *cred = proc0.p_ucred;
int error;
KKASSERT(synth_inited != 0);
KKASSERT(synth_mp != NULL);
KKASSERT(synth_mp->mnt_ncmountpt.mount != NULL);
if (synth_synced < 2) {
sync_devs();
++synth_synced;
}
error = nlookup_init_root(&nd, devname, UIO_SYSSPACE, NLC_FOLLOW,
cred, &synth_mp->mnt_ncmountpt,
&synth_mp->mnt_ncmountpt);
if (error) {
panic("synth: nlookup_init_root failed with %d", error);
}
error = nlookup(&nd);
if (error == 0) {
if (nd.nl_nch.ncp->nc_vp == NULL) {
kprintf("synth: nc_vp == NULL\n");
return (NULL);
}
nch = nd.nl_nch;
cache_zero(&nd.nl_nch);
}
nlookup_done(&nd);
if (error) {
if (error != ENOENT) {
kprintf("synth: nlookup of %s failed with %d\n",
devname, error);
}
return (NULL);
}
vp = nch.ncp->nc_vp;
error = vget(vp, LK_EXCLUSIVE);
cache_unlock(&nch);
if (error) {
kprintf("synth: could not vget vnode\n");
return (NULL);
}
return (vp);
}
static void
synthinit(void *arg __unused)
{
int error;
if ((error = vfs_rootmountalloc("devfs", "dummy", &synth_mp))) {
panic("synth: vfs_rootmountalloc failed with %d", error);
}
if ((error = VFS_MOUNT(synth_mp, NULL, NULL, proc0.p_ucred))) {
panic("synth: vfs_mount failed with %d", error);
}
if ((error = VFS_ROOT(synth_mp, &synth_vp))) {
panic("synth: vfs_root failed with %d", error);
}
cache_allocroot(&synth_mp->mnt_ncmountpt, synth_mp, synth_vp);
cache_unlock(&synth_mp->mnt_ncmountpt);
vput(synth_vp);
synth_inited = 1;
}
SYSINIT(synthinit, SI_SUB_VFS, SI_ORDER_ANY, synthinit, NULL);