diff options
author | Ian Moffett <ian@osmora.org> | 2025-09-27 18:01:35 -0400 |
---|---|---|
committer | Ian Moffett <ian@osmora.org> | 2025-09-27 18:01:35 -0400 |
commit | 0487527441dff0c16d206bdf1747daa625b7597d (patch) | |
tree | 500efce2b3405636133fb6278fd07c7249972fd5 /src/sys/fs | |
parent | f933a2b93b8887e7104b15df85c6a8a3ed99df69 (diff) |
kern: fs: Add initial devfs implementation
Signed-off-by: Ian Moffett <ian@osmora.org>
Diffstat (limited to 'src/sys/fs')
-rw-r--r-- | src/sys/fs/devfs.c | 166 |
1 files changed, 166 insertions, 0 deletions
diff --git a/src/sys/fs/devfs.c b/src/sys/fs/devfs.c new file mode 100644 index 0000000..7553003 --- /dev/null +++ b/src/sys/fs/devfs.c @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2025 Ian Marco Moffett and L5 engineers + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Description: Device filesystem + * Author: Ian Marco Moffett + */ + +#include <sys/errno.h> +#include <sys/mount.h> +#include <sys/syslog.h> +#include <os/vnode.h> +#include <os/kalloc.h> +#include <fs/devfs.h> +#include <string.h> + +static struct vop devfs_vops; +static TAILQ_HEAD(, devfs_node) nodelist; + +/* + * Find a node within the device filesystem + */ +static int +devfs_lookup(struct vop_lookup_args *args) +{ + int error; + struct devfs_node *dnp = NULL; + struct vnode *vp; + + if (args == NULL) { + return -EINVAL; + } + + /* Need a pointer to write the result */ + if (args->vpp == NULL) { + return -EINVAL; + } + + TAILQ_FOREACH(dnp, &nodelist, link) { + if (dnp == NULL) { + continue; + } + + if (strcmp(dnp->name, args->name) != 0) { + continue; + } + + /* Found it! Create a vnode */ + error = vfs_valloc(&vp, VTYPE_FILE, 0); + if (error < 0) { + return error; + } + + vp->data = dnp; + *args->vpp = vp; + return 0; + } + + return -ENOENT; +} + +/* + * Register a new device to devfs + */ +int +devfs_register(const char *name, dev_type_t type, void *devsw, int flags) +{ + struct devfs_node *dnp; + size_t devname_len; + struct vop_lookup_args args; + struct vnode *vp; + + if (name == NULL || devsw == NULL) { + return -EINVAL; + } + + if (type >= __DEVFS_NTYPE) { + return -EINVAL; + } + + dnp = kalloc(sizeof(*dnp)); + if (dnp == NULL) { + return -ENOMEM; + } + + switch (type) { + case DEVFS_NONE: + case DEVFS_CDEV: + dnp->type = type; + break; + } + + devname_len = strlen(name); + memcpy(dnp->name, name, devname_len); + TAILQ_INSERT_TAIL(&nodelist, dnp, link); + return 0; +} + +/* + * Initialize the device filesystem + */ +static int +devfs_init(struct fs_info *fip) +{ + (void)fip; + TAILQ_INIT(&nodelist); + return 0; +} + +/* + * Mount the device filesystem + */ +static int +devfs_mount(struct fs_info *fip, struct mount_args *margs) +{ + int error; + struct vnode *vp; + + if (fip == NULL || margs == NULL) { + return -1; + } + + error = vfs_valloc(&margs->vp_res, VTYPE_DIR, 0); + if (error < 0) { + return error; + } + + vp = margs->vp_res; + vp->vops = &devfs_vops; + return 0; +} + +static struct vop devfs_vops = { + .lookup = devfs_lookup +}; + +struct vfsops g_devfs_vfops = { + .init = devfs_init, + .mount = devfs_mount +}; |