diff options
| author | Felix Morgner <felix.morgner@ost.ch> | 2026-08-25 22:49:44 +0200 |
|---|---|---|
| committer | Felix Morgner <felix.morgner@ost.ch> | 2026-08-26 11:16:17 +0200 |
| commit | 660c4548f2da83b938fba88e39020eae2796dc0e (patch) | |
| tree | ba41de4cb796845a3c5d8083c1601fe8fcf34092 /kernel | |
| parent | 94383569926c6566ed8c102addc709cb0429f398 (diff) | |
| download | kernel-660c4548f2da83b938fba88e39020eae2796dc0e.tar.xz kernel-660c4548f2da83b938fba88e39020eae2796dc0e.zip | |
kernel/fs: ext2: add a simple write batching type
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | kernel/kernel/filesystem/ext2/filesystem.hpp | 2 | ||||
| -rw-r--r-- | kernel/kernel/filesystem/ext2/write_batch.cpp | 67 | ||||
| -rw-r--r-- | kernel/kernel/filesystem/ext2/write_batch.hpp | 53 |
4 files changed, 123 insertions, 0 deletions
diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index 1a5e2421..35c3a957 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -80,6 +80,7 @@ target_sources("kernel_lib" PRIVATE "kernel/filesystem/ext2/filesystem.cpp" "kernel/filesystem/ext2/inode.cpp" "kernel/filesystem/ext2/module.cpp" + "kernel/filesystem/ext2/write_batch.cpp" # Rootfs Filesystem "kernel/filesystem/rootfs/filesystem.cpp" diff --git a/kernel/kernel/filesystem/ext2/filesystem.hpp b/kernel/kernel/filesystem/ext2/filesystem.hpp index 93836b91..f43e357c 100644 --- a/kernel/kernel/filesystem/ext2/filesystem.hpp +++ b/kernel/kernel/filesystem/ext2/filesystem.hpp @@ -191,6 +191,8 @@ namespace kernel::filesystem::ext2 -> kstd::result<void>; private: + friend struct write_batch; + //! Allocate a single inode in the file system. //! //! @param state The driver state to operate on. diff --git a/kernel/kernel/filesystem/ext2/write_batch.cpp b/kernel/kernel/filesystem/ext2/write_batch.cpp new file mode 100644 index 00000000..e8663d21 --- /dev/null +++ b/kernel/kernel/filesystem/ext2/write_batch.cpp @@ -0,0 +1,67 @@ +#include <kernel/filesystem/ext2/write_batch.hpp> + +#include <kernel/filesystem/ext2/filesystem.hpp> +#include <kernel/filesystem/ext2/inode.hpp> +#include <kernel/filesystem/ext2/mount_state.hpp> + +#include <kapi/system.hpp> + +#include <algorithm> +#include <cstddef> +#include <ranges> + +namespace kernel::filesystem::ext2 +{ + + write_batch::write_batch(filesystem & filesystem, mount_state & state) + : m_filesystem{filesystem} + , m_state{state} + {} + + write_batch::~write_batch() + { + std::ranges::for_each(m_dirty_groups, [this](auto index) { + auto & descriptor = m_state.block_group_descriptors.at(index); + auto result = m_filesystem.write_block_group_descriptor(descriptor, index, m_state); + + if (!result) + { + kapi::system::panic("[FS:ext2] failed to write block groups descriptor", result.error()); + } + }); + + if (!m_dirty_groups.empty()) + { + auto result = m_filesystem.write_superblock(m_state); + if (!result) + { + kapi::system::panic("[FS:ext2] failed to write superblock", result.error()); + } + } + + std::ranges::for_each(m_dirty_inodes, [this](auto inode) { + auto result = m_filesystem.write_inode(inode->number(), inode->data(), m_state); + if (!result) + { + kapi::system::panic("[FS:ext2] failed to write inode", result.error()); + } + }); + } + + auto write_batch::mark_group(std::size_t index) -> void + { + if (std::ranges::find(m_dirty_groups, index) == std::ranges::end(m_dirty_groups)) + { + m_dirty_groups.push_back(index); + } + } + + auto write_batch::mark_inode(inode & inode) -> void + { + if (std::ranges::find(m_dirty_inodes, &inode) == std::ranges::end(m_dirty_inodes)) + { + m_dirty_inodes.push_back(&inode); + } + } + +} // namespace kernel::filesystem::ext2 diff --git a/kernel/kernel/filesystem/ext2/write_batch.hpp b/kernel/kernel/filesystem/ext2/write_batch.hpp new file mode 100644 index 00000000..103684ac --- /dev/null +++ b/kernel/kernel/filesystem/ext2/write_batch.hpp @@ -0,0 +1,53 @@ +#ifndef TEACHOS_KERNEL_FILESYSTEM_EXT2_WRITE_BATCH +#define TEACHOS_KERNEL_FILESYSTEM_EXT2_WRITE_BATCH + +#include <kstd/vector.hpp> + +#include <cstddef> + +namespace kernel::filesystem::ext2 +{ + + struct filesystem; + struct inode; + struct mount_state; + + //! A RAII write batching type. + //! + //! Any metadata writes are first appended to the batch. On destruction, the write is committed to the filesystem. + struct write_batch + { + //! Construct a new write batch for the given filesystem and mount state. + //! + //! @param filesystem The filesystem driver to use for writes. + //! @param state The driver state to operate on. + write_batch(filesystem & filesystem, mount_state & state); + + write_batch(write_batch const &) = delete; + write_batch(write_batch &&) = delete; + auto operator=(write_batch const &) = delete; + auto operator=(write_batch &&) = delete; + + //! Commit and destroy the batch. + ~write_batch(); + + //! Mark the group with the given index as dirty. + //! + //! @param index The index of the group to mark. + auto mark_group(std::size_t index) -> void; + + //! Mark the given inode as dirty. + //! + //! @param inode The inode to mark. + auto mark_inode(inode & inode) -> void; + + private: + filesystem & m_filesystem; + mount_state & m_state; + kstd::vector<std::size_t> m_dirty_groups{}; + kstd::vector<inode *> m_dirty_inodes{}; + }; + +} // namespace kernel::filesystem::ext2 + +#endif |
