From 98ccb3a2d41015b42d46d8b382decc755a003c3f Mon Sep 17 00:00:00 2001 From: Ian Moffett Date: Tue, 4 Jun 2024 13:41:11 -0400 Subject: project: Initial commit Signed-off-by: Ian Moffett --- builddeps/binutils.patch | 99 ++++++++++++++++++++++++++++++ builddeps/gcc.patch | 157 +++++++++++++++++++++++++++++++++++++++++++++++ builddeps/limine.cfg | 8 +++ 3 files changed, 264 insertions(+) create mode 100644 builddeps/binutils.patch create mode 100644 builddeps/gcc.patch create mode 100644 builddeps/limine.cfg (limited to 'builddeps') diff --git a/builddeps/binutils.patch b/builddeps/binutils.patch new file mode 100644 index 0000000..728d82f --- /dev/null +++ b/builddeps/binutils.patch @@ -0,0 +1,99 @@ +diff -ruN binutils-2.42-copy/bfd/config.bfd binutils-2.42/bfd/config.bfd +--- binutils-2.42-copy/bfd/config.bfd 2024-01-28 19:00:00.000000000 -0500 ++++ binutils-2.42/bfd/config.bfd 2024-03-03 11:27:01.508232956 -0500 +@@ -665,6 +665,11 @@ + targ_selvecs= + targ64_selvecs=x86_64_elf64_vec + ;; ++ i[3-7]86-*-hyra*) ++ targ_defvec=i386_elf32_vec ++ targ_selvecs= ++ targ64_selvecs=x86_64_elf64_vec ++ ;; + #ifdef BFD64 + x86_64-*-cloudabi*) + targ_defvec=x86_64_elf64_cloudabi_vec +@@ -729,6 +734,11 @@ + targ_defvec=x86_64_elf64_vec + targ_selvecs=i386_elf32_vec + want64=true ++ ;; ++ x86_64-*-hyra*) ++ targ_defvec=x86_64_elf64_vec ++ targ_selvecs=i386_elf32_vec ++ want64=true + ;; + x86_64-*-gnu*) + targ_defvec=x86_64_elf64_vec +diff -ruN binutils-2.42-copy/config.sub binutils-2.42/config.sub +--- binutils-2.42-copy/config.sub 2024-01-28 19:00:00.000000000 -0500 ++++ binutils-2.42/config.sub 2024-03-03 11:27:01.508232956 -0500 +@@ -1766,7 +1766,7 @@ + | onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \ + | midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \ + | nsk* | powerunix* | genode* | zvmoe* | qnx* | emx* | zephyr* \ +- | fiwix* | mlibc* | cos* | mbr* ) ++ | fiwix* | mlibc* | cos* | mbr* | hyra* ) + ;; + # This one is extra strict with allowed versions + sco3.2v2 | sco3.2v[4-9]* | sco5v6*) +diff -ruN binutils-2.42-copy/gas/configure.tgt binutils-2.42/gas/configure.tgt +--- binutils-2.42-copy/gas/configure.tgt 2024-01-28 19:00:00.000000000 -0500 ++++ binutils-2.42/gas/configure.tgt 2024-03-03 11:27:01.508232956 -0500 +@@ -229,6 +229,7 @@ + i386-*-beos*) fmt=elf ;; + i386-*-elfiamcu) fmt=elf arch=iamcu ;; + i386-*-elf*) fmt=elf ;; ++ i386-*-hyra*) fmt=elf em=gnu ;; + i386-*-fuchsia*) fmt=elf ;; + i386-*-haiku*) fmt=elf em=haiku ;; + i386-*-genode*) fmt=elf ;; +diff -ruN binutils-2.42-copy/gprofng/libcollector/configure.ac binutils-2.42/gprofng/libcollector/configure.ac +--- binutils-2.42-copy/gprofng/libcollector/configure.ac 2024-01-28 19:00:00.000000000 -0500 ++++ binutils-2.42/gprofng/libcollector/configure.ac 2024-03-03 11:27:01.508232956 -0500 +@@ -18,7 +18,7 @@ + + m4_include([../../bfd/version.m4]) + AC_INIT([gprofng], BFD_VERSION) +-AC_CONFIG_MACRO_DIRS([../../config ../..]) ++#AC_CONFIG_MACRO_DIRS([../../config ../..]) + AC_CONFIG_AUX_DIR(../..) + AC_CANONICAL_TARGET + AM_INIT_AUTOMAKE +diff -ruN binutils-2.42-copy/ld/configure.tgt binutils-2.42/ld/configure.tgt +--- binutils-2.42-copy/ld/configure.tgt 2024-01-28 19:00:00.000000000 -0500 ++++ binutils-2.42/ld/configure.tgt 2024-03-03 11:29:12.677328228 -0500 +@@ -384,6 +384,10 @@ + i[3-7]86-*-redox*) targ_emul=elf_i386 + targ_extra_emuls=elf_x86_64 + ;; ++i[3-7]86-*-hyra*) ++ targ_emul=elf_i386 ++ targ_extra_emuls=elf_x86_64 ++ ;; + i[3-7]86-*-solaris2*) targ_emul=elf_i386_sol2 + targ_extra_emuls="elf_i386_ldso elf_i386 elf_iamcu elf_x86_64_sol2 elf_x86_64" + targ_extra_libpath=$targ_extra_emuls +@@ -1023,6 +1027,10 @@ + x86_64-*-redox*) targ_emul=elf_x86_64 + targ_extra_emuls=elf_i386 + ;; ++x86_64-*-hyra*) ++ targ_emul=elf_x86_64 ++ targ_extra_emuls=elf_i386 ++ ;; + x86_64-*-solaris2*) targ_emul=elf_x86_64_sol2 + targ_extra_emuls="elf_x86_64 elf_i386_sol2 elf_i386_ldso elf_i386 elf_iamcu" + targ_extra_libpath=$targ_extra_emuls +diff -ruN binutils-2.42-copy/libiberty/configure.ac binutils-2.42/libiberty/configure.ac +--- binutils-2.42-copy/libiberty/configure.ac 2024-01-28 19:00:00.000000000 -0500 ++++ binutils-2.42/libiberty/configure.ac 2024-03-03 11:27:01.508232956 -0500 +@@ -37,7 +37,7 @@ + libiberty_topdir="${srcdir}/.." + fi + AC_SUBST(libiberty_topdir) +-AC_CONFIG_AUX_DIR($libiberty_topdir) ++AC_CONFIG_AUX_DIR([.]) + + dnl Very limited version of automake's enable-maintainer-mode + diff --git a/builddeps/gcc.patch b/builddeps/gcc.patch new file mode 100644 index 0000000..d01c442 --- /dev/null +++ b/builddeps/gcc.patch @@ -0,0 +1,157 @@ +diff -ruN gcc-13.2.0-copy/config.sub gcc-13.2.0/config.sub +--- gcc-13.2.0-copy/config.sub 2024-03-03 11:35:31.049089458 -0500 ++++ gcc-13.2.0/config.sub 2024-03-03 11:43:08.078903300 -0500 +@@ -1749,7 +1749,7 @@ + | onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \ + | midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \ + | nsk* | powerunix* | genode* | zvmoe* | qnx* | emx* | zephyr* \ +- | fiwix* ) ++ | fiwix* | hyra* ) + ;; + # This one is extra strict with allowed versions + sco3.2v2 | sco3.2v[4-9]* | sco5v6*) +diff -ruN gcc-13.2.0-copy/fixincludes/mkfixinc.sh gcc-13.2.0/fixincludes/mkfixinc.sh +--- gcc-13.2.0-copy/fixincludes/mkfixinc.sh 2024-03-03 11:35:30.112403110 -0500 ++++ gcc-13.2.0/fixincludes/mkfixinc.sh 2024-03-03 11:43:52.212764492 -0500 +@@ -20,6 +20,8 @@ + powerpcle-*-eabisim* | \ + powerpcle-*-eabi* | \ + *-*-vxworks7* | \ ++ *-hyra* | \ ++ *-*-hyra* | \ + *-musl* ) + # IF there is no include fixing, + # THEN create a no-op fixer and exit +diff -ruN gcc-13.2.0-copy/gcc/config/hyra.h gcc-13.2.0/gcc/config/hyra.h +--- gcc-13.2.0-copy/gcc/config/hyra.h 1969-12-31 19:00:00.000000000 -0500 ++++ gcc-13.2.0/gcc/config/hyra.h 2024-03-03 11:45:20.143810858 -0500 +@@ -0,0 +1,29 @@ ++#undef TARGET_HYRA ++#define TARGET_HYRA 1 ++ ++#undef LIB_SPEC ++#define LIB_SPEC "-lc" ++ ++#undef STARTFILE_SPEC ++#define STARTFILE_SPEC "%{!shared:crt0.o%s} crti.o%s %{shared:crtbeginS.o%s;:crtbegin.o%s}" ++ ++#undef ENDFILE_SPEC ++#define ENDFILE_SPEC "%{shared:crtendS.o%s;:crtend.o%s} crtn.o%s" ++ ++#define GNU_USER_LINK_EMULATION32 "elf_i386" ++#define GNU_USER_LINK_EMULATION64 "elf_x86_64" ++#define GNU_USER_LINK_EMULATIONX32 "elf32_x86_64" ++ ++#define GNU_USER_DYNAMIC_LINKER32 "/usr/lib/ld_i386.so" ++#define GNU_USER_DYNAMIC_LINKER64 "/usr/lib/ld.so" ++#define GNU_USER_DYNAMIC_LINKERX32 "/usr/lib/ld32.so" ++ ++#undef TARGET_OS_CPP_BUILTINS ++#define TARGET_OS_CPP_BUILTINS() \ ++ do { \ ++ builtin_define ("__hyra__"); \ ++ builtin_define ("__unix__"); \ ++ builtin_assert ("system=hyra"); \ ++ builtin_assert ("system=unix"); \ ++ builtin_assert ("system=posix"); \ ++ } while (0); +diff -ruN gcc-13.2.0-copy/gcc/config.gcc gcc-13.2.0/gcc/config.gcc +--- gcc-13.2.0-copy/gcc/config.gcc 2024-03-03 11:35:31.552433364 -0500 ++++ gcc-13.2.0/gcc/config.gcc 2024-03-03 11:47:40.945471968 -0500 +@@ -843,6 +843,15 @@ + *-*-fuchsia*) + native_system_header_dir=/include + ;; ++*-*-hyra*) ++ extra_options="$extra_options gnu-user.opt" ++ gas=yes ++ gnu_ld=yes ++ default_use_cxa_atexit=yes ++ use_gcc_stdint=wrap ++ tmake_file="${tmake_file} t-slibgcc" ++ thread_file='posix' ++ ;; + *-*-linux* | frv-*-*linux* | *-*-kfreebsd*-gnu | *-*-gnu* | *-*-kopensolaris*-gnu | *-*-uclinuxfdpiceabi) + extra_options="$extra_options gnu-user.opt" + gas=yes +@@ -2218,6 +2227,9 @@ + tmake_file="${tmake_file} i386/t-x86_64-elf" + tm_file="${tm_file} i386/unix.h i386/att.h elfos.h newlib-stdint.h i386/i386elf.h i386/x86-64.h fuchsia.h" + ;; ++x86_64-*-hyra*) ++ tm_file="${tm_file} i386/unix.h i386/att.h elfos.h gnu-user.h glibc-stdint.h i386/x86-64.h i386/gnu-user-common.h i386/gnu-user64.h hyra.h" ++ ;; + ia64*-*-elf*) + tm_file="${tm_file} elfos.h newlib-stdint.h ia64/sysv4.h ia64/elf.h" + tmake_file="ia64/t-ia64" +diff -ruN gcc-13.2.0-copy/libgcc/config.host gcc-13.2.0/libgcc/config.host +--- gcc-13.2.0-copy/libgcc/config.host 2024-03-03 11:35:30.195738195 -0500 ++++ gcc-13.2.0/libgcc/config.host 2024-03-03 11:49:47.703619260 -0500 +@@ -281,6 +281,11 @@ + tmake_file="$tmake_file t-crtstuff-pic t-libgcc-pic t-eh-dw2-dip t-slibgcc t-slibgcc-fuchsia" + extra_parts="crtbegin.o crtend.o" + ;; ++*-*-hyra*) ++ extra_parts="$extra_parts crtbegin.o crtbeginS.o crtend.o crtendS.o" ++ tmake_file="$tmake_file t-crtstuff-pic" ++ tmake_file="$tmake_file t-slibgcc t-slibgcc-gld t-slibgcc-elf-ver t-libgcc-pic" ++ ;; + *-*-linux* | frv-*-*linux* | *-*-kfreebsd*-gnu | *-*-gnu* | *-*-kopensolaris*-gnu | *-*-uclinuxfdpiceabi) + tmake_file="$tmake_file t-crtstuff-pic t-libgcc-pic t-eh-dw2-dip t-slibgcc t-slibgcc-gld t-slibgcc-elf-ver t-linux" + extra_parts="crtbegin.o crtbeginS.o crtbeginT.o crtend.o crtendS.o" +@@ -715,6 +720,10 @@ + x86_64-*-fuchsia*) + tmake_file="$tmake_file t-libgcc-pic" + ;; ++x86_64-*-hyra*) ++ extra_parts="$extra_parts crtprec32.o crtprec64.o crtprec80.o crtfastmath.o" ++ tmake_file="$tmake_file i386/t-crtpc t-crtfm i386/t-crtstuff t-dfprules" ++ ;; + i[34567]86-*-dragonfly*) + tmake_file="${tmake_file} i386/t-dragonfly i386/t-crtstuff" + md_unwind_header=i386/dragonfly-unwind.h +diff -ruN gcc-13.2.0-copy/libgcc/configure.ac gcc-13.2.0/libgcc/configure.ac +--- gcc-13.2.0-copy/libgcc/configure.ac 2024-03-03 11:35:30.195738195 -0500 ++++ gcc-13.2.0/libgcc/configure.ac 2024-03-03 11:50:05.950497937 -0500 +@@ -46,7 +46,7 @@ + libgcc_topdir="${srcdir}/.." + fi + AC_SUBST(libgcc_topdir) +-AC_CONFIG_AUX_DIR($libgcc_topdir) ++AC_CONFIG_AUX_DIR([.]) + AC_CONFIG_HEADER(auto-target.h:config.in) + + AC_ARG_ENABLE(shared, +diff -ruN gcc-13.2.0-copy/libiberty/configure.ac gcc-13.2.0/libiberty/configure.ac +--- gcc-13.2.0-copy/libiberty/configure.ac 2024-03-03 11:35:35.829189807 -0500 ++++ gcc-13.2.0/libiberty/configure.ac 2024-03-03 11:50:29.010765475 -0500 +@@ -37,7 +37,7 @@ + libiberty_topdir="${srcdir}/.." + fi + AC_SUBST(libiberty_topdir) +-AC_CONFIG_AUX_DIR($libiberty_topdir) ++AC_CONFIG_AUX_DIR([.]) + + dnl Very limited version of automake's enable-maintainer-mode + +diff -ruN gcc-13.2.0-copy/libstdc++-v3/crossconfig.m4 gcc-13.2.0/libstdc++-v3/crossconfig.m4 +--- gcc-13.2.0-copy/libstdc++-v3/crossconfig.m4 2024-03-03 11:35:30.979087987 -0500 ++++ gcc-13.2.0/libstdc++-v3/crossconfig.m4 2024-03-03 11:51:42.994954128 -0500 +@@ -140,6 +140,17 @@ + SECTION_FLAGS='-ffunction-sections -fdata-sections' + AC_SUBST(SECTION_FLAGS) + ;; ++*-hyra*) ++ GLIBCXX_CHECK_COMPILER_FEATURES ++ GLIBCXX_CHECK_LINKER_FEATURES ++ GLIBCXX_CHECK_MATH_SUPPORT ++ GLIBCXX_CHECK_STDLIB_SUPPORT ++ AC_DEFINE(_GLIBCXX_USE_DEV_RANDOM) ++ AC_DEFINE(_GLIBCXX_USE_RANDOM_TR1) ++ GCC_CHECK_TLS ++ AC_CHECK_FUNCS(aligned_alloc posix_memalign memalign _aligned_malloc) ++ AC_CHECK_FUNCS(timespec_get) ++ ;; + + *-hpux*) + SECTION_FLAGS='-ffunction-sections -fdata-sections' diff --git a/builddeps/limine.cfg b/builddeps/limine.cfg new file mode 100644 index 0000000..ec496b7 --- /dev/null +++ b/builddeps/limine.cfg @@ -0,0 +1,8 @@ +TIMEOUT=0 + +:Hyra + +PROTOCOL=limine +KERNEL_PATH=boot:///boot/hyra-kernel +MODULE_PATH=boot:///boot/initramfs.tar +EDITOR_ENABLED=no -- cgit v1.2.3 From c2056f5a365c85780dd2d2835547723f6f60c192 Mon Sep 17 00:00:00 2001 From: Ian Moffett Date: Wed, 19 Jun 2024 22:18:16 -0400 Subject: kernel: Add initramfs and initial VFS code Signed-off-by: Ian Moffett --- Makefile.in | 9 +- builddeps/limine.cfg | 2 +- sys/fs/initramfs.c | 263 +++++++++++++++++++++++++++++++++++++++++++++ sys/include/fs/initramfs.h | 37 +++++++ sys/include/sys/mount.h | 84 +++++++++++++++ sys/include/sys/namei.h | 44 ++++++++ sys/include/sys/vnode.h | 74 +++++++++++++ sys/kern/init_main.c | 4 + sys/kern/vfs_init.c | 70 ++++++++++++ sys/kern/vfs_lookup.c | 83 ++++++++++++++ sys/kern/vfs_subr.c | 122 +++++++++++++++++++++ 11 files changed, 790 insertions(+), 2 deletions(-) create mode 100644 sys/fs/initramfs.c create mode 100644 sys/include/fs/initramfs.h create mode 100644 sys/include/sys/mount.h create mode 100644 sys/include/sys/namei.h create mode 100644 sys/include/sys/vnode.h create mode 100644 sys/kern/vfs_init.c create mode 100644 sys/kern/vfs_lookup.c create mode 100644 sys/kern/vfs_subr.c (limited to 'builddeps') diff --git a/Makefile.in b/Makefile.in index 0142b13..b6af9d9 100644 --- a/Makefile.in +++ b/Makefile.in @@ -46,7 +46,7 @@ override KERNEL_ASMOBJECTS = $(KERNEL_ASMFILES:.S=.S.o) override KERNEL_HEADER_DEPS = $(KERNEL_CFILES:.c=.d) .PHONY: all -all: base base/boot/hyra-kernel iso +all: base base/boot/hyra-kernel ramfs iso rm -f sys/include/machine rm -rf iso_root @@ -60,6 +60,12 @@ base: run: $(QEMU) $(QEMU_FLAGS) +.PHONY: ramfs +ramfs: + cd base/; find . -name "*" | cpio --create --format=odc \ + --no-absolute-filenames > ../ramfs.cpio + $(PROMPT) " RAMFS " $(shell pwd)/ramfs.cpio + .PHONY: clean clean: rm -f $(KERNEL_ASMOBJECTS) $(KERNEL_OBJECTS) $(KERNEL_HEADER_DEPS) @@ -70,6 +76,7 @@ iso: mkdir -p iso_root/boot/ mkdir -p iso_root/EFI/BOOT/ cp stand/limine/BOOTX64.EFI iso_root/EFI/BOOT/ + mv ramfs.cpio iso_root/boot/ cp builddeps/limine.cfg stand/limine/limine-bios.sys \ stand/limine/limine-bios-cd.bin stand/limine/limine-uefi-cd.bin iso_root/ cp base/boot/* iso_root/boot/ diff --git a/builddeps/limine.cfg b/builddeps/limine.cfg index ec496b7..87b39de 100644 --- a/builddeps/limine.cfg +++ b/builddeps/limine.cfg @@ -4,5 +4,5 @@ TIMEOUT=0 PROTOCOL=limine KERNEL_PATH=boot:///boot/hyra-kernel -MODULE_PATH=boot:///boot/initramfs.tar +MODULE_PATH=boot:///boot/ramfs.cpio EDITOR_ENABLED=no diff --git a/sys/fs/initramfs.c b/sys/fs/initramfs.c new file mode 100644 index 0000000..4c47da8 --- /dev/null +++ b/sys/fs/initramfs.c @@ -0,0 +1,263 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define CPIO_TRAILER "TRAILER!!!" + +/* + * File or directory. + */ +struct initramfs_node { + const char *path; /* Path */ + void *data; /* File data */ + size_t size; /* File size */ + mode_t mode; /* Perms and type */ +}; + +/* + * ODC CPIO header + */ +struct cpio_hdr { + char c_magic[6]; + char c_dev[6]; + char c_ino[6]; + char c_mode[6]; + char c_uid[6]; + char c_gid[6]; + char c_nlink[6]; + char c_rdev[6]; + char c_mtime[11]; + char c_namesize[6]; + char c_filesize[11]; +}; + +static volatile struct limine_module_request mod_req = { + .id = LIMINE_MODULE_REQUEST, + .revision = 0 +}; + +static const char *initramfs = NULL; +static uint64_t initramfs_size; + +/* + * Fetch a module from the bootloader. + * This is used to fetch the ramfs image. + */ +static char * +get_module(const char *path, uint64_t *size) { + for (uint64_t i = 0; i < mod_req.response->module_count; ++i) { + if (strcmp(mod_req.response->modules[i]->path, path) == 0) { + *size = mod_req.response->modules[i]->size; + return mod_req.response->modules[i]->address; + } + } + + return NULL; +} + +/* + * Convert octal to base 10 + */ +static uint32_t +oct2dec(const char *in, size_t sz) +{ + size_t val = 0; + + for (size_t i = 0; i < sz; ++i) { + val = val * 8 + (in[i] - '0'); + } + + return val; +} + +/* + * Get a file from initramfs + * + * @path: Path of file to get. + * @res: Pointer to new resulting node. + */ +static int +initramfs_get_file(const char *path, struct initramfs_node *res) +{ + const struct cpio_hdr *hdr; + struct initramfs_node node; + uintptr_t addr; + size_t namesize, filesize; + mode_t mode; + + addr = (uintptr_t)initramfs; + for (;;) { + hdr = (void *)addr; + namesize = oct2dec(hdr->c_namesize, sizeof(hdr->c_namesize)); + filesize = oct2dec(hdr->c_filesize, sizeof(hdr->c_filesize)); + mode = oct2dec(hdr->c_mode, sizeof(hdr->c_mode)); + + /* Make sure the magic is correct */ + if (strncmp(hdr->c_magic, "070707", 6) != 0) { + return -EINVAL; + } + + addr += sizeof(struct cpio_hdr); + node.path = (const char *)addr; + + /* Is this the requested file? */ + if (strcmp(node.path, path) == 0) { + node.data = (void *)(addr + namesize); + node.size = filesize; + node.mode = mode; + *res = node; + return 0; + } + + /* Get next header and see if we are at the end */ + addr += (namesize + filesize); + if (strcmp(node.path, CPIO_TRAILER) == 0) { + break; + } + } + + return -ENOENT; +} + +static int +initramfs_lookup(struct vop_lookup_args *args) +{ + int status, vtype; + struct initramfs_node *n; + struct vnode *vp; + const char *path = args->name; + + if (*path == '/') { + ++path; + } + + n = dynalloc(sizeof(*n)); + if (n == NULL) { + return -ENOMEM; + } + + /* Now does this file exist? */ + if ((status = initramfs_get_file(path, n)) != 0) { + dynfree(n); + return status; + } + + vtype = ISSET(n->mode, 0040000) ? VDIR : VREG; + + /* Try to create a new vnode */ + if ((status = vfs_alloc_vnode(&vp, vtype)) != 0) { + dynfree(n); + return status; + } + + vp->data = n; + vp->vops = &g_initramfs_vops; + *args->vpp = vp; + return 0; +} + +static int +initramfs_read(struct vnode *vp, struct sio_txn *sio) +{ + struct initramfs_node *n = vp->data; + uint8_t *src, *dest; + uint32_t count = 0; + + /* Ensure pointers are valid */ + if (n == NULL) + return -EIO; + if (sio->buf == NULL) + return -EIO; + + src = n->data; + dest = sio->buf; + + /* Copy the file data */ + for (size_t i = 0; i < sio->len; ++i) { + if ((sio->offset + i) >= n->size) { + break; + } + dest[i] = src[sio->offset + i]; + ++count; + } + + return count; +} + +static int +initramfs_reclaim(struct vnode *vp) +{ + if (vp->data != NULL) { + dynfree(vp->data); + } + + return 0; +} + +static int +initramfs_init(struct fs_info *fip) +{ + struct mount *mp; + int status; + + initramfs = get_module("/boot/ramfs.cpio", &initramfs_size); + if (initramfs == NULL) { + panic("Failed to open initramfs cpio image\n"); + } + + status = vfs_alloc_vnode(&g_root_vnode, VDIR); + if (__unlikely(status != 0)) { + panic("Failed to create root vnode for ramfs\n"); + } + + g_root_vnode->vops = &g_initramfs_vops; + mp = vfs_alloc_mount(g_root_vnode, fip); + TAILQ_INSERT_TAIL(&g_mountlist, mp, mnt_list); + return 0; +} + +const struct vops g_initramfs_vops = { + .lookup = initramfs_lookup, + .read = initramfs_read, + .reclaim = initramfs_reclaim +}; + +const struct vfsops g_initramfs_vfsops = { + .init = initramfs_init +}; diff --git a/sys/include/fs/initramfs.h b/sys/include/fs/initramfs.h new file mode 100644 index 0000000..897079c --- /dev/null +++ b/sys/include/fs/initramfs.h @@ -0,0 +1,37 @@ +/* + * 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. + */ + +#ifndef _INITRAMFS_H_ +#define _INITRAMFS_H_ + +#include + +extern const struct vops g_initramfs_vops; + +#endif /* _INITRAMFS_H_ */ diff --git a/sys/include/sys/mount.h b/sys/include/sys/mount.h new file mode 100644 index 0000000..e46cda9 --- /dev/null +++ b/sys/include/sys/mount.h @@ -0,0 +1,84 @@ +/* + * 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. + */ + +#ifndef _SYS_MOUNT_H_ +#define _SYS_MOUNT_H_ + +#include +#include +#include +#include +#include + +#if defined(_KERNEL) + +#define FS_NAME_MAX 16 /* Length of fs name including nul */ + +/* + * Filesystem types. + */ +#define MOUNT_RAMFS "initramfs" + +struct vfsops; +struct mount; + +/* Mount list */ +typedef TAILQ_HEAD(, mount) mountlist_t; +extern mountlist_t g_mountlist; + +/* Filesystem operations */ +extern const struct vfsops g_initramfs_vfsops; + +struct mount { + struct spinlock lock; + struct vnode *vp; + const struct vfsops *mnt_ops; + void *data; + TAILQ_ENTRY(mount) mnt_list; +}; + +struct fs_info { + char name[FS_NAME_MAX]; /* FS Type name */ + const struct vfsops *vfsops; /* Operations vector */ + int flags; /* Flags for this filesystem */ + int refcount; /* Mount count of this type */ +}; + +struct vfsops { + int(*init)(struct fs_info *fip); + int(*mount)(struct mount *mp, const char *path, void *data, + struct nameidata *ndp); +}; + +void vfs_init(void); +struct mount *vfs_alloc_mount(struct vnode *vp, struct fs_info *fip); +struct fs_info *vfs_byname(const char *name); + +#endif /* _KERNEL */ +#endif /* _SYS_MOUNT_H_ */ diff --git a/sys/include/sys/namei.h b/sys/include/sys/namei.h new file mode 100644 index 0000000..bd3c0db --- /dev/null +++ b/sys/include/sys/namei.h @@ -0,0 +1,44 @@ +/* + * 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. + */ + +#ifndef _SYS_NAMEI_H_ +#define _SYS_NAMEI_H_ + +#include +#include + +struct nameidata { + const char *path; /* Pathname */ + uint32_t flags; + struct vnode *vp; /* Vnode result */ +}; + +int namei(struct nameidata *ndp); + +#endif /* !_SYS_NAMEI_H_ */ diff --git a/sys/include/sys/vnode.h b/sys/include/sys/vnode.h new file mode 100644 index 0000000..1caf2cb --- /dev/null +++ b/sys/include/sys/vnode.h @@ -0,0 +1,74 @@ +/* + * 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. + */ + +#ifndef _SYS_VNODE_H_ +#define _SYS_VNODE_H_ + +#include + +#if defined(_KERNEL) + +struct vops; + +struct vnode { + int type; + int flags; + void *data; + const struct vops *vops; +}; + +/* Vnode type flags */ +#define VNON 0x00 /* Uninitialized */ +#define VREG 0x01 /* Regular file */ +#define VDIR 0x02 /* Directory */ +#define VCHR 0x03 /* Character device */ +#define VBLK 0x04 /* Block device */ + +struct vop_lookup_args { + const char *name; /* Current path component */ + struct vnode *dirvp; /* Directory vnode */ + struct vnode **vpp; /* Result vnode */ +}; + +struct vops { + int(*lookup)(struct vop_lookup_args *args); + int(*read)(struct vnode *vp, struct sio_txn *sio); + int(*reclaim)(struct vnode *vp); +}; + +extern struct vnode *g_root_vnode; + +int vfs_alloc_vnode(struct vnode **res, int type); +int vfs_release_vnode(struct vnode *vp); + +int vfs_vop_lookup(struct vnode *vp, struct vop_lookup_args *args); +int vfs_vop_read(struct vnode *vp, struct sio_txn *sio); + +#endif /* _KERNEL */ +#endif /* !_SYS_VNODE_H_ */ diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c index 6018dfe..09b8d2d 100644 --- a/sys/kern/init_main.c +++ b/sys/kern/init_main.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -52,6 +53,9 @@ main(void) /* Startup the BSP */ cpu_startup(&g_bsp_ci); + /* Init the virtual file system */ + vfs_init(); + /* Start scheduler and bootstrap APs */ sched_init(); mp_bootstrap_aps(&g_bsp_ci); 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 +#include +#include +#include +#include + +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 +#include +#include +#include +#include + +/* + * 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 +#include +#include +#include +#include + +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); +} -- cgit v1.2.3