diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/kapi/filesystem.cpp | 12 | ||||
| -rw-r--r-- | kernel/kernel/filesystem/devfs/filesystem.cpp | 10 | ||||
| -rw-r--r-- | kernel/kernel/filesystem/devfs/filesystem.hpp | 12 | ||||
| -rw-r--r-- | kernel/kernel/filesystem/error.hpp | 5 | ||||
| -rw-r--r-- | kernel/kernel/filesystem/ext2/filesystem.hpp | 3 | ||||
| -rw-r--r-- | kernel/kernel/filesystem/filesystem.hpp | 12 | ||||
| -rw-r--r-- | kernel/kernel/filesystem/path.hpp | 32 | ||||
| -rw-r--r-- | kernel/kernel/filesystem/rootfs/filesystem.cpp | 9 | ||||
| -rw-r--r-- | kernel/kernel/filesystem/rootfs/filesystem.hpp | 12 | ||||
| -rw-r--r-- | kernel/kernel/filesystem/vfs.cpp | 46 | ||||
| -rw-r--r-- | kernel/kernel/filesystem/vfs.hpp | 18 | ||||
| -rw-r--r-- | kernel/kernel/test_support/filesystem/filesystem.cpp | 12 | ||||
| -rw-r--r-- | kernel/kernel/test_support/filesystem/filesystem.hpp | 9 |
13 files changed, 184 insertions, 8 deletions
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 |
