aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukas Oesch <lukasoesch20@gmail.com>2026-03-15 20:37:14 +0100
committerLukas Oesch <lukasoesch20@gmail.com>2026-03-17 16:43:15 +0100
commit760752ef2045aaceb0393911a0919f9bc0104282 (patch)
treeecd7b04a9f21c9984bf6ada8b7e2b74bb43dc32d
parent6d8ae9c708d43ab3d98d6a1f2fbb4e5f74a4a2aa (diff)
downloadteachos-760752ef2045aaceb0393911a0919f9bc0104282.tar.xz
teachos-760752ef2045aaceb0393911a0919f9bc0104282.zip
implement first inode draft, fix make_device_node, implement first draft of resolve_path (currently with temp m_device_nodes in vfs -> has later to be deleted again, just for tests)
-rw-r--r--kernel/filesystem/include/filesystem/filesystem.hpp4
-rw-r--r--kernel/filesystem/include/filesystem/inode.hpp15
-rw-r--r--kernel/filesystem/include/filesystem/vfs.hpp15
-rw-r--r--kernel/filesystem/src/ext2/ext2_filesystem.cpp4
-rw-r--r--kernel/filesystem/src/filesystem.cpp2
-rw-r--r--kernel/filesystem/src/inode.cpp56
-rw-r--r--kernel/filesystem/src/vfs.cpp77
7 files changed, 156 insertions, 17 deletions
diff --git a/kernel/filesystem/include/filesystem/filesystem.hpp b/kernel/filesystem/include/filesystem/filesystem.hpp
index a5a1047..2077ed6 100644
--- a/kernel/filesystem/include/filesystem/filesystem.hpp
+++ b/kernel/filesystem/include/filesystem/filesystem.hpp
@@ -12,10 +12,10 @@ namespace filesystem
virtual auto mount(devices::device * device) -> int = 0;
- [[nodiscard]] auto root_inode() const -> inode *;
+ [[nodiscard]] auto root_inode() const -> inode const &;
protected:
- inode * m_root_inode{}; // TODO BA-FS26 set during mount?
+ inode m_root_inode{}; // TODO BA-FS26 set during mount?
};
} // namespace filesystem
diff --git a/kernel/filesystem/include/filesystem/inode.hpp b/kernel/filesystem/include/filesystem/inode.hpp
index 44ec09a..eb8440f 100644
--- a/kernel/filesystem/include/filesystem/inode.hpp
+++ b/kernel/filesystem/include/filesystem/inode.hpp
@@ -1,13 +1,28 @@
#ifndef TEACH_OS_KERNEL_FILESYSTEM_INODE_HPP
#define TEACH_OS_KERNEL_FILESYSTEM_INODE_HPP
+#include "devices/device.hpp"
+
#include <cstddef>
+
namespace filesystem
{
struct inode
{
+ inode() = default;
+ explicit inode(devices::device * device);
+
+ [[nodiscard]] auto is_device() const -> bool;
+ [[nodiscard]] auto is_block_device() const -> bool;
+ [[nodiscard]] auto major_device() const -> size_t;
+ [[nodiscard]] auto minor_device() const -> size_t;
+ [[nodiscard]] auto backing_device() const -> devices::device *;
+
auto read(void * buffer, size_t offset, size_t size) const -> size_t;
auto write(void const * buffer, size_t offset, size_t size) -> size_t;
+
+ private:
+ devices::device * m_device{};
};
} // namespace filesystem
diff --git a/kernel/filesystem/include/filesystem/vfs.hpp b/kernel/filesystem/include/filesystem/vfs.hpp
index 182666d..a881241 100644
--- a/kernel/filesystem/include/filesystem/vfs.hpp
+++ b/kernel/filesystem/include/filesystem/vfs.hpp
@@ -2,10 +2,14 @@
#define TEACH_OS_KERNEL_FILESYSTEM_VFS_HPP
#include "devices/device.hpp"
+#include "filesystem/custody.hpp"
+#include "filesystem/inode.hpp"
#include "filesystem/mount.hpp"
+#include "filesystem/open_file_description.hpp"
#include <array>
#include <optional>
+#include <string_view>
namespace filesystem
{
@@ -16,13 +20,22 @@ namespace filesystem
~vfs() = default;
- auto make_device_node(devices::device * device) -> void;
+ auto open(std::string_view path) -> std::optional<open_file_description>;
private:
+ struct device_node_entry
+ {
+ std::string_view name;
+ inode node;
+ };
+
vfs() = default;
+ auto make_device_node(devices::device * device) -> void;
+ [[nodiscard]] auto resolve_path(std::string_view path) -> std::optional<custody>;
std::optional<mount> m_root_mount;
std::array<mount, 10> m_mounts; // TODO BA-FS26 remove when kstd::vector is available and used
+ std::array<std::optional<device_node_entry>, 10> m_device_nodes; // TODO BA-FS26 use kstd::vector
};
} // namespace filesystem
diff --git a/kernel/filesystem/src/ext2/ext2_filesystem.cpp b/kernel/filesystem/src/ext2/ext2_filesystem.cpp
index 7111d13..97257a2 100644
--- a/kernel/filesystem/src/ext2/ext2_filesystem.cpp
+++ b/kernel/filesystem/src/ext2/ext2_filesystem.cpp
@@ -1,6 +1,7 @@
#include "filesystem/ext2/ext2_filesystem.hpp"
#include "devices/device.hpp"
+#include "filesystem/inode.hpp"
namespace filesystem::ext2
{
@@ -10,6 +11,9 @@ namespace filesystem::ext2
{
return -1; // TODO BA-FS26 panic or errorcode?
}
+
+ m_root_inode = inode{}; // TODO BA-FS26 set properly during mount?
+
// TODO BA-FS26 implement
return 0;
}
diff --git a/kernel/filesystem/src/filesystem.cpp b/kernel/filesystem/src/filesystem.cpp
index 2c63766..cdfe7f8 100644
--- a/kernel/filesystem/src/filesystem.cpp
+++ b/kernel/filesystem/src/filesystem.cpp
@@ -4,7 +4,7 @@
namespace filesystem
{
- auto filesystem::root_inode() const -> inode *
+ auto filesystem::root_inode() const -> inode const &
{
return m_root_inode;
}
diff --git a/kernel/filesystem/src/inode.cpp b/kernel/filesystem/src/inode.cpp
index 7bca507..a1427e2 100644
--- a/kernel/filesystem/src/inode.cpp
+++ b/kernel/filesystem/src/inode.cpp
@@ -2,18 +2,74 @@
#include "kapi/system.hpp"
+#include "devices/device.hpp"
+
#include <cstddef>
namespace filesystem
{
+ inode::inode(devices::device * device)
+ : m_device(device)
+ {
+ if (!m_device)
+ {
+ kapi::system::panic("[FILESYSTEM] inode constructed with null device.");
+ }
+ }
+
+ auto inode::is_device() const -> bool
+ {
+ return m_device != nullptr;
+ }
+
+ auto inode::is_block_device() const -> bool
+ {
+ return is_device() && m_device->is_block_device();
+ }
+
+ auto inode::major_device() const -> size_t
+ {
+ if (!is_device())
+ {
+ kapi::system::panic("[FILESYSTEM] inode::major_device called on non-device inode.");
+ }
+
+ return m_device->major();
+ }
+
+ auto inode::minor_device() const -> size_t
+ {
+ if (!is_device())
+ {
+ kapi::system::panic("[FILESYSTEM] inode::minor_device called on non-device inode.");
+ }
+
+ return m_device->minor();
+ }
+
+ auto inode::backing_device() const -> devices::device *
+ {
+ return m_device;
+ }
+
auto inode::read(void * /*buffer*/, size_t /*offset*/, size_t /*size*/) const -> size_t
{
+ if (is_device())
+ {
+ kapi::system::panic("[FILESYSTEM] inode::read called on device inode. Open it as a device file first.");
+ }
+
// TODO BA-FS26
return 0;
}
auto inode::write(void const *, size_t, size_t) -> size_t
{
+ if (is_device())
+ {
+ kapi::system::panic("[FILESYSTEM] inode::write called on device inode. Open it as a device file first.");
+ }
+
kapi::system::panic("[FILESYSTEM] inode::write is not implemented yet");
return 0;
}
diff --git a/kernel/filesystem/src/vfs.cpp b/kernel/filesystem/src/vfs.cpp
index 573994a..2ecf847 100644
--- a/kernel/filesystem/src/vfs.cpp
+++ b/kernel/filesystem/src/vfs.cpp
@@ -4,13 +4,17 @@
#include "devices/device.hpp"
#include "devices/storage/storage_management.hpp"
+#include "filesystem/custody.hpp"
+#include "filesystem/device_file.hpp"
#include "filesystem/ext2/ext2_filesystem.hpp"
+#include "filesystem/inode.hpp"
+#include "filesystem/inode_file.hpp"
#include "filesystem/mount.hpp"
+#include "filesystem/open_file_description.hpp"
#include <kstd/cstring>
#include <algorithm>
-#include <array>
#include <optional>
#include <string_view>
@@ -23,12 +27,11 @@ namespace filesystem
// TODO BA-FS26 @Felix better solution? while dynamic memory not available?
// TODO BA-FS26 remove when dynamic memory available;
constinit auto static root_fs = std::optional<ext2::ext2_filesystem>{};
- // TODO BA-FS26 use kstd::vector when available
- constinit auto static filesystems = std::array<std::optional<ext2::ext2_filesystem>, 1>{};
- // TODO BA-FS26 @Felix
- // TODO BA-FS26 depends on the length of ram_disk_device name
- constinit std::array<char, 10> device_mount_path = {'/', 'd', 'e', 'v', '/', 'x', 'x', 'x', 'x', '\0'};
+ // TODO BA-FS26 remove when dynamic memory available;
+ constinit auto static temp_device_file = std::optional<device_file>{};
+ // TODO BA-FS26 remove when dynamic memory available;
+ constinit auto static temp_inode_file = std::optional<inode_file>{};
} // namespace
auto vfs::init() -> void
@@ -71,19 +74,67 @@ namespace filesystem
return *active_vfs;
}
+ auto vfs::open(std::string_view path) -> std::optional<open_file_description>
+ {
+ if (auto custody = resolve_path(path))
+ {
+ auto * node = custody->get_inode();
+ if (node->is_device())
+ {
+ temp_device_file.emplace(node->backing_device());
+ temp_device_file->open();
+ return open_file_description{&*temp_device_file};
+ }
+
+ temp_inode_file.emplace(node);
+ temp_inode_file->open();
+ return open_file_description{&*temp_inode_file};
+ }
+
+ return std::nullopt;
+ }
+
auto vfs::make_device_node(devices::device * device) -> void
{
- auto device_name = device->name();
- kstd::libc::memcpy(&device_mount_path[5], device_name.data(), device_name.size());
+ if (!device)
+ {
+ kapi::system::panic("[FILESYSTEM] make_device_node called with null device.");
+ }
+
+ auto const device_name = device->name();
+
+ // TODO BA-FS26 this logic isn't needed anymore when kstd::vector available, just use push_back
+ auto const slot = std::ranges::find_if(m_device_nodes, [](auto const & entry) { return !entry.has_value(); });
+ if (slot == m_device_nodes.end())
+ {
+ kapi::system::panic("[FILESYSTEM] No free slot available for device nodes.");
+ }
+
+ slot->emplace(device_node_entry{device_name, inode{device}});
+ }
+
+ auto vfs::resolve_path(std::string_view path) -> std::optional<custody>
+ {
+ // 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 use kstd::vector and push_back when available
- filesystems[0].emplace(ext2::ext2_filesystem{});
- if (filesystems[0]->mount(device) != 0)
+ constexpr auto device_prefix = std::string_view{"/dev/"};
+ if (path.starts_with(device_prefix))
{
- kapi::system::panic("[FILESYSTEM] Failed to mount device filesystem.");
+ 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 custody{nullptr, &entry->value().node};
+ }
+
+ return std::nullopt;
}
- m_mounts[0] = mount{std::string_view{device_mount_path.data()}, &*filesystems[0]};
+ return std::nullopt;
}
} // namespace filesystem \ No newline at end of file