aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcel Braun <marcel.braun@ost.ch>2026-06-07 18:47:00 +0200
committerFelix Morgner <felix.morgner@ost.ch>2026-07-14 20:56:06 +0200
commit1db4c39c28c58c01ae13e15be4849c1fc9e9efff (patch)
tree661a0c105aa05eec3a5eaf5b9edbb195aae501ec
parent2574721fa34f34d0d4f0909cedf006f77d82734c (diff)
downloadkernel-1db4c39c28c58c01ae13e15be4849c1fc9e9efff.tar.xz
kernel-1db4c39c28c58c01ae13e15be4849c1fc9e9efff.zip
Save wip of create_inode
-rw-r--r--kernel/kernel/filesystem/ext2/filesystem.cpp87
-rw-r--r--kernel/kernel/filesystem/ext2/filesystem.hpp19
2 files changed, 100 insertions, 6 deletions
diff --git a/kernel/kernel/filesystem/ext2/filesystem.cpp b/kernel/kernel/filesystem/ext2/filesystem.cpp
index 8860f213..7b0bce0e 100644
--- a/kernel/kernel/filesystem/ext2/filesystem.cpp
+++ b/kernel/kernel/filesystem/ext2/filesystem.cpp
@@ -153,6 +153,93 @@ namespace kernel::filesystem::ext2
return kstd::failure(vfs_errc::no_such_file_or_directory);
}
+ auto filesystem::create_inode(kstd::shared_ptr<kernel::filesystem::inode> const & parent, std::string_view name)
+ -> kstd::result<kstd::shared_ptr<kernel::filesystem::inode>>
+ {
+ if (!parent)
+ {
+ return kstd::failure(vfs_errc::invalid_inode);
+ }
+
+ if (!parent->is_directory())
+ {
+ return kstd::failure(vfs_errc::not_a_directory);
+ }
+
+ auto maybe_inode_number = allocate_inode();
+ if (!maybe_inode_number)
+ {
+ return kstd::failure(maybe_inode_number.error());
+ }
+
+ auto inode_number = maybe_inode_number.value();
+
+ inode_data new_inode_data{};
+
+ // TODO set mode depending on type/mode
+ new_inode_data.mode = 0x8000;
+ new_inode_data.size = 0;
+ new_inode_data.dir_acl = 0;
+ new_inode_data.links_count = 1;
+ new_inode_data.blocks = 0;
+ new_inode_data.block.fill(0);
+
+ if (auto write_result = write_inode(inode_number, new_inode_data); !write_result)
+ {
+ return kstd::failure(write_result.error());
+ }
+
+ // add directory entry to parent
+ if (auto * ext2_parent = static_cast<inode *>(parent.get()))
+ {
+ if (auto result = add_directory_entry(ext2_parent, name, inode_number, new_inode_data.mode);
+ !result) // TODO handle mode correctly
+ {
+ return kstd::failure(result.error());
+ }
+ // TODO
+ }
+ }
+
+ auto filesystem::add_directory_entry(inode * ext2_parent, std::string_view name, uint32_t inode_number, uint16_t mode)
+ -> kstd::result<void>
+ {
+ auto block_count = inode_block_count(ext2_parent->data());
+ auto const last_block_index = block_count - 1;
+ auto const global_block_number =
+ map_inode_block_index_to_global_block_number(last_block_index, ext2_parent->data());
+
+ if (!global_block_number)
+ {
+ return kstd::failure(global_block_number.error());
+ }
+
+ kstd::vector<uint8_t> buffer(block_size());
+ if (auto read_result = read_block(*global_block_number, buffer.data()); !read_result)
+ {
+ return kstd::failure(read_result.error());
+ }
+
+ auto offset = 0uz;
+ while (true)
+ {
+ auto const * entry = reinterpret_cast<linked_directory_entry const *>(buffer.data() + offset);
+
+ if (offset + entry->rec_len >= block_size())
+ {
+ break;
+ }
+
+ offset += entry->rec_len;
+ }
+
+ auto const * last_entry = reinterpret_cast<linked_directory_entry const *>(buffer.data() + offset);
+
+ auto const last_entry_actual_length = 0; // TODO
+
+ return kstd::success();
+ }
+
auto filesystem::read_inode(uint32_t inode_number) const -> kstd::result<kstd::shared_ptr<inode>>
{
if (auto inode_offset = calculate_inode_offset(inode_number))
diff --git a/kernel/kernel/filesystem/ext2/filesystem.hpp b/kernel/kernel/filesystem/ext2/filesystem.hpp
index 33b7b95c..eaa42d01 100644
--- a/kernel/kernel/filesystem/ext2/filesystem.hpp
+++ b/kernel/kernel/filesystem/ext2/filesystem.hpp
@@ -68,6 +68,15 @@ namespace kernel::filesystem::ext2
-> kstd::result<kstd::shared_ptr<kernel::filesystem::inode>> override;
/**
+ @brief Creates a new inode with @p name within a @p parent directory.
+ @param parent The parent directory inode.
+ @param name The name of the inode to create.
+ @return A pointer to the created inode, or a null pointer if creation failed.
+ */
+ [[nodiscard]] auto create_inode(kstd::shared_ptr<kernel::filesystem::inode> const & parent, std::string_view name)
+ -> kstd::result<kstd::shared_ptr<kernel::filesystem::inode>>; // TODO move into base class and override
+
+ /**
@brief Gets the size of a block in the filesystem.
@return The size of a block in bytes.
*/
@@ -103,12 +112,6 @@ namespace kernel::filesystem::ext2
auto allocate_blocks(size_t count) -> kstd::result<kstd::vector<uint32_t>>;
/**
- @brief Allocates a new inode.
- @return The inode number within the filesystem.
- */
- auto allocate_inode() -> kstd::result<uint32_t>;
-
- /**
@brief Gets the size of an inode in the filesystem.
@return The size of an inode in bytes.
*/
@@ -162,6 +165,10 @@ namespace kernel::filesystem::ext2
[[nodiscard]] auto indirect_levels() const -> std::array<indirect_level, 3>;
+ auto allocate_inode() -> kstd::result<uint32_t>;
+ auto add_directory_entry(inode * ext2_parent, std::string_view name, uint32_t inode_number, uint16_t mode)
+ -> kstd::result<void>;
+
[[nodiscard]] auto calculate_inode_offset(uint32_t inode_number) const -> kstd::result<size_t>;
[[nodiscard]] auto read_inode(uint32_t inode_number) const -> kstd::result<kstd::shared_ptr<inode>>;
[[nodiscard]] auto read_block_number_at_index(uint32_t block_number, size_t index) const -> kstd::result<uint32_t>;