/* * VOP_CREAT */ static int emufs_creat(struct vnode *dir, const char *name, bool excl, mode_t mode, struct vnode **ret) { struct emufs_vnode *ev = dir->vn_data; struct emufs_fs *ef = dir->vn_fs->fs_data; struct emufs_vnode *newguy; uint32_t handle; int result; int isdir; result = emu_open(ev->ev_emu, ev->ev_handle, name, true, excl, mode, &handle, &isdir); if (result) { return result; } result = emufs_loadvnode(ef, handle, isdir, &newguy); if (result) { emu_close(ev->ev_emu, handle); return result; } *ret = &newguy->ev_v; return 0; }
/* * VOP_LOOKUP */ static int emufs_lookup(struct vnode *dir, char *pathname, struct vnode **ret) { struct emufs_vnode *ev = dir->vn_data; struct emufs_fs *ef = dir->vn_fs->fs_data; struct emufs_vnode *newguy; uint32_t handle; int result; int isdir; result = emu_open(ev->ev_emu, ev->ev_handle, pathname, false, false, 0, &handle, &isdir); if (result) { return result; } result = emufs_loadvnode(ef, handle, isdir, &newguy); if (result) { emu_close(ev->ev_emu, handle); return result; } *ret = &newguy->ev_v; return 0; }
/* * Routine for "mounting" an emufs - we're not really mounted in the * sense that the VFS understands that term, because we're not * connected to a block device. * * Basically, we just add ourselves to the name list in the VFS layer. */ static int emufs_addtovfs(struct emu_softc *sc, const char *devname) { struct emufs_fs *ef; int result; ef = kmalloc(sizeof(struct emufs_fs)); if (ef==NULL) { return ENOMEM; } ef->ef_fs.fs_sync = emufs_sync; ef->ef_fs.fs_getvolname = emufs_getvolname; ef->ef_fs.fs_getroot = emufs_getroot; ef->ef_fs.fs_unmount = emufs_unmount; ef->ef_fs.fs_data = ef; ef->ef_emu = sc; ef->ef_root = NULL; ef->ef_vnodes = vnodearray_create(); if (ef->ef_vnodes == NULL) { kfree(ef); return ENOMEM; } result = emufs_loadvnode(ef, EMU_ROOTHANDLE, 1, &ef->ef_root); if (result) { kfree(ef); return result; } KASSERT(ef->ef_root!=NULL); result = vfs_addfs(devname, &ef->ef_fs); if (result) { VOP_DECREF(&ef->ef_root->ev_v); kfree(ef); } return result; }