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.cpp114
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