diff options
| author | Lukas Oesch <lukasoesch20@gmail.com> | 2026-03-26 20:09:37 +0100 |
|---|---|---|
| committer | Lukas Oesch <lukasoesch20@gmail.com> | 2026-03-26 21:19:33 +0100 |
| commit | 31ac3e6ffff00b7ac3b3dbb3db38c44409251b34 (patch) | |
| tree | 34662655c070f90f2c5b861056a8e5eb13acfa1a | |
| parent | 74351bbcd440189bafa79c806dd3ae8255f42c11 (diff) | |
| download | teachos-31ac3e6ffff00b7ac3b3dbb3db38c44409251b34.tar.xz teachos-31ac3e6ffff00b7ac3b3dbb3db38c44409251b34.zip | |
first draft of an devfs implementation
| -rw-r--r-- | kernel/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | kernel/include/kernel/filesystem/devfs/devfs_filesystem.hpp | 25 | ||||
| -rw-r--r-- | kernel/include/kernel/filesystem/devfs/devfs_root_inode.hpp | 19 | ||||
| -rw-r--r-- | kernel/include/kernel/filesystem/device_inode.hpp | 2 | ||||
| -rw-r--r-- | kernel/include/kernel/filesystem/vfs.hpp | 13 | ||||
| -rw-r--r-- | kernel/src/filesystem/devfs/devfs_filesystem.cpp | 57 | ||||
| -rw-r--r-- | kernel/src/filesystem/devfs/devfs_root_inode.cpp | 22 | ||||
| -rw-r--r-- | kernel/src/filesystem/device_inode.cpp | 5 | ||||
| -rw-r--r-- | kernel/src/filesystem/vfs.cpp | 50 |
9 files changed, 146 insertions, 49 deletions
diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index 406ac54..eb762ac 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -21,6 +21,8 @@ add_executable("kernel" "src/devices/storage/storage_management.cpp" "src/devices/storage/ram_disk/ram_disk_controller.cpp" "src/devices/storage/ram_disk/ram_disk_device.cpp" + "src/filesystem/devfs/devfs_filesystem.cpp" + "src/filesystem/devfs/devfs_root_inode.cpp" "src/filesystem/ext2/ext2_file.cpp" "src/filesystem/ext2/ext2_filesystem.cpp" "src/filesystem/ext2/ext2_inode.cpp" diff --git a/kernel/include/kernel/filesystem/devfs/devfs_filesystem.hpp b/kernel/include/kernel/filesystem/devfs/devfs_filesystem.hpp new file mode 100644 index 0000000..5559c2a --- /dev/null +++ b/kernel/include/kernel/filesystem/devfs/devfs_filesystem.hpp @@ -0,0 +1,25 @@ +#ifndef TEACH_OS_KERNEL_FILESYSTEM_DEVFS_DEVFS_FILESYSTEM_HPP +#define TEACH_OS_KERNEL_FILESYSTEM_DEVFS_DEVFS_FILESYSTEM_HPP + +#include "kernel/devices/device.hpp" +#include "kernel/filesystem/filesystem.hpp" +#include "kernel/filesystem/inode.hpp" + +#include <kstd/memory> +#include <kstd/vector> + +#include <string_view> + +namespace filesystem::devfs +{ + struct devfs_filesystem : filesystem + { + auto mount(kstd::shared_ptr<devices::device> const & device) -> int override; + auto lookup(kstd::shared_ptr<inode> const & parent, std::string_view name) -> kstd::shared_ptr<inode> override; + + private: + auto build_device_inode_table() -> void; + }; +} // namespace filesystem::devfs + +#endif
\ No newline at end of file diff --git a/kernel/include/kernel/filesystem/devfs/devfs_root_inode.hpp b/kernel/include/kernel/filesystem/devfs/devfs_root_inode.hpp new file mode 100644 index 0000000..b1d37ab --- /dev/null +++ b/kernel/include/kernel/filesystem/devfs/devfs_root_inode.hpp @@ -0,0 +1,19 @@ +#ifndef TEACH_OS_KERNEL_FILESYSTEM_DEVFS_DEVFS_ROOT_INODE_HPP +#define TEACH_OS_KERNEL_FILESYSTEM_DEVFS_DEVFS_ROOT_INODE_HPP + +#include "kernel/filesystem/inode.hpp" + +#include <cstddef> + +namespace filesystem::devfs +{ + struct devfs_root_inode : inode + { + devfs_root_inode(); + + auto read(void * buffer, size_t offset, size_t size) const -> size_t override; + auto write(void const * buffer, size_t offset, size_t size) -> size_t override; + }; +} // namespace filesystem::devfs + +#endif
\ No newline at end of file diff --git a/kernel/include/kernel/filesystem/device_inode.hpp b/kernel/include/kernel/filesystem/device_inode.hpp index ce0f91c..1cf08d4 100644 --- a/kernel/include/kernel/filesystem/device_inode.hpp +++ b/kernel/include/kernel/filesystem/device_inode.hpp @@ -18,6 +18,8 @@ namespace filesystem auto read(void * buffer, size_t offset, size_t size) const -> size_t override; auto write(void const * buffer, size_t offset, size_t size) -> size_t override; + [[nodiscard]] auto device() const -> kstd::shared_ptr<devices::device> const &; + private: using block_op = void (*)(size_t idx, size_t off, size_t len, size_t done, devices::block_device * device, std::byte * scratch, void * buffer); diff --git a/kernel/include/kernel/filesystem/vfs.hpp b/kernel/include/kernel/filesystem/vfs.hpp index cf268a3..f301b7a 100644 --- a/kernel/include/kernel/filesystem/vfs.hpp +++ b/kernel/include/kernel/filesystem/vfs.hpp @@ -1,17 +1,13 @@ #ifndef TEACH_OS_KERNEL_FILESYSTEM_VFS_HPP #define TEACH_OS_KERNEL_FILESYSTEM_VFS_HPP -#include "kernel/devices/device.hpp" #include "kernel/filesystem/dentry.hpp" #include "kernel/filesystem/filesystem.hpp" -#include "kernel/filesystem/inode.hpp" #include "kernel/filesystem/mount_table.hpp" #include "kernel/filesystem/open_file_description.hpp" #include <kstd/memory> -#include <kstd/vector> -#include <optional> #include <string_view> namespace filesystem @@ -27,18 +23,9 @@ namespace filesystem auto do_mount(std::string_view path, kstd::shared_ptr<filesystem> const & filesystem) -> int; private: - // TODO BA-FS26 remove again and use devtempfs - struct device_node_entry - { - std::string_view name; - kstd::shared_ptr<inode> node; - }; - kstd::vector<std::optional<device_node_entry>> m_device_nodes; // TODO BA-FS26 remove again, use devtempfs - vfs() = default; auto init_internal() -> void; - auto make_device_node(kstd::shared_ptr<devices::device> const & device) -> void; [[nodiscard]] auto resolve_path(std::string_view path) -> kstd::shared_ptr<dentry>; mount_table m_mount_table; diff --git a/kernel/src/filesystem/devfs/devfs_filesystem.cpp b/kernel/src/filesystem/devfs/devfs_filesystem.cpp new file mode 100644 index 0000000..cfd2d88 --- /dev/null +++ b/kernel/src/filesystem/devfs/devfs_filesystem.cpp @@ -0,0 +1,57 @@ +#include "kernel/filesystem/devfs/devfs_filesystem.hpp" + +#include "kernel/devices/device.hpp" +#include "kernel/devices/storage/storage_management.hpp" +#include "kernel/filesystem/devfs/devfs_root_inode.hpp" +#include "kernel/filesystem/device_inode.hpp" +#include "kernel/filesystem/inode.hpp" + +#include <kstd/memory> + +#include <algorithm> +#include <string_view> + +namespace filesystem::devfs +{ + auto devfs_filesystem::mount(kstd::shared_ptr<devices::device> const & /*device*/) -> int + { + m_root_inode = kstd::make_shared<devfs_root_inode>(); + build_device_inode_table(); + return 0; + } + + auto devfs_filesystem::lookup(kstd::shared_ptr<inode> const & parent, std::string_view name) + -> kstd::shared_ptr<inode> + { + if (!parent || !parent->is_directory()) + { + return nullptr; + } + + if (parent.get() != m_root_inode.get()) + { + return nullptr; + } + + auto it = std::ranges::find_if(m_inodes, [&](auto const & dev_node) { + auto device_inode_ptr = static_cast<device_inode *>(dev_node.get()); + if (!device_inode_ptr) + { + return false; + } + return device_inode_ptr->device()->name() == name; + }); + return (it != m_inodes.end()) ? *it : nullptr; + } + + auto devfs_filesystem::build_device_inode_table() -> void + { + m_inodes.clear(); + + auto storage_mgmt = devices::storage::storage_management::get(); + std::ranges::for_each(storage_mgmt.all_controllers(), [&](auto const & controller) { + std::ranges::for_each(controller->all_devices(), + [&](auto const & device) { m_inodes.push_back(kstd::make_shared<device_inode>(device)); }); + }); + } +} // namespace filesystem::devfs
\ No newline at end of file diff --git a/kernel/src/filesystem/devfs/devfs_root_inode.cpp b/kernel/src/filesystem/devfs/devfs_root_inode.cpp new file mode 100644 index 0000000..53441b0 --- /dev/null +++ b/kernel/src/filesystem/devfs/devfs_root_inode.cpp @@ -0,0 +1,22 @@ +#include "kernel/filesystem/devfs/devfs_root_inode.hpp" + +#include "kernel/filesystem/inode.hpp" + +#include <cstddef> + +namespace filesystem::devfs +{ + devfs_root_inode::devfs_root_inode() + : inode(inode_kind::directory) + {} + + auto devfs_root_inode::read(void * /*buffer*/, size_t /*offset*/, size_t /*size*/) const -> size_t + { + return 0; + } + + auto devfs_root_inode::write(void const * /*buffer*/, size_t /*offset*/, size_t /*size*/) -> size_t + { + return 0; + } +} // namespace filesystem::devfs
\ No newline at end of file diff --git a/kernel/src/filesystem/device_inode.cpp b/kernel/src/filesystem/device_inode.cpp index 812b43a..64cd6e9 100644 --- a/kernel/src/filesystem/device_inode.cpp +++ b/kernel/src/filesystem/device_inode.cpp @@ -76,6 +76,11 @@ namespace filesystem } } + auto device_inode::device() const -> kstd::shared_ptr<devices::device> const & + { + return m_device; + } + auto device_inode::process_blocks(size_t offset, size_t size, void * buffer, block_op op) const -> size_t { if (buffer == nullptr) diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index 483bae5..368d994 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -2,10 +2,9 @@ #include "kapi/system.hpp" -#include "kernel/devices/device.hpp" #include "kernel/devices/storage/storage_management.hpp" #include "kernel/filesystem/dentry.hpp" -#include "kernel/filesystem/device_inode.hpp" +#include "kernel/filesystem/devfs/devfs_filesystem.hpp" #include "kernel/filesystem/ext2/ext2_filesystem.hpp" #include "kernel/filesystem/filesystem.hpp" #include "kernel/filesystem/mount.hpp" @@ -14,7 +13,6 @@ #include <kstd/memory> -#include <algorithm> #include <optional> #include <ranges> #include <string_view> @@ -52,12 +50,18 @@ namespace filesystem auto boot_root_fs = kstd::make_shared<ext2::ext2_filesystem>(); boot_root_fs->mount(boot_device); - do_mount("/", boot_root_fs); + 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); - // TODO BA-FS26 use do_mount when tempdevfs is implemented -> just call /dev/ with all devices in devtempfs - std::ranges::for_each(storage_mgmt.all_controllers(), [&](auto controller) { - std::ranges::for_each(controller->all_devices(), [&](auto device) { make_device_node(device); }); - }); + if (do_mount("/dev", device_fs) != 0) + { + kapi::system::panic("[FILESYSTEM] failed to mount devfs at /dev."); + } } else { @@ -118,39 +122,13 @@ namespace filesystem return -1; } - auto vfs::make_device_node(kstd::shared_ptr<devices::device> const & device) -> void - { - if (!device) - { - kapi::system::panic("[FILESYSTEM] make_device_node called with null device."); - } - - m_device_nodes.push_back(device_node_entry{device->name().view(), kstd::make_shared<device_inode>(device)}); - } - auto vfs::resolve_path(std::string_view path) -> kstd::shared_ptr<dentry> { - // TODO BA-FS26 implement real path resolution with mounts and directories etc. - // For now, just support device nodes at /dev/<device_name>. + // 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 - constexpr auto device_prefix = std::string_view{"/dev/"}; - if (path.starts_with(device_prefix)) - { - auto const device_name = path.substr(device_prefix.size()); - auto entry = std::ranges::find_if(m_device_nodes, [&](auto const & device_entry) { - return device_entry.has_value() && device_entry->name == device_name; - }); - - if (entry != m_device_nodes.end()) - { - return kstd::make_shared<dentry>(nullptr, entry->value().node); - } - - return nullptr; - } - else if (!path.empty() && path.front() == '/') + if (!path.empty() && path.front() == '/') { auto root_mount = m_mount_table.get_root_mount(); if (!root_mount) |
