#include #include #include #include #include #include #include #include #include #include #include enum { Hbase, Hkdev, }; static int get_kdev(char *lst) { int len = 0; for (VfsMount *m = vfs_mount_seed(); m; m = m->prev) { if (m->prefix_len == 0) { continue; /* that's us */ } assert(m->prefix_len > 6); assert(memcmp(m->prefix, "/kdev/", 6) == 0); len += m->prefix_len - 6 + 1; if (lst) { memcpy(lst, m->prefix + 6, m->prefix_len - 6); lst += m->prefix_len - 6; *lst++ = '\0'; } } return len; } static long handle(VfsReq *req) { static char *kdev = NULL; static int kdev_len = 0; const char *lst = NULL; int len = 0; if (!req->caller) return -1; if (req->type != VFSOP_OPEN) { switch ((uintptr_t __force)req->id) { case Hbase: lst = "kdev/"; len = strlen(lst) + 1; break; case Hkdev: if (!kdev) { kdev_len = get_kdev(NULL); kdev = kmalloc(kdev_len); get_kdev(kdev); } lst = kdev; len = kdev_len; break; default: assert(false); } } switch (req->type) { case VFSOP_OPEN: if (reqpathcmp(req, "/")) return Hbase; if (reqpathcmp(req, "/kdev/")) return Hkdev; return -ENOENT; case VFSOP_READ: return req_readcopy(req, lst, len); case VFSOP_GETSIZE: return len; default: return -ENOSYS; } } static void accept(VfsReq *req) { vfsreq_finish_short(req, handle(req)); } void vfs_root_init(void) { vfs_root_register("", accept); }