aboutsummaryrefslogtreecommitdiff
path: root/kernel/include
diff options
context:
space:
mode:
authorMarcel Braun <marcel.braun@ost.ch>2026-04-12 19:15:38 +0200
committerMarcel Braun <marcel.braun@ost.ch>2026-04-12 19:15:38 +0200
commit4d2a1d028f8ba28b655026b93124e71a12562619 (patch)
treef49deef4dd3e8728fd1000b04c0908966f37663f /kernel/include
parent21fd1281cf19572e202d583689b99c33ec68da50 (diff)
parentcb7edbe6d4454ee5b217b522f62f4a7b92475a32 (diff)
downloadteachos-develop-BA-FS26.tar.xz
teachos-develop-BA-FS26.zip
Merge branch 'ext2' into 'develop-BA-FS26'HEADdevelop-BA-FS26
ext2 and tests See merge request teachos/kernel!22
Diffstat (limited to 'kernel/include')
-rw-r--r--kernel/include/kernel/devices/block_device_utils.hpp29
-rw-r--r--kernel/include/kernel/filesystem/dentry.hpp57
-rw-r--r--kernel/include/kernel/filesystem/devfs/filesystem.hpp21
-rw-r--r--kernel/include/kernel/filesystem/devfs/inode.hpp22
-rw-r--r--kernel/include/kernel/filesystem/device_inode.hpp31
-rw-r--r--kernel/include/kernel/filesystem/ext2/block_group_descriptor.hpp5
-rw-r--r--kernel/include/kernel/filesystem/ext2/filesystem.hpp70
-rw-r--r--kernel/include/kernel/filesystem/ext2/inode.hpp49
-rw-r--r--kernel/include/kernel/filesystem/ext2/linked_directory_entry.hpp8
-rw-r--r--kernel/include/kernel/filesystem/ext2/superblock.hpp10
-rw-r--r--kernel/include/kernel/filesystem/file_descriptor_table.hpp34
-rw-r--r--kernel/include/kernel/filesystem/filesystem.hpp51
-rw-r--r--kernel/include/kernel/filesystem/inode.hpp47
-rw-r--r--kernel/include/kernel/filesystem/mount.hpp38
-rw-r--r--kernel/include/kernel/filesystem/mount_table.hpp35
-rw-r--r--kernel/include/kernel/filesystem/open_file_description.hpp34
-rw-r--r--kernel/include/kernel/filesystem/rootfs/filesystem.hpp21
-rw-r--r--kernel/include/kernel/filesystem/rootfs/inode.hpp34
-rw-r--r--kernel/include/kernel/filesystem/vfs.hpp52
-rw-r--r--kernel/include/kernel/test_support/boot_modules.hpp10
-rw-r--r--kernel/include/kernel/test_support/devices/block_device.hpp31
-rw-r--r--kernel/include/kernel/test_support/devices/character_device.hpp23
-rw-r--r--kernel/include/kernel/test_support/devices/storage/management.hpp10
-rw-r--r--kernel/include/kernel/test_support/filesystem/ext2.hpp17
-rw-r--r--kernel/include/kernel/test_support/filesystem/file_descriptor_table.hpp10
-rw-r--r--kernel/include/kernel/test_support/filesystem/filesystem.hpp22
-rw-r--r--kernel/include/kernel/test_support/filesystem/inode.hpp19
-rw-r--r--kernel/include/kernel/test_support/filesystem/storage_boot_module_fixture.hpp32
-rw-r--r--kernel/include/kernel/test_support/filesystem/storage_boot_module_vfs_fixture.hpp24
-rw-r--r--kernel/include/kernel/test_support/filesystem/vfs.hpp10
30 files changed, 826 insertions, 30 deletions
diff --git a/kernel/include/kernel/devices/block_device_utils.hpp b/kernel/include/kernel/devices/block_device_utils.hpp
index 5e862ba..7b1daec 100644
--- a/kernel/include/kernel/devices/block_device_utils.hpp
+++ b/kernel/include/kernel/devices/block_device_utils.hpp
@@ -9,7 +9,34 @@
namespace kernel::devices::block_device_utils
{
- auto read(kstd::shared_ptr<kapi::devices::device> const & device, void * buffer, size_t offset, size_t size) -> size_t;
+ /**
+ @brief Utility functions for block devices, such as reading/writing data at specific offsets. These functions handle
+ the necessary logic to interact with block devices, such as calculating block boundaries and ensuring proper access
+ patterns. They abstract away the details of block device interactions, providing a simple interface for reading and
+ writing data to block devices.
+ */
+
+ /**
+ @brief Reads data from a @p device into a @p buffer, starting at a specific @p offset and for a given @p size.
+ @warning Panics if @p buffer or @p device is null.
+ @param device The block device to read from.
+ @param buffer The buffer to read data into.
+ @param offset The offset on the block device to start reading from.
+ @param size The number of bytes to read.
+ @return The number of bytes actually read, which may be less than the requested size.
+ */
+ auto read(kstd::shared_ptr<kapi::devices::device> const & device, void * buffer, size_t offset, size_t size)
+ -> size_t;
+
+ /**
+ @brief Writes data from a @p buffer to a @p device, starting at a specific @p offset and for a given @p size.
+ @warning Panics if @p buffer or @p device is null.
+ @param device The block device to write to.
+ @param buffer The buffer to write data from.
+ @param offset The offset on the block device to start writing to.
+ @param size The number of bytes to write.
+ @return The number of bytes actually written, which may be less than the requested size.
+ */
auto write(kstd::shared_ptr<kapi::devices::device> const & device, void const * buffer, size_t offset, size_t size)
-> size_t;
} // namespace kernel::devices::block_device_utils
diff --git a/kernel/include/kernel/filesystem/dentry.hpp b/kernel/include/kernel/filesystem/dentry.hpp
index fc85a7d..58a918f 100644
--- a/kernel/include/kernel/filesystem/dentry.hpp
+++ b/kernel/include/kernel/filesystem/dentry.hpp
@@ -12,23 +12,78 @@
namespace kernel::filesystem
{
+ /**
+ @brief Represents a directory entry (dentry) in the filesystem. A dentry is a node in the directory tree that
+ represents a file or directory. It contains a reference to its parent dentry, a reference to the associated real
+ filesystem inode, and a list of child dentries.
+ */
struct dentry
{
+ /**
+ @brief Flags for the dentry.
+ */
enum class dentry_flags : uint32_t
{
dcache_mounted = 1 << 15
};
- dentry(kstd::shared_ptr<dentry> const & parent, kstd::shared_ptr<inode> const & node, std::string_view name = {});
+ /**
+ @brief Create a dentry with the given @p parent, associated @p inode, and optional @p name. The dentry is
+ initialized with the provided parent and inode, and the name is stored for lookup purposes.
+ @param parent The parent dentry.
+ @param inode The associated inode for this dentry.
+ @param name The name of the dentry (optional).
+ */
+ dentry(kstd::shared_ptr<dentry> const & parent, kstd::shared_ptr<inode> const & inode, std::string_view name = {});
+ /**
+ @brief Get the associated inode.
+ @return A reference to the associated inode.
+ */
[[nodiscard]] auto get_inode() const -> kstd::shared_ptr<inode> const &;
+
+ /**
+ @brief Get the parent dentry.
+ @return A reference to the parent dentry.
+ */
[[nodiscard]] auto get_parent() const -> kstd::shared_ptr<dentry> const &;
+ /**
+ @brief Get the name of the dentry.
+ @return The name of the dentry.
+ */
+ [[nodiscard]] auto get_name() const -> std::string_view;
+
+ /**
+ @brief Add a @p child dentry.
+ @param child The child dentry to add.
+ */
auto add_child(kstd::shared_ptr<dentry> const & child) -> void;
+
+ /**
+ @brief Find a child dentry by @p name.
+ @param name The name of the child dentry to find.
+ @return A pointer to the found child dentry, or a null pointer if not found.
+ */
[[nodiscard]] auto find_child(std::string_view name) const -> kstd::shared_ptr<dentry>;
+ /**
+ @brief Set a @p flag for the dentry.
+ @param flag The flag to set.
+ */
auto set_flag(dentry_flags flag) -> void;
+
+ /**
+ @brief Unset a @p flag for the dentry.
+ @param flag The flag to unset.
+ */
auto unset_flag(dentry_flags flag) -> void;
+
+ /**
+ @brief Check if the dentry has a specific @p flag.
+ @param flag The flag to check.
+ @return True if the dentry has the flag, false otherwise.
+ */
[[nodiscard]] auto has_flag(dentry_flags flag) const -> bool;
private:
diff --git a/kernel/include/kernel/filesystem/devfs/filesystem.hpp b/kernel/include/kernel/filesystem/devfs/filesystem.hpp
index 29ae388..137eca3 100644
--- a/kernel/include/kernel/filesystem/devfs/filesystem.hpp
+++ b/kernel/include/kernel/filesystem/devfs/filesystem.hpp
@@ -2,6 +2,7 @@
#define TEACH_OS_KERNEL_FILESYSTEM_DEVFS_FILESYSTEM_HPP
#include "kapi/devices/device.hpp"
+
#include "kernel/filesystem/filesystem.hpp"
#include "kernel/filesystem/inode.hpp"
@@ -12,9 +13,27 @@
namespace kernel::filesystem::devfs
{
+ /**
+ @brief A filesystem for managing device nodes in the virtual filesystem. This filesystem provides a way to represent
+ devices as files in the /dev directory, allowing user-space applications to interact with devices using standard file
+ operations. The devfs filesystem dynamically creates inodes for devices registered in the system, enabling seamless
+ access to device functionality through the filesystem interface.
+ */
struct filesystem : kernel::filesystem::filesystem
{
- auto mount(kstd::shared_ptr<kapi::devices::device> const & device) -> int override;
+ /**
+ @brief Initializes the devfs instance and builds the device inode table.
+ @param device Backing device passed by the generic filesystem interface (not required by devfs).
+ @return The result of the mount operation.
+ */
+ auto mount(kstd::shared_ptr<kapi::devices::device> const & device) -> operation_result override;
+
+ /**
+ @brief Looks up an inode by @p name within a @p parent directory.
+ @param parent The parent directory inode.
+ @param name The name of the inode to look up.
+ @return A pointer to the found inode, or a null pointer if not found.
+ */
auto lookup(kstd::shared_ptr<kernel::filesystem::inode> const & parent, std::string_view name)
-> kstd::shared_ptr<kernel::filesystem::inode> override;
diff --git a/kernel/include/kernel/filesystem/devfs/inode.hpp b/kernel/include/kernel/filesystem/devfs/inode.hpp
index 9c11edf..c117bd2 100644
--- a/kernel/include/kernel/filesystem/devfs/inode.hpp
+++ b/kernel/include/kernel/filesystem/devfs/inode.hpp
@@ -7,11 +7,33 @@
namespace kernel::filesystem::devfs
{
+ /**
+ @brief Inode implementation for the devfs filesystem.
+ This inode represents root device node in the /dev directory.
+ */
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.
+ @param size Number of bytes requested.
+ @return Number of bytes read (always 0 because this inode does not expose file data).
+ */
auto read(void * buffer, size_t offset, size_t size) const -> size_t override;
+
+ /**
+ @brief Writes to the devfs directory inode.
+ @param buffer Source buffer.
+ @param offset Write offset in bytes.
+ @param size Number of bytes requested.
+ @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;
};
} // namespace kernel::filesystem::devfs
diff --git a/kernel/include/kernel/filesystem/device_inode.hpp b/kernel/include/kernel/filesystem/device_inode.hpp
index 18a98f5..c33be2a 100644
--- a/kernel/include/kernel/filesystem/device_inode.hpp
+++ b/kernel/include/kernel/filesystem/device_inode.hpp
@@ -2,6 +2,7 @@
#define TEACH_OS_KERNEL_FILESYSTEM_DEVICE_INODE_HPP
#include "kapi/devices/device.hpp"
+
#include "kernel/filesystem/inode.hpp"
#include <kstd/memory>
@@ -10,13 +11,43 @@
namespace kernel::filesystem
{
+ /**
+ @brief Inode implementation for device inodes in the filesystem. This inode represents a device file that provides
+ access to a device registered in the system. The device inode allows reading from and writing to the associated
+ device.
+ */
struct device_inode : inode
{
+ /**
+ @brief Create a device inode with the given @p device.
+ @param device The device to associate with the inode.
+ */
explicit device_inode(kstd::shared_ptr<kapi::devices::device> const & device);
+ /**
+ @brief Read data from the device inode (and in the background from the associated device) into a @p buffer, starting
+ at @p offset and reading @p size bytes.
+ @param buffer The buffer to read data into.
+ @param offset The offset to read from.
+ @param size The number of bytes to read.
+ @return The number of bytes read.
+ */
auto read(void * buffer, size_t offset, size_t size) const -> size_t override;
+
+ /**
+ @brief Write data to the device inode (and in the background from the associated device) from a @p buffer, starting
+ at @p offset and writing @p size bytes.
+ @param buffer The buffer containing data to write.
+ @param offset The offset to write to.
+ @param size The number of bytes to write.
+ @return The number of bytes written.
+ */
auto write(void const * buffer, size_t offset, size_t size) -> size_t override;
+ /**
+ @brief Get the associated device.
+ @return A reference to the associated device.
+ */
[[nodiscard]] auto device() const -> kstd::shared_ptr<kapi::devices::device> const &;
private:
diff --git a/kernel/include/kernel/filesystem/ext2/block_group_descriptor.hpp b/kernel/include/kernel/filesystem/ext2/block_group_descriptor.hpp
index a23c045..7fbba3f 100644
--- a/kernel/include/kernel/filesystem/ext2/block_group_descriptor.hpp
+++ b/kernel/include/kernel/filesystem/ext2/block_group_descriptor.hpp
@@ -6,7 +6,10 @@
namespace kernel::filesystem::ext2
{
- struct block_group_descriptor
+ /**
+ @brief Represents a block group descriptor in the ext2 filesystem.
+ */
+ struct [[gnu::packed]] block_group_descriptor
{
uint32_t block_bitmap;
uint32_t inode_bitmap;
diff --git a/kernel/include/kernel/filesystem/ext2/filesystem.hpp b/kernel/include/kernel/filesystem/ext2/filesystem.hpp
index 078da31..a71385f 100644
--- a/kernel/include/kernel/filesystem/ext2/filesystem.hpp
+++ b/kernel/include/kernel/filesystem/ext2/filesystem.hpp
@@ -2,20 +2,88 @@
#define TEACH_OS_KERNEL_FILESYSTEM_EXT2_FILESYSTEM_HPP
#include "kapi/devices/device.hpp"
+
+#include "kernel/filesystem/ext2/block_group_descriptor.hpp"
+#include "kernel/filesystem/ext2/inode.hpp"
+#include "kernel/filesystem/ext2/superblock.hpp"
#include "kernel/filesystem/filesystem.hpp"
#include "kernel/filesystem/inode.hpp"
#include <kstd/memory>
+#include <kstd/vector>
+#include <cstddef>
+#include <cstdint>
#include <string_view>
namespace kernel::filesystem::ext2
{
+ /**
+ @brief Constants related to the ext2 filesystem.
+ */
+ namespace constants
+ {
+ constexpr size_t inline base_block_size = 1024;
+ constexpr size_t inline superblock_offset = base_block_size;
+ constexpr uint16_t inline magic_number = 0xEF53;
+
+ constexpr uint32_t inline root_inode_number = 2;
+
+ constexpr size_t inline direct_block_count = 12;
+ constexpr size_t inline singly_indirect_block_index = direct_block_count;
+ constexpr size_t inline doubly_indirect_block_index = singly_indirect_block_index + 1;
+ constexpr size_t inline triply_indirect_block_index = doubly_indirect_block_index + 1;
+
+ constexpr uint16_t inline mode_mask = 0xF000;
+ constexpr uint16_t inline mode_regular = 0x8000;
+ constexpr uint16_t inline mode_directory = 0x4000;
+ } // namespace constants
+
+ /**
+ @brief A filesystem implementation for the ext2 filesystem format. This class provides methods for mounting an ext2
+ filesystem, and looking up inodes.
+ */
struct filesystem : kernel::filesystem::filesystem
{
- auto mount(kstd::shared_ptr<kapi::devices::device> const & device) -> int override;
+ /**
+ @brief Initializes the ext2 filesystem with the given @p device.
+ @param device The device to mount.
+ @return The result of the mount operation.
+ */
+ auto mount(kstd::shared_ptr<kapi::devices::device> const & device) -> operation_result override;
+
+ /**
+ @brief Looks up an inode by @p name within a @p parent directory.
+ @param parent The parent directory inode.
+ @param name The name of the inode to look up.
+ @return A pointer to the found inode, or a null pointer if not found.
+ */
auto lookup(kstd::shared_ptr<kernel::filesystem::inode> const & parent, std::string_view name)
-> kstd::shared_ptr<kernel::filesystem::inode> override;
+
+ /**
+ @brief Gets the size of a block in the filesystem.
+ @return The size of a block in bytes.
+ */
+ auto get_block_size() -> size_t;
+
+ /**
+ @brief Maps an inode block index to a global block number.
+ @param inode_block_index The index of the block within the inode.
+ @param data The inode data.
+ @return The global block number.
+ */
+ auto map_inode_block_index_to_global_block_number(uint32_t inode_block_index, inode_data data) -> uint32_t;
+
+ private:
+ auto read_inode(uint32_t inode_number) -> kstd::shared_ptr<kernel::filesystem::ext2::inode>;
+ auto read_block_number_at_index(uint32_t block_number, uint32_t index) -> uint32_t;
+
+ auto get_inode_size() -> size_t;
+ auto get_inode_block_count(inode_data const & data) -> uint32_t;
+
+ superblock m_superblock{};
+ kstd::vector<block_group_descriptor> m_block_group_descriptors;
};
} // namespace kernel::filesystem::ext2
diff --git a/kernel/include/kernel/filesystem/ext2/inode.hpp b/kernel/include/kernel/filesystem/ext2/inode.hpp
index 2c27c17..a1645cd 100644
--- a/kernel/include/kernel/filesystem/ext2/inode.hpp
+++ b/kernel/include/kernel/filesystem/ext2/inode.hpp
@@ -11,13 +11,13 @@
namespace kernel::filesystem::ext2
{
- 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;
+ struct filesystem;
+ /**
+ @brief Represents the data associated with an ext2 inode.
+ */
+ struct [[gnu::packed]] inode_data
+ {
uint16_t mode;
uint16_t uid;
uint32_t size;
@@ -30,15 +30,48 @@ namespace kernel::filesystem::ext2
uint32_t blocks;
uint32_t flags;
uint32_t osd1;
- // uint32_t block[15]; // TODO BA-FS26 really correct?
std::array<uint32_t, 15> block; // NOLINT(readability-magic-numbers)
uint32_t generation;
uint32_t file_acl;
uint32_t dir_acl;
uint32_t faddr;
- // uint8_t osd2[12]; // TODO BA-FS26 really correct?
std::array<uint8_t, 12> osd2; // NOLINT(readability-magic-numbers)
};
+
+ struct inode : kernel::filesystem::inode
+ {
+ /**
+ @brief Create an ext2 inode associated with the given filesystem.
+ */
+ explicit inode(filesystem * fs);
+
+ /**
+ @brief Reads from the ext2 inode into a @p buffer, starting at the specified @p offset and for a given @p size.
+ @param buffer Destination buffer.
+ @param offset Read offset in bytes.
+ @param size Number of bytes requested.
+ @return Number of bytes read.
+ */
+ auto read(void * buffer, size_t offset, size_t size) const -> size_t override;
+
+ /**
+ @brief Writes to the ext2 inode into a @p buffer, starting at the specified @p offset and for a given @p size.
+ @warning This method is not implemented yet and will panic if called.
+ @param buffer Source buffer.
+ @param offset Write offset in bytes.
+ @param size Number of bytes requested.
+ @return Number of bytes written.
+ */
+ 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{};
+
+ private:
+ filesystem * m_filesystem;
+ };
} // namespace kernel::filesystem::ext2
#endif \ No newline at end of file
diff --git a/kernel/include/kernel/filesystem/ext2/linked_directory_entry.hpp b/kernel/include/kernel/filesystem/ext2/linked_directory_entry.hpp
index 8dd42a1..4097cbb 100644
--- a/kernel/include/kernel/filesystem/ext2/linked_directory_entry.hpp
+++ b/kernel/include/kernel/filesystem/ext2/linked_directory_entry.hpp
@@ -6,14 +6,16 @@
namespace kernel::filesystem::ext2
{
- struct linked_directory_entry
+ /**
+ @brief Represents a linked directory entry in the ext2 filesystem.
+ */
+ struct [[gnu::packed]] linked_directory_entry
{
uint32_t inode;
uint16_t rec_len;
uint8_t name_len;
uint8_t file_type;
- uint8_t pad;
- std::array<uint8_t, 255> name; // NOLINT(readability-magic-numbers)
+ std::array<char, 255> name; // NOLINT(readability-magic-numbers)
};
} // namespace kernel::filesystem::ext2
diff --git a/kernel/include/kernel/filesystem/ext2/superblock.hpp b/kernel/include/kernel/filesystem/ext2/superblock.hpp
index 8600b4c..41ad935 100644
--- a/kernel/include/kernel/filesystem/ext2/superblock.hpp
+++ b/kernel/include/kernel/filesystem/ext2/superblock.hpp
@@ -6,7 +6,10 @@
namespace kernel::filesystem::ext2
{
- struct superblock
+ /**
+ @brief Represents the superblock in the ext2 filesystem.
+ */
+ struct [[gnu::packed]] superblock
{
uint32_t inodes_count;
uint32_t blocks_count;
@@ -41,11 +44,8 @@ namespace kernel::filesystem::ext2
uint32_t feature_compat;
uint32_t feature_incompat;
uint32_t feature_ro_compat;
- // uint8_t uuid[16]; // TODO BA-FS26 really correct?
std::array<uint8_t, 16> uuid;
- // uint8_t volume_name[16]; // TODO BA-FS26 really correct?
std::array<uint8_t, 16> volume_name;
- // uint8_t last_mounted[64]; // TODO BA-FS26 really correct?
std::array<uint8_t, 64> last_mounted;
uint32_t algorithm_usage_bitmap;
@@ -55,14 +55,12 @@ namespace kernel::filesystem::ext2
uint16_t padding1;
// Journaling Support
- // uint8_t journal_uuid[16]; // TODO BA-FS26 really correct?
std::array<uint8_t, 16> journal_uuid;
uint32_t journal_inum;
uint32_t journal_dev;
uint32_t last_orphan;
// Directory Indexing Support
- // uint32_t hash_seed[4]; // TODO BA-FS26 really correct?
std::array<uint32_t, 4> hash_seed;
uint8_t def_hash_version;
std::array<uint8_t, 3> padding2;
diff --git a/kernel/include/kernel/filesystem/file_descriptor_table.hpp b/kernel/include/kernel/filesystem/file_descriptor_table.hpp
index 91e2960..5d52c19 100644
--- a/kernel/include/kernel/filesystem/file_descriptor_table.hpp
+++ b/kernel/include/kernel/filesystem/file_descriptor_table.hpp
@@ -8,15 +8,49 @@
namespace kernel::filesystem
{
+ /**
+ @brief A table for managing file descriptors in the filesystem. This class provides methods for adding, retrieving,
+ and removing open file descriptions.
+ */
struct file_descriptor_table
{
+ /**
+ @brief Initialize the global file descriptor table. This method creates the singleton instance of the file
+ descriptor table.
+ @warning Panics if called more than once.
+ */
auto static init() -> void;
+
+ /**
+ @brief Get the global file descriptor table instance.
+ @return A reference to the global file descriptor table.
+ @warning Panics if the file descriptor table has not been initialized.
+ */
auto static get() -> file_descriptor_table &;
+ /**
+ @brief Destructor for the file descriptor table.
+ */
~file_descriptor_table() = default;
+ /**
+ @brief Add a file to the descriptor table.
+ @param f The file description to add.
+ @return The file descriptor index assigned to the file, or -1 on failure.
+ */
auto add_file(kstd::shared_ptr<open_file_description> const & f) -> int;
+
+ /**
+ @brief Get a file from the descriptor table.
+ @param fd The file descriptor index to retrieve.
+ @return A pointer to the requested file description, or a null pointer if not found.
+ */
[[nodiscard]] auto get_file(int fd) const -> kstd::shared_ptr<open_file_description>;
+
+ /**
+ @brief Remove a file from the descriptor table.
+ @param fd The file descriptor index to remove.
+ */
auto remove_file(int fd) -> void;
private:
diff --git a/kernel/include/kernel/filesystem/filesystem.hpp b/kernel/include/kernel/filesystem/filesystem.hpp
index 1d86178..ef6929a 100644
--- a/kernel/include/kernel/filesystem/filesystem.hpp
+++ b/kernel/include/kernel/filesystem/filesystem.hpp
@@ -2,6 +2,7 @@
#define TEACH_OS_KERNEL_FILESYSTEM_FILESYSTEM_HPP
#include "kapi/devices/device.hpp"
+
#include "kernel/filesystem/inode.hpp"
#include <kstd/memory>
@@ -11,15 +12,63 @@
namespace kernel::filesystem
{
+ /**
+ @brief A base class for implementing filesystems in the kernel. This class provides a common interface for managing
+ files and directories within the virtual filesystem.
+ */
struct filesystem
{
+ enum class operation_result : int
+ {
+ success = 0,
+ invalid_magic_number = -1,
+ invalid_root_inode = -2,
+ unmount_failed = -3
+ };
+
+ /**
+ @brief Virtual destructor for the filesystem.
+ */
virtual ~filesystem() = default;
- virtual auto mount(kstd::shared_ptr<kapi::devices::device> const & device) -> int;
+ /**
+ @brief Probes the given @p device to determine if it contains a recognizable filesystem, and if so, mounts it and
+ returns a pointer to the mounted filesystem instance. This method iterates through known filesystem types and
+ attempts to initialize it with the device until the mount was successful or all types have been tried.
+ @param device The device to probe and mount.
+ @return A pointer to the mounted filesystem instance if successful, or a null pointer if no recognizable filesystem
+ is found on the device.
+ @warning Panics if @p device is null.
+ */
+ auto static probe_and_mount(kstd::shared_ptr<kapi::devices::device> const & device) -> kstd::shared_ptr<filesystem>;
+
+ /**
+ @brief Initializes the filesystem with the given @p device.
+ @param device The device to mount.
+ @return The result of the mount operation.
+ */
+ virtual auto mount(kstd::shared_ptr<kapi::devices::device> const & device) -> operation_result;
+
+ /**
+ @brief Looks up a child inode within the given @p parent inode with the specified @p name. This method must be
+ implemented by concrete filesystem subclasses to provide the logic for traversing the filesystem structure and
+ finding the requested inode.
+ @param parent The parent inode.
+ @param name The name of the child inode to look up.
+ @return A pointer to the requested child inode, or a null pointer if not found.
+ */
virtual auto lookup(kstd::shared_ptr<inode> const & parent, std::string_view name) -> 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 &;
+ /**
+ @brief Returns a reference to the device associated with the filesystem.
+ */
+ [[nodiscard]] auto device() const -> kstd::shared_ptr<kapi::devices::device> const &;
+
protected:
kstd::shared_ptr<inode> m_root_inode{};
kstd::shared_ptr<kapi::devices::device> m_device{};
diff --git a/kernel/include/kernel/filesystem/inode.hpp b/kernel/include/kernel/filesystem/inode.hpp
index d97b5ab..5208be2 100644
--- a/kernel/include/kernel/filesystem/inode.hpp
+++ b/kernel/include/kernel/filesystem/inode.hpp
@@ -5,8 +5,14 @@
namespace kernel::filesystem
{
+ /**
+ @brief Represents an inode in the filesystem.
+ */
struct inode
{
+ /**
+ @brief Represents the kind of an inode.
+ */
enum class inode_kind
{
regular,
@@ -14,18 +20,57 @@ namespace kernel::filesystem
device
};
+ /**
+ @brief Create an inode with the given @p kind.
+ @param kind The kind of the inode.
+ */
explicit inode(inode_kind kind);
+ /**
+ @brief Virtual destructor for the inode.
+ */
virtual ~inode() = default;
+ /**
+ @brief Reads from the inode into a @p buffer, starting at the specified @p offset and for a given @p size. This
+ method must be implemented by concrete inode subclasses.
+ @param buffer Destination buffer.
+ @param offset Read offset in bytes.
+ @param size Number of bytes requested.
+ @return Number of bytes read.
+ */
virtual auto read(void * buffer, size_t offset, size_t size) const -> size_t = 0;
+
+ /**
+ @brief Writes to the inode into a @p buffer, starting at the specified @p offset and for a given @p size. This
+ method must be implemented by concrete inode subclasses.
+ @param buffer Source buffer.
+ @param offset Write offset in bytes.
+ @param size Number of bytes to write.
+ @return Number of bytes written.
+ */
virtual auto write(void const * buffer, size_t offset, size_t size) -> size_t = 0;
+ /**
+ @brief Returns whether the inode is a directory.
+ @return true if the inode is a directory, false otherwise.
+ */
[[nodiscard]] 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;
+
+ /**
+ @brie