aboutsummaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorFelix Morgner <felix.morgner@ost.ch>2026-08-25 22:49:44 +0200
committerFelix Morgner <felix.morgner@ost.ch>2026-08-26 11:16:17 +0200
commit660c4548f2da83b938fba88e39020eae2796dc0e (patch)
treeba41de4cb796845a3c5d8083c1601fe8fcf34092 /kernel
parent94383569926c6566ed8c102addc709cb0429f398 (diff)
downloadkernel-660c4548f2da83b938fba88e39020eae2796dc0e.tar.xz
kernel-660c4548f2da83b938fba88e39020eae2796dc0e.zip
kernel/fs: ext2: add a simple write batching type
Diffstat (limited to 'kernel')
-rw-r--r--kernel/CMakeLists.txt1
-rw-r--r--kernel/kernel/filesystem/ext2/filesystem.hpp2
-rw-r--r--kernel/kernel/filesystem/ext2/write_batch.cpp67
-rw-r--r--kernel/kernel/filesystem/ext2/write_batch.hpp53
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