aboutsummaryrefslogtreecommitdiff
path: root/kernel/kernel/filesystem/ext2/inode.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/kernel/filesystem/ext2/inode.cpp')
-rw-r--r--kernel/kernel/filesystem/ext2/inode.cpp73
1 files changed, 73 insertions, 0 deletions
diff --git a/kernel/kernel/filesystem/ext2/inode.cpp b/kernel/kernel/filesystem/ext2/inode.cpp
index aa0c6368..c57ced93 100644
--- a/kernel/kernel/filesystem/ext2/inode.cpp
+++ b/kernel/kernel/filesystem/ext2/inode.cpp
@@ -1,6 +1,9 @@
#include <kernel/filesystem/ext2/inode.hpp>
+#include <kernel/filesystem/directory_listing_cursor.hpp>
+#include <kernel/filesystem/directory_listing_entry.hpp>
#include <kernel/filesystem/error.hpp>
+#include <kernel/filesystem/ext2/directory_iterator.hpp>
#include <kernel/filesystem/ext2/error.hpp>
#include <kernel/filesystem/ext2/filesystem.hpp>
#include <kernel/filesystem/ext2/mount_state.hpp>
@@ -15,6 +18,7 @@
#include <kstd/memory.hpp>
#include <kstd/mutex.hpp>
#include <kstd/result.hpp>
+#include <kstd/string.hpp>
#include <kstd/units.hpp>
#include <algorithm>
@@ -22,11 +26,39 @@
#include <cstdint>
#include <optional>
#include <span>
+#include <utility>
using namespace kstd::units_literals;
namespace kernel::filesystem::ext2
{
+
+ namespace
+ {
+ constexpr auto to_file_type(std::uint8_t entry_type) noexcept -> kapi::filesystem::file_type
+ {
+ switch (entry_type)
+ {
+ case 1:
+ return kapi::filesystem::file_type::regular;
+ case 2:
+ return kapi::filesystem::file_type::directory;
+ case 3:
+ return kapi::filesystem::file_type::character_device;
+ case 4:
+ return kapi::filesystem::file_type::block_device;
+ case 5:
+ return kapi::filesystem::file_type::fifo;
+ case 6:
+ return kapi::filesystem::file_type::socket;
+ case 7:
+ return kapi::filesystem::file_type::symbolic_link;
+ default:
+ return kapi::filesystem::file_type{};
+ }
+ }
+ } // namespace
+
inode::inode(uint32_t inode_number, inode_data const & data)
: m_inode_number(inode_number)
, m_data(data)
@@ -194,6 +226,47 @@ namespace kernel::filesystem::ext2
return result;
}
+ auto inode::read_directory(directory_listing_cursor position, std::span<directory_listing_entry> entries) const
+ -> kstd::result<std::pair<std::size_t, directory_listing_cursor>>
+ {
+ if (!is_directory())
+ {
+ return kstd::failure(vfs_errc::not_a_directory);
+ }
+
+ auto state = get_driver_data();
+ if (!state)
+ {
+ return kstd::failure(state.error());
+ }
+
+ auto guard = kstd::lock_guard{(*state)->lock};
+
+ auto count = 0uz;
+ auto it = directory_iterator{*this, kstd::bytes{position.value}, **state};
+
+ for (; it != directory_iterator{} && count < entries.size(); ++it)
+ {
+ if (it->inode == 0)
+ {
+ continue;
+ }
+
+ entries[count++] = directory_listing_entry{
+ .name = kstd::string{it->name()},
+ .type = to_file_type(it->file_type),
+ .inode_number = it->inode,
+ };
+
+ if (count == entries.size())
+ {
+ break;
+ }
+ }
+
+ return std::pair{count, directory_listing_cursor{it.offset().value}};
+ }
+
auto inode::append_blocks(size_t count, write_batch & batch) -> bool
{
auto state = get_driver_data();