aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--kernel/src/filesystem/ext2/filesystem.cpp48
-rw-r--r--kernel/src/main.cpp2
2 files changed, 49 insertions, 1 deletions
diff --git a/kernel/src/filesystem/ext2/filesystem.cpp b/kernel/src/filesystem/ext2/filesystem.cpp
index 31dc6f2..82fcba9 100644
--- a/kernel/src/filesystem/ext2/filesystem.cpp
+++ b/kernel/src/filesystem/ext2/filesystem.cpp
@@ -5,11 +5,13 @@
#include "kernel/devices/block_device_utils.hpp"
#include "kernel/filesystem/ext2/block_group_descriptor.hpp"
#include "kernel/filesystem/ext2/inode.hpp"
+#include "kernel/filesystem/ext2/linked_directory_entry.hpp"
#include "kernel/filesystem/ext2/superblock.hpp"
#include "kernel/filesystem/filesystem.hpp"
#include "kernel/filesystem/inode.hpp"
#include <kstd/memory>
+#include <kstd/string>
#include <kstd/vector>
#include <cstddef>
@@ -24,6 +26,7 @@ namespace kernel::filesystem::ext2
constexpr uint16_t MAGIC_NUMBER = 0xEF53;
constexpr uint32_t ROOT_INODE_NUMBER = 2;
+ constexpr size_t DIRECT_BLOCK_COUNT = 12;
// Mode bits
constexpr uint16_t S_IFMT = 0xF000;
@@ -67,9 +70,52 @@ namespace kernel::filesystem::ext2
return 0;
}
- auto filesystem::lookup(kstd::shared_ptr<kernel::filesystem::inode> const & /*parent*/, std::string_view name)
+ auto filesystem::lookup(kstd::shared_ptr<kernel::filesystem::inode> const & parent, std::string_view name)
-> kstd::shared_ptr<kernel::filesystem::inode>
{
+ if (!parent || !parent->is_directory())
+ {
+ return nullptr;
+ }
+
+ auto * ext2_parent = static_cast<inode *>(parent.get());
+ if (!ext2_parent)
+ {
+ return nullptr;
+ }
+
+ auto const block_size = get_block_size();
+ auto const & inode_data = ext2_parent->m_data;
+ kstd::vector<uint8_t> buffer(block_size);
+
+ for (size_t i = 0; i < DIRECT_BLOCK_COUNT && inode_data.block[i] != 0; ++i)
+ {
+ kernel::devices::block_device_utils::read(m_device, buffer.data(), inode_data.block[i] * block_size, block_size);
+
+ size_t offset = 0;
+ while (offset < block_size)
+ {
+ auto * entry = reinterpret_cast<linked_directory_entry const *>(buffer.data() + offset);
+ if (entry->inode == 0)
+ break;
+
+ // Stop if the directory entry is malformed to avoid overruns/loops.
+ // if (entry->rec_len < sizeof(linked_directory_entry) || offset + entry->rec_len > block_size)
+ // {
+ // break;
+ // }
+
+ std::string_view entry_name(reinterpret_cast<char const *>(entry->name.data()), entry->name_len);
+ if (entry_name == name)
+ {
+ return read_inode(entry->inode);
+ }
+
+ offset += entry->rec_len;
+ }
+ }
+
+ return nullptr;
// TODO BA-FS26 implement ext2 directory traversal and inode loading
if (name == "dev")
{
diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp
index 8df6767..258c28b 100644
--- a/kernel/src/main.cpp
+++ b/kernel/src/main.cpp
@@ -117,6 +117,8 @@ auto test_file_lookup() -> void
auto vfs = kernel::filesystem::vfs::get();
auto storage_mgmt = kernel::devices::storage::management::get();
+ auto ofd_hello = vfs.open("/hello.txt");
+
auto ofd1 = vfs.open("/a/b/c");
auto ofd2 = vfs.open("/dev/ram0");
auto ofd3 = vfs.open("/a/d/e");