diff options
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/init_main.c | 72 | ||||
-rw-r--r-- | sys/kern/kern_fork.c | 78 | ||||
-rw-r--r-- | sys/kern/kern_lock.c | 43 | ||||
-rw-r--r-- | sys/kern/kern_panic.c | 58 | ||||
-rw-r--r-- | sys/kern/kern_sched.c | 179 | ||||
-rw-r--r-- | sys/kern/kern_syslog.c | 105 | ||||
-rw-r--r-- | sys/kern/vfs_init.c | 70 | ||||
-rw-r--r-- | sys/kern/vfs_lookup.c | 83 | ||||
-rw-r--r-- | sys/kern/vfs_subr.c | 122 |
9 files changed, 810 insertions, 0 deletions
diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c new file mode 100644 index 0000000..df955ee --- /dev/null +++ b/sys/kern/init_main.c @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team. + * 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 Hyra 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. + */ + +#include <sys/reboot.h> +#include <sys/syslog.h> +#include <sys/sched.h> +#include <sys/mount.h> +#include <sys/proc.h> +#include <dev/cons/cons.h> +#include <dev/acpi/acpi.h> +#include <machine/cpu.h> +#include <vm/vm.h> + +static struct proc proc0; + +int +main(void) +{ + /* Startup the console */ + cons_init(); + kprintf("Starting Hyra/%s v%s: %s\n", HYRA_ARCH, HYRA_VERSION, + HYRA_BUILDDATE); + + /* Start the ACPI subsystem */ + acpi_init(); + + /* Init the virtual memory subsystem */ + vm_init(); + + /* Startup the BSP */ + cpu_startup(&g_bsp_ci); + + /* Init process 0 */ + md_td_init(&proc0, NULL, 0); + + /* Init the virtual file system */ + vfs_init(); + + /* Start scheduler and bootstrap APs */ + sched_init(); + mp_bootstrap_aps(&g_bsp_ci); + + /* Nothing left to do... halt */ + cpu_reboot(REBOOT_HALT); + __builtin_unreachable(); +} diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c new file mode 100644 index 0000000..64e0caf --- /dev/null +++ b/sys/kern/kern_fork.c @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team. + * 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 Hyra 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. + */ + +#include <sys/types.h> +#include <sys/proc.h> +#include <sys/errno.h> +#include <sys/sched.h> +#include <vm/dynalloc.h> +#include <string.h> + +static size_t nthreads = 0; + +/* + * Fork1 - fork and direct a thread to 'ip' + * + * @cur: Current process. + * @flags: Flags to set. + * @ip: Location for new thread to start at. + * @newprocp: Will contain new thread if not NULL. + */ +int +fork1(struct proc *cur, int flags, void(*ip)(void), struct proc **newprocp) +{ + struct proc *newproc; + int status = 0; + + newproc = dynalloc(sizeof(*newproc)); + if (newproc == NULL) + return -ENOMEM; + + /* + * We want to zero the proc to ensure it is in known + * state. We then want to initialize machine dependent + * fields. + */ + memset(newproc, 0, sizeof(*newproc)); + status = md_td_init(newproc, cur, (uintptr_t)ip); + if (status != 0) + goto done; + + /* Set proc output if we can */ + if (newprocp != NULL) + *newprocp = newproc; + + newproc->pid = nthreads++; + sched_enqueue_td(newproc); +done: + if (status != 0) + dynfree(newproc); + + return status; +} diff --git a/sys/kern/kern_lock.c b/sys/kern/kern_lock.c new file mode 100644 index 0000000..9047a21 --- /dev/null +++ b/sys/kern/kern_lock.c @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team. + * 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 Hyra 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. + */ + +#include <sys/spinlock.h> +#include <sys/types.h> + +void +spinlock_acquire(struct spinlock *lock) +{ + while (__atomic_test_and_set(&lock->lock, __ATOMIC_ACQUIRE)); +} + +void +spinlock_release(struct spinlock *lock) +{ + __atomic_clear(&lock->lock, __ATOMIC_RELEASE); +} diff --git a/sys/kern/kern_panic.c b/sys/kern/kern_panic.c new file mode 100644 index 0000000..0a17456 --- /dev/null +++ b/sys/kern/kern_panic.c @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team. + * 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 Hyra 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. + */ + +#include <sys/panic.h> +#include <sys/spinlock.h> +#include <sys/syslog.h> +#include <sys/reboot.h> + +/* + * Tells the user something terribly wrong happened then + * halting the system as soon as possible. + * + * XXX: There is no need to cleanup stuff here (e.g `va_list ap`) + * as we won't be returning from here anyways and the source + * of the panic could be *anywhere* so it's best not to mess with + * things. + */ +void +panic(const char *fmt, ...) +{ + va_list ap; + static struct spinlock lock = {0}; + + spinlock_acquire(&lock); /* Never released */ + va_start(ap, fmt); + + kprintf(OMIT_TIMESTAMP "panic: "); + vkprintf(fmt, &ap); + + cpu_reboot(REBOOT_HALT); + __builtin_unreachable(); +} diff --git a/sys/kern/kern_sched.c b/sys/kern/kern_sched.c new file mode 100644 index 0000000..c370311 --- /dev/null +++ b/sys/kern/kern_sched.c @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team. + * 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 Hyra 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. + */ + +#include <sys/types.h> +#include <sys/sched.h> +#include <sys/schedvar.h> +#include <sys/cdefs.h> +#include <sys/syslog.h> +#include <machine/frame.h> +#include <machine/cpu.h> +#include <vm/pmap.h> +#include <dev/timer.h> +#include <assert.h> +#include <string.h> + +#define pr_trace(fmt, ...) kprintf("ksched: " fmt, ##__VA_ARGS__) + +void sched_switch(struct trapframe *tf); + +static sched_policy_t policy = SCHED_POLICY_RR; + +/* + * Thread ready queues - all threads ready to be + * scheduled should be added to the toplevel queue. + */ +static struct sched_queue qlist[SCHED_NQUEUE]; + +/* + * Thread queue lock - all operations to `qlist' + * must be done with this lock acquired. + */ +__cacheline_aligned static struct spinlock tdq_lock = {0}; + +/* + * Perform timer oneshot + */ +static inline void +sched_oneshot(bool now) +{ + struct timer timer; + size_t usec = now ? SHORT_TIMESLICE_USEC : DEFAULT_TIMESLICE_USEC; + tmrr_status_t tmr_status; + + tmr_status = req_timer(TIMER_SCHED, &timer); + __assert(tmr_status == TMRR_SUCCESS); + + timer.oneshot_us(usec); +} + +static struct proc * +sched_dequeue_td(void) +{ + struct sched_queue *queue; + struct proc *td = NULL; + + spinlock_acquire(&tdq_lock); + + for (size_t i = 0; i < SCHED_NQUEUE; ++i) { + queue = &qlist[i]; + if (!TAILQ_EMPTY(&queue->q)) { + td = TAILQ_FIRST(&queue->q); + TAILQ_REMOVE(&queue->q, td, link); + break; + } + } + + spinlock_release(&tdq_lock); + return td; +} + +/* + * Add a thread to the scheduler. + */ +void +sched_enqueue_td(struct proc *td) +{ + struct sched_queue *queue; + + spinlock_acquire(&tdq_lock); + queue = &qlist[td->priority]; + + TAILQ_INSERT_TAIL(&queue->q, td, link); + spinlock_release(&tdq_lock); +} + +/* + * Return the currently running thread. + */ +struct proc * +this_td(void) +{ + struct cpu_info *ci; + + ci = this_cpu(); + return ci->curtd; +} + +/* + * Perform a context switch. + * + * TODO + */ +void +sched_switch(struct trapframe *tf) +{ + struct cpu_info *ci; + struct pcb *pcbp; + struct proc *next_td, *td; + + ci = this_cpu(); + td = ci->curtd; + + /* Do we have threads to switch to? */ + if ((next_td = sched_dequeue_td()) == NULL) { + sched_oneshot(false); + return; + } + + /* Re-enqueue the old thread */ + if (td != NULL) { + memcpy(&td->tf, tf, sizeof(td->tf)); + sched_enqueue_td(td); + } + + memcpy(tf, &next_td->tf, sizeof(*tf)); + ci->curtd = next_td; + pcbp = &next_td->pcb; + + pmap_switch_vas(pcbp->addrsp); + sched_oneshot(false); +} + +/* + * Main scheduler loop + */ +void +sched_enter(void) +{ + sched_oneshot(false); + for (;;); +} + +void +sched_init(void) +{ + /* Setup the queues */ + for (int i = 0; i < SCHED_NQUEUE; ++i) { + TAILQ_INIT(&qlist[i].q); + } + + pr_trace("Prepared %d queues (policy=0x%x)\n", + SCHED_NQUEUE, policy); +} diff --git a/sys/kern/kern_syslog.c b/sys/kern/kern_syslog.c new file mode 100644 index 0000000..6962a69 --- /dev/null +++ b/sys/kern/kern_syslog.c @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team. + * 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 Hyra 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. + */ + +#include <sys/syslog.h> +#include <sys/spinlock.h> +#include <dev/cons/cons.h> +#include <dev/timer.h> +#include <stdarg.h> +#include <string.h> + +/* Global logger lock */ +static struct spinlock lock = {0}; + +static void +syslog_write(const char *s, size_t len) +{ + const char *p = s; + + while (len--) { + cons_putch(&g_root_scr, *p); + ++p; + } +} + +/* + * XXX: Not serialized + */ +void +vkprintf(const char *fmt, va_list *ap) +{ + char buffer[1024] = {0}; + + vsnprintf(buffer, sizeof(buffer), fmt, *ap); + syslog_write(buffer, strlen(buffer)); +} + +void +kprintf(const char *fmt, ...) +{ + va_list ap; + char timestamp[64] = "[ 0.000000] "; + const char *fmt_p = fmt; + bool use_timestamp = true; + bool has_counter = true; + struct timer tmr; + + /* + * If the first char is OMIT_TIMESTAMP, then we won't + * print out the timestamp. + */ + if (*fmt == OMIT_TIMESTAMP[0]) { + ++fmt_p; + use_timestamp = false; + } + + /* See if we have a timer */ + if (req_timer(TIMER_GP, &tmr) != TMRR_SUCCESS) { + has_counter = false; + } + + /* If we can use the counter, format the timestamp */ + if (has_counter) { + if (tmr.get_time_sec != NULL && tmr.get_time_usec != NULL) { + snprintf(timestamp, sizeof(timestamp), "[ %d.%06d] ", + tmr.get_time_sec(), tmr.get_time_usec()); + } + } + + if (use_timestamp) { + syslog_write(timestamp, strlen(timestamp)); + } + + spinlock_acquire(&lock); + va_start(ap, fmt); + + vkprintf(fmt_p, &ap); + va_end(ap); + spinlock_release(&lock); +} diff --git a/sys/kern/vfs_init.c b/sys/kern/vfs_init.c new file mode 100644 index 0000000..aafbc00 --- /dev/null +++ b/sys/kern/vfs_init.c @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team. + * 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 Hyra 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. + */ + +#include <sys/param.h> +#include <sys/mount.h> +#include <sys/vnode.h> +#include <sys/panic.h> +#include <string.h> + +struct vnode *g_root_vnode = NULL; +static struct fs_info fs_list[] = { + {MOUNT_RAMFS, &g_initramfs_vfsops, 0, 0}, +}; + +void +vfs_init(void) +{ + struct fs_info *fs; + const struct vfsops *vfsops; + + TAILQ_INIT(&g_mountlist); + + for (size_t i= 0; i < NELEM(fs_list); ++i) { + fs = &fs_list[i]; + vfsops = fs->vfsops; + + /* Try to initialize the filesystem */ + if (vfsops->init != NULL) { + vfsops->init(fs); + } + } +} + +struct fs_info * +vfs_byname(const char *name) +{ + for (int i = 0; i < NELEM(fs_list); ++i) { + if (strcmp(fs_list[i].name, name) == 0) { + return &fs_list[i]; + } + } + + return NULL; +} diff --git a/sys/kern/vfs_lookup.c b/sys/kern/vfs_lookup.c new file mode 100644 index 0000000..83924c6 --- /dev/null +++ b/sys/kern/vfs_lookup.c @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team. + * 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 Hyra 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. + */ + +#include <sys/namei.h> +#include <sys/vnode.h> +#include <sys/errno.h> +#include <vm/dynalloc.h> +#include <string.h> + +/* + * Convert a path to a vnode. + * + * @ndp: Nameidata containing the path and resulting + * vnode. + * + * TODO: Add support for lookups with individual + * path components + */ +int +namei(struct nameidata *ndp) +{ + struct vnode *vp; + struct vop_lookup_args lookup_args; + const char *path = ndp->path; + int status; + + if (path == NULL) { + return -EINVAL; + } + + /* Path must start with "/" */ + if (*path != '/') { + return -EINVAL; + } + + /* Just return the root vnode if we can */ + if (strcmp(path, "/") == 0) { + ndp->vp = g_root_vnode; + return 0; + } + + /* + * Some filesystems (like initramfs) may only understand + * full paths, so try passing it through. + */ + lookup_args.name = path; + lookup_args.dirvp = g_root_vnode; + lookup_args.vpp = &vp; + status = vfs_vop_lookup(lookup_args.dirvp, &lookup_args); + + if (status != 0) { + return status; + } + + ndp->vp = vp; + return 0; +} diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c new file mode 100644 index 0000000..04d64e3 --- /dev/null +++ b/sys/kern/vfs_subr.c @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team. + * 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 Hyra 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. + */ + +#include <sys/vnode.h> +#include <sys/errno.h> +#include <sys/mount.h> +#include <vm/dynalloc.h> +#include <string.h> + +mountlist_t g_mountlist; + +int +vfs_alloc_vnode(struct vnode **res, int type) +{ + struct vnode *vp = dynalloc(sizeof(struct vnode)); + + if (vp == NULL) { + return -ENOMEM; + } + + memset(vp, 0, sizeof(*vp)); + vp->type = type; + *res = vp; + return 0; +} + +/* + * Allocate a mount structure. + * + * @vp: Vnode this mount structure covers. + * @fip: File system information. + */ +struct mount * +vfs_alloc_mount(struct vnode *vp, struct fs_info *fip) +{ + struct mount *mp; + + mp = dynalloc(sizeof(*mp)); + + if (mp == NULL) { + return NULL; + } + + memset(mp, 0, sizeof(*mp)); + mp->vp = vp; + mp->mnt_ops = fip->vfsops; + return mp; +} + +/* + * Release a vnode and its resources from + * memory. + */ +int +vfs_release_vnode(struct vnode *vp) +{ + const struct vops *vops = vp->vops; + int status = 0; + + if (vp == NULL) { + return -EINVAL; + } + + if (vops->reclaim != NULL) { + status = vops->reclaim(vp); + } + + dynfree(vp); + return status; +} + +int +vfs_vop_lookup(struct vnode *vp, struct vop_lookup_args *args) +{ + const struct vops *vops = vp->vops; + + if (vops == NULL) + return -EIO; + if (vops->lookup == NULL) + return -EIO; + + return vops->lookup(args); +} + +int +vfs_vop_read(struct vnode *vp, struct sio_txn *sio) +{ + const struct vops *vops = vp->vops; + + if (vops == NULL) + return -EIO; + if (vops->read == NULL) + return -EIO; + + return vops->read(vp, sio); +} |