aboutsummaryrefslogtreecommitdiff
path: root/kernel/include
diff options
context:
space:
mode:
authorMarcel Braun <marcel.braun@ost.ch>2026-05-05 23:25:47 +0200
committerMarcel Braun <marcel.braun@ost.ch>2026-05-05 23:25:47 +0200
commitea450f4ed742a37b40a4e1dcaf8d17328d635472 (patch)
treecd9511ff9145dd993f257c2fcca4d8d06e857625 /kernel/include
parent3082340fa8ab3c7c0da5d2f9d321d2367d399b20 (diff)
parent4522374b902ee9a30c83c2ec23880522e80febea (diff)
downloadkernel-ea450f4ed742a37b40a4e1dcaf8d17328d635472.tar.xz
kernel-ea450f4ed742a37b40a4e1dcaf8d17328d635472.zip
Merge branch 'symbolic-links' into 'develop-BA-FS26'
Symbolic links See merge request teachos/kernel!29
Diffstat (limited to 'kernel/include')
-rw-r--r--kernel/include/kernel/filesystem/constants.hpp13
-rw-r--r--kernel/include/kernel/filesystem/dentry.hpp8
-rw-r--r--kernel/include/kernel/filesystem/devfs/inode.hpp11
-rw-r--r--kernel/include/kernel/filesystem/device_inode.hpp6
-rw-r--r--kernel/include/kernel/filesystem/ext2/filesystem.hpp1
-rw-r--r--kernel/include/kernel/filesystem/ext2/inode.hpp32
-rw-r--r--kernel/include/kernel/filesystem/inode.hpp29
-rw-r--r--kernel/include/kernel/filesystem/mount_table.hpp10
-rw-r--r--kernel/include/kernel/filesystem/open_file_table.hpp4
-rw-r--r--kernel/include/kernel/filesystem/path.hpp71
-rw-r--r--kernel/include/kernel/filesystem/rootfs/inode.hpp11
-rw-r--r--kernel/include/kernel/filesystem/vfs.hpp4
-rw-r--r--kernel/include/kernel/test_support/filesystem/inode.hpp4
13 files changed, 161 insertions, 43 deletions
diff --git a/kernel/include/kernel/filesystem/constants.hpp b/kernel/include/kernel/filesystem/constants.hpp
new file mode 100644
index 0000000..aff512a
--- /dev/null
+++ b/kernel/include/kernel/filesystem/constants.hpp
@@ -0,0 +1,13 @@
+#ifndef TEACH_OS_KERNEL_FILESYSTEM_CONSTANTS_HPP
+#define TEACH_OS_KERNEL_FILESYSTEM_CONSTANTS_HPP
+
+#include <cstddef>
+namespace kernel::filesystem::constants
+{
+ constexpr size_t inline max_path_length = 4096;
+
+ constexpr size_t inline symlink_max_path_length = 4096;
+ constexpr size_t inline symloop_max = 40;
+} // namespace kernel::filesystem::constants
+
+#endif \ No newline at end of file
diff --git a/kernel/include/kernel/filesystem/dentry.hpp b/kernel/include/kernel/filesystem/dentry.hpp
index 94fa39a..bd62735 100644
--- a/kernel/include/kernel/filesystem/dentry.hpp
+++ b/kernel/include/kernel/filesystem/dentry.hpp
@@ -24,7 +24,7 @@ namespace kernel::filesystem
*/
enum class dentry_flags : uint32_t
{
- dcache_mounted = 1 << 15
+ mounted = 1 << 15
};
/**
@@ -55,6 +55,12 @@ namespace kernel::filesystem
[[nodiscard]] auto get_name() const -> std::string_view;
/**
+ @brief Get the full path of the dentry by traversing up to the root.
+ @return The full path of the dentry.
+ */
+ [[nodiscard]] auto get_full_path() const -> kstd::string;
+
+ /**
@brief Add a @p child dentry.
@param child The child dentry to add.
*/
diff --git a/kernel/include/kernel/filesystem/devfs/inode.hpp b/kernel/include/kernel/filesystem/devfs/inode.hpp
index 0fab280..e428891 100644
--- a/kernel/include/kernel/filesystem/devfs/inode.hpp
+++ b/kernel/include/kernel/filesystem/devfs/inode.hpp
@@ -14,11 +14,6 @@ namespace kernel::filesystem::devfs
struct inode : kernel::filesystem::inode
{
/**
- @brief Create a devfs inode. The inode is initialized with the appropriate kind (directory).
- */
- inode();
-
- /**
@brief Reads from the devfs directory inode.
@param buffer Destination buffer.
@param offset Read offset in bytes.
@@ -35,6 +30,12 @@ namespace kernel::filesystem::devfs
@return Number of bytes written (always 0 because writes are not supported for this inode).
*/
auto write(void const * buffer, size_t offset, size_t size) -> size_t override;
+
+ /**
+ @brief Check if this inode represents a directory.
+ @return returns true, since this inode represents the /dev directory in the devfs filesystem.
+ */
+ [[nodiscard]] auto is_directory() const -> bool override;
};
} // namespace kernel::filesystem::devfs
diff --git a/kernel/include/kernel/filesystem/device_inode.hpp b/kernel/include/kernel/filesystem/device_inode.hpp
index 2f79fca..f4aa2d1 100644
--- a/kernel/include/kernel/filesystem/device_inode.hpp
+++ b/kernel/include/kernel/filesystem/device_inode.hpp
@@ -50,6 +50,12 @@ namespace kernel::filesystem
*/
[[nodiscard]] auto device() const -> kstd::shared_ptr<kapi::devices::device> const &;
+ /**
+ @brief Check if this inode represents a device.
+ @return returns true, since this indoe is a device inode and represents a device.
+ */
+ [[nodiscard]] auto is_device() const -> bool override;
+
private:
kstd::shared_ptr<kapi::devices::device> m_device;
};
diff --git a/kernel/include/kernel/filesystem/ext2/filesystem.hpp b/kernel/include/kernel/filesystem/ext2/filesystem.hpp
index 516e71d..d22433f 100644
--- a/kernel/include/kernel/filesystem/ext2/filesystem.hpp
+++ b/kernel/include/kernel/filesystem/ext2/filesystem.hpp
@@ -35,6 +35,7 @@ namespace kernel::filesystem::ext2
constexpr uint16_t inline mode_mask = 0xF000;
constexpr uint16_t inline mode_regular = 0x8000;
constexpr uint16_t inline mode_directory = 0x4000;
+ constexpr uint16_t inline mode_symbolic_link = 0xA000;
} // namespace constants
/**
diff --git a/kernel/include/kernel/filesystem/ext2/inode.hpp b/kernel/include/kernel/filesystem/ext2/inode.hpp
index 9291eea..b8f892a 100644
--- a/kernel/include/kernel/filesystem/ext2/inode.hpp
+++ b/kernel/include/kernel/filesystem/ext2/inode.hpp
@@ -20,7 +20,7 @@ namespace kernel::filesystem::ext2
{
uint16_t mode;
uint16_t uid;
- uint32_t size;
+ uint32_t size; // TODO BA-FS26 signed?
uint32_t atime;
uint32_t ctime;
uint32_t mtime;
@@ -42,8 +42,10 @@ namespace kernel::filesystem::ext2
{
/**
@brief Create an ext2 inode associated with the given filesystem.
+ @param fs The ext2 filesystem that this inode belongs to.
+ @param data The data associated with this inode, read from the disk.
*/
- explicit inode(filesystem * fs);
+ explicit inode(filesystem * fs, inode_data const & data);
/**
@brief Reads from the ext2 inode into a @p buffer, starting at the specified @p offset and for a given @p size.
@@ -65,12 +67,32 @@ namespace kernel::filesystem::ext2
auto write(void const * buffer, size_t offset, size_t size) -> size_t override;
/**
- @brief The raw inode data as read from the disk.
- */
- inode_data m_data{};
+ @brief Get the data associated with this inode.
+ @return A reference to the inode data.
+ */
+ [[nodiscard]] auto data() const -> inode_data const &;
+
+ /**
+ @brief Check if this inode represents a directory.
+ @return returns true if this inode represents a directory, false otherwise.
+ */
+ [[nodiscard]] auto is_directory() const -> bool override;
+
+ /**
+ @brief Check if this inode represents a regular file.
+ @return returns true if this inode represents a regular file, false otherwise.
+ */
+ [[nodiscard]] auto is_regular() const -> bool override;
+
+ /**
+ @brief Check if this inode represents a symbolic link.
+ @return returns true if this inode represents a symbolic link, false otherwise.
+ */
+ [[nodiscard]] auto is_symbolic_link() const -> bool override;
private:
filesystem * m_filesystem;
+ inode_data m_data{};
};
} // namespace kernel::filesystem::ext2
diff --git a/kernel/include/kernel/filesystem/inode.hpp b/kernel/include/kernel/filesystem/inode.hpp
index 5208be2..b34b921 100644
--- a/kernel/include/kernel/filesystem/inode.hpp
+++ b/kernel/include/kernel/filesystem/inode.hpp
@@ -11,20 +11,9 @@ namespace kernel::filesystem
struct inode
{
/**
- @brief Represents the kind of an inode.
+ @brief Create an inode.
*/
- enum class inode_kind
- {
- regular,
- directory,
- device
- };
-
- /**
- @brief Create an inode with the given @p kind.
- @param kind The kind of the inode.
- */
- explicit inode(inode_kind kind);
+ inode() = default;
/**
@brief Virtual destructor for the inode.
@@ -55,23 +44,25 @@ namespace kernel::filesystem
@brief Returns whether the inode is a directory.
@return true if the inode is a directory, false otherwise.
*/
- [[nodiscard]] auto is_directory() const -> bool;
+ [[nodiscard]] virtual auto is_directory() const -> bool;
/**
@brief Returns whether the inode is a regular file.
@return true if the inode is a regular file, false otherwise.
*/
- [[nodiscard]] auto is_regular() const -> bool;
+ [[nodiscard]] virtual auto is_regular() const -> bool;
/**
@brief Returns whether the inode is a device.
@return true if the inode is a device, false otherwise.
*/
- [[nodiscard]] auto is_device() const -> bool;
+ [[nodiscard]] virtual auto is_device() const -> bool;
- // TODO BA-FS26 avoid public member
- public:
- inode_kind m_kind{inode_kind::regular};
+ /**
+ @brief Returns whether the inode is a symbolic link.
+ @return true if the inode is a symbolic link, false otherwise.
+ */
+ [[nodiscard]] virtual auto is_symbolic_link() const -> bool;
};
} // namespace kernel::filesystem
diff --git a/kernel/include/kernel/filesystem/mount_table.hpp b/kernel/include/kernel/filesystem/mount_table.hpp
index 00277ea..8e57d9e 100644
--- a/kernel/include/kernel/filesystem/mount_table.hpp
+++ b/kernel/include/kernel/filesystem/mount_table.hpp
@@ -39,13 +39,19 @@ namespace kernel::filesystem
[[nodiscard]] auto remove_mount(std::string_view path) -> operation_result;
/**
- @brief Finds the mount with the longest prefix matching the given @p path. This method is used to determine which
- mounted filesystem should handle a given path lookup.
+ @brief Finds the mount with the longest prefix matching the given @p path.
@param path The path to match against the mount paths in the table.
@return A pointer to the mount with the longest matching prefix, or a null pointer if no mount matches the path.
*/
[[nodiscard]] auto find_longest_prefix_mount(std::string_view path) const -> kstd::shared_ptr<mount>;
+ /**
+ @brief Finds the mount with the exact mount path matching the given @p path.
+ @param path The path to match against the mount paths in the table.
+ @return A pointer to the mount with the exact matching path, or a null pointer if no mount matches the path.
+ */
+ [[nodiscard]] auto find_exact_mount(std::string_view path) const -> kstd::shared_ptr<mount>;
+
private:
[[nodiscard]] auto has_child_mounts(kstd::shared_ptr<mount> const & parent_mount) const -> bool;
diff --git a/kernel/include/kernel/filesystem/open_file_table.hpp b/kernel/include/kernel/filesystem/open_file_table.hpp
index 2f9a421..694f3b6 100644
--- a/kernel/include/kernel/filesystem/open_file_table.hpp
+++ b/kernel/include/kernel/filesystem/open_file_table.hpp
@@ -34,10 +34,10 @@ namespace kernel::filesystem
/**
@brief Add a file to the open file table.
- @param f The file descriptor to add.
+ @param fd The file descriptor to add.
@return The file descriptor index assigned to the file, or -1 on failure.
*/
- auto add_file(kstd::shared_ptr<open_file_descriptor> const & f) -> int;
+ auto add_file(kstd::shared_ptr<open_file_descriptor> const & fd) -> int;
/**
@brief Get a file from the open file table.
diff --git a/kernel/include/kernel/filesystem/path.hpp b/kernel/include/kernel/filesystem/path.hpp
new file mode 100644
index 0000000..4845bf1
--- /dev/null
+++ b/kernel/include/kernel/filesystem/path.hpp
@@ -0,0 +1,71 @@
+#ifndef TEACH_OS_KERNEL_FILESYSTEM_PATH_HPP
+#define TEACH_OS_KERNEL_FILESYSTEM_PATH_HPP
+
+#include <kernel/filesystem/constants.hpp>
+
+#include <kstd/string>
+
+#include <ranges>
+#include <string_view>
+
+namespace kernel::filesystem::path
+{
+ /**
+ @brief Provides utilities for handling filesystem paths, including validation and splitting into components.
+ */
+
+ /**
+ @brief Checks if the given path is within the maximum allowed length.
+ @param path The path to check.
+ @return true if the path length is valid, false otherwise.
+ */
+ auto inline is_valid_path_length(std::string_view path) -> bool
+ {
+ return path.length() < kernel::filesystem::constants::max_path_length;
+ }
+
+ /**
+ @brief Checks if the given path is a valid absolute path (starts with '/').
+ @param path The path to check.
+ @return true if the path is a valid absolute path, false otherwise.
+ */
+ auto inline is_valid_absolute_path(std::string_view path) -> bool
+ {
+ return !path.empty() && path.front() == '/' && is_valid_path_length(path);
+ }
+
+ /**
+ @brief Checks if the given path is a valid relative path (doesn't start with '/').
+ @param path The path to check.
+ @return true if the path is a valid relative path, false otherwise.
+ */
+ auto inline is_valid_relative_path(std::string_view path) -> bool
+ {
+ return !path.empty() && path.front() != '/' && is_valid_path_length(path);
+ }
+
+ /**
+ @brief Checks if the given path is a valid path (either absolute or relative).
+ @param path The path to check.
+ @return true if the path is a valid path, false otherwise.
+ */
+ auto inline is_valid_path(std::string_view path) -> bool
+ {
+ return is_valid_absolute_path(path) || is_valid_relative_path(path);
+ }
+
+ /**
+ @brief Splits the given path into its components.
+ @param path The path to split.
+ @return A range of strings representing the components of the path.
+ */
+ auto inline split(std::string_view path)
+ {
+ return std::views::split(path, '/') | std::views::filter([](auto const & part) { return !part.empty(); }) |
+ std::views::transform(
+ [](auto const & part) { return kstd::string(std::string_view(part.begin(), part.end())); });
+ }
+
+} // namespace kernel::filesystem::path
+
+#endif // TEACH_OS_KERNEL_FILESYSTEM_PATH_HPP \ No newline at end of file
diff --git a/kernel/include/kernel/filesystem/rootfs/inode.hpp b/kernel/include/kernel/filesystem/rootfs/inode.hpp
index 37d0a30..58035ea 100644
--- a/kernel/include/kernel/filesystem/rootfs/inode.hpp
+++ b/kernel/include/kernel/filesystem/rootfs/inode.hpp
@@ -22,11 +22,6 @@ namespace kernel::filesystem::rootfs
struct inode : kernel::filesystem::inode
{
/**
- @brief Create a rootfs inode. The inode is initialized with the appropriate kind (directory).
- */
- inode();
-
- /**
@brief Reads from the rootfs directory inode.
@param buffer Destination buffer.
@param offset Read offset in bytes.
@@ -57,6 +52,12 @@ namespace kernel::filesystem::rootfs
*/
auto lookup_child(std::string_view name) -> kstd::shared_ptr<inode>;
+ /**
+ @brief Check if this inode represents a directory.
+ @return returns true, since this inode represents the root directory in the rootfs filesystem.
+ */
+ [[nodiscard]] auto is_directory() const -> bool override;
+
private:
kstd::vector<std::pair<kstd::string, kstd::shared_ptr<inode>>> m_children;
};
diff --git a/kernel/include/kernel/filesystem/vfs.hpp b/kernel/include/kernel/filesystem/vfs.hpp
index 881f458..7e66fb7 100644
--- a/kernel/include/kernel/filesystem/vfs.hpp
+++ b/kernel/include/kernel/filesystem/vfs.hpp
@@ -77,8 +77,8 @@ namespace kernel::filesystem
auto init_internal() -> void;
[[nodiscard]] auto resolve_path(std::string_view path) -> kstd::shared_ptr<dentry>;
- auto do_mount_internal(std::string_view path, kstd::shared_ptr<dentry> const & mount_point_dentry,
- kstd::shared_ptr<filesystem> const & fs) -> void;
+ auto do_mount_internal(kstd::shared_ptr<dentry> const & mount_point_dentry, kstd::shared_ptr<filesystem> const & fs)
+ -> void;
mount_table m_mount_table;
};
diff --git a/kernel/include/kernel/test_support/filesystem/inode.hpp b/kernel/include/kernel/test_support/filesystem/inode.hpp
index 9d17917..8a76437 100644
--- a/kernel/include/kernel/test_support/filesystem/inode.hpp
+++ b/kernel/include/kernel/test_support/filesystem/inode.hpp
@@ -9,10 +9,10 @@ namespace kernel::tests::filesystem
{
struct inode : kernel::filesystem::inode
{
- inode();
-
auto read(void * buffer, size_t offset, size_t size) const -> size_t override;
auto write(void const * buffer, size_t offset, size_t size) -> size_t override;
+
+ [[nodiscard]] auto is_regular() const -> bool override;
};
} // namespace kernel::tests::filesystem