From a6f93bf8df0dbfa7d19aa1168bfc8b052e41c42f Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Sat, 28 Mar 2026 17:28:32 +0100 Subject: fix vfs mount with /dev & /a and rootfs & devfs --- kernel/src/filesystem/vfs.cpp | 122 ++++++++++++++++++------------------------ 1 file changed, 51 insertions(+), 71 deletions(-) (limited to 'kernel/src/filesystem/vfs.cpp') diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index 40c97f8..da7fa05 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -37,11 +37,11 @@ namespace filesystem auto vfs::init_internal() -> void { - auto virtual_fs = kstd::make_shared(); - virtual_fs->mount(nullptr); + auto root_fs = kstd::make_shared(); + root_fs->mount(nullptr); - auto virtual_root_dentry = kstd::make_shared(nullptr, virtual_fs->root_inode(), "/"); - m_mount_table.add_mount(kstd::make_shared(nullptr, virtual_root_dentry, virtual_fs)); + auto root_fs_root_dentry = kstd::make_shared(nullptr, root_fs->root_inode()); + m_mount_table.add_mount(kstd::make_shared(nullptr, root_fs_root_dentry, root_fs, "")); auto storage_mgmt = devices::storage::storage_management::get(); if (auto boot_device = storage_mgmt.determine_boot_device()) @@ -49,24 +49,12 @@ namespace filesystem // TODO BA-FS26 detect fs type from boot device and load corresponding fs, for now just assume ext2 auto boot_root_fs = kstd::make_shared(); boot_root_fs->mount(boot_device); - - if (do_mount("/", boot_root_fs) != 0) - { - kapi::system::panic("[FILESYSTEM] failed to mount root filesystem."); - } - - auto device_fs = kstd::make_shared(); - device_fs->mount(nullptr); - - if (do_mount("/dev", device_fs) != 0) - { - kapi::system::panic("[FILESYSTEM] failed to mount devfs at /dev."); - } - } - else - { - // TODO BA-FS26 ?? what when no boot_device == no modules loaded?? + do_mount_internal("/", root_fs_root_dentry, boot_root_fs); } + + auto device_fs = kstd::make_shared(); + device_fs->mount(nullptr); + do_mount_internal("/dev", root_fs_root_dentry, device_fs); } auto vfs::get() -> vfs & @@ -107,77 +95,69 @@ namespace filesystem return -1; // TODO BA-FS26 panic or errorcode? } - if (auto mount_dentry = resolve_path(path)) + if (auto mount_point_dentry = resolve_path(path)) { - // TODO BA-FS26 check if mount point is already mounted and handle it (unmount old fs, fail, etc.) - - auto new_fs_root = kstd::make_shared(mount_dentry, filesystem->root_inode()); - auto new_mount = kstd::make_shared(mount_dentry, new_fs_root, filesystem); - m_mount_table.add_mount(new_mount); - mount_dentry->set_flag(dentry::dentry_flags::dcache_mounted); - + do_mount_internal(path, mount_point_dentry, filesystem); return 0; } return -1; } + auto vfs::do_mount_internal(std::string_view path, kstd::shared_ptr const & mount_point_dentry, + kstd::shared_ptr const & fs) -> void + { + // TODO BA-FS26 check if mount point is already mounted and handle it (unmount old fs, fail, etc.) + auto new_fs_root = kstd::make_shared(mount_point_dentry, fs->root_inode()); + auto new_mount = kstd::make_shared(mount_point_dentry, new_fs_root, fs, path); + m_mount_table.add_mount(new_mount); + } + auto vfs::resolve_path(std::string_view path) -> kstd::shared_ptr { // TODO BA-FS26 implement full path resolution semantics. // TODO BA-FS26 better path validation // TODO BA-FS26 implement a path parser (maybe in libs?) and use it here and in do_mount - if (!path.empty() && path.front() == '/') + if (path.empty() || path.front() != '/') + return nullptr; + + // TODO BA-FS26 longest match in mount_table -> jump into final fs directly + // TODO BA-FS26 performance optimization first check mounted_flag O(1) then check mount_table O(n) + + auto best_mount = m_mount_table.find_longest_prefix_mount(path); + if (!best_mount) { - auto root_mount = m_mount_table.get_root_mount(); - if (!root_mount) - { - kapi::system::panic("[FILESYSTEM] no root mount found."); - } + kapi::system::panic("[FILESYSTEM] no root mount found."); + } - auto current_dentry = root_mount->root_dentry(); - auto current_fs = root_mount->get_filesystem(); + auto current_dentry = best_mount->root_dentry(); + auto current_fs = best_mount->get_filesystem(); - auto path_parts = - std::views::split(path, '/') | std::views::filter([](auto const & part) { return !part.empty(); }); - for (auto const & part : path_parts) + std::string_view remaining = path.substr(best_mount->get_mount_path().size()); + + auto path_parts = + std::views::split(remaining, '/') | std::views::filter([](auto const & part) { return !part.empty(); }); + + for (auto const & part : path_parts) + { + std::string_view part_view{part}; + + auto next_dentry = current_dentry->find_child(part_view); + if (!next_dentry) { - std::string_view part_view{part}; - auto next_dentry = current_dentry->find_child(part_view); - - if (!next_dentry) - { - if (auto found_inode = current_fs->lookup(current_dentry->get_inode(), part_view)) - { - next_dentry = kstd::make_shared(current_dentry, found_inode, part_view); - current_dentry->add_child(next_dentry); - } - else - { - return nullptr; - } - } - - // TODO BA-FS26 use while to allow stacked mounts? - if (next_dentry->has_flag(dentry::dentry_flags::dcache_mounted)) - { - auto found_mount = m_mount_table.find_mount_by_dentry(next_dentry); - if (!found_mount) - kapi::system::panic("[FILESYSTEM] dcache_mounted set but no covering mount found."); - current_fs = found_mount->get_filesystem(); - current_dentry = found_mount->root_dentry(); - } - else - { - current_dentry = next_dentry; - } + auto found_inode = current_fs->lookup(current_dentry->get_inode(), part_view); + if (!found_inode) + return nullptr; + + next_dentry = kstd::make_shared(current_dentry, found_inode, part_view); + current_dentry->add_child(next_dentry); } - return current_dentry; + current_dentry = next_dentry; } - return nullptr; + return current_dentry; } } // namespace filesystem \ No newline at end of file -- cgit v1.2.3