From 1c65a2c8919cb23b9fd05e9033795e2fe00cfce7 Mon Sep 17 00:00:00 2001 From: Matheus Date: Mon, 5 Oct 2026 14:33:30 -0300 Subject: [PATCH] devfs: add anonymous variants to register/remove The current devfs code requires registered devices to have a name on creation. This makes temporary/hidden devices like pty master ends appear for a split second on the devfs tree. Add a way of registering/removing devfs nodes which do not have a name on the tree. --- kernel-src/fs/devfs.c | 47 ++++++++++++++++++++++++++++++- kernel-src/include/kernel/devfs.h | 7 ++++- 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/kernel-src/fs/devfs.c b/kernel-src/fs/devfs.c index e71dd3f3..d172aa10 100644 --- a/kernel-src/fs/devfs.c +++ b/kernel-src/fs/devfs.c @@ -527,8 +527,41 @@ int devfs_getbyname(char *name, vnode_t **ret) { cleanup: return error; } + +int devfs_register_anonymous(devops_t *devops, int type, int major, int minor, mode_t mode, + cred_t *cred, vnode_t **out) { + __assert(type == V_TYPE_CHDEV || type == V_TYPE_BLKDEV); + devnode_t *master = slab_allocate(nodecache); + if (master == NULL) + return ENOMEM; + + master->vnode.type = type; + master->devops = devops; + master->attr.mode = mode; + master->attr.rdevmajor = major; + master->attr.rdevminor = minor; + master->attr.uid = cred == NULL ? 0 : cred->euid; + master->attr.gid = cred == NULL ? 0 : cred->egid; + + int key[2] = {major, minor}; + + MUTEX_ACQUIRE(&tablelock); + int error = hashtable_set(&devtable, master, key, sizeof(key), true); + MUTEX_RELEASE(&tablelock); + if (error) { + destroy_node(master); + return error; + } + + VOP_HOLD(&master->vnode); + *out = &master->vnode; + + return 0; +} + // register new device -int devfs_register(devops_t *devops, char *name, int type, int major, int minor, mode_t mode, cred_t *cred) { +int devfs_register(devops_t *devops, char *name, int type, int major, int minor, mode_t mode, + cred_t *cred) { __assert(type == V_TYPE_CHDEV || type == V_TYPE_BLKDEV); devnode_t *master = slab_allocate(nodecache); if (master == NULL) @@ -613,6 +646,18 @@ int devfs_getnode(vnode_t *physical, int major, int minor, vnode_t **node) { return 0; } +void devfs_remove_anonymous(int major, int minor) { + int key[2] = {major, minor}; + void *master; + MUTEX_ACQUIRE(&tablelock); + __assert(hashtable_get(&devtable, &master, key, sizeof(key)) == 0); + __assert(hashtable_remove(&devtable, key, sizeof(key)) == 0); + MUTEX_RELEASE(&tablelock); + + vnode_t *vnode = master; + VOP_RELEASE(vnode); +} + void devfs_remove(char *name, int major, int minor) { int key[2] = {major, minor}; // remove devtable reference diff --git a/kernel-src/include/kernel/devfs.h b/kernel-src/include/kernel/devfs.h index d83b9dee..cfcb2068 100644 --- a/kernel-src/include/kernel/devfs.h +++ b/kernel-src/include/kernel/devfs.h @@ -23,6 +23,7 @@ #define DEV_MAJOR_PROF 14 #define DEV_MAJOR_INPUT 15 #define DEV_MAJOR_AUDIO 16 +#define DEV_MAJOR_KCOV 17 typedef struct { int (*open)(int minor, vnode_t **vnode, int flags); @@ -49,9 +50,13 @@ typedef struct devnode_t { void devfs_init(); int devfs_getnode(vnode_t *physical, int major, int minor, vnode_t **node); -int devfs_register(devops_t *devops, char *name, int type, int major, int minor, mode_t mode, cred_t *cred); +int devfs_register_anonymous(devops_t *devops, int type, int major, int minor, mode_t mode, + cred_t *cred, vnode_t **out); +int devfs_register(devops_t *devops, char *name, int type, int major, int minor, mode_t mode, + cred_t *cred); int devfs_getbyname(char *name, vnode_t **ret); int devfs_createdir(char *name); +void devfs_remove_anonymous(int major, int minor); void devfs_remove(char *name, int major, int minor); #endif