From 380388c8c49889338d7803e1d9776320d166874e Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Fri, 28 Aug 2026 16:10:18 +0200 Subject: kernel/vfs: replace owning_mount with driver_state --- kernel/CMakeLists.txt | 1 + kernel/kernel/filesystems/devfs/filesystem.cpp | 20 ++++- .../kernel/filesystems/ext2/directory_iterator.cpp | 6 +- .../kernel/filesystems/ext2/directory_iterator.hpp | 8 +- .../filesystems/ext2/directory_iterator.tests.cpp | 6 +- kernel/kernel/filesystems/ext2/driver_state.hpp | 27 +++++++ kernel/kernel/filesystems/ext2/filesystem.cpp | 94 +++++++++++----------- kernel/kernel/filesystems/ext2/filesystem.hpp | 26 +++--- .../kernel/filesystems/ext2/filesystem.tests.cpp | 60 +++++++------- kernel/kernel/filesystems/ext2/inode.cpp | 85 ++++++++----------- kernel/kernel/filesystems/ext2/inode.hpp | 12 +-- kernel/kernel/filesystems/ext2/inode.tests.cpp | 68 ++++++++-------- kernel/kernel/filesystems/ext2/mount_state.hpp | 26 ------ kernel/kernel/filesystems/ext2/write_batch.cpp | 4 +- kernel/kernel/filesystems/ext2/write_batch.hpp | 7 +- kernel/kernel/vfs.cpp | 12 +-- kernel/kernel/vfs.hpp | 5 +- kernel/kernel/vfs/driver_state.cpp | 24 ++++++ kernel/kernel/vfs/driver_state.hpp | 25 ++++++ kernel/kernel/vfs/filesystem.hpp | 3 +- kernel/kernel/vfs/inode.cpp | 9 ++- kernel/kernel/vfs/inode.hpp | 10 ++- kernel/kernel/vfs/mount.cpp | 30 ++++--- kernel/kernel/vfs/mount.hpp | 14 ++-- 24 files changed, 320 insertions(+), 262 deletions(-) create mode 100644 kernel/kernel/filesystems/ext2/driver_state.hpp delete mode 100644 kernel/kernel/filesystems/ext2/mount_state.hpp create mode 100644 kernel/kernel/vfs/driver_state.cpp create mode 100644 kernel/kernel/vfs/driver_state.hpp (limited to 'kernel') diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index 359ad1f6..341f396a 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -63,6 +63,7 @@ target_sources("kernel_lib" PRIVATE "kernel/vfs/device_number_registry.cpp" "kernel/vfs/directory_file_descriptor.cpp" "kernel/vfs/driver_registry.cpp" + "kernel/vfs/driver_state.cpp" "kernel/vfs/error.cpp" "kernel/vfs/inode.cpp" "kernel/vfs/mount_table.cpp" diff --git a/kernel/kernel/filesystems/devfs/filesystem.cpp b/kernel/kernel/filesystems/devfs/filesystem.cpp index b6a3c084..aa6006b0 100644 --- a/kernel/kernel/filesystems/devfs/filesystem.cpp +++ b/kernel/kernel/filesystems/devfs/filesystem.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -23,6 +24,11 @@ namespace kernel::filesystems::devfs static_assert(sizeof(kernel::vfs::filesystem) == sizeof(devfs::filesystem)); + struct driver_state : vfs::driver_state + { + kstd::shared_ptr root; + }; + auto filesystem::probe(inode_ptr const & inode) const -> kstd::result { if (inode) @@ -36,7 +42,11 @@ namespace kernel::filesystems::devfs auto filesystem::mount(inode_ptr const &) -> kstd::result { auto root = kstd::make_shared(); - return mount_result{root, root}; + auto state = kstd::make_shared(); + + state->root = root; + + return mount_result{root, state}; } auto filesystem::lookup(inode_ptr const & parent, std::string_view name, driver_data_ptr driver_data) const @@ -52,7 +62,13 @@ namespace kernel::filesystems::devfs return kstd::failure(vfs::errc::not_a_directory); } - if (parent.get() != driver_data.get()) + auto state = static_pointer_cast(driver_data); + if (!state) + { + return kstd::failure(vfs::errc::invalid_argument); + } + + if (parent.get() != state->root.get()) { return kstd::failure(vfs::errc::invalid_inode); } diff --git a/kernel/kernel/filesystems/ext2/directory_iterator.cpp b/kernel/kernel/filesystems/ext2/directory_iterator.cpp index 1c94a863..2d5a2fe4 100644 --- a/kernel/kernel/filesystems/ext2/directory_iterator.cpp +++ b/kernel/kernel/filesystems/ext2/directory_iterator.cpp @@ -1,8 +1,8 @@ #include +#include #include #include -#include #include @@ -14,11 +14,11 @@ using namespace kstd::literals; namespace kernel::filesystems::ext2 { - directory_iterator::directory_iterator(inode const & inode, mount_state const & state) + directory_iterator::directory_iterator(inode const & inode, driver_state const & state) : directory_iterator{inode, 0_B, state} {} - directory_iterator::directory_iterator(inode const & inode, kstd::bytes offset, mount_state const & state) + directory_iterator::directory_iterator(inode const & inode, kstd::bytes offset, driver_state const & state) : m_inode{&inode} , m_state{&state} , m_file_offset{offset} diff --git a/kernel/kernel/filesystems/ext2/directory_iterator.hpp b/kernel/kernel/filesystems/ext2/directory_iterator.hpp index 41a37e74..5ddcbec3 100644 --- a/kernel/kernel/filesystems/ext2/directory_iterator.hpp +++ b/kernel/kernel/filesystems/ext2/directory_iterator.hpp @@ -1,9 +1,9 @@ #ifndef TEACHOS_KERNEL_FILESYSTEMS_EXT2_DIRECTORY_ITERATOR_HPP #define TEACHOS_KERNEL_FILESYSTEMS_EXT2_DIRECTORY_ITERATOR_HPP +#include #include #include -#include #include #include @@ -26,9 +26,9 @@ namespace kernel::filesystems::ext2 constexpr directory_iterator() = default; - directory_iterator(inode const & inode, mount_state const & state); + directory_iterator(inode const & inode, driver_state const & state); - directory_iterator(inode const & inode, kstd::bytes offset, mount_state const & state); + directory_iterator(inode const & inode, kstd::bytes offset, driver_state const & state); auto operator*() const -> reference; @@ -46,7 +46,7 @@ namespace kernel::filesystems::ext2 auto read() -> void; kstd::observer_ptr m_inode{}; - kstd::observer_ptr m_state{}; + kstd::observer_ptr m_state{}; kstd::bytes m_file_offset{}; kstd::vector m_buffer{}; }; diff --git a/kernel/kernel/filesystems/ext2/directory_iterator.tests.cpp b/kernel/kernel/filesystems/ext2/directory_iterator.tests.cpp index 795c5cbf..9f986039 100644 --- a/kernel/kernel/filesystems/ext2/directory_iterator.tests.cpp +++ b/kernel/kernel/filesystems/ext2/directory_iterator.tests.cpp @@ -1,9 +1,9 @@ #include #include +#include #include #include -#include #include #include #include @@ -38,7 +38,7 @@ SCENARIO_METHOD(kernel::tests::vfs::storage_boot_module_fixture, auto root = (*mount)->root_dentry()->inode(); auto const & root_ext2_inode = static_cast(*root); - auto mount_state = static_pointer_cast((*mount)->driver_data()); + auto mount_state = static_pointer_cast((*mount)->driver_state()); WHEN("iterating from begin to the default-constructed end sentinel") { @@ -85,7 +85,7 @@ SCENARIO_METHOD(kernel::tests::vfs::storage_boot_module_fixture, auto root = (*mount)->root_dentry()->inode(); auto const & root_ext2_inode = static_cast(*root); - auto mount_state = static_pointer_cast((*mount)->driver_data()); + auto mount_state = static_pointer_cast((*mount)->driver_state()); auto original = kernel::filesystems::ext2::directory_iterator{root_ext2_inode, *mount_state}; auto const first_name = std::string{&original->name_start, original->name_len}; diff --git a/kernel/kernel/filesystems/ext2/driver_state.hpp b/kernel/kernel/filesystems/ext2/driver_state.hpp new file mode 100644 index 00000000..87dbb1f3 --- /dev/null +++ b/kernel/kernel/filesystems/ext2/driver_state.hpp @@ -0,0 +1,27 @@ +#ifndef TEACHOS_KERNEL_FILESYSTEMS_EXT2_DRIVER_STATE_HPP +#define TEACHOS_KERNEL_FILESYSTEMS_EXT2_DRIVER_STATE_HPP + +#include +#include +#include +#include + +#include + +#include +#include + +namespace kernel::filesystems::ext2 +{ + + struct driver_state : vfs::driver_state + { + struct superblock superblock{}; + kstd::vector block_group_descriptors{}; + kstd::shared_ptr backing_inode{}; + mutable kapi::tracked_mutex lock{}; + }; + +} // namespace kernel::filesystems::ext2 + +#endif \ No newline at end of file diff --git a/kernel/kernel/filesystems/ext2/filesystem.cpp b/kernel/kernel/filesystems/ext2/filesystem.cpp index a2468fcb..384dfc77 100644 --- a/kernel/kernel/filesystems/ext2/filesystem.cpp +++ b/kernel/kernel/filesystems/ext2/filesystem.cpp @@ -2,10 +2,10 @@ #include #include +#include #include #include #include -#include #include #include #include @@ -231,7 +231,7 @@ namespace kernel::filesystems::ext2 //! //! @param state The driver state to operate on. //! @return The revision level. - [[nodiscard]] constexpr auto revision_level(mount_state const & state) -> uint32_t + [[nodiscard]] constexpr auto revision_level(driver_state const & state) -> uint32_t { return state.superblock.rev_level; } @@ -240,7 +240,7 @@ namespace kernel::filesystems::ext2 //! //! @param state The driver state to operate on. //! @return The size of an inode in bytes. - [[nodiscard]] auto inode_size(mount_state const & state) -> kstd::bytes + [[nodiscard]] auto inode_size(driver_state const & state) -> kstd::bytes { return kstd::bytes(revision_level(state) == constants::good_old_revision ? 128 : state.superblock.inode_size); } @@ -251,7 +251,7 @@ namespace kernel::filesystems::ext2 //! @param buffer The buffer to read the block data into. //! @param state The state to operate on. //! @return The number of bytes read. - [[nodiscard]] auto read_block(uint32_t block_number, std::span buffer, mount_state const & state) + [[nodiscard]] auto read_block(uint32_t block_number, std::span buffer, driver_state const & state) -> kstd::result { if (buffer.size() < block_size(state).value) @@ -269,7 +269,7 @@ namespace kernel::filesystems::ext2 //! @param buffer The buffer containing the data to write. //! @param state The state to operate on. //! @return The number of bytes written. - [[nodiscard]] auto write_block(uint32_t block_number, std::span buffer, mount_state & state) + [[nodiscard]] auto write_block(uint32_t block_number, std::span buffer, driver_state & state) -> kstd::result { if (buffer.size() < block_size(state).value) @@ -286,9 +286,10 @@ namespace kernel::filesystems::ext2 //! @param state The driver state to operate on. //! @param batch The active write batch. //! @return An inode number on success, an error otherwise. - auto allocate_inode(mount_state & state, write_batch & batch) -> kstd::result + auto allocate_inode(driver_state & state, write_batch & batch) -> kstd::result { - auto & [superblock, block_group_descriptors, _, __] = state; + auto & superblock = state.superblock; + auto & block_group_descriptors = state.block_group_descriptors; if (block_group_descriptors.empty() || superblock.free_inodes_count == 0) { @@ -344,7 +345,7 @@ namespace kernel::filesystems::ext2 //! @param batch The active write batch. //! @return Nothing on success, an error code otherwise. auto add_directory_entry(inode & directory, std::string_view name, inode & child, std::uint16_t mode, - mount_state & state, write_batch & batch) -> kstd::result + driver_state & state, write_batch & batch) -> kstd::result { auto const last_block_index = block_count(directory, state) - 1; auto const global_block = inode_block_number(last_block_index, directory, state); @@ -444,7 +445,7 @@ namespace kernel::filesystems::ext2 //! @param state The driver state to operate on. //! @param batch The active write batch. //! @return Nothing on success, an error otherwise. - auto init_directory(inode & directory, inode & parent, mount_state & state, write_batch & batch) + auto init_directory(inode & directory, inode & parent, driver_state & state, write_batch & batch) -> kstd::result { if (!directory.append_blocks(1, batch)) @@ -491,7 +492,7 @@ namespace kernel::filesystems::ext2 //! @param number The number of the inode. //! @param state The driver state to operate on. //! @return The offset to the filesystem start of the inode. - [[nodiscard]] auto calculate_inode_offset(std::uint32_t number, mount_state const & state) + [[nodiscard]] auto calculate_inode_offset(std::uint32_t number, driver_state const & state) -> kstd::result { auto const inodes_per_group = state.superblock.inodes_per_group; @@ -516,7 +517,7 @@ namespace kernel::filesystems::ext2 //! @param number The number of the inode to read. //! @param state The driver state to operate on. //! @return The read inode on success, an error otherwise. - [[nodiscard]] auto read_inode(std::uint32_t number, mount_state const & state) + [[nodiscard]] auto read_inode(std::uint32_t number, driver_state const & state) -> kstd::result> { if (auto inode_offset = calculate_inode_offset(number, state)) @@ -544,7 +545,7 @@ namespace kernel::filesystems::ext2 //! @param index The index into the indirect block to read from. //! @param state The driver state to operate on. //! @return The block number at the given index in the given indirect block on success, an error otherwise. - [[nodiscard]] auto read_block_number_at_index(std::uint32_t block, std::size_t index, mount_state const & state) + [[nodiscard]] auto read_block_number_at_index(std::uint32_t block, std::size_t index, driver_state const & state) -> kstd::result { uint32_t block_number_buffer = 0; @@ -565,7 +566,7 @@ namespace kernel::filesystems::ext2 //! //! @param state The driver state to operate on. //! @return The filesystem offset of the block group descriptor table. - [[nodiscard]] auto block_group_descriptor_table_offset(mount_state const & state) -> kstd::bytes + [[nodiscard]] auto block_group_descriptor_table_offset(driver_state const & state) -> kstd::bytes { return block_size(state) == 1024_B ? 2 * block_size(state) : block_size(state); } @@ -608,8 +609,10 @@ namespace kernel::filesystems::ext2 auto filesystem::mount(inode_ptr const & backing_inode) -> kstd::result { - auto const mount_state = kstd::make_shared(); - auto & [superblock, block_group_descriptors, backing, _] = *mount_state; + auto const driver_state = kstd::make_shared(); + auto & superblock = driver_state->superblock; + auto & block_group_descriptors = driver_state->block_group_descriptors; + auto & backing = driver_state->backing_inode; backing = backing_inode; @@ -630,13 +633,13 @@ namespace kernel::filesystems::ext2 block_group_descriptors = kstd::vector(num_block_groups); auto const block_group_descriptors_bytes = kstd::raw_bytes(block_group_descriptors); if (auto read_result = - backing->read(block_group_descriptors_bytes, block_group_descriptor_table_offset(*mount_state)); + backing->read(block_group_descriptors_bytes, block_group_descriptor_table_offset(*driver_state)); !read_result) { return kstd::failure(read_result.error()); } - auto const root = read_inode(constants::root_inode_number, *mount_state); + auto const root = read_inode(constants::root_inode_number, *driver_state); if (!root) { @@ -648,7 +651,7 @@ namespace kernel::filesystems::ext2 return kstd::failure(errc::invalid_root_inode); } - return mount_result{*root, mount_state}; + return mount_result{*root, driver_state}; } auto filesystem::lookup(inode_ptr const & parent, std::string_view name, driver_data_ptr driver_data) const @@ -665,15 +668,15 @@ namespace kernel::filesystems::ext2 return kstd::failure(vfs::errc::not_a_directory); } - auto const mount_state = static_pointer_cast(driver_data); - if (!mount_state) + auto const driver_state = static_pointer_cast(driver_data); + if (!driver_state) { return kstd::failure(vfs::errc::not_mounted); } - auto guard = kstd::lock_guard{mount_state->lock}; + auto guard = kstd::lock_guard{driver_state->lock}; - for (auto it = directory_iterator{*directory, *mount_state}; it != directory_iterator{}; ++it) + for (auto it = directory_iterator{*directory, *driver_state}; it != directory_iterator{}; ++it) { if (it->inode == 0) { @@ -682,7 +685,7 @@ namespace kernel::filesystems::ext2 if (it->name() == name) { - return read_inode(it->inode, *mount_state); + return read_inode(it->inode, *driver_state); } } @@ -710,16 +713,16 @@ namespace kernel::filesystems::ext2 return kstd::failure(vfs::errc::invalid_argument); } - auto const mount_state = static_pointer_cast(driver_data); - if (!mount_state) + auto const driver_state = static_pointer_cast(driver_data); + if (!driver_state) { return kstd::failure(vfs::errc::invalid_driver_data); } - auto guard = kstd::lock_guard{mount_state->lock}; - auto batch = write_batch{*mount_state}; + auto guard = kstd::lock_guard{driver_state->lock}; + auto batch = write_batch{*driver_state}; - auto maybe_inode_number = allocate_inode(*mount_state, batch); + auto maybe_inode_number = allocate_inode(*driver_state, batch); if (!maybe_inode_number) { return kstd::failure(maybe_inode_number.error()); @@ -744,10 +747,10 @@ namespace kernel::filesystems::ext2 } auto created = kstd::make_shared(inode_number, data); - created->set_owning_mount(ext2_parent->owning_mount().lock()); + created->set_driver_state(ext2_parent->driver_state().lock()); // TODO: preallocate blocks depending on type and m_superblock.prealloc_dir_blocks or m_superblock.prealloc_blocks; - if (auto result = add_directory_entry(*ext2_parent, name, *created, data.mode, *mount_state, batch); !result) + if (auto result = add_directory_entry(*ext2_parent, name, *created, data.mode, *driver_state, batch); !result) { return kstd::failure(result.error()); } @@ -755,11 +758,11 @@ namespace kernel::filesystems::ext2 if (created->is_directory()) { // TODO increment used_dirs_count in block group descriptor - if (auto result = init_directory(*created, *ext2_parent, *mount_state, batch); !result) + if (auto result = init_directory(*created, *ext2_parent, *driver_state, batch); !result) { return kstd::failure(result.error()); } - set_data_size(*created, block_size(*mount_state), *mount_state); + set_data_size(*created, block_size(*driver_state), *driver_state); } batch.mark_inode(*created); @@ -770,17 +773,17 @@ namespace kernel::filesystems::ext2 //! @name Free Functions //! @{ - auto block_size(mount_state const & state) -> kstd::bytes + auto block_size(driver_state const & state) -> kstd::bytes { return kstd::bytes{constants::base_block_size.value << state.superblock.log_block_size}; } - auto block_count(inode const & inode, mount_state const & state) -> uint32_t + auto block_count(inode const & inode, driver_state const & state) -> uint32_t { return inode.data().blocks / (2 << state.superblock.log_block_size); } - auto data_size(inode const & inode, mount_state const & state) -> kstd::bytes + auto data_size(inode const & inode, driver_state const & state) -> kstd::bytes { uint64_t size = inode.data().size; @@ -792,7 +795,7 @@ namespace kernel::filesystems::ext2 return kstd::bytes{size}; } - auto set_data_size(inode & inode, kstd::bytes new_size, mount_state const & state) -> void + auto set_data_size(inode & inode, kstd::bytes new_size, driver_state const & state) -> void { if (revision_level(state) > constants::good_old_revision && inode.is_regular()) { @@ -801,7 +804,7 @@ namespace kernel::filesystems::ext2 inode.data().size = static_cast(new_size.value); } - auto do_read(inode const & inode, std::span buffer, kstd::bytes offset, mount_state const & state) + auto do_read(inode const & inode, std::span buffer, kstd::bytes offset, driver_state const & state) -> kstd::result { auto const max_readable = data_size(inode, state) - offset; @@ -849,9 +852,10 @@ namespace kernel::filesystems::ext2 return bytes_read; } - auto allocate_blocks(size_t count, mount_state & state, write_batch & batch) -> kstd::result> + auto allocate_blocks(size_t count, driver_state & state, write_batch & batch) -> kstd::result> { - auto & [superblock, block_group_descriptors, backing_inode, _] = state; + auto & superblock = state.superblock; + auto & block_group_descriptors = state.block_group_descriptors; if (block_group_descriptors.empty() || count > superblock.free_blocks_count) { @@ -921,12 +925,12 @@ namespace kernel::filesystems::ext2 return allocated_blocks; } - auto update_inode_block_count(inode_data & data, uint32_t delta, mount_state & state) -> void + auto update_inode_block_count(inode_data & data, uint32_t delta, driver_state & state) -> void { data.blocks += delta * (2 << state.superblock.log_block_size); } - auto write_inode(uint32_t inode_number, inode_data const & data, mount_state & state) -> kstd::result + auto write_inode(uint32_t inode_number, inode_data const & data, driver_state & state) -> kstd::result { if (auto inode_offset = calculate_inode_offset(inode_number, state)) { @@ -938,7 +942,7 @@ namespace kernel::filesystems::ext2 } } - auto inode_block_number(size_t index, inode const & inode, mount_state const & state) -> kstd::result + auto inode_block_number(size_t index, inode const & inode, driver_state const & state) -> kstd::result { auto const & block_array = inode.data().block; @@ -997,7 +1001,7 @@ namespace kernel::filesystems::ext2 } auto write_global_block_number_to_inode_block_index(size_t inode_block_index, inode_data & data, - uint32_t global_block_number, mount_state & state, + uint32_t global_block_number, driver_state & state, write_batch & batch) -> kstd::result { if (inode_block_index < constants::direct_block_count) @@ -1080,7 +1084,7 @@ namespace kernel::filesystems::ext2 } auto write_block_group_descriptor(block_group_descriptor const & block_group_descriptor, - size_t block_group_descriptor_index, mount_state const & state) + size_t block_group_descriptor_index, driver_state const & state) -> kstd::result { // TODO update all block group descriptors @@ -1091,7 +1095,7 @@ namespace kernel::filesystems::ext2 .transform([](auto) {}); } - auto write_superblock(mount_state & state) -> kstd::result + auto write_superblock(driver_state & state) -> kstd::result { // TODO update all superblock copies return state.backing_inode->write(kstd::raw_bytes(state.superblock), constants::superblock_offset) diff --git a/kernel/kernel/filesystems/ext2/filesystem.hpp b/kernel/kernel/filesystems/ext2/filesystem.hpp index cdf552c9..7ea7b43a 100644 --- a/kernel/kernel/filesystems/ext2/filesystem.hpp +++ b/kernel/kernel/filesystems/ext2/filesystem.hpp @@ -3,9 +3,9 @@ #include #include +#include #include #include -#include #include #include #include @@ -80,28 +80,28 @@ namespace kernel::filesystems::ext2 //! //! @param state The driver state to operate on. //! @return The size of a block in bytes. - [[nodiscard]] auto block_size(mount_state const & state) -> kstd::bytes; + [[nodiscard]] auto block_size(driver_state const & state) -> kstd::bytes; //! Get the number of blocks allocated to an inode. //! //! @param inode The inode whose block count to query. //! @param state The driver state to operate on. //! @return The number of blocks allocated to the inode. - [[nodiscard]] auto block_count(inode const & inode, mount_state const & state) -> uint32_t; + [[nodiscard]] auto block_count(inode const & inode, driver_state const & state) -> uint32_t; //! Determine the size of an inode's data on disk. //! //! @param inode The inode whose data size to determine. //! @param state The driver state to operate on. //! @return The size of the data referenced by the inode. - [[nodiscard]] auto data_size(inode const & inode, mount_state const & state) -> kstd::bytes; + [[nodiscard]] auto data_size(inode const & inode, driver_state const & state) -> kstd::bytes; //! Set the size of an inode's data on disk. //! //! @param inode The inode whose data size to set. //! @param new_size The size to set. //! @param state The driver state to operate on. - auto set_data_size(inode & inode, kstd::bytes new_size, mount_state const & state) -> void; + auto set_data_size(inode & inode, kstd::bytes new_size, driver_state const & state) -> void; //! Perform the actual read of the requested data. //! @@ -111,7 +111,7 @@ namespace kernel::filesystems::ext2 //! @param state The driver state to operate on. //! @return The number of bytes read on success, an error otherwise. [[nodiscard]] auto do_read(inode const & inode, std::span buffer, kstd::bytes offset, - mount_state const & state) -> kstd::result; + driver_state const & state) -> kstd::result; //! Allocate a specified number of blocks. //! @@ -119,21 +119,21 @@ namespace kernel::filesystems::ext2 //! @param state The state to operate on. //! @param batch The active write batch. //! @return A vector of the allocated block numbers. - auto allocate_blocks(size_t count, mount_state & state, write_batch & batch) -> kstd::result>; + auto allocate_blocks(size_t count, driver_state & state, write_batch & batch) -> kstd::result>; //! Update the number of blocks allocated to an inode. //! //! @param data The inode data. //! @param state The state to operate on. //! @param delta The change in the number of blocks. - auto update_inode_block_count(inode_data & data, uint32_t delta, mount_state & state) -> void; + auto update_inode_block_count(inode_data & data, uint32_t delta, driver_state & state) -> void; //! Write an inode to the backing inode. //! //! @param inode_number The number of the inode to write. //! @param state The state to operate on. //! @param data The inode data to write. - auto write_inode(uint32_t inode_number, inode_data const & data, mount_state & state) -> kstd::result; + auto write_inode(uint32_t inode_number, inode_data const & data, driver_state & state) -> kstd::result; //! Get the block number associated with the nth block of an inode. //! @@ -141,7 +141,7 @@ namespace kernel::filesystems::ext2 //! @param inode The inode. //! @param state The state to operate on. //! @return The global block number on success, an error otherwise. - [[nodiscard]] auto inode_block_number(size_t index, inode const & inode, mount_state const & state) + [[nodiscard]] auto inode_block_number(size_t index, inode const & inode, driver_state const & state) -> kstd::result; //! Write a global block number to an inode block index. @@ -152,13 +152,13 @@ namespace kernel::filesystems::ext2 //! @param state The state to operate on. //! @param batch The active write batch. auto write_global_block_number_to_inode_block_index(size_t block_index, inode_data & data, - uint32_t global_block_number, mount_state & state, + uint32_t global_block_number, driver_state & state, write_batch & batch) -> kstd::result; [[nodiscard]] auto write_block_group_descriptor(block_group_descriptor const & block_group_descriptor, - size_t block_group_descriptor_index, mount_state const & state) + size_t block_group_descriptor_index, driver_state const & state) -> kstd::result; - [[nodiscard]] auto write_superblock(mount_state & state) -> kstd::result; + [[nodiscard]] auto write_superblock(driver_state & state) -> kstd::result; } // namespace kernel::filesystems::ext2 #endif diff --git a/kernel/kernel/filesystems/ext2/filesystem.tests.cpp b/kernel/kernel/filesystems/ext2/filesystem.tests.cpp index 4ace4e3d..c7130e99 100644 --- a/kernel/kernel/filesystems/ext2/filesystem.tests.cpp +++ b/kernel/kernel/filesystems/ext2/filesystem.tests.cpp @@ -2,9 +2,9 @@ #include #include +#include #include #include -#include #include #include #include @@ -54,7 +54,7 @@ SCENARIO_METHOD(kernel::tests::vfs::storage_boot_module_fixture, "Ext2 filesyste auto fs = kstd::make_shared(); auto mount = kernel::vfs::mount::create(nullptr, fs, nullptr, nullptr, dev_inode); auto root = (*mount)->root_dentry()->inode(); - auto driver_data = (*mount)->driver_data(); + auto driver_data = (*mount)->driver_state(); REQUIRE(mount); THEN("the root inode is available and is a directory") @@ -68,12 +68,12 @@ SCENARIO_METHOD(kernel::tests::vfs::storage_boot_module_fixture, "Ext2 filesyste auto information = fs->lookup(root, "information", driver_data); REQUIRE(information); REQUIRE(information.value()->is_directory()); - (*information)->set_owning_mount(*mount); + (*information)->set_driver_state(driver_data); auto info_1 = fs->lookup(*information, "info_1.txt", driver_data); REQUIRE(info_1); REQUIRE(info_1.value()->is_regular()); - (*info_1)->set_owning_mount(*mount); + (*info_1)->set_driver_state(driver_data); } THEN("lookup returns null for invalid inputs") @@ -82,10 +82,10 @@ SCENARIO_METHOD(kernel::tests::vfs::storage_boot_module_fixture, "Ext2 filesyste auto information = fs->lookup(root, "information", driver_data); REQUIRE(information); - (*information)->set_owning_mount(*mount); + (*information)->set_driver_state(driver_data); auto info_1 = fs->lookup(*information, "info_1.txt", driver_data); REQUIRE(info_1); - (*info_1)->set_owning_mount(*mount); + (*info_1)->set_driver_state(driver_data); REQUIRE(!fs->lookup(*info_1, "anything", driver_data)); REQUIRE(!fs->lookup(root, "does_not_exist", driver_data)); @@ -111,7 +111,7 @@ SCENARIO_METHOD(kernel::tests::vfs::storage_boot_module_fixture, "Ext2 filesyste auto fs = kstd::make_shared(); auto mount = kernel::vfs::mount::create(nullptr, fs, nullptr, nullptr, dev_inode); auto root = (*mount)->root_dentry()->inode(); - auto driver_data = (*mount)->driver_data(); + auto driver_data = (*mount)->driver_state(); REQUIRE(mount); THEN("a file can be created") @@ -122,11 +122,11 @@ SCENARIO_METHOD(kernel::tests::vfs::storage_boot_module_fixture, "Ext2 filesyste auto new_inode = fs->create_inode(root, "blub", kapi::filesystem::file_type::regular, driver_data); REQUIRE(new_inode); REQUIRE(new_inode.value()->is_regular()); - (*new_inode)->set_owning_mount(*mount); + (*new_inode)->set_driver_state(driver_data); lookup_result = fs->lookup(root, "blub", driver_data); REQUIRE(lookup_result); - (*lookup_result)->set_owning_mount(*mount); + (*lookup_result)->set_driver_state(driver_data); } THEN("a directory can be created") @@ -146,12 +146,12 @@ SCENARIO_METHOD(kernel::tests::vfs::storage_boot_module_fixture, "Ext2 filesyste { auto new_directory = fs->create_inode(root, "blub", kapi::filesystem::file_type::directory, driver_data); REQUIRE(new_directory); - (*new_directory)->set_owning_mount(*mount); + (*new_directory)->set_driver_state(driver_data); auto new_file = fs->create_inode(new_directory.value(), "blub_file", kapi::filesystem::file_type::regular, driver_data); REQUIRE(new_file); - (*new_file)->set_owning_mount(*mount); + (*new_file)->set_driver_state(driver_data); auto lookup_result = fs->lookup(new_directory.value(), "blub_file", driver_data); REQUIRE(lookup_result); @@ -214,8 +214,8 @@ SCENARIO("Ext2 block mapping includes direct and all indirect levels", "[filesys auto fs = kstd::make_shared(); auto mount = fs->mount(dev_inode); REQUIRE(mount); - auto mount_state = static_pointer_cast(mount->second); - REQUIRE(mount_state); + auto driver_state = static_pointer_cast(mount->second); + REQUIRE(driver_state); auto inode_data = kernel::filesystems::ext2::inode_data{}; inode_data.block[0] = 7; @@ -241,16 +241,16 @@ SCENARIO("Ext2 block mapping includes direct and all indirect levels", "[filesys THEN("mapping resolves direct, singly, doubly and triply indirect indexes") { - REQUIRE(inode_block_number(0, inode, *mount_state) == 7); - REQUIRE(inode_block_number(singly_start, inode, *mount_state) == 31); - REQUIRE(inode_block_number(doubly_start, inode, *mount_state) == 42); - REQUIRE(inode_block_number(triply_start, inode, *mount_state) == 53); + REQUIRE(inode_block_number(0, inode, *driver_state) == 7); + REQUIRE(inode_block_number(singly_start, inode, *driver_state) == 31); + REQUIRE(inode_block_number(doubly_start, inode, *driver_state) == 42); + REQUIRE(inode_block_number(triply_start, inode, *driver_state) == 53); } THEN("mapping returns error for out-of-range indexes") { auto const beyond_triply = triply_start + numbers_per_block * numbers_per_block * numbers_per_block; - REQUIRE(!inode_block_number(beyond_triply, inode, *mount_state)); + REQUIRE(!inode_block_number(beyond_triply, inode, *driver_state)); } } } @@ -291,8 +291,8 @@ SCENARIO("Ext2 block writing includes direct and all indirect levels", "[filesys auto fs = kstd::make_shared(); auto mount = fs->mount(dev_inode); REQUIRE(mount); - auto mount_state = static_pointer_cast(mount->second); - REQUIRE(mount_state); + auto driver_state = static_pointer_cast(mount->second); + REQUIRE(driver_state); auto read_u32 = [&](kstd::bytes offset) -> uint32_t { auto value = uint32_t{0}; @@ -314,32 +314,32 @@ SCENARIO("Ext2 block writing includes direct and all indirect levels", "[filesys constexpr auto doubly_global_block_number = 303; constexpr auto triply_global_block_number = 404; - auto batch = kernel::filesystems::ext2::write_batch{*mount_state}; + auto batch = kernel::filesystems::ext2::write_batch{*driver_state}; - REQUIRE(write_global_block_number_to_inode_block_index(0, inode_data, direct_global_block_number, *mount_state, + REQUIRE(write_global_block_number_to_inode_block_index(0, inode_data, direct_global_block_number, *driver_state, batch)); REQUIRE(inode_data.block[0] == direct_global_block_number); REQUIRE(write_global_block_number_to_inode_block_index(singly_start, inode_data, singly_global_block_number, - *mount_state, batch)); + *driver_state, batch)); REQUIRE(inode_data.block[12] == 16); REQUIRE(read_u32(static_cast(inode_data.block[12]) * block_size.value) == singly_global_block_number); REQUIRE(write_global_block_number_to_inode_block_index(singly_start + 1, inode_data, - singly_global_block_number + 1, *mount_state, batch)); + singly_global_block_number + 1, *driver_state, batch)); REQUIRE(read_u32(static_cast(inode_data.block[12]) * block_size.value + 1 * kstd::size_of()) == singly_global_block_number + 1); REQUIRE(write_global_block_number_to_inode_block_index(doubly_start, inode_data, doubly_global_block_number, - *mount_state, batch)); + *driver_state, batch)); REQUIRE(inode_data.block[13] == 17); auto const doubly_leaf_table = read_u32(static_cast(inode_data.block[13]) * block_size); REQUIRE(doubly_leaf_table == 18); REQUIRE(read_u32(static_cast(doubly_leaf_table) * block_size) == doubly_global_block_number); REQUIRE(write_global_block_number_to_inode_block_index(triply_start, inode_data, triply_global_block_number, - *mount_state, batch)); + *driver_state, batch)); REQUIRE(inode_data.block[14] == 19); auto const triply_middle_table = read_u32(static_cast(inode_data.block[14]) * block_size); REQUIRE(triply_middle_table == 20); @@ -349,10 +349,10 @@ SCENARIO("Ext2 block writing includes direct and all indirect levels", "[filesys auto inode = kernel::filesystems::ext2::inode{42, inode_data}; - REQUIRE(inode_block_number(0, inode, *mount_state) == direct_global_block_number); - REQUIRE(inode_block_number(singly_start, inode, *mount_state) == singly_global_block_number); - REQUIRE(inode_block_number(doubly_start, inode, *mount_state) == doubly_global_block_number); - REQUIRE(inode_block_number(triply_start, inode, *mount_state) == triply_global_block_number); + REQUIRE(inode_block_number(0, inode, *driver_state) == direct_global_block_number); + REQUIRE(inode_block_number(singly_start, inode, *driver_state) == singly_global_block_number); + REQUIRE(inode_block_number(doubly_start, inode, *driver_state) == doubly_global_block_number); + REQUIRE(inode_block_number(triply_start, inode, *driver_state) == triply_global_block_number); } } } diff --git a/kernel/kernel/filesystems/ext2/inode.cpp b/kernel/kernel/filesystems/ext2/inode.cpp index f9322723..22e95ee7 100644 --- a/kernel/kernel/filesystems/ext2/inode.cpp +++ b/kernel/kernel/filesystems/ext2/inode.cpp @@ -1,9 +1,9 @@ #include #include +#include #include #include -#include #include #include #include @@ -73,20 +73,20 @@ namespace kernel::filesystems::ext2 return requested_size; } - auto state = get_driver_data(); + auto state = static_pointer_cast(driver_state().lock()); if (!state) { - return kstd::failure(state.error()); + return kstd::failure(vfs::errc::not_mounted); } - auto backing_inode = (*state)->backing_inode; - if (!(*state)->backing_inode) + auto backing_inode = state->backing_inode; + if (!state->backing_inode) { return kstd::failure(vfs::errc::not_mounted); } - auto guard = kstd::lock_guard{(*state)->lock}; - return ext2::do_read(*this, buffer, offset, **state); + auto guard = kstd::lock_guard{state->lock}; + return ext2::do_read(*this, buffer, offset, *state); } auto inode::write(std::span buffer, kstd::bytes offset) -> kstd::result @@ -99,25 +99,25 @@ namespace kernel::filesystems::ext2 // TODO check maximum file size of filesystem // TODO handle sparse files - auto state = get_driver_data(); + auto state = static_pointer_cast(driver_state().lock()); if (!state) { - return kstd::failure(state.error()); + return kstd::failure(vfs::errc::not_mounted); } - auto backing_inode = (*state)->backing_inode; - if (!(*state)->backing_inode) + auto backing_inode = state->backing_inode; + if (!state->backing_inode) { return kstd::failure(vfs::errc::not_mounted); } - auto guard = kstd::lock_guard{(*state)->lock}; - auto batch = write_batch{**state}; + auto guard = kstd::lock_guard{state->lock}; + auto batch = write_batch{*state}; - auto const new_inode_size = std::max(ext2::data_size(*this, **state), offset + kstd::bytes{buffer.size()}); + auto const new_inode_size = std::max(ext2::data_size(*this, *state), offset + kstd::bytes{buffer.size()}); - auto block_size = ext2::block_size(**state); - auto const current_block_count = ext2::block_count(*this, **state); + auto block_size = ext2::block_size(*state); + auto const current_block_count = ext2::block_count(*this, *state); auto const max_new_inode_size_without_new_blocks = current_block_count * block_size; if (new_inode_size > max_new_inode_size_without_new_blocks) @@ -138,7 +138,7 @@ namespace kernel::filesystems::ext2 while (bytes_written < kstd::bytes{buffer.size()}) { - auto const block_number = ext2::inode_block_number(block_index, *this, **state); + auto const block_number = ext2::inode_block_number(block_index, *this, *state); // TODO BA-FS26 if blocknumber == 0 --> handle sparse file if (!block_number) { @@ -163,7 +163,7 @@ namespace kernel::filesystems::ext2 in_block_offset = 0_B; } - ext2::set_data_size(*this, std::max(ext2::data_size(*this, **state), offset + bytes_written), **state); + ext2::set_data_size(*this, std::max(ext2::data_size(*this, *state), offset + bytes_written), *state); batch.mark_inode(*this); return bytes_written; } @@ -233,16 +233,16 @@ namespace kernel::filesystems::ext2 return kstd::failure(vfs::errc::not_a_directory); } - auto state = get_driver_data(); + auto state = static_pointer_cast(driver_state().lock()); if (!state) { - return kstd::failure(state.error()); + return kstd::failure(vfs::errc::not_mounted); } - auto guard = kstd::lock_guard{(*state)->lock}; + auto guard = kstd::lock_guard{state->lock}; auto count = 0uz; - auto it = directory_iterator{*this, kstd::bytes{position.value}, **state}; + auto it = directory_iterator{*this, kstd::bytes{position.value}, *state}; for (; it != directory_iterator{} && count < entries.size(); ++it) { @@ -268,13 +268,13 @@ namespace kernel::filesystems::ext2 auto inode::append_blocks(size_t count, write_batch & batch) -> bool { - auto state = get_driver_data(); + auto state = static_pointer_cast(driver_state().lock()); if (!state) { return false; } - auto new_blocks = ext2::allocate_blocks(count, **state, batch); + auto new_blocks = ext2::allocate_blocks(count, *state, batch); if (!new_blocks) { return false; @@ -282,30 +282,29 @@ namespace kernel::filesystems::ext2 for (auto i = 0uz; i < new_blocks->size(); ++i) { - auto const block_index = ext2::block_count(*this, **state) + i; + auto const block_index = ext2::block_count(*this, *state) + i; auto const global_block_number = new_blocks->at(i); if (auto write_result = ext2::write_global_block_number_to_inode_block_index(block_index, m_data, - global_block_number, **state, batch); + global_block_number, *state, batch); !write_result) { return false; } } - ext2::update_inode_block_count(m_data, count, **state); + ext2::update_inode_block_count(m_data, count, *state); return true; } auto inode::set_size(kstd::bytes new_size) -> void { - auto driver_data = get_driver_data(); - if (!driver_data) + auto state = static_pointer_cast(driver_state().lock()); + if (!state) { return; } - auto state = static_pointer_cast(*driver_data); auto guard = kstd::lock_guard{state->lock}; return ext2::set_data_size(*this, new_size, *state); } @@ -322,14 +321,14 @@ namespace kernel::filesystems::ext2 auto inode::size() const -> kstd::bytes { - auto state = get_driver_data(); + auto state = static_pointer_cast(driver_state().lock()); if (!state) { return 0_B; } - auto guard = kstd::lock_guard{(*state)->lock}; - return ext2::data_size(*this, **state); + auto guard = kstd::lock_guard{state->lock}; + return ext2::data_size(*this, *state); } [[nodiscard]] auto inode::number() const -> uint32_t @@ -337,24 +336,4 @@ namespace kernel::filesystems::ext2 return m_inode_number; } - auto inode::get_driver_data() -> kstd::result> - { - if (auto mount = owning_mount().lock()) - { - return static_pointer_cast(mount->driver_data()); - } - - return kstd::failure(vfs::errc::not_mounted); - } - - auto inode::get_driver_data() const -> kstd::result> - { - if (auto mount = owning_mount().lock()) - { - return static_pointer_cast(mount->driver_data()); - } - - return kstd::failure(vfs::errc::not_mounted); - } - } // namespace kernel::filesystems::ext2 diff --git a/kernel/kernel/filesystems/ext2/inode.hpp b/kernel/kernel/filesystems/ext2/inode.hpp index 6d40d73c..cffbf679 100644 --- a/kernel/kernel/filesystems/ext2/inode.hpp +++ b/kernel/kernel/filesystems/ext2/inode.hpp @@ -1,7 +1,7 @@ #ifndef TEACHOS_KERNEL_FILESYSTEM_EXT2_INODE_HPP #define TEACHOS_KERNEL_FILESYSTEM_EXT2_INODE_HPP -#include +#include #include #include @@ -139,16 +139,6 @@ namespace kernel::filesystems::ext2 //! @} private: - //! Get the filesystem driver data associated with this inode. - //! - //! @return The filesystem driver data on success, and error otherwise. - [[nodiscard]] auto get_driver_data() -> kstd::result>; - - //! Get the filesystem driver data associated with this inode. - //! - //! @return The filesystem driver data on success, and error otherwise. - [[nodiscard]] auto get_driver_data() const -> kstd::result>; - //! The inode number on disk. uint32_t m_inode_number{}; //! The inode data. diff --git a/kernel/kernel/filesystems/ext2/inode.tests.cpp b/kernel/kernel/filesystems/ext2/inode.tests.cpp index f0b38571..d7d27553 100644 --- a/kernel/kernel/filesystems/ext2/inode.tests.cpp +++ b/kernel/kernel/filesystems/ext2/inode.tests.cpp @@ -2,9 +2,9 @@ #include #include +#include #include #include -#include #include #include #include @@ -128,18 +128,18 @@ SCENARIO_METHOD(kernel::tests::vfs::storage_boot_module_fixture, "Ext2 inode rea auto fs = kstd::make_shared(); auto mount = kernel::vfs::mount::create(nullptr, fs, nullptr, nullptr, dev_inode); auto root = (*mount)->root_dentry()->inode(); - auto driver_data = (*mount)->driver_data(); REQUIRE(mount); + auto driver_state = (*mount)->driver_state(); - auto information = fs->lookup(root, "information", driver_data); + auto information = fs->lookup(root, "information", driver_state); REQUIRE(information); - (*information)->set_owning_mount(*mount); + (*information)->set_driver_state(driver_state); - auto file = fs->lookup(*information, "info_1.txt", driver_data); + auto file = fs->lookup(*information, "info_1.txt", driver_state); REQUIRE(file); REQUIRE(file.value()->is_regular()); - (*file)->set_owning_mount(*mount); + (*file)->set_driver_state(driver_state); THEN("reading from offset zero returns expected file prefix") { @@ -178,6 +178,7 @@ SCENARIO("Ext2 inode handles zeros in block mappings as file holes", "[filesyste auto mount = kernel::vfs::mount::create(nullptr, fs, nullptr, nullptr, dev_inode); auto root = (*mount)->root_dentry()->inode(); REQUIRE(mount); + auto driver_state = (*mount)->driver_state(); auto data = kernel::filesystems::ext2::inode_data{}; data.block[0] = 30; @@ -189,7 +190,7 @@ SCENARIO("Ext2 inode handles zeros in block mappings as file holes", "[filesyste kernel::tests::filesystems::ext2::write_bytes(*device, 31 * block_size, "World!", 6_B); auto inode = kernel::filesystems::ext2::inode{42, data}; - inode.set_owning_mount(*mount); + inode.set_driver_state(driver_state); auto buffer = kstd::vector(data.size, std::byte{0xAB}); @@ -219,6 +220,7 @@ SCENARIO("Ext2 inode handles zeros in block mappings as file holes", "[filesyste auto mount = kernel::vfs::mount::create(nullptr, fs, nullptr, nullptr, dev_inode); auto root = (*mount)->root_dentry()->inode(); REQUIRE(mount); + auto driver_state = (*mount)->driver_state(); auto data = kernel::filesystems::ext2::inode_data{}; data.block[0] = 30; @@ -234,7 +236,7 @@ SCENARIO("Ext2 inode handles zeros in block mappings as file holes", "[filesyste kernel::tests::filesystems::ext2::write_bytes(*device, 51 * block_size, "World!", 6_B); auto inode = kernel::filesystems::ext2::inode{42, data}; - inode.set_owning_mount(*mount); + inode.set_driver_state(driver_state); auto buffer = kstd::vector(data.size, std::byte{0xAB}); @@ -267,13 +269,14 @@ SCENARIO("Ext2 inode handles zeros in block mappings as file holes", "[filesyste auto mount = kernel::vfs::mount::create(nullptr, fs, nullptr, nullptr, dev_inode); auto root = (*mount)->root_dentry()->inode(); REQUIRE(mount); + auto driver_state = (*mount)->driver_state(); auto data = kernel::filesystems::ext2::inode_data{}; data.block[12] = 0; data.size = block_size.value * 15; auto inode = kernel::filesystems::ext2::inode{42, data}; - inode.set_owning_mount(*mount); + inode.set_driver_state(driver_state); auto buffer = kstd::vector(block_size.value * 15, std::byte{0xAB}); @@ -301,6 +304,7 @@ SCENARIO("Ext2 inode read across block boundaries", "[filesystem][ext2][inode]") auto mount = kernel::vfs::mount::create(nullptr, fs, nullptr, nullptr, dev_inode); auto root = (*mount)->root_dentry()->inode(); REQUIRE(mount); + auto driver_state = (*mount)->driver_state(); auto inode_data = kernel::filesystems::ext2::inode_data{}; inode_data.size = block_size.value * 2; @@ -309,7 +313,7 @@ SCENARIO("Ext2 inode read across block boundaries", "[filesystem][ext2][inode]") inode_data.block[1] = 21; kernel::tests::filesystems::ext2::write_bytes(*device, 21 * block_size, "World!", 6_B); auto inode = kernel::filesystems::ext2::inode{42, inode_data}; - inode.set_owning_mount(*mount); + inode.set_driver_state(driver_state); auto buffer = kstd::vector(12, std::byte{0x00}); @@ -341,20 +345,17 @@ SCENARIO_METHOD(kernel::tests::vfs::storage_boot_module_fixture, "Ext2 inode wri auto fs = kstd::make_shared(); auto mount = kernel::vfs::mount::create(nullptr, fs, nullptr, nullptr, dev_inode); auto root = (*mount)->root_dentry()->inode(); - auto driver_data = (*mount)->driver_data(); REQUIRE(mount); + auto driver_state = static_pointer_cast((*mount)->driver_state()); - auto information = fs->lookup(root, "information", driver_data); + auto information = fs->lookup(root, "information", driver_state); REQUIRE(information); - (*information)->set_owning_mount(*mount); + (*information)->set_driver_state(driver_state); - auto file = fs->lookup(*information, "info_1.txt", driver_data); + auto file = fs->lookup(*information, "info_1.txt", driver_state); REQUIRE(file); REQUIRE(file.value()->is_regular()); - (*file)->set_owning_mount(*mount); - - auto mount_state = static_pointer_cast(driver_data); - REQUIRE(mount_state); + (*file)->set_driver_state(driver_state); THEN("writing to the inode updates backing device and the inode size") { @@ -380,8 +381,8 @@ SCENARIO_METHOD(kernel::tests::vfs::storage_boot_module_fixture, "Ext2 inode wri { auto inode = static_pointer_cast(file.value()); - auto const block_size = kernel::filesystems::ext2::block_size(*mount_state); - auto const expected_allocated_blocks = 32 * block_count(*inode, *mount_state); + auto const block_size = kernel::filesystems::ext2::block_size(*driver_state); + auto const expected_allocated_blocks = 32 * block_count(*inode, *driver_state); auto write_buffer = kstd::vector(block_size.value * expected_allocated_blocks, std::byte{'A'}); @@ -394,7 +395,7 @@ SCENARIO_METHOD(kernel::tests::vfs::storage_boot_module_fixture, "Ext2 inode wri REQUIRE(std::ranges::all_of(read_buffer, [](std::byte c) { return c == std::byte{'A'}; })); REQUIRE(inode->size().value == write_buffer.size()); - REQUIRE(block_count(*inode, *mount_state) == expected_allocated_blocks); + REQUIRE(block_count(*inode, *driver_state) == expected_allocated_blocks); } THEN("writing to a an inode of type directory panics") @@ -442,8 +443,8 @@ SCENARIO("Ext2 inode write across block boundaries", "[filesystem][ext2][inode]" auto mount = kernel::vfs::mount::create(nullptr, fs, nullptr, nullptr, dev_inode); auto root = (*mount)->root_dentry()->inode(); REQUIRE(mount); - auto mount_state = static_pointer_cast((*mount)->driver_data()); - REQUIRE(mount_state); + auto driver_state = static_pointer_cast((*mount)->driver_state()); + REQUIRE(driver_state); auto inode_data = kernel::filesystems::ext2::inode_data{}; inode_data.size = 5; @@ -454,10 +455,10 @@ SCENARIO("Ext2 inode write across block boundaries", "[filesystem][ext2][inode]" uint32_t inode_number = 3; auto const inode_data_offset = block_group_descriptor.inode_table * block_size + - kstd::bytes{(inode_number - 1) * mount_state->superblock.inode_size}; + kstd::bytes{(inode_number - 1) * driver_state->superblock.inode_size}; auto inode = kernel::filesystems::ext2::inode{inode_number, inode_data}; - inode.set_owning_mount(*mount); + inode.set_driver_state(driver_state); REQUIRE(dev_inode->write(kstd::raw_bytes(inode), inode_data_offset)); auto const buffer = @@ -470,7 +471,7 @@ SCENARIO("Ext2 inode write across block boundaries", "[filesystem][ext2][inode]" auto inode_data = kernel::filesystems::ext2::inode_data{}; REQUIRE(dev_inode->read(kstd::raw_bytes(inode_data), inode_data_offset)); auto read_inode = kernel::filesystems::ext2::inode{inode_number, inode_data}; - read_inode.set_owning_mount(*mount); + read_inode.set_driver_state(driver_state); return read_inode; }; @@ -583,6 +584,7 @@ SCENARIO("Ext2 inode get_size() and set_size() handles size correctly depending auto mount = kernel::vfs::mount::create(nullptr, fs, nullptr, nullptr, dev_inode); auto root = (*mount)->root_dentry()->inode(); REQUIRE(mount); + auto driver_state = (*mount)->driver_state(); auto data = kernel::filesystems::ext2::inode_data{}; data.size = 256; @@ -593,7 +595,7 @@ SCENARIO("Ext2 inode get_size() and set_size() handles size correctly depending data.mode = mode; auto inode = kernel::filesystems::ext2::inode{42, data}; - inode.set_owning_mount(*mount); + inode.set_driver_state(driver_state); REQUIRE(inode.size() == expected_initial_size); @@ -629,6 +631,7 @@ SCENARIO("Ext2 inode get_size() and set_size() handles size correctly depending auto mount = kernel::vfs::mount::create(nullptr, fs, nullptr, nullptr, dev_inode); auto root = (*mount)->root_dentry()->inode(); REQUIRE(mount); + auto driver_state = (*mount)->driver_state(); auto data = kernel::filesystems::ext2::inode_data{}; data.size = 256; @@ -639,7 +642,7 @@ SCENARIO("Ext2 inode get_size() and set_size() handles size correctly depending data.mode = mode; auto inode = kernel::filesystems::ext2::inode{42, data}; - inode.set_owning_mount(*mount); + inode.set_driver_state(driver_state); REQUIRE(inode.size() == expected_initial_size); @@ -705,12 +708,12 @@ SCENARIO_METHOD(kernel::tests::vfs::storage_boot_module_fixture, auto fs = kstd::make_shared(); auto mount = kernel::vfs::mount::create(nullptr, fs, nullptr, nullptr, dev_inode); auto root = (*mount)->root_dentry()->inode(); - auto driver_data = (*mount)->driver_data(); + auto driver_state = (*mount)->driver_state(); REQUIRE(mount); - auto information = fs->lookup(root, "information", driver_data); + auto information = fs->lookup(root, "information", driver_state); REQUIRE(information); - (*information)->set_owning_mount(*mount); + (*information)->set_driver_state(driver_state); WHEN("read_directory is called with a buffer large enough for everything in it") { @@ -796,6 +799,7 @@ SCENARIO("Ext2 inode read_directory skips deleted entries and paginates correctl auto fs = kstd::make_shared(); auto mount = kernel::vfs::mount::create(nullptr, fs, nullptr, nullptr, dev_inode); REQUIRE(mount); + auto driver_state = (*mount)->driver_state(); auto block = std::vector(block_size.value, std::byte{0}); auto offset = 0uz; @@ -817,7 +821,7 @@ SCENARIO("Ext2 inode read_directory skips deleted entries and paginates correctl data.block[0] = 30; auto directory = kernel::filesystems::ext2::inode{3, data}; - directory.set_owning_mount(*mount); + directory.set_driver_state(driver_state); WHEN("read_directory is called one entry at a time, chaining the returned cursor") { diff --git a/kernel/kernel/filesystems/ext2/mount_state.hpp b/kernel/kernel/filesystems/ext2/mount_state.hpp deleted file mode 100644 index 8103f4fb..00000000 --- a/kernel/kernel/filesystems/ext2/mount_state.hpp +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef TEACHOS_KERNEL_FILESYSTEMS_EXT2_MOUNT_STATE_HPP -#define TEACHOS_KERNEL_FILESYSTEMS_EXT2_MOUNT_STATE_HPP - -#include -#include -#include - -#include - -#include -#include - -namespace kernel::filesystems::ext2 -{ - - struct mount_state - { - struct superblock superblock{}; - kstd::vector block_group_descriptors{}; - kstd::shared_ptr backing_inode{}; - mutable kapi::tracked_mutex lock{}; - }; - -} // namespace kernel::filesystems::ext2 - -#endif \ No newline at end of file diff --git a/kernel/kernel/filesystems/ext2/write_batch.cpp b/kernel/kernel/filesystems/ext2/write_batch.cpp index f9a86a82..0bec30f4 100644 --- a/kernel/kernel/filesystems/ext2/write_batch.cpp +++ b/kernel/kernel/filesystems/ext2/write_batch.cpp @@ -1,8 +1,8 @@ #include +#include #include #include -#include #include @@ -13,7 +13,7 @@ namespace kernel::filesystems::ext2 { - write_batch::write_batch(mount_state & state) + write_batch::write_batch(driver_state & state) : m_state{state} {} diff --git a/kernel/kernel/filesystems/ext2/write_batch.hpp b/kernel/kernel/filesystems/ext2/write_batch.hpp index 926936df..dc4502b3 100644 --- a/kernel/kernel/filesystems/ext2/write_batch.hpp +++ b/kernel/kernel/filesystems/ext2/write_batch.hpp @@ -1,6 +1,8 @@ #ifndef TEACHOS_KERNEL_FILESYSTEMS_EXT2_WRITE_BATCH_HPP #define TEACHOS_KERNEL_FILESYSTEMS_EXT2_WRITE_BATCH_HPP +#include + #include #include @@ -9,7 +11,6 @@ namespace kernel::filesystems::ext2 { struct inode; - struct mount_state; //! A RAII write batching type. //! @@ -19,7 +20,7 @@ namespace kernel::filesystems::ext2 //! Construct a new write batch for the given filesystem and mount state. //! //! @param state The driver state to operate on. - explicit write_batch(mount_state & state); + explicit write_batch(driver_state & state); write_batch(write_batch const &) = delete; write_batch(write_batch &&) = delete; @@ -40,7 +41,7 @@ namespace kernel::filesystems::ext2 auto mark_inode(inode & inode) -> void; private: - mount_state & m_state; + driver_state & m_state; kstd::vector m_dirty_groups{}; kstd::vector m_dirty_inodes{}; }; diff --git a/kernel/kernel/vfs.cpp b/kernel/kernel/vfs.cpp index 9dee6386..1f996fb4 100644 --- a/kernel/kernel/vfs.cpp +++ b/kernel/kernel/vfs.cpp @@ -307,9 +307,9 @@ namespace kernel::vfs if (auto fs = mount_context->filesystem()) { if (auto new_inode = - fs->create_inode(parent_dentry->inode(), name, type, mount_context->driver_data(), raw_device)) + fs->create_inode(parent_dentry->inode(), name, type, mount_context->driver_state(), raw_device)) { - (*new_inode)->set_owning_mount(mount_context); + (*new_inode)->set_driver_state(mount_context->driver_state()); auto new_dentry = kstd::make_shared(parent_dentry, *new_inode, name); parent_dentry->add_child(new_dentry); @@ -322,8 +322,8 @@ namespace kernel::vfs } auto vfs::graft_persistent_device_fs(kstd::shared_ptr const & device_fs, - kstd::shared_ptr const & root_inode, kstd::shared_ptr driver_data) - -> void + kstd::shared_ptr const & root_inode, + kstd::shared_ptr driver_data) -> void { auto [root_mount_point_dentry, root_mount] = resolve_path_internal("/").value_or(std::pair{nullptr, nullptr}); if (root_mount_point_dentry && root_mount) @@ -402,13 +402,13 @@ namespace kernel::vfs if (!next_dentry) { auto current_fs = current_mount->filesystem(); - auto found_inode = current_fs->lookup(current_dentry->inode(), part, current_mount->driver_data()); + auto found_inode = current_fs->lookup(current_dentry->inode(), part, current_mount->driver_state()); if (!found_inode) { return kstd::failure(found_inode.error()); } - (*found_inode)->set_owning_mount(current_mount); + (*found_inode)->set_driver_state(current_mount->driver_state()); next_dentry = kstd::make_shared(current_dentry, *found_inode, part); current_dentry->add_child(next_dentry); diff --git a/kernel/kernel/vfs.hpp b/kernel/kernel/vfs.hpp index 136d5f5c..8688536a 100644 --- a/kernel/kernel/vfs.hpp +++ b/kernel/kernel/vfs.hpp @@ -8,6 +8,7 @@ #include // IWYU pragma: export #include // IWYU pragma: export #include // IWYU pragma: export +#include // IWYU pragma: export #include // IWYU pragma: export #include // IWYU pragma: export #include // IWYU pragma: export @@ -124,8 +125,8 @@ namespace kernel::vfs [[nodiscard]] auto find_mount(std::string_view path) const -> kstd::result; auto graft_persistent_device_fs(kstd::shared_ptr const & device_fs, - kstd::shared_ptr const & root_inode, kstd::shared_ptr driver_data) - -> void; + kstd::shared_ptr const & root_inode, + kstd::shared_ptr driver_data) -> void; auto create_inode(std::string_view path, kapi::filesystem::file_type type, std::optional raw_device = std::nullopt) -> kstd::result; diff --git a/kernel/kernel/vfs/driver_state.cpp b/kernel/kernel/vfs/driver_state.cpp new file mode 100644 index 00000000..18f11659 --- /dev/null +++ b/kernel/kernel/vfs/driver_state.cpp @@ -0,0 +1,24 @@ +#include + +#include + +#include + +namespace kernel::vfs +{ + + driver_state::driver_state(kstd::weak_ptr owner) + : m_owner{owner} + {} + + [[nodiscard]] auto driver_state::owner() const noexcept -> kstd::weak_ptr + { + return m_owner; + } + + auto driver_state::set_owner(kstd::weak_ptr owner) noexcept -> void + { + m_owner = owner; + } + +} // namespace kernel::vfs \ No newline at end of file diff --git a/kernel/kernel/vfs/driver_state.hpp b/kernel/kernel/vfs/driver_state.hpp new file mode 100644 index 00000000..2756ea8a --- /dev/null +++ b/kernel/kernel/vfs/driver_state.hpp @@ -0,0 +1,25 @@ +#ifndef KERNEL_VFS_DRIVER_STATE_HPP +#define KERNEL_VFS_DRIVER_STATE_HPP + +#include + +namespace kernel::vfs +{ + + struct driver_state + { + virtual ~driver_state() = default; + + explicit driver_state(kstd::weak_ptr owner = {}); + + [[nodiscard]] auto owner() const noexcept -> kstd::weak_ptr; + + auto set_owner(kstd::weak_ptr owner) noexcept -> void; + + private: + kstd::weak_ptr m_owner; + }; + +} // namespace kernel::vfs + +#endif \ No newline at end of file diff --git a/kernel/kernel/vfs/filesystem.hpp b/kernel/kernel/vfs/filesystem.hpp index 52abb437..0c33b2b4 100644 --- a/kernel/kernel/vfs/filesystem.hpp +++ b/kernel/kernel/vfs/filesystem.hpp @@ -1,6 +1,7 @@ #ifndef TEACHOS_KERNEL_VFS_FILESYSTEM_HPP #define TEACHOS_KERNEL_VFS_FILESYSTEM_HPP +#include #include #include @@ -24,7 +25,7 @@ namespace kernel::vfs struct filesystem { using filesystem_ptr = kstd::shared_ptr; - using driver_data_ptr = kstd::shared_ptr; + using driver_data_ptr = kstd::shared_ptr; using inode_ptr = kstd::shared_ptr; using mount_result = std::pair; diff --git a/kernel/kernel/vfs/inode.cpp b/kernel/kernel/vfs/inode.cpp index 9bf44512..3ca77827 100644 --- a/kernel/kernel/vfs/inode.cpp +++ b/kernel/kernel/vfs/inode.cpp @@ -1,5 +1,6 @@ #include +#include #include #include @@ -88,14 +89,14 @@ namespace kernel::vfs return kstd::failure(errc::not_a_directory); } - auto inode::owning_mount() const noexcept -> kstd::weak_ptr + auto inode::driver_state() const noexcept -> kstd::weak_ptr { - return m_owning_mount; + return m_driver_state; } - auto inode::set_owning_mount(kstd::shared_ptr const & source) noexcept -> void + auto inode::set_driver_state(kstd::shared_ptr const & source) noexcept -> void { - m_owning_mount = source; + m_driver_state = source; } } // namespace kernel::vfs \ No newline at end of file diff --git a/kernel/kernel/vfs/inode.hpp b/kernel/kernel/vfs/inode.hpp index d8db8046..63e73315 100644 --- a/kernel/kernel/vfs/inode.hpp +++ b/kernel/kernel/vfs/inode.hpp @@ -1,6 +1,8 @@ #ifndef TEACHOS_KERNEL_VFS_INODE_HPP #define TEACHOS_KERNEL_VFS_INODE_HPP +#include + #include #include @@ -116,23 +118,23 @@ namespace kernel::vfs //! @} - //! @name Mount Resolution + //! @name Driver State Resolution //! @{ //! Get the mount this inode belongs to. //! //! @return The mount this inode belongs to. - [[nodiscard]] auto owning_mount() const noexcept -> kstd::weak_ptr; + [[nodiscard]] auto driver_state() const noexcept -> kstd::weak_ptr; //! Define which mount this inode belongs to. //! //! @param source The mount this inode belongs to. - auto set_owning_mount(kstd::shared_ptr const & source) noexcept -> void; + auto set_driver_state(kstd::shared_ptr const & source) noexcept -> void; //! @} private: - kstd::weak_ptr m_owning_mount{}; + kstd::weak_ptr m_driver_state{}; }; } // namespace kernel::vfs diff --git a/kernel/kernel/vfs/mount.cpp b/kernel/kernel/vfs/mount.cpp index 22496307..b5fdfa39 100644 --- a/kernel/kernel/vfs/mount.cpp +++ b/kernel/kernel/vfs/mount.cpp @@ -1,6 +1,7 @@ #include #include +#include #include #include @@ -15,14 +16,15 @@ namespace kernel::vfs { mount::mount(dentry_ptr const & mount_dentry, dentry_ptr const & root_dentry, filesystem_ptr const & fs, - mount_ptr const & parent_mount, mount_ptr const & source_mount, kstd::shared_ptr driver_data) - : m_mount_dentry(mount_dentry) - , m_root_dentry(root_dentry) - , m_filesystem(fs) - , m_parent_mount(parent_mount) - , m_source_mount(source_mount) - , m_driver_data(driver_data) - , m_ref_count(0) + mount_ptr const & parent_mount, mount_ptr const & source_mount, + kstd::shared_ptr driver_state) + : m_mount_dentry{mount_dentry} + , m_root_dentry{root_dentry} + , m_filesystem{fs} + , m_parent_mount{parent_mount} + , m_source_mount{source_mount} + , m_driver_state{driver_state} + , m_ref_count{0} { if (!m_filesystem) { @@ -31,7 +33,7 @@ namespace kernel::vfs } auto mount::attach(dentry_ptr const & mount_dentry, filesystem_ptr const & fs, - kstd::shared_ptr const & root_inode, kstd::shared_ptr driver_data, + kstd::shared_ptr const & root_inode, kstd::shared_ptr driver_data, mount_ptr const & parent_mount, mount_ptr const & source_mount) -> mount_ptr { auto root_dentry = mount_dentry @@ -42,7 +44,11 @@ namespace kernel::vfs new mount{mount_dentry, root_dentry, fs, parent_mount, source_mount, driver_data} }; - root_inode->set_owning_mount(instance); + if (driver_data) + { + root_inode->set_driver_state(driver_data); + driver_data->set_owner(instance); + } return instance; } @@ -103,9 +109,9 @@ namespace kernel::vfs return m_source_mount.lock(); } - auto mount::driver_data() const -> kstd::shared_ptr + auto mount::driver_state() const -> kstd::shared_ptr { - return m_driver_data; + return m_driver_state; } auto mount::increment_ref_count() -> void diff --git a/kernel/kernel/vfs/mount.hpp b/kernel/kernel/vfs/mount.hpp index b59d3de8..beecb759 100644 --- a/kernel/kernel/vfs/mount.hpp +++ b/kernel/kernel/vfs/mount.hpp @@ -2,6 +2,7 @@ #define TEACHOS_KERNEL_VFS_MOUNT_HPP #include +#include #include #include @@ -28,11 +29,11 @@ namespace kernel::vfs //! @param mount_dentry The directory entry where the filesystem is mounted. //! @param fs The filesystem instance being mounted. //! @param root_inode The backing inode for the filesystem, must not be null. - //! @param driver_data The filesystem specific driver data. + //! @param driver_state The filesystem specific driver data. //! @param parent_mount The parent mount which contains the mount_dentry. //! @param source_mount The mount that the filesystem originates from. auto static attach(dentry_ptr const & mount_dentry, filesystem_ptr const & fs, inode_ptr const & root_inode, - kstd::shared_ptr driver_data, mount_ptr const & parent_mount, + kstd::shared_ptr driver_state, mount_ptr const & parent_mount, mount_ptr const & source_mount) -> mount_ptr; //! Create a new mount with the given parameters. @@ -64,7 +65,7 @@ namespace kernel::vfs [[nodiscard]] auto source_mount() const -> mount_ptr; //! Get the data of the attached filesystem driver. - [[nodiscard]] auto driver_data() const -> kstd::shared_ptr; + [[nodiscard]] auto driver_state() const -> kstd::shared_ptr; //! Increment the reference count for this mount. auto increment_ref_count() -> void; @@ -92,16 +93,17 @@ namespace kernel::vfs //! @param fs The filesystem instance being mounted. //! @param parent_mount The parent mount which contains the mount_dentry. //! @param source_mount The mount that the filesystem originates from. - //! @param driver_data The driver specific state data. + //! @param driver_state The driver specific state data. mount(dentry_ptr const & mount_dentry, dentry_ptr const & root_dentry, filesystem_ptr const & fs, - mount_ptr const & parent_mount, mount_ptr const & source_mount, kstd::shared_ptr driver_data); + mount_ptr const & parent_mount, mount_ptr const & source_mount, + kstd::shared_ptr driver_state); dentry_ptr m_mount_dentry{}; dentry_ptr m_root_dentry{}; filesystem_ptr m_filesystem{}; mount_ptr m_parent_mount{}; kstd::weak_ptr m_source_mount{}; - kstd::shared_ptr m_driver_data{}; + kstd::shared_ptr m_driver_state{}; std::atomic_size_t m_ref_count{0}; }; } // namespace kernel::vfs -- cgit v1.2.3