aboutsummaryrefslogtreecommitdiff
path: root/kernel/src/filesystem/vfs.cpp
diff options
context:
space:
mode:
authorLukas Oesch <lukasoesch20@gmail.com>2026-03-28 17:28:32 +0100
committerLukas Oesch <lukasoesch20@gmail.com>2026-03-28 17:28:32 +0100
commita6f93bf8df0dbfa7d19aa1168bfc8b052e41c42f (patch)
treeb07657406fd2ce67e69819326b0c76e9409ef77c /kernel/src/filesystem/vfs.cpp
parent4f7ae11655807acf68f49637cc9dd01a03af36d5 (diff)
downloadteachos-a6f93bf8df0dbfa7d19aa1168bfc8b052e41c42f.tar.xz
teachos-a6f93bf8df0dbfa7d19aa1168bfc8b052e41c42f.zip
fix vfs mount with /dev & /a and rootfs & devfs
Diffstat (limited to 'kernel/src/filesystem/vfs.cpp')
-rw-r--r--kernel/src/filesystem/vfs.cpp122
1 files changed, 51 insertions, 71 deletions
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<rootfs::rootfs_filesystem>();
- virtual_fs->mount(nullptr);
+ auto root_fs = kstd::make_shared<rootfs::rootfs_filesystem>();
+ root_fs->mount(nullptr);
- auto virtual_root_dentry = kstd::make_shared<dentry>(nullptr, virtual_fs->root_inode(), "/");
- m_mount_table.add_mount(kstd::make_shared<mount>(nullptr, virtual_root_dentry, virtual_fs));
+ auto root_fs_root_dentry = kstd::make_shared<dentry>(nullptr, root_fs->root_inode());
+ m_mount_table.add_mount(kstd::make_shared<mount>(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<ext2::ext2_filesystem>();
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<devfs::devfs_filesystem>();
- 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<devfs::devfs_filesystem>();
+ 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<dentry>(mount_dentry, filesystem->root_inode());
- auto new_mount = kstd::make_shared<mount>(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<dentry> const & mount_point_dentry,
+ kstd::shared_ptr<filesystem> 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<dentry>(mount_point_dentry, fs->root_inode());
+ auto new_mount = kstd::make_shared<mount>(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<dentry>
{
// 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<dentry>(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<dentry>(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