aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--kapi/kapi/filesystem.hpp18
-rw-r--r--kernel/kapi/filesystem.cpp12
-rw-r--r--kernel/kernel/filesystem/devfs/filesystem.cpp10
-rw-r--r--kernel/kernel/filesystem/devfs/filesystem.hpp12
-rw-r--r--kernel/kernel/filesystem/error.hpp5
-rw-r--r--kernel/kernel/filesystem/ext2/filesystem.hpp3
-rw-r--r--kernel/kernel/filesystem/filesystem.hpp12
-rw-r--r--kernel/kernel/filesystem/path.hpp32
-rw-r--r--kernel/kernel/filesystem/rootfs/filesystem.cpp9
-rw-r--r--kernel/kernel/filesystem/rootfs/filesystem.hpp12
-rw-r--r--kernel/kernel/filesystem/vfs.cpp46
-rw-r--r--kernel/kernel/filesystem/vfs.hpp18
-rw-r--r--kernel/kernel/test_support/filesystem/filesystem.cpp12
-rw-r--r--kernel/kernel/test_support/filesystem/filesystem.hpp9
14 files changed, 202 insertions, 8 deletions
diff --git a/kapi/kapi/filesystem.hpp b/kapi/kapi/filesystem.hpp
index 5346a96d..1656a17f 100644
--- a/kapi/kapi/filesystem.hpp
+++ b/kapi/kapi/filesystem.hpp
@@ -1,6 +1,7 @@
#ifndef TEACHOS_KAPI_FILESYSTEM_HPP
#define TEACHOS_KAPI_FILESYSTEM_HPP
+#include <kstd/result.hpp>
#include <kstd/system_error.hpp>
#include <cstddef>
@@ -69,6 +70,23 @@ namespace kapi::filesystem
@qualifier kernel-defined
*/
auto write(size_t file_descriptor, void const * buffer, size_t size) -> std::expected<std::size_t, kstd::error_code>;
+
+ /**
+ @brief Creates a new directory at the specified @p path.
+ @param path The path where the new directory should be created.
+ @return 0 on success, -1 on failure.
+ @qualifier kernel-defined
+ */
+ auto mkdir(std::string_view path) -> kstd::result<void>;
+
+ /**
+ @brief Creates a new file at the specified @p path.
+ @param path The path where the new file should be created.
+ @return 0 on success, -1 on failure.
+ @qualifier kernel-defined
+ */
+ // TODO remove again after the open method supports an optional create flag
+ auto create(std::string_view path) -> kstd::result<void>;
} // namespace kapi::filesystem
#endif // TEACHOS_KAPI_FILESYSTEM_HPP \ No newline at end of file
diff --git a/kernel/kapi/filesystem.cpp b/kernel/kapi/filesystem.cpp
index efde1336..822095e6 100644
--- a/kernel/kapi/filesystem.cpp
+++ b/kernel/kapi/filesystem.cpp
@@ -5,6 +5,7 @@
#include <kernel/filesystem/vfs.hpp>
#include <kstd/memory.hpp>
+#include <kstd/result.hpp>
#include <kstd/system_error.hpp>
#include <cstddef>
@@ -53,4 +54,15 @@ namespace kapi::filesystem
return descriptor->write(buffer, size);
});
}
+
+ auto mkdir(std::string_view path) -> kstd::result<void>
+ {
+ return kernel::filesystem::vfs::get().mkdir(path);
+ }
+
+ auto create(std::string_view path) -> kstd::result<void>
+ {
+ return kernel::filesystem::vfs::get().create(path);
+ }
+
} // namespace kapi::filesystem \ No newline at end of file
diff --git a/kernel/kernel/filesystem/devfs/filesystem.cpp b/kernel/kernel/filesystem/devfs/filesystem.cpp
index 7ffcb3c4..66799988 100644
--- a/kernel/kernel/filesystem/devfs/filesystem.cpp
+++ b/kernel/kernel/filesystem/devfs/filesystem.cpp
@@ -1,12 +1,13 @@
#include <kernel/filesystem/devfs/filesystem.hpp>
-#include "kernel/filesystem/filesystem.hpp"
#include <kernel/devices/storage/management.hpp>
#include <kernel/filesystem/devfs/inode.hpp>
#include <kernel/filesystem/device_inode.hpp>
#include <kernel/filesystem/error.hpp>
+#include <kernel/filesystem/filesystem.hpp>
#include <kernel/filesystem/inode.hpp>
#include <kernel/filesystem/type.hpp>
+#include <kernel/filesystem/vfs_types.hpp>
#include <kapi/devices/device.hpp>
@@ -82,6 +83,13 @@ namespace kernel::filesystem::devfs
return kstd::failure(vfs_errc::no_such_file_or_directory);
}
+ auto filesystem::create_inode(kstd::shared_ptr<kernel::filesystem::inode> const &, std::string_view,
+ kernel::filesystem::vfs_types::inode_type)
+ -> kstd::result<kstd::shared_ptr<kernel::filesystem::inode>>
+ {
+ return kstd::failure(vfs_errc::read_only_file_system);
+ }
+
auto filesystem::build_device_inode_table() -> void
{
m_inodes.clear();
diff --git a/kernel/kernel/filesystem/devfs/filesystem.hpp b/kernel/kernel/filesystem/devfs/filesystem.hpp
index dadeaf7d..be3c119c 100644
--- a/kernel/kernel/filesystem/devfs/filesystem.hpp
+++ b/kernel/kernel/filesystem/devfs/filesystem.hpp
@@ -4,6 +4,7 @@
#include <kernel/filesystem/device_inode.hpp>
#include <kernel/filesystem/filesystem.hpp>
#include <kernel/filesystem/inode.hpp>
+#include <kernel/filesystem/vfs_types.hpp>
#include <kstd/memory.hpp>
#include <kstd/result.hpp>
@@ -38,6 +39,17 @@ namespace kernel::filesystem::devfs
[[nodiscard]] auto lookup(kstd::shared_ptr<kernel::filesystem::inode> const & parent, std::string_view name) const
-> 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.
+ @param inode_type The type of inode to be created.
+ @return Always returns nullptr, as creating new inodes is not supported in devfs.
+ */
+ [[nodiscard]] auto create_inode(kstd::shared_ptr<kernel::filesystem::inode> const & parent, std::string_view name,
+ kernel::filesystem::vfs_types::inode_type inode_type)
+ -> kstd::result<kstd::shared_ptr<kernel::filesystem::inode>> override;
+
private:
auto build_device_inode_table() -> void;
diff --git a/kernel/kernel/filesystem/error.hpp b/kernel/kernel/filesystem/error.hpp
index 56f56ce4..82ba33b3 100644
--- a/kernel/kernel/filesystem/error.hpp
+++ b/kernel/kernel/filesystem/error.hpp
@@ -24,6 +24,7 @@ namespace kernel::filesystem
invalid_inode,
not_a_directory,
is_a_directory,
+ read_only_file_system,
};
namespace detail
@@ -65,6 +66,8 @@ namespace kernel::filesystem
return "not a directory";
case vfs_errc::is_a_directory:
return "is a directory";
+ case vfs_errc::read_only_file_system:
+ return "readonly filesystem";
default:
return "unknown VFS error";
}
@@ -95,6 +98,8 @@ namespace kernel::filesystem
return make_error_condition(kstd::errc::not_a_directory);
case vfs_errc::is_a_directory:
return make_error_condition(kstd::errc::is_a_directory);
+ case vfs_errc::read_only_file_system:
+ return make_error_condition(kstd::errc::read_only_file_system);
default:
return kstd::error_condition{value, *this};
}
diff --git a/kernel/kernel/filesystem/ext2/filesystem.hpp b/kernel/kernel/filesystem/ext2/filesystem.hpp
index 03398f00..9af9aeb1 100644
--- a/kernel/kernel/filesystem/ext2/filesystem.hpp
+++ b/kernel/kernel/filesystem/ext2/filesystem.hpp
@@ -16,7 +16,6 @@
#include <array>
#include <cstddef>
#include <cstdint>
-#include <optional>
#include <string_view>
namespace kernel::filesystem::ext2
@@ -77,7 +76,7 @@ namespace kernel::filesystem::ext2
*/
[[nodiscard]] auto create_inode(kstd::shared_ptr<kernel::filesystem::inode> const & parent, std::string_view name,
kernel::filesystem::vfs_types::inode_type inode_type)
- -> kstd::result<kstd::shared_ptr<kernel::filesystem::inode>>; // TODO move into base class and override
+ -> kstd::result<kstd::shared_ptr<kernel::filesystem::inode>> override;
/**
@brief Gets the size of a block in the filesystem.
diff --git a/kernel/kernel/filesystem/filesystem.hpp b/kernel/kernel/filesystem/filesystem.hpp
index 1264d00d..aa6286bf 100644
--- a/kernel/kernel/filesystem/filesystem.hpp
+++ b/kernel/kernel/filesystem/filesystem.hpp
@@ -2,6 +2,7 @@
#define TEACH_OS_KERNEL_FILESYSTEM_FILESYSTEM_HPP
#include <kernel/filesystem/inode.hpp>
+#include <kernel/filesystem/vfs_types.hpp>
#include <kstd/memory.hpp>
#include <kstd/result.hpp>
@@ -54,6 +55,17 @@ namespace kernel::filesystem
-> kstd::result<kstd::shared_ptr<inode>> = 0;
/**
+ @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.
+ @param inode_type The type of inode to be created.
+ @return A pointer to the created inode, or a null pointer if creation failed.
+ */
+ [[nodiscard]] virtual auto create_inode(kstd::shared_ptr<inode> const & parent, std::string_view name,
+ vfs_types::inode_type inode_type)
+ -> kstd::result<kstd::shared_ptr<inode>> = 0;
+
+ /**
@brief Returns a reference to the root inode of the filesystem.
*/
[[nodiscard]] auto root_inode() const -> kstd::shared_ptr<inode> const &;
diff --git a/kernel/kernel/filesystem/path.hpp b/kernel/kernel/filesystem/path.hpp
index 438c22f3..c2d8e588 100644
--- a/kernel/kernel/filesystem/path.hpp
+++ b/kernel/kernel/filesystem/path.hpp
@@ -7,6 +7,7 @@
#include <ranges>
#include <string_view>
+#include <utility>
namespace kernel::filesystem::path
{
@@ -66,6 +67,37 @@ namespace kernel::filesystem::path
[](auto const & part) { return kstd::string(std::string_view(part.begin(), part.end())); });
}
+ /**
+ @brief Splits the given path into its parent path and filename components.
+ @param path The path to split.
+ @return A pair of string views representing the parent path and filename.
+ */
+ auto inline split_into_path_and_filename(std::string_view path) -> std::pair<std::string_view, std::string_view>
+ {
+ if (path.empty())
+ {
+ return {"", ""};
+ }
+
+ auto search_from = path.length() > 1 ? path.length() - 2 : 0;
+ auto last_separator_index = path.rfind('/', search_from);
+
+ if (last_separator_index == std::string_view::npos)
+ {
+ return {"", path};
+ }
+ else
+ {
+ auto parent_path = path.substr(0, last_separator_index);
+ if (parent_path.empty())
+ {
+ parent_path = "/";
+ }
+ auto filename = path.substr(last_separator_index + 1);
+ return {parent_path, filename};
+ }
+ }
+
} // namespace kernel::filesystem::path
#endif // TEACH_OS_KERNEL_FILESYSTEM_PATH_HPP \ No newline at end of file
diff --git a/kernel/kernel/filesystem/rootfs/filesystem.cpp b/kernel/kernel/filesystem/rootfs/filesystem.cpp
index fef43e28..5ff56547 100644
--- a/kernel/kernel/filesystem/rootfs/filesystem.cpp
+++ b/kernel/kernel/filesystem/rootfs/filesystem.cpp
@@ -5,6 +5,7 @@
#include <kernel/filesystem/inode.hpp>
#include <kernel/filesystem/rootfs/inode.hpp>
#include <kernel/filesystem/type.hpp>
+#include <kernel/filesystem/vfs_types.hpp>
#include <kstd/memory.hpp>
#include <kstd/result.hpp>
@@ -14,7 +15,6 @@
namespace kernel::filesystem::rootfs
{
-
struct type final : kernel::filesystem::type
{
[[nodiscard]] auto name() const noexcept -> std::string_view override
@@ -47,4 +47,11 @@ namespace kernel::filesystem::rootfs
{
return kstd::failure(vfs_errc::no_such_file_or_directory);
}
+
+ auto filesystem::create_inode(kstd::shared_ptr<kernel::filesystem::inode> const &, std::string_view,
+ kernel::filesystem::vfs_types::inode_type)
+ -> kstd::result<kstd::shared_ptr<kernel::filesystem::inode>>
+ {
+ return kstd::failure(vfs_errc::read_only_file_system);
+ }
} // namespace kernel::filesystem::rootfs
diff --git a/kernel/kernel/filesystem/rootfs/filesystem.hpp b/kernel/kernel/filesystem/rootfs/filesystem.hpp
index 8507d8b8..498503c5 100644
--- a/kernel/kernel/filesystem/rootfs/filesystem.hpp
+++ b/kernel/kernel/filesystem/rootfs/filesystem.hpp
@@ -3,6 +3,7 @@
#include <kernel/filesystem/filesystem.hpp>
#include <kernel/filesystem/inode.hpp>
+#include <kernel/filesystem/vfs_types.hpp>
#include <kstd/memory.hpp>
#include <kstd/result.hpp>
@@ -37,6 +38,17 @@ namespace kernel::filesystem::rootfs
*/
[[nodiscard]] auto lookup(kstd::shared_ptr<kernel::filesystem::inode> const & parent, std::string_view name) const
-> 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.
+ @param inode_type The type of inode to be created.
+ @return Always returns nullptr, as creating new inodes is not supported in devfs.
+ */
+ [[nodiscard]] auto create_inode(kstd::shared_ptr<kernel::filesystem::inode> const & parent, std::string_view name,
+ kernel::filesystem::vfs_types::inode_type inode_type)
+ -> kstd::result<kstd::shared_ptr<kernel::filesystem::inode>> override;
};
} // namespace kernel::filesystem::rootfs
diff --git a/kernel/kernel/filesystem/vfs.cpp b/kernel/kernel/filesystem/vfs.cpp
index d128bbf5..2e4145db 100644
--- a/kernel/kernel/filesystem/vfs.cpp
+++ b/kernel/kernel/filesystem/vfs.cpp
@@ -9,6 +9,7 @@
#include <kernel/filesystem/mount_table.hpp>
#include <kernel/filesystem/path.hpp>
#include <kernel/filesystem/rootfs/filesystem.hpp>
+#include <kernel/filesystem/vfs_types.hpp>
#include <kapi/system.hpp>
@@ -171,6 +172,51 @@ namespace kernel::filesystem
return kstd::failure(vfs_errc::unmount_failed);
}
+ auto vfs::mkdir(std::string_view path) -> kstd::result<void>
+ {
+ return create_inode(path, vfs_types::inode_type::directory);
+ }
+
+ auto vfs::create(std::string_view path) -> kstd::result<void>
+ {
+ return create_inode(path, vfs_types::inode_type::regular);
+ }
+
+ auto vfs::create_inode(std::string_view path, vfs_types::inode_type type) -> kstd::result<void>
+ {
+ if (!path::is_valid_path(path))
+ {
+ return kstd::failure(vfs_errc::invalid_path);
+ }
+
+ auto [parent_path, name] = path::split_into_path_and_filename(path);
+ if (name.empty())
+ {
+ return kstd::failure(vfs_errc::invalid_path);
+ }
+
+ auto resolved_parent = resolve_path_internal(parent_path);
+ if (!resolved_parent)
+ {
+ return kstd::failure(resolved_parent.error());
+ }
+
+ auto [parent_dentry, mount_context] = *resolved_parent;
+
+ if (auto fs = mount_context->get_filesystem())
+ {
+ if (auto new_inode = fs->create_inode(parent_dentry->get_inode(), name, type))
+ {
+ auto new_dentry = kstd::make_shared<dentry>(parent_dentry, *new_inode, name);
+ parent_dentry->add_child(new_dentry);
+
+ return kstd::success();
+ }
+ }
+
+ return kstd::failure(vfs_errc::no_such_file_or_directory);
+ }
+
auto vfs::do_mount_internal(dentry_ptr const & mount_point_dentry, mount_ptr const & parent_mount, fs_ptr const & fs,
mount_ptr const & source_mount) -> void
{
diff --git a/kernel/kernel/filesystem/vfs.hpp b/kernel/kernel/filesystem/vfs.hpp
index 9dfd3637..beb336a4 100644
--- a/kernel/kernel/filesystem/vfs.hpp
+++ b/kernel/kernel/filesystem/vfs.hpp
@@ -6,6 +6,7 @@
#include <kernel/filesystem/filesystem.hpp>
#include <kernel/filesystem/mount.hpp>
#include <kernel/filesystem/mount_table.hpp>
+#include <kernel/filesystem/vfs_types.hpp>
#include <kstd/memory.hpp>
#include <kstd/result.hpp>
@@ -77,6 +78,21 @@ namespace kernel::filesystem
*/
auto unmount(std::string_view path) -> kstd::result<void>;
+ /**
+ @brief Create a new directory at the specified @p path.
+ @param path The path where the new directory should be created.
+ @return The result of the mkdir operation.
+ */
+ auto mkdir(std::string_view path) -> kstd::result<void>;
+
+ /**
+ @brief Create a new file at the specified @p path.
+ @param path The path where the new file should be created.
+ @return The result of the create operation.
+ */
+ // TODO remove again after the open method supports an optional create flag
+ auto create(std::string_view path) -> kstd::result<void>;
+
private:
/**
* Note: Resolving a dentry requires traversing mount points; since the
@@ -100,6 +116,8 @@ namespace kernel::filesystem
auto graft_persistent_device_fs(kstd::shared_ptr<devfs::filesystem> const & device_fs) -> void;
+ auto create_inode(std::string_view path, vfs_types::inode_type type) -> kstd::result<void>;
+
mount_table m_mount_table{};
};
} // namespace kernel::filesystem
diff --git a/kernel/kernel/test_support/filesystem/filesystem.cpp b/kernel/kernel/test_support/filesystem/filesystem.cpp
index 38cea2f1..b48c7935 100644
--- a/kernel/kernel/test_support/filesystem/filesystem.cpp
+++ b/kernel/kernel/test_support/filesystem/filesystem.cpp
@@ -1,18 +1,26 @@
#include <kernel/test_support/filesystem/filesystem.hpp>
#include <kernel/filesystem/inode.hpp>
+#include <kernel/filesystem/vfs_types.hpp>
#include <kernel/test_support/filesystem/inode.hpp>
#include <kstd/memory.hpp>
+#include <kstd/result.hpp>
#include <kstd/system_error.hpp>
-#include <expected>
#include <string_view>
namespace kernel::tests::filesystem
{
auto filesystem::lookup(kstd::shared_ptr<kernel::filesystem::inode> const &, std::string_view) const
- -> std::expected<kstd::shared_ptr<kernel::filesystem::inode>, kstd::error_code>
+ -> kstd::result<kstd::shared_ptr<kernel::filesystem::inode>>
+ {
+ return kstd::make_shared<inode>();
+ }
+
+ auto filesystem::create_inode(kstd::shared_ptr<kernel::filesystem::inode> const &, std::string_view,
+ kernel::filesystem::vfs_types::inode_type)
+ -> kstd::result<kstd::shared_ptr<kernel::filesystem::inode>>
{
return kstd::make_shared<inode>();
}
diff --git a/kernel/kernel/test_support/filesystem/filesystem.hpp b/kernel/kernel/test_support/filesystem/filesystem.hpp
index e6e0f416..17edd079 100644
--- a/kernel/kernel/test_support/filesystem/filesystem.hpp
+++ b/kernel/kernel/test_support/filesystem/filesystem.hpp
@@ -3,11 +3,12 @@
#include <kernel/filesystem/filesystem.hpp>
#include <kernel/filesystem/inode.hpp>
+#include <kernel/filesystem/vfs_types.hpp>
#include <kstd/memory.hpp>
+#include <kstd/result.hpp>
#include <kstd/system_error.hpp>
-#include <expected>
#include <string_view>
namespace kernel::tests::filesystem
@@ -17,7 +18,11 @@ namespace kernel::tests::filesystem
filesystem() = default;
[[nodiscard]] auto lookup(kstd::shared_ptr<kernel::filesystem::inode> const & parent, std::string_view name) const
- -> std::expected<kstd::shared_ptr<kernel::filesystem::inode>, kstd::error_code> override;
+ -> kstd::result<kstd::shared_ptr<kernel::filesystem::inode>> override;
+
+ [[nodiscard]] auto create_inode(kstd::shared_ptr<kernel::filesystem::inode> const & parent, std::string_view name,
+ kernel::filesystem::vfs_types::inode_type inode_type)
+ -> kstd::result<kstd::shared_ptr<kernel::filesystem::inode>> override;
};
} // namespace kernel::tests::filesystem