aboutsummaryrefslogtreecommitdiff
path: root/kernel/src/filesystem
diff options
context:
space:
mode:
authorMarcel Braun <marcel.braun@ost.ch>2026-03-28 19:16:27 +0100
committerMarcel Braun <marcel.braun@ost.ch>2026-03-28 19:16:27 +0100
commit2864e0b061f923a3c73c608b9c27ca4a7116e27c (patch)
tree7175be5fcaa789e0bfd6d0aeb4e7f6ac756cabf6 /kernel/src/filesystem
parent05269b10e50a80f557c2be475904ff15dc1bbec4 (diff)
parent8a9bf5a90b7f46d5c615b55a3fc418b419db4926 (diff)
downloadteachos-2864e0b061f923a3c73c608b9c27ca4a7116e27c.tar.xz
teachos-2864e0b061f923a3c73c608b9c27ca4a7116e27c.zip
Merge branch 'vfs' into 'develop-BA-FS26'
implement basic vfs See merge request teachos/kernel!16
Diffstat (limited to 'kernel/src/filesystem')
-rw-r--r--kernel/src/filesystem/custody.cpp30
-rw-r--r--kernel/src/filesystem/dentry.cpp61
-rw-r--r--kernel/src/filesystem/devfs/devfs_filesystem.cpp58
-rw-r--r--kernel/src/filesystem/devfs/devfs_root_inode.cpp22
-rw-r--r--kernel/src/filesystem/device_inode.cpp (renamed from kernel/src/filesystem/device_file.cpp)32
-rw-r--r--kernel/src/filesystem/ext2/ext2_file.cpp20
-rw-r--r--kernel/src/filesystem/ext2/ext2_filesystem.cpp24
-rw-r--r--kernel/src/filesystem/ext2/ext2_inode.cpp24
-rw-r--r--kernel/src/filesystem/file_descriptor_table.cpp24
-rw-r--r--kernel/src/filesystem/filesystem.cpp15
-rw-r--r--kernel/src/filesystem/inode.cpp85
-rw-r--r--kernel/src/filesystem/inode_file.cpp35
-rw-r--r--kernel/src/filesystem/mount.cpp23
-rw-r--r--kernel/src/filesystem/mount_table.cpp38
-rw-r--r--kernel/src/filesystem/open_file_description.cpp14
-rw-r--r--kernel/src/filesystem/rootfs/rootfs_filesystem.cpp29
-rw-r--r--kernel/src/filesystem/rootfs/rootfs_inode.cpp39
-rw-r--r--kernel/src/filesystem/vfs.cpp146
18 files changed, 472 insertions, 247 deletions
diff --git a/kernel/src/filesystem/custody.cpp b/kernel/src/filesystem/custody.cpp
deleted file mode 100644
index a4dd12c..0000000
--- a/kernel/src/filesystem/custody.cpp
+++ /dev/null
@@ -1,30 +0,0 @@
-#include "kernel/filesystem/custody.hpp"
-
-#include "kapi/system.hpp"
-
-#include "kernel/filesystem/inode.hpp"
-
-#include <kstd/memory>
-
-namespace filesystem
-{
- custody::custody(kstd::shared_ptr<custody> const & parent, kstd::shared_ptr<inode> const & node)
- : m_parent(parent)
- , m_inode(node)
- {
- if (!m_inode)
- {
- kapi::system::panic("[FILESYSTEM] custody constructed with null inode.");
- }
- }
-
- auto custody::get_inode() const -> kstd::shared_ptr<inode> const &
- {
- return m_inode;
- }
-
- auto custody::get_parent() const -> kstd::shared_ptr<custody> const &
- {
- return m_parent;
- }
-} // namespace filesystem \ No newline at end of file
diff --git a/kernel/src/filesystem/dentry.cpp b/kernel/src/filesystem/dentry.cpp
new file mode 100644
index 0000000..76949f2
--- /dev/null
+++ b/kernel/src/filesystem/dentry.cpp
@@ -0,0 +1,61 @@
+#include "kernel/filesystem/dentry.hpp"
+
+#include "kapi/system.hpp"
+
+#include "kernel/filesystem/inode.hpp"
+
+#include <kstd/memory>
+
+#include <algorithm>
+#include <cstdint>
+#include <string_view>
+
+namespace filesystem
+{
+ dentry::dentry(kstd::shared_ptr<dentry> const & parent, kstd::shared_ptr<inode> const & node, std::string_view name)
+ : m_name(name)
+ , m_parent(parent)
+ , m_inode(node)
+ {
+ if (!m_inode)
+ {
+ kapi::system::panic("[FILESYSTEM] dentry constructed with null inode.");
+ }
+ }
+
+ auto dentry::get_inode() const -> kstd::shared_ptr<inode> const &
+ {
+ return m_inode;
+ }
+
+ auto dentry::get_parent() const -> kstd::shared_ptr<dentry> const &
+ {
+ return m_parent;
+ }
+
+ auto dentry::add_child(kstd::shared_ptr<dentry> const & child) -> void
+ {
+ m_children.push_back(child);
+ }
+
+ auto dentry::find_child(std::string_view name) const -> kstd::shared_ptr<dentry>
+ {
+ auto it = std::ranges::find_if(m_children, [&](auto const & child) { return child->m_name == name; });
+ return (it != m_children.end()) ? *it : nullptr;
+ }
+
+ auto dentry::set_flag(dentry_flags flag) -> void
+ {
+ m_flags |= static_cast<uint32_t>(flag);
+ }
+
+ auto dentry::unset_flag(dentry_flags flag) -> void
+ {
+ m_flags &= ~static_cast<uint32_t>(flag);
+ }
+
+ auto dentry::has_flag(dentry_flags flag) const -> bool
+ {
+ return (m_flags & static_cast<uint32_t>(flag)) != 0;
+ }
+} // namespace filesystem \ No newline at end of file
diff --git a/kernel/src/filesystem/devfs/devfs_filesystem.cpp b/kernel/src/filesystem/devfs/devfs_filesystem.cpp
new file mode 100644
index 0000000..c4cd81a
--- /dev/null
+++ b/kernel/src/filesystem/devfs/devfs_filesystem.cpp
@@ -0,0 +1,58 @@
+#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 &) -> 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_file.cpp b/kernel/src/filesystem/device_inode.cpp
index c6db5af..64cd6e9 100644
--- a/kernel/src/filesystem/device_file.cpp
+++ b/kernel/src/filesystem/device_inode.cpp
@@ -1,9 +1,10 @@
-#include "kernel/filesystem/device_file.hpp"
+#include "kernel/filesystem/device_inode.hpp"
#include "kapi/system.hpp"
#include "kernel/devices/block_device.hpp"
#include "kernel/devices/device.hpp"
+#include "kernel/filesystem/inode.hpp"
#include <kstd/cstring>
#include <kstd/memory>
@@ -14,21 +15,17 @@
namespace filesystem
{
- device_file::device_file(kstd::shared_ptr<devices::device> const & device)
- : m_device(device)
+ device_inode::device_inode(kstd::shared_ptr<devices::device> const & device)
+ : inode(inode_kind::device)
+ , m_device(device)
{
- if (!m_device)
+ if (!device)
{
- kapi::system::panic("[FILESYSTEM] device_file constructed with null device.");
+ kapi::system::panic("[FILESYSTEM] device_inode constructed with null device.");
}
}
- auto device_file::open() -> void
- {
- // Hook point for permission checks or lazy metadata loading.
- }
-
- auto device_file::read(void * buffer, size_t offset, size_t size) const -> size_t
+ auto device_inode::read(void * buffer, size_t offset, size_t size) const -> size_t
{
if (m_device->is_block_device())
{
@@ -53,7 +50,7 @@ namespace filesystem
}
}
- auto device_file::write(void const * buffer, size_t offset, size_t size) -> size_t
+ auto device_inode::write(void const * buffer, size_t offset, size_t size) -> size_t
{
if (m_device->is_block_device())
{
@@ -79,11 +76,16 @@ namespace filesystem
}
}
- auto device_file::process_blocks(size_t offset, size_t size, void * buffer, block_op op) const -> size_t
+ 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)
{
- kapi::system::panic("[FILESYSTEM] device_file::write called with null buffer.");
+ kapi::system::panic("[FILESYSTEM] device_file::process_blocks called with null buffer.");
}
if (size == 0)
@@ -121,4 +123,4 @@ namespace filesystem
return processed;
}
-} // namespace filesystem
+} // namespace filesystem \ No newline at end of file
diff --git a/kernel/src/filesystem/ext2/ext2_file.cpp b/kernel/src/filesystem/ext2/ext2_file.cpp
new file mode 100644
index 0000000..7217c77
--- /dev/null
+++ b/kernel/src/filesystem/ext2/ext2_file.cpp
@@ -0,0 +1,20 @@
+#include "kernel/filesystem/ext2/ext2_file.hpp"
+
+#include "kapi/system.hpp"
+
+#include <cstddef>
+
+namespace filesystem::ext2
+{
+ auto ext2_file::read(void * /*buffer*/, size_t /*offset*/, size_t /*size*/) const -> size_t
+ {
+ kapi::system::panic("[FILESYSTEM] ext2_file::read is not implemented yet.");
+ return 0;
+ }
+
+ auto ext2_file::write(void const * /*buffer*/, size_t /*offset*/, size_t /*size*/) -> size_t
+ {
+ kapi::system::panic("[FILESYSTEM] ext2_file::write is not implemented yet.");
+ return 0;
+ }
+} // namespace filesystem::ext2
diff --git a/kernel/src/filesystem/ext2/ext2_filesystem.cpp b/kernel/src/filesystem/ext2/ext2_filesystem.cpp
index 408b292..373c6a2 100644
--- a/kernel/src/filesystem/ext2/ext2_filesystem.cpp
+++ b/kernel/src/filesystem/ext2/ext2_filesystem.cpp
@@ -1,8 +1,9 @@
#include "kernel/filesystem/ext2/ext2_filesystem.hpp"
#include "kernel/devices/device.hpp"
+#include "kernel/filesystem/ext2/ext2_inode.hpp"
+#include "kernel/filesystem/filesystem.hpp"
#include "kernel/filesystem/inode.hpp"
-#include "kernel/filesystem/inode_metadata.hpp"
#include <kstd/memory>
@@ -12,22 +13,25 @@ namespace filesystem::ext2
{
auto ext2_filesystem::mount(kstd::shared_ptr<devices::device> const & device) -> int
{
- if (!device)
- {
- return -1; // TODO BA-FS26 panic or errorcode?
- }
-
- m_device = device;
+ filesystem::mount(device); // TODO BA-FS26 error handling?
// TODO BA-FS26 load proper root inode from ext2 metadata
- m_root_inode = inode{inode_kind::directory};
+ // m_root_inode = inode{inode_kind::directory};
// TODO BA-FS26 implement
+ m_root_inode = kstd::make_shared<ext2_inode>();
return 0;
}
- auto ext2_filesystem::lookup(inode const & /*parent*/, std::string_view /*name*/) -> inode *
+ auto ext2_filesystem::lookup(kstd::shared_ptr<inode> const & /*parent*/, std::string_view name)
+ -> kstd::shared_ptr<inode>
{
// TODO BA-FS26 implement ext2 directory traversal and inode loading
- return nullptr;
+ if (name == "dev")
+ {
+ // TODO BA-FS26 just for testing
+ return nullptr;
+ }
+
+ return kstd::make_shared<ext2_inode>();
}
} // namespace filesystem::ext2
diff --git a/kernel/src/filesystem/ext2/ext2_inode.cpp b/kernel/src/filesystem/ext2/ext2_inode.cpp
new file mode 100644
index 0000000..3cc0fb2
--- /dev/null
+++ b/kernel/src/filesystem/ext2/ext2_inode.cpp
@@ -0,0 +1,24 @@
+#include "kernel/filesystem/ext2/ext2_inode.hpp"
+
+#include "kernel/filesystem/inode.hpp"
+
+#include <cstddef>
+
+namespace filesystem::ext2
+{
+ ext2_inode::ext2_inode()
+ : inode(inode_kind::regular)
+ {}
+
+ auto ext2_inode::read(void * /*buffer*/, size_t /*offset*/, size_t /*size*/) const -> size_t
+ {
+ // TODO BA-FS26 implement
+ return 0;
+ }
+
+ auto ext2_inode::write(void const * /*buffer*/, size_t /*offset*/, size_t /*size*/) -> size_t
+ {
+ // TODO BA-FS26 implement
+ return 0;
+ }
+} // namespace filesystem::ext2 \ No newline at end of file
diff --git a/kernel/src/filesystem/file_descriptor_table.cpp b/kernel/src/filesystem/file_descriptor_table.cpp
index 814322e..6eb3845 100644
--- a/kernel/src/filesystem/file_descriptor_table.cpp
+++ b/kernel/src/filesystem/file_descriptor_table.cpp
@@ -4,6 +4,8 @@
#include "kernel/filesystem/open_file_description.hpp"
+#include <kstd/memory>
+
#include <algorithm>
#include <cstddef>
#include <optional>
@@ -35,9 +37,15 @@ namespace filesystem
return *global_file_descriptor_table;
}
- auto file_descriptor_table::add_file(open_file_description & file_description) -> int
+ auto file_descriptor_table::add_file(kstd::shared_ptr<open_file_description> const & file_description) -> int
{
- auto it = std::ranges::find_if(m_open_files, [](auto & open_file) { return !open_file.has_value(); });
+ if (!file_description)
+ {
+ // TODO BA-FS26 panic or errorcode?
+ return -1;
+ }
+
+ auto it = std::ranges::find_if(m_open_files, [](auto const & open_file) { return open_file == nullptr; });
if (it != m_open_files.end())
{
*it = file_description;
@@ -48,20 +56,20 @@ namespace filesystem
return static_cast<int>(m_open_files.size() - 1);
}
- auto file_descriptor_table::get_file(int fd) const -> std::optional<open_file_description>
+ auto file_descriptor_table::get_file(int fd) const -> kstd::shared_ptr<open_file_description>
{
if (fd < 0)
{
- return std::nullopt;
+ return nullptr;
}
auto const index = static_cast<size_t>(fd);
- if (index >= m_open_files.size() || !m_open_files.at(fd).has_value())
+ if (index >= m_open_files.size())
{
- return std::nullopt;
+ return nullptr;
}
- return m_open_files.at(fd);
+ return m_open_files.at(index);
}
auto file_descriptor_table::remove_file(int fd) -> void
@@ -77,6 +85,6 @@ namespace filesystem
return;
}
- m_open_files.at(fd).reset();
+ m_open_files.at(index) = nullptr;
}
} // namespace filesystem \ No newline at end of file
diff --git a/kernel/src/filesystem/filesystem.cpp b/kernel/src/filesystem/filesystem.cpp
index 86b7940..0e33d95 100644
--- a/kernel/src/filesystem/filesystem.cpp
+++ b/kernel/src/filesystem/filesystem.cpp
@@ -1,10 +1,23 @@
#include "kernel/filesystem/filesystem.hpp"
+#include "kernel/devices/device.hpp"
#include "kernel/filesystem/inode.hpp"
+#include <kstd/memory>
+
namespace filesystem
{
- auto filesystem::root_inode() const -> inode const &
+ auto filesystem::mount(kstd::shared_ptr<devices::device> const & device) -> int
+ {
+ if (!device)
+ {
+ return -1; // TODO BA-FS26 panic or errorcode?
+ }
+ m_device = device;
+ return 0;
+ }
+
+ auto filesystem::root_inode() const -> kstd::shared_ptr<inode> const &
{
return m_root_inode;
}
diff --git a/kernel/src/filesystem/inode.cpp b/kernel/src/filesystem/inode.cpp
index af73662..de3282f 100644
--- a/kernel/src/filesystem/inode.cpp
+++ b/kernel/src/filesystem/inode.cpp
@@ -1,44 +1,11 @@
#include "kernel/filesystem/inode.hpp"
-#include "kapi/system.hpp"
-
-#include "kernel/devices/device.hpp"
-#include "kernel/filesystem/inode_metadata.hpp"
-
-#include <kstd/memory>
-
-#include <cstddef>
-
namespace filesystem
{
inode::inode(inode_kind kind)
: m_kind(kind)
{}
- inode::inode(kstd::shared_ptr<devices::device> const & device)
- : m_kind(inode_kind::device)
- , m_device(device)
- {
- if (!m_device)
- {
- kapi::system::panic("[FILESYSTEM] inode constructed with null device.");
- }
- }
-
- auto inode::metadata() const -> inode_metadata
- {
- auto meta = inode_metadata{};
- meta.kind = m_kind;
-
- if (is_device())
- {
- meta.major = m_device->major();
- meta.minor = m_device->minor();
- }
-
- return meta;
- }
-
auto inode::is_directory() const -> bool
{
return m_kind == inode_kind::directory;
@@ -53,56 +20,4 @@ namespace filesystem
{
return m_kind == inode_kind::device;
}
-
- 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 -> kstd::shared_ptr<devices::device> const &
- {
- 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;
- }
} // namespace filesystem \ No newline at end of file
diff --git a/kernel/src/filesystem/inode_file.cpp b/kernel/src/filesystem/inode_file.cpp
deleted file mode 100644
index 7abac7b..0000000
--- a/kernel/src/filesystem/inode_file.cpp
+++ /dev/null
@@ -1,35 +0,0 @@
-#include "kernel/filesystem/inode_file.hpp"
-
-#include "kapi/system.hpp"
-
-#include "kernel/filesystem/inode.hpp"
-
-#include <kstd/memory>
-
-#include <cstddef>
-
-namespace filesystem
-{
- inode_file::inode_file(kstd::shared_ptr<inode> const & inode)
- : m_inode(inode)
- {
- if (!m_inode)
- {
- kapi::system::panic("[FILESYSTEM] inode_file constructed with null inode");
- }
- }
-
- auto inode_file::open() -> void
- {
- // Hook point for permission checks or lazy metadata loading.
- }
-
- auto inode_file::read(void * buffer, size_t offset, size_t size) const -> size_t
- {
- return m_inode->read(buffer, offset, size);
- }
- auto inode_file::write(void const * buffer, size_t offset, size_t size) -> size_t
- {
- return m_inode->write(buffer, offset, size);
- }
-} // namespace filesystem \ No newline at end of file
diff --git a/kernel/src/filesystem/mount.cpp b/kernel/src/filesystem/mount.cpp
index a2c501f..afc07fa 100644
--- a/kernel/src/filesystem/mount.cpp
+++ b/kernel/src/filesystem/mount.cpp
@@ -2,16 +2,21 @@
#include "kapi/system.hpp"
+#include "kernel/filesystem/dentry.hpp"
#include "kernel/filesystem/filesystem.hpp"
#include <kstd/memory>
+#include <kstd/string>
#include <string_view>
namespace filesystem
{
- mount::mount(std::string_view const & path, kstd::shared_ptr<filesystem> const & fs)
- : m_path(path)
+ mount::mount(kstd::shared_ptr<dentry> const & mount_dentry, kstd::shared_ptr<dentry> const & root_dentry,
+ kstd::shared_ptr<filesystem> const & fs, std::string_view mount_path)
+ : m_mount_path(mount_path)
+ , m_mount_dentry(mount_dentry)
+ , m_root_dentry(root_dentry)
, m_filesystem(fs)
{
if (!m_filesystem)
@@ -20,13 +25,23 @@ namespace filesystem
}
}
- auto mount::path() const -> std::string_view
+ auto mount::get_mount_dentry() const -> kstd::shared_ptr<dentry>
{
- return m_path;
+ return m_mount_dentry;
}
auto mount::get_filesystem() const -> kstd::shared_ptr<filesystem> const &
{
return m_filesystem;
}
+
+ auto mount::root_dentry() const -> kstd::shared_ptr<dentry> const &
+ {
+ return m_root_dentry;
+ }
+
+ auto mount::get_mount_path() const -> std::string_view
+ {
+ return m_mount_path.view();
+ }
} // namespace filesystem \ No newline at end of file
diff --git a/kernel/src/filesystem/mount_table.cpp b/kernel/src/filesystem/mount_table.cpp
new file mode 100644
index 0000000..b9e57d4
--- /dev/null
+++ b/kernel/src/filesystem/mount_table.cpp
@@ -0,0 +1,38 @@
+#include "kernel/filesystem/mount_table.hpp"
+
+#include "kernel/filesystem/mount.hpp"
+
+#include <kstd/memory>
+
+#include <cstddef>
+#include <string_view>
+
+namespace filesystem
+{
+ void mount_table::add_mount(kstd::shared_ptr<mount> mount)
+ {
+ m_mounts.push_back(mount);
+ }
+
+ auto mount_table::find_longest_prefix_mount(std::string_view path) const -> kstd::shared_ptr<mount>
+ {
+ kstd::shared_ptr<mount> mount_with_longest_prefix = nullptr;
+ std::size_t best_len = 0;
+
+ for (auto const & mount : m_mounts)
+ {
+ auto mp = mount->get_mount_path();
+
+ // /a/b/c should match /a/b but not /a/bb or /a/b/c/d, / should match everything
+ bool is_prefix = path.starts_with(mp) && (mp == "/" || path.size() == mp.size() || path[mp.size()] == '/');
+
+ if (is_prefix && mp.size() >= best_len)
+ {
+ mount_with_longest_prefix = mount;
+ best_len = mp.size();
+ }
+ }
+
+ return mount_with_longest_prefix;
+ }
+} // namespace filesystem \ No newline at end of file
diff --git a/kernel/src/filesystem/open_file_description.cpp b/kernel/src/filesystem/open_file_description.cpp
index ff4d678..93c38ac 100644
--- a/kernel/src/filesystem/open_file_description.cpp
+++ b/kernel/src/filesystem/open_file_description.cpp
@@ -1,6 +1,6 @@
#include "kernel/filesystem/open_file_description.hpp"
-#include "kernel/filesystem/file.hpp"
+#include "kernel/filesystem/inode.hpp"
#include <kstd/memory>
#include <kstd/os/error.hpp>
@@ -9,26 +9,26 @@
namespace filesystem
{
- open_file_description::open_file_description(kstd::shared_ptr<file> const & file)
- : m_file(file)
+ open_file_description::open_file_description(kstd::shared_ptr<inode> const & inode)
+ : m_inode(inode)
, m_offset(0)
{
- if (!file)
+ if (!inode)
{
- kstd::os::panic("[FILESYSTEM] open_file_description constructed with null file.");
+ kstd::os::panic("[FILESYSTEM] open_file_description constructed with null inode.");
}
}
auto open_file_description::read(void * buffer, size_t size) -> size_t
{
- auto read_bytes = m_file->read(buffer, m_offset, size);
+ auto read_bytes = m_inode->read(buffer, m_offset, size);
m_offset += read_bytes;
return read_bytes;
}
auto open_file_description::write(void const * buffer, size_t size) -> size_t
{
- auto written_bytes = m_file->write(buffer, m_offset, size);
+ auto written_bytes = m_inode->write(buffer, m_offset, size);
m_offset += written_bytes;
return written_bytes;
}
diff --git a/kernel/src/filesystem/rootfs/rootfs_filesystem.cpp b/kernel/src/filesystem/rootfs/rootfs_filesystem.cpp
new file mode 100644
index 0000000..22502aa
--- /dev/null
+++ b/kernel/src/filesystem/rootfs/rootfs_filesystem.cpp
@@ -0,0 +1,29 @@
+#include "kernel/filesystem/rootfs/rootfs_filesystem.hpp"
+
+#include "kernel/devices/device.hpp"
+#include "kernel/filesystem/inode.hpp"
+#include "kernel/filesystem/rootfs/rootfs_inode.hpp"
+
+#include <kstd/memory>
+
+#include <string_view>
+
+namespace filesystem::rootfs
+{
+ auto rootfs_filesystem::mount(kstd::shared_ptr<devices::device> const &) -> int
+ {
+ auto rfs_inode = kstd::make_shared<rootfs_inode>();
+ rfs_inode->add_child("dev");
+ m_root_inode = rfs_inode;
+
+ return 0;
+ }
+
+ auto rootfs_filesystem::lookup(kstd::shared_ptr<inode> const & parent, std::string_view name)
+ -> kstd::shared_ptr<inode>
+ {
+ if (auto * rfs_inode = static_cast<rootfs_inode *>(parent.get()))
+ return rfs_inode->lookup_child(name);
+ return nullptr;
+ }
+} // namespace filesystem::rootfs
diff --git a/kernel/src/filesystem/rootfs/rootfs_inode.cpp b/kernel/src/filesystem/rootfs/rootfs_inode.cpp
new file mode 100644
index 0000000..9bbfbce
--- /dev/null
+++ b/kernel/src/filesystem/rootfs/rootfs_inode.cpp
@@ -0,0 +1,39 @@
+#include "kernel/filesystem/rootfs/rootfs_inode.hpp"
+
+#include "kernel/filesystem/inode.hpp"
+
+#include <kstd/memory>
+#include <kstd/string>
+
+#include <algorithm>
+#include <cstddef>
+#include <string_view>
+#include <utility>
+
+namespace filesystem::rootfs
+{
+ rootfs_inode::rootfs_inode()
+ : inode(inode_kind::directory)
+ {}
+
+ auto rootfs_inode::read(void * /*buffer*/, size_t /*offset*/, size_t /*size*/) const -> size_t
+ {
+ return 0;
+ }
+
+ auto rootfs_inode::write(void const * /*buffer*/, size_t /*offset*/, size_t /*size*/) -> size_t
+ {
+ return 0;
+ }
+
+ auto rootfs_inode::add_child(std::string_view name) -> void
+ {
+ m_children.push_back(std::make_pair(kstd::string{name}, kstd::make_shared<rootfs_inode>()));
+ }
+
+ auto rootfs_inode::lookup_child(std::string_view name) -> kstd::shared_ptr<inode>
+ {
+ auto it = std::ranges::find_if(m_children, [&](auto const & pair) { return pair.first == name; });
+ return (it != m_children.end()) ? it->second : nullptr;
+ }
+} // namespace filesystem::rootfs
diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp
index 4e0b6bf..7a90531 100644
--- a/kernel/src/filesystem/vfs.cpp
+++ b/kernel/src/filesystem/vfs.cpp
@@ -2,20 +2,19 @@
#include "kapi/system.hpp"
-#include "kernel/devices/device.hpp"
#include "kernel/devices/storage/storage_management.hpp"
-#include "kernel/filesystem/custody.hpp"
-#include "kernel/filesystem/device_file.hpp"
+#include "kernel/filesystem/dentry.hpp"
+#include "kernel/filesystem/devfs/devfs_filesystem.hpp"
#include "kernel/filesystem/ext2/ext2_filesystem.hpp"
-#include "kernel/filesystem/inode.hpp"
-#include "kernel/filesystem/inode_file.hpp"
+#include "kernel/filesystem/filesystem.hpp"
#include "kernel/filesystem/mount.hpp"
#include "kernel/filesystem/open_file_description.hpp"
+#include "kernel/filesystem/rootfs/rootfs_filesystem.hpp"
#include <kstd/memory>
-#include <algorithm>
#include <optional>
+#include <ranges>
#include <string_view>
namespace filesystem
@@ -33,26 +32,29 @@ namespace filesystem
}
active_vfs.emplace(vfs{});
+ active_vfs->init_internal();
+ }
- auto storage_mgmt = devices::storage::storage_management::get();
- if (auto boot_device = storage_mgmt.determine_boot_device())
- {
- active_vfs->m_root_fs = kstd::make_shared<ext2::ext2_filesystem>();
- if (active_vfs->m_root_fs->mount(boot_device) != 0)
- {
- kapi::system::panic("[FILESYSTEM] Failed to mount root filesystem.");
- }
+ auto vfs::init_internal() -> void
+ {
+ auto root_fs = kstd::make_shared<rootfs::rootfs_filesystem>();
+ root_fs->mount(nullptr);
- active_vfs->m_root_mount = mount{"/", active_vfs->m_root_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, ""));
- std::ranges::for_each(storage_mgmt.all_controllers(), [&](auto controller) {
- std::ranges::for_each(controller->all_devices(), [&](auto device) { active_vfs->make_device_node(device); });
- });
- }
- else
+ auto storage_mgmt = devices::storage::storage_management::get();
+ if (auto boot_device = storage_mgmt.determine_boot_device())
{
-