diff options
Diffstat (limited to 'kernel/kernel/filesystem/ext2/inode.cpp')
| -rw-r--r-- | kernel/kernel/filesystem/ext2/inode.cpp | 114 |
1 files changed, 81 insertions, 33 deletions
diff --git a/kernel/kernel/filesystem/ext2/inode.cpp b/kernel/kernel/filesystem/ext2/inode.cpp index 8da80191..5e80f40b 100644 --- a/kernel/kernel/filesystem/ext2/inode.cpp +++ b/kernel/kernel/filesystem/ext2/inode.cpp @@ -1,12 +1,15 @@ #include <kernel/filesystem/ext2/inode.hpp> +#include <kernel/filesystem/error.hpp> #include <kernel/filesystem/ext2/filesystem.hpp> #include <kernel/filesystem/inode.hpp> +#include <kernel/filesystem/mount.hpp> #include <kapi/filesystem.hpp> #include <kapi/system.hpp> #include <kstd/cstring.hpp> +#include <kstd/memory.hpp> #include <kstd/result.hpp> #include <kstd/units.hpp> @@ -20,16 +23,10 @@ using namespace kstd::units_literals; namespace kernel::filesystem::ext2 { - inode::inode(filesystem * fs, uint32_t inode_number, inode_data const & data) - : m_filesystem(fs) - , m_inode_number(inode_number) + inode::inode(uint32_t inode_number, inode_data const & data) + : m_inode_number(inode_number) , m_data(data) - { - if (!m_filesystem) - { - kapi::system::panic("[EXT2] ext2::inode constructed with filesystem null pointer"); - } - } + {} auto inode::read(std::span<std::byte> buffer, kstd::bytes offset) const -> kstd::result<kstd::bytes> { @@ -43,20 +40,26 @@ namespace kernel::filesystem::ext2 return requested_size; } - auto block_index = offset / m_filesystem->block_size(); - auto in_block_offset = offset % m_filesystem->block_size(); + auto filesystem = get_filesystem(); + if (!filesystem) + { + return kstd::failure(filesystem.error()); + } + + auto block_index = offset / (*filesystem)->block_size(); + auto in_block_offset = offset % (*filesystem)->block_size(); auto bytes_read = 0_B; while (bytes_read < requested_size) { - auto const block_number = m_filesystem->map_inode_block_index_to_global_block_number(block_index, m_data); + auto const block_number = (*filesystem)->map_inode_block_index_to_global_block_number(block_index, m_data); if (!block_number) { break; } - auto const bytes_to_read = std::min(requested_size - bytes_read, m_filesystem->block_size() - in_block_offset); + auto const bytes_to_read = std::min(requested_size - bytes_read, (*filesystem)->block_size() - in_block_offset); if (block_number == 0) { kstd::libc::memset(buffer.data() + bytes_read, 0, bytes_to_read.value); @@ -64,10 +67,10 @@ namespace kernel::filesystem::ext2 } else { - auto const block_start_offset = block_number.value() * m_filesystem->block_size(); + auto const block_start_offset = block_number.value() * (*filesystem)->block_size(); auto const read_offset = block_start_offset + in_block_offset; auto const read_result = - m_filesystem->backing_inode()->read(buffer.subspan(bytes_read.value, bytes_to_read.value), read_offset); + (*filesystem)->backing_inode()->read(buffer.subspan(bytes_read.value, bytes_to_read.value), read_offset); if (!read_result) { return kstd::failure(read_result.error()); @@ -95,14 +98,20 @@ namespace kernel::filesystem::ext2 auto const new_inode_size = std::max(this->size(), offset + kstd::bytes{buffer.size()}); - auto const current_block_count = m_filesystem->inode_block_count(m_data); - auto const max_new_inode_size_without_new_blocks = current_block_count * m_filesystem->block_size(); + auto filesystem = get_filesystem(); + if (!filesystem) + { + return kstd::failure(filesystem.error()); + } + + auto const current_block_count = (*filesystem)->inode_block_count(m_data); + auto const max_new_inode_size_without_new_blocks = current_block_count * (*filesystem)->block_size(); if (new_inode_size > max_new_inode_size_without_new_blocks) { auto const additional_blocks_needed = - (new_inode_size - max_new_inode_size_without_new_blocks + m_filesystem->block_size() - 1_B) / - m_filesystem->block_size(); + (new_inode_size - max_new_inode_size_without_new_blocks + (*filesystem)->block_size() - 1_B) / + (*filesystem)->block_size(); if (!append_blocks(additional_blocks_needed)) { @@ -111,14 +120,14 @@ namespace kernel::filesystem::ext2 } } - auto block_index = offset / m_filesystem->block_size(); - auto in_block_offset = offset % m_filesystem->block_size(); + auto block_index = offset / (*filesystem)->block_size(); + auto in_block_offset = offset % (*filesystem)->block_size(); auto bytes_written = 0_B; while (bytes_written < kstd::bytes{buffer.size()}) { - auto const block_number = m_filesystem->map_inode_block_index_to_global_block_number(block_index, m_data); + auto const block_number = (*filesystem)->map_inode_block_index_to_global_block_number(block_index, m_data); // TODO BA-FS26 if blocknumber == 0 --> handle sparse file if (!block_number) { @@ -126,13 +135,14 @@ namespace kernel::filesystem::ext2 } auto const bytes_to_write = - std::min(kstd::bytes{buffer.size()} - bytes_written, m_filesystem->block_size() - in_block_offset); + std::min(kstd::bytes{buffer.size()} - bytes_written, (*filesystem)->block_size() - in_block_offset); - auto const block_start_offset = block_number.value() * m_filesystem->block_size(); + auto const block_start_offset = block_number.value() * (*filesystem)->block_size(); auto const write_offset = block_start_offset + in_block_offset; - auto const write_result = - m_filesystem->backing_inode()->write(buffer.subspan(bytes_written.value, bytes_to_write.value), write_offset); + auto const write_result = (*filesystem) + ->backing_inode() + ->write(buffer.subspan(bytes_written.value, bytes_to_write.value), write_offset); if (!write_result) { return kstd::failure(write_result.error()); @@ -145,7 +155,7 @@ namespace kernel::filesystem::ext2 } set_size(std::max(this->size(), offset + bytes_written)); - if (auto write_result = m_filesystem->write_inode(m_inode_number, m_data); !write_result) + if (auto write_result = (*filesystem)->write_inode(m_inode_number, m_data); !write_result) { return kstd::failure(write_result.error()); } @@ -155,7 +165,13 @@ namespace kernel::filesystem::ext2 auto inode::append_blocks(size_t count) -> bool { - auto new_blocks = m_filesystem->allocate_blocks(count); + auto filesystem = get_filesystem(); + if (!filesystem) + { + return false; + } + + auto new_blocks = (*filesystem)->allocate_blocks(count); if (!new_blocks) { return false; @@ -163,18 +179,18 @@ namespace kernel::filesystem::ext2 for (auto i = 0uz; i < new_blocks->size(); ++i) { - auto const block_index = m_filesystem->inode_block_count(m_data) + i; + auto const block_index = (*filesystem)->inode_block_count(m_data) + i; auto const global_block_number = new_blocks->at(i); if (auto write_result = - m_filesystem->write_global_block_number_to_inode_block_index(block_index, m_data, global_block_number); + (*filesystem)->write_global_block_number_to_inode_block_index(block_index, m_data, global_block_number); !write_result) { return false; } } - m_filesystem->update_inode_block_count(m_data, count); + (*filesystem)->update_inode_block_count(m_data, count); return true; } @@ -248,7 +264,13 @@ namespace kernel::filesystem::ext2 { uint64_t size = m_data.size; - if (m_filesystem->revision_level() > constants::good_old_revision && is_regular()) + auto filesystem = get_filesystem(); + if (!filesystem) + { + return 0_B; + } + + if ((*filesystem)->revision_level() > constants::good_old_revision && is_regular()) { size |= static_cast<uint64_t>(m_data.dir_acl) << 32; } @@ -258,7 +280,13 @@ namespace kernel::filesystem::ext2 auto inode::set_size(kstd::bytes new_size) -> void { - if (m_filesystem->revision_level() > constants::good_old_revision && is_regular()) + auto filesystem = get_filesystem(); + if (!filesystem) + { + return; + } + + if ((*filesystem)->revision_level() > constants::good_old_revision && is_regular()) { m_data.dir_acl = static_cast<uint32_t>(new_size.value >> 32); } @@ -270,4 +298,24 @@ namespace kernel::filesystem::ext2 return m_inode_number; } + auto inode::get_filesystem() -> kstd::result<kstd::shared_ptr<filesystem>> + { + if (auto mount = owning_mount().lock()) + { + return static_pointer_cast<filesystem>(mount->get_filesystem()); + } + + return kstd::failure(vfs_errc::not_mounted); + } + + auto inode::get_filesystem() const -> kstd::result<kstd::shared_ptr<filesystem const>> + { + if (auto mount = owning_mount().lock()) + { + return static_pointer_cast<filesystem>(mount->get_filesystem()); + } + + return kstd::failure(vfs_errc::not_mounted); + } + } // namespace kernel::filesystem::ext2 |
