mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-10-27 12:48:22 +00:00
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.
This commit is contained in:
+46
-1
@@ -527,8 +527,41 @@ int devfs_getbyname(char *name, vnode_t **ret) {
|
|||||||
cleanup:
|
cleanup:
|
||||||
return error;
|
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
|
// 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);
|
__assert(type == V_TYPE_CHDEV || type == V_TYPE_BLKDEV);
|
||||||
devnode_t *master = slab_allocate(nodecache);
|
devnode_t *master = slab_allocate(nodecache);
|
||||||
if (master == NULL)
|
if (master == NULL)
|
||||||
@@ -613,6 +646,18 @@ int devfs_getnode(vnode_t *physical, int major, int minor, vnode_t **node) {
|
|||||||
return 0;
|
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) {
|
void devfs_remove(char *name, int major, int minor) {
|
||||||
int key[2] = {major, minor};
|
int key[2] = {major, minor};
|
||||||
// remove devtable reference
|
// remove devtable reference
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
#define DEV_MAJOR_PROF 14
|
#define DEV_MAJOR_PROF 14
|
||||||
#define DEV_MAJOR_INPUT 15
|
#define DEV_MAJOR_INPUT 15
|
||||||
#define DEV_MAJOR_AUDIO 16
|
#define DEV_MAJOR_AUDIO 16
|
||||||
|
#define DEV_MAJOR_KCOV 17
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int (*open)(int minor, vnode_t **vnode, int flags);
|
int (*open)(int minor, vnode_t **vnode, int flags);
|
||||||
@@ -49,9 +50,13 @@ typedef struct devnode_t {
|
|||||||
|
|
||||||
void devfs_init();
|
void devfs_init();
|
||||||
int devfs_getnode(vnode_t *physical, int major, int minor, vnode_t **node);
|
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_getbyname(char *name, vnode_t **ret);
|
||||||
int devfs_createdir(char *name);
|
int devfs_createdir(char *name);
|
||||||
|
void devfs_remove_anonymous(int major, int minor);
|
||||||
void devfs_remove(char *name, int major, int minor);
|
void devfs_remove(char *name, int major, int minor);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user