diff options
Diffstat (limited to 'kernel/kernel/filesystem/ext2/inode.cpp')
| -rw-r--r-- | kernel/kernel/filesystem/ext2/inode.cpp | 73 |
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(); |
