diff options
18 files changed, 485 insertions, 374 deletions
diff --git a/kapi/include/kapi/filesystem.hpp b/kapi/include/kapi/filesystem.hpp index db77bda..94d42ce 100644 --- a/kapi/include/kapi/filesystem.hpp +++ b/kapi/include/kapi/filesystem.hpp @@ -8,14 +8,66 @@ namespace kapi::filesystem { + /** + @brief The kapi::filesystem namespace provides the interface for filesystem operations in the kernel. It includes + functions for mounting and unmounting filesystems, as well as basic file operations such as opening, closing, reading + from, and writing to files. The actual implementation of these functions is in the kernel's filesystem subsystem, + which will handle the specifics of different filesystem types and their interactions with the underlying storage + devices. + */ + + /** + @brief Mounts a filesystem from the specified @p source at the specified @p target path. + @param source The source device or filesystem to mount. + @param target The target mount point. + @return 0 on success, -1 on failure. + @qualifier kernel-defined + */ auto mount(std::string_view source, std::string_view target) -> int; + + /** + @brief Unmounts a filesystem from the specified @p target path. + @param target The target mount point to unmount. + @return 0 on success, -1 on failure. + @qualifier kernel-defined + */ auto umount(std::string_view target) -> int; + /** + @brief Opens a file at the specified @p path. + @param path The path to the file to open. + @return A file descriptor on success, -1 on failure. + @qualifier kernel-defined + */ auto open(std::string_view path) -> int; - auto close(int fd) -> int; - auto read(int fd, void * buffer, size_t size) -> ssize_t; - auto write(int fd, void const * buffer, size_t size) -> ssize_t; + /** + @brief Closes a @p file_descriptor. + @param file_descriptor The file descriptor to close. + @return 0 on success, -1 on failure. + @qualifier kernel-defined + */ + auto close(int file_descriptor) -> int; + + /** + @brief Reads @p size bytes into @p buffer from a @p file_descriptor. + @param file_descriptor The file descriptor to read from. + @param buffer The buffer to store the read data. + @param size The number of bytes to read. + @return The number of bytes read on success, -1 on failure. + @qualifier kernel-defined + */ + auto read(int file_descriptor, void * buffer, size_t size) -> ssize_t; + + /** + @brief Writes @p size bytes from @p buffer to a @p file_descriptor. + @param file_descriptor The file descriptor to write to. + @param buffer The buffer containing the data to write. + @param size The number of bytes to write. + @return The number of bytes written on success, -1 on failure. + @qualifier kernel-defined + */ + auto write(int file_descriptor, void const * buffer, size_t size) -> ssize_t; } // namespace kapi::filesystem #endif // TEACHOS_KAPI_FILESYSTEM_HPP
\ No newline at end of file diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index d4484cd..909ccf7 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -47,12 +47,12 @@ target_sources("kernel_lib" PRIVATE # Filesystem Subsystem "src/filesystem/dentry.cpp" "src/filesystem/device_inode.cpp" - "src/filesystem/file_descriptor_table.cpp" "src/filesystem/filesystem.cpp" "src/filesystem/inode.cpp" "src/filesystem/mount_table.cpp" "src/filesystem/mount.cpp" - "src/filesystem/open_file_description.cpp" + "src/filesystem/open_file_descriptor.cpp" + "src/filesystem/open_file_table.cpp" "src/filesystem/vfs.cpp" # DevFS Filesystem @@ -192,10 +192,10 @@ if(BUILD_TESTING) "src/filesystem/rootfs/inode.tests.cpp" "src/filesystem/dentry.tests.cpp" "src/filesystem/device_inode.tests.cpp" - "src/filesystem/file_descriptor_table.tests.cpp" "src/filesystem/mount_table.tests.cpp" "src/filesystem/mount.tests.cpp" - "src/filesystem/open_file_description.tests.cpp" + "src/filesystem/open_file_descriptor.tests.cpp" + "src/filesystem/open_file_table.tests.cpp" "src/filesystem/vfs.tests.cpp" # Storage Subsystem Tests diff --git a/kernel/include/kernel/filesystem/file_descriptor_table.hpp b/kernel/include/kernel/filesystem/file_descriptor_table.hpp deleted file mode 100644 index 293dc36..0000000 --- a/kernel/include/kernel/filesystem/file_descriptor_table.hpp +++ /dev/null @@ -1,64 +0,0 @@ -#ifndef TEACH_OS_KERNEL_FILESYSTEM_FILE_DESCRIPTOR_TABLE_HPP -#define TEACH_OS_KERNEL_FILESYSTEM_FILE_DESCRIPTOR_TABLE_HPP - -#include <kernel/filesystem/open_file_description.hpp> - -#include <kstd/memory> -#include <kstd/vector> - -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. - @return 0 on success, or -1 on failure. - */ - auto remove_file(int fd) -> int; - - private: - file_descriptor_table() = default; - - kstd::vector<kstd::shared_ptr<open_file_description>> m_open_files{}; - }; -} // namespace kernel::filesystem - -#endif
\ No newline at end of file diff --git a/kernel/include/kernel/filesystem/open_file_description.hpp b/kernel/include/kernel/filesystem/open_file_descriptor.hpp index fad41e4..036dcf0 100644 --- a/kernel/include/kernel/filesystem/open_file_description.hpp +++ b/kernel/include/kernel/filesystem/open_file_descriptor.hpp @@ -1,5 +1,5 @@ -#ifndef TEACH_OS_KERNEL_FILESYSTEM_OPEN_FILE_DESCRIPTION_HPP -#define TEACH_OS_KERNEL_FILESYSTEM_OPEN_FILE_DESCRIPTION_HPP +#ifndef TEACH_OS_KERNEL_FILESYSTEM_OPEN_FILE_DESCRIPTOR_HPP +#define TEACH_OS_KERNEL_FILESYSTEM_OPEN_FILE_DESCRIPTOR_HPP #include <kernel/filesystem/inode.hpp> @@ -10,24 +10,24 @@ namespace kernel::filesystem { /** - @brief Represents an open file description in the filesystem. This class encapsulates the state of an open file, + @brief Represents an open file descriptor in the filesystem. This class encapsulates the state of an open file, including a reference to the associated inode and the current file offset. */ - struct open_file_description + struct open_file_descriptor { /** - @brief Constructs an open file description for the given @p inode. - @param inode The inode to associate with the open file description. + @brief Constructs an open file descriptor for the given @p inode. + @param inode The inode to associate with the open file descriptor. */ - explicit open_file_description(kstd::shared_ptr<inode> const & inode); + explicit open_file_descriptor(kstd::shared_ptr<inode> const & inode); /** - @brief Destructor for the open file description. + @brief Destructor for the open file descriptor. */ - ~open_file_description() = default; + ~open_file_descriptor() = default; /** - @brief Reads data from the open file description into a @p buffer, starting at the current file offset and for a + @brief Reads data from the open file descriptor into a @p buffer, starting at the current file offset and for a given @p size. The file offset is advanced by the number of bytes read. @param buffer The buffer to read data into. @@ -37,7 +37,7 @@ namespace kernel::filesystem auto read(void * buffer, size_t size) -> size_t; /** - @brief Writes data to the open file description from a @p buffer, starting at the current file offset and for a + @brief Writes data to the open file descriptor from a @p buffer, starting at the current file offset and for a given @p size. The file offset is advanced by the number of bytes written. @param buffer The buffer to write data from. @@ -47,7 +47,7 @@ namespace kernel::filesystem auto write(void const * buffer, size_t size) -> size_t; /** - @brief Returns the current file offset for this open file description. + @brief Returns the current file offset for this open file descriptor. @return The current file offset in bytes. */ [[nodiscard]] auto offset() const -> size_t; diff --git a/kernel/include/kernel/filesystem/open_file_table.hpp b/kernel/include/kernel/filesystem/open_file_table.hpp new file mode 100644 index 0000000..2f9a421 --- /dev/null +++ b/kernel/include/kernel/filesystem/open_file_table.hpp @@ -0,0 +1,63 @@ +#ifndef TEACH_OS_KERNEL_FILESYSTEM_OPEN_FILE_TABLE_HPP +#define TEACH_OS_KERNEL_FILESYSTEM_OPEN_FILE_TABLE_HPP + +#include <kernel/filesystem/open_file_descriptor.hpp> + +#include <kstd/memory> +#include <kstd/vector> + +namespace kernel::filesystem +{ + /** + @brief A table for managing file descriptors in the filesystem. This class provides methods for adding, retrieving, + and removing open file descriptors. + */ + struct open_file_table + { + /** + @brief Initialize the global open file table. This method creates the singleton instance of the open file table. + @warning Panics if called more than once. + */ + auto static init() -> void; + + /** + @brief Get the global open file table instance. + @return A reference to the global open file table. + @warning Panics if the open file table has not been initialized. + */ + auto static get() -> open_file_table &; + + /** + @brief Destructor for the open file table. + */ + ~open_file_table() = default; + + /** + @brief Add a file to the open file table. + @param f 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; + + /** + @brief Get a file from the open file table. + @param fd The file descriptor index to retrieve. + @return A pointer to the requested file descriptor, or a null pointer if not found. + */ + [[nodiscard]] auto get_file(int fd) const -> kstd::shared_ptr<open_file_descriptor>; + + /** + @brief Remove a file from the open file table. + @param fd The file descriptor index to remove. + @return 0 on success, or -1 on failure. + */ + auto remove_file(int fd) -> int; + + private: + open_file_table() = default; + + kstd::vector<kstd::shared_ptr<open_file_descriptor>> m_open_files{}; + }; +} // namespace kernel::filesystem + +#endif
\ No newline at end of file diff --git a/kernel/include/kernel/filesystem/vfs.hpp b/kernel/include/kernel/filesystem/vfs.hpp index 5b5c868..881f458 100644 --- a/kernel/include/kernel/filesystem/vfs.hpp +++ b/kernel/include/kernel/filesystem/vfs.hpp @@ -4,7 +4,6 @@ #include <kernel/filesystem/dentry.hpp> #include <kernel/filesystem/filesystem.hpp> #include <kernel/filesystem/mount_table.hpp> -#include <kernel/filesystem/open_file_description.hpp> #include <kstd/memory> diff --git a/kernel/include/kernel/test_support/filesystem/file_descriptor_table.hpp b/kernel/include/kernel/test_support/filesystem/file_descriptor_table.hpp deleted file mode 100644 index bbc0f4a..0000000 --- a/kernel/include/kernel/test_support/filesystem/file_descriptor_table.hpp +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef TEACHOS_KERNEL_TEST_SUPPORT_FILESYSTEM_FILE_DESCRIPTOR_TABLE_HPP -#define TEACHOS_KERNEL_TEST_SUPPORT_FILESYSTEM_FILE_DESCRIPTOR_TABLE_HPP - -namespace kernel::tests::filesystem::file_descriptor_table -{ - //! Deinitialize the file descriptor table singleton. - auto deinit() -> void; -} // namespace kernel::tests::filesystem::file_descriptor_table - -#endif
\ No newline at end of file diff --git a/kernel/include/kernel/test_support/filesystem/open_file_table.hpp b/kernel/include/kernel/test_support/filesystem/open_file_table.hpp new file mode 100644 index 0000000..46b0334 --- /dev/null +++ b/kernel/include/kernel/test_support/filesystem/open_file_table.hpp @@ -0,0 +1,10 @@ +#ifndef TEACHOS_KERNEL_TEST_SUPPORT_FILESYSTEM_OPEN_FILE_TABLE_HPP +#define TEACHOS_KERNEL_TEST_SUPPORT_FILESYSTEM_OPEN_FILE_TABLE_HPP + +namespace kernel::tests::filesystem::open_file_table +{ + //! Deinitialize the open file table singleton. + auto deinit() -> void; +} // namespace kernel::tests::filesystem::open_file_table + +#endif
\ No newline at end of file diff --git a/kernel/kapi/filesystem.cpp b/kernel/kapi/filesystem.cpp index c8d4c6d..4c68f28 100644 --- a/kernel/kapi/filesystem.cpp +++ b/kernel/kapi/filesystem.cpp @@ -1,7 +1,7 @@ #include <kapi/filesystem.hpp> -#include <kernel/filesystem/file_descriptor_table.hpp> -#include <kernel/filesystem/open_file_description.hpp> +#include <kernel/filesystem/open_file_descriptor.hpp> +#include <kernel/filesystem/open_file_table.hpp> #include <kernel/filesystem/vfs.hpp> #include <kstd/memory> @@ -35,33 +35,33 @@ namespace kapi::filesystem { if (auto dentry = kernel::filesystem::vfs::get().open(path)) { - auto open_file_description = kstd::make_shared<kernel::filesystem::open_file_description>(dentry->get_inode()); - return kernel::filesystem::file_descriptor_table::get().add_file(open_file_description); + auto open_file_descriptor = kstd::make_shared<kernel::filesystem::open_file_descriptor>(dentry->get_inode()); + return kernel::filesystem::open_file_table::get().add_file(open_file_descriptor); } return -1; } - auto close(int fd) -> int + auto close(int file_descriptor) -> int { - return kernel::filesystem::file_descriptor_table::get().remove_file(fd); + return kernel::filesystem::open_file_table::get().remove_file(file_descriptor); } - auto read(int fd, void * buffer, size_t size) -> ssize_t + auto read(int file_descriptor, void * buffer, size_t size) -> ssize_t { - if (auto open_file_description = kernel::filesystem::file_descriptor_table::get().get_file(fd)) + if (auto open_file_descriptor = kernel::filesystem::open_file_table::get().get_file(file_descriptor)) { - return open_file_description->read(buffer, size); + return open_file_descriptor->read(buffer, size); } return -1; } - auto write(int fd, void const * buffer, size_t size) -> ssize_t + auto write(int file_descriptor, void const * buffer, size_t size) -> ssize_t { - if (auto open_file_description = kernel::filesystem::file_descriptor_table::get().get_file(fd)) + if (auto open_file_descriptor = kernel::filesystem::open_file_table::get().get_file(file_descriptor)) { - return open_file_description->write(buffer, size); + return open_file_descriptor->write(buffer, size); } return -1; diff --git a/kernel/src/filesystem/file_descriptor_table.cpp b/kernel/src/filesystem/file_descriptor_table.cpp deleted file mode 100644 index db7692b..0000000 --- a/kernel/src/filesystem/file_descriptor_table.cpp +++ /dev/null @@ -1,98 +0,0 @@ -#include <kernel/filesystem/file_descriptor_table.hpp> - -#include <kernel/filesystem/open_file_description.hpp> - -#include <kapi/system.hpp> - -#include <kstd/memory> - -#include <algorithm> -#include <cstddef> -#include <optional> - -namespace -{ - constinit auto static global_file_descriptor_table = std::optional<kernel::filesystem::file_descriptor_table>{}; -} // namespace - -namespace kernel::filesystem -{ - auto file_descriptor_table::init() -> void - { - if (global_file_descriptor_table) - { - kapi::system::panic("[FILESYSTEM] File descriptor table has already been initialized."); - } - - global_file_descriptor_table.emplace(file_descriptor_table{}); - } - - auto file_descriptor_table::get() -> file_descriptor_table & - { - if (!global_file_descriptor_table) - { - kapi::system::panic("[FILESYSTEM] File descriptor table has not been initialized."); - } - - return *global_file_descriptor_table; - } - - auto file_descriptor_table::add_file(kstd::shared_ptr<open_file_description> const & file_description) -> int - { - if (!file_description) - { - return -1; - } - - auto it = std::ranges::find_if(m_open_files, [](auto const & open_file) { return open_file == nullptr; }); - if (it != m_open_files.end()) - { - *it = file_description; - return static_cast<int>(it - m_open_files.begin()); - } - - m_open_files.push_back(file_description); - return static_cast<int>(m_open_files.size() - 1); - } - - auto file_descriptor_table::get_file(int fd) const -> kstd::shared_ptr<open_file_description> - { - if (fd < 0) - { - return nullptr; - } - - auto const index = static_cast<size_t>(fd); - if (index >= m_open_files.size()) - { - return nullptr; - } - - return m_open_files.at(index); - } - - auto file_descriptor_table::remove_file(int fd) -> int - { - if (fd < 0) - { - return -1; - } - - auto const index = static_cast<size_t>(fd); - if (index >= m_open_files.size()) - { - return -1; - } - - m_open_files.at(index) = nullptr; - return 0; - } -} // namespace kernel::filesystem - -namespace kernel::tests::filesystem::file_descriptor_table -{ - auto deinit() -> void - { - global_file_descriptor_table.reset(); - } -} // namespace kernel::tests::filesystem::file_descriptor_table diff --git a/kernel/src/filesystem/file_descriptor_table.tests.cpp b/kernel/src/filesystem/file_descriptor_table.tests.cpp deleted file mode 100644 index 86ed7bf..0000000 --- a/kernel/src/filesystem/file_descriptor_table.tests.cpp +++ /dev/null @@ -1,113 +0,0 @@ -#include <kernel/filesystem/file_descriptor_table.hpp> - -#include <kernel/filesystem/open_file_description.hpp> -#include <kernel/test_support/filesystem/inode.hpp> - -#include <kstd/memory> -#include <kstd/print> -#include <kstd/vector> - -#include <catch2/catch_test_macros.hpp> - -SCENARIO("File descriptor table add/get file", "[filesystem][file_descriptor_table]") -{ - GIVEN("a file descriptor table and an open file description") - { - auto & table = kernel::filesystem::file_descriptor_table::get(); - auto inode = kstd::make_shared<kernel::tests::filesystem::inode>(); - auto file_description_1 = kstd::make_shared<kernel::filesystem::open_file_description>(inode); - auto file_description_2 = kstd::make_shared<kernel::filesystem::open_file_description>(inode); - - WHEN("adding the open file description to the file descriptor table") - { - auto fd_1 = table.add_file(file_description_1); - auto fd_2 = table.add_file(file_description_2); - auto fd_3 = table.add_file(file_description_2); - - THEN("a valid file descriptor is returned") - { - REQUIRE(fd_1 == 0); - REQUIRE(fd_2 == 1); - REQUIRE(fd_3 == 2); - } - - THEN("the file description can be retrieved using the returned file descriptor") - { - auto retrieved_description = table.get_file(fd_1); - REQUIRE(retrieved_description == file_description_1); - } - } - } - - GIVEN("a invalid open file description") - { - auto & table = kernel::filesystem::file_descriptor_table::get(); - - THEN("adding a null file description returns an error code") - { - auto fd = table.add_file(nullptr); - REQUIRE(fd == -1); - } - - THEN("retrieving a file description with a negative file descriptor returns a null pointer") - { - auto retrieved_description = table.get_file(-1); - REQUIRE(retrieved_description == nullptr); - } - - THEN("retrieving a file description with an out-of-bounds file descriptor returns a null pointer") - { - auto retrieved_description = table.get_file(1000); - REQUIRE(retrieved_description == nullptr); - } - } -} - -SCENARIO("File descriptor table remove file", "[filesystem][file_descriptor_table]") -{ - GIVEN("a file descriptor table with an open file description") - { - auto & table = kernel::filesystem::file_descriptor_table::get(); - auto inode = kstd::make_shared<kernel::tests::filesystem::inode>(); - auto file_description = kstd::make_shared<kernel::filesystem::open_file_description>(inode); - auto fd = table.add_file(file_description); - - WHEN("removing the file description using the file descriptor") - { - table.remove_file(fd); - - THEN("the file description can no longer be retrieved using the file descriptor") - { - auto retrieved_description = table.get_file(fd); - REQUIRE(retrieved_description == nullptr); - } - } - - WHEN("removing a file description the other file descriptor keep the same index") - { - auto fd2 = table.add_file(file_description); - table.remove_file(fd); - - THEN("the second file description can still be retrieved using its file descriptor") - { - auto retrieved_description = table.get_file(fd2); - REQUIRE(retrieved_description == file_description); - } - } - } - - GIVEN("an invalid file descriptor") - { - auto & table = kernel::filesystem::file_descriptor_table::get(); - - THEN("removing a file with a negative file descriptor does nothing") - { - REQUIRE_NOTHROW(table.remove_file(-1)); - } - - THEN("removing a file with an out-of-bounds file descriptor does nothing") - { - REQUIRE_NOTHROW(table.remove_file(1000)); - } - } -}
\ No newline at end of file diff --git a/kernel/src/filesystem/open_file_description.cpp b/kernel/src/filesystem/open_file_descriptor.cpp index 3033e2b..25bffbd 100644 --- a/kernel/src/filesystem/open_file_description.cpp +++ b/kernel/src/filesystem/open_file_descriptor.cpp @@ -1,6 +1,5 @@ -#include <kernel/filesystem/open_file_description.hpp> - #include <kernel/filesystem/inode.hpp> +#include <kernel/filesystem/open_file_descriptor.hpp> #include <kstd/memory> #include <kstd/os/error.hpp> @@ -9,31 +8,31 @@ namespace kernel::filesystem { - open_file_description::open_file_description(kstd::shared_ptr<inode> const & inode) + open_file_descriptor::open_file_descriptor(kstd::shared_ptr<inode> const & inode) : m_inode(inode) , m_offset(0) { if (!inode) { - kstd::os::panic("[FILESYSTEM] open_file_description constructed with null inode."); + kstd::os::panic("[FILESYSTEM] open_file_descriptor constructed with null inode."); } } - auto open_file_description::read(void * buffer, size_t size) -> size_t + auto open_file_descriptor::read(void * buffer, size_t size) -> size_t { auto read_bytes = m_inode->read(buffer, m_offset, size); m_offset += read_bytes; return read_bytes; } - auto open_file_description::write(void const * buffer, size_t size) -> size_t + auto open_file_descriptor::write(void const * buffer, size_t size) -> size_t { auto written_bytes = m_inode->write(buffer, m_offset, size); m_offset += written_bytes; return written_bytes; } - auto open_file_description::offset() const -> size_t + auto open_file_descriptor::offset() const -> size_t { return m_offset; } diff --git a/kernel/src/filesystem/open_file_description.tests.cpp b/kernel/src/filesystem/open_file_descriptor.tests.cpp index ce3c81a..095e203 100644 --- a/kernel/src/filesystem/open_file_description.tests.cpp +++ b/kernel/src/filesystem/open_file_descriptor.tests.cpp @@ -1,5 +1,4 @@ -#include <kernel/filesystem/open_file_description.hpp> - +#include <kernel/filesystem/open_file_descriptor.hpp> #include <kernel/filesystem/vfs.hpp> #include <kernel/test_support/filesystem/inode.hpp> #include <kernel/test_support/filesystem/storage_boot_module_vfs_fixture.hpp> @@ -14,63 +13,63 @@ #include <filesystem> #include <string_view> -SCENARIO("Open file description construction", "[filesystem][open_file_description]") +SCENARIO("Open file descriptor construction", "[filesystem][open_file_descriptor]") { - GIVEN("an inode and an open file description for that inode") + GIVEN("an inode and an open file descriptor for that inode") { auto inode = kstd::make_shared<kernel::tests::filesystem::inode>(); - auto file_description = kernel::filesystem::open_file_description{inode}; + auto file_descriptor = kernel::filesystem::open_file_descriptor{inode}; THEN("the initial offset is zero") { - REQUIRE(file_description.offset() == 0); + REQUIRE(file_descriptor.offset() == 0); } } } -SCENARIO("Open file description read/write offset management", "[filesystem][open_file_description]") +SCENARIO("Open file descriptor read/write offset management", "[filesystem][open_file_descriptor]") { - GIVEN("an inode that tracks read/write calls and an open file description for that inode") + GIVEN("an inode that tracks read/write calls and an open file descriptor for that inode") { auto inode = kstd::make_shared<kernel::tests::filesystem::inode>(); - auto file_description = kernel::filesystem::open_file_description{inode}; + auto file_descriptor = kernel::filesystem::open_file_descriptor{inode}; THEN("the offset is updated correctly after reads") { - REQUIRE(file_description.read(nullptr, 100) == 100); - REQUIRE(file_description.offset() == 100); - REQUIRE(file_description.read(nullptr, 50) == 50); - REQUIRE(file_description.offset() == 150); + REQUIRE(file_descriptor.read(nullptr, 100) == 100); + REQUIRE(file_descriptor.offset() == 100); + REQUIRE(file_descriptor.read(nullptr, 50) == 50); + REQUIRE(file_descriptor.offset() == 150); } THEN("the offset is updated correctly after writes") { - REQUIRE(file_description.write(nullptr, 200) == 200); - REQUIRE(file_description.offset() == 200); - REQUIRE(file_description.write(nullptr, 25) == 25); - REQUIRE(file_description.offset() == 225); + REQUIRE(file_descriptor.write(nullptr, 200) == 200); + REQUIRE(file_descriptor.offset() == 200); + REQUIRE(file_descriptor.write(nullptr, 25) == 25); + REQUIRE(file_descriptor.offset() == 225); } THEN("reads and writes both update the same offset") { - REQUIRE(file_description.read(nullptr, 10) == 10); - REQUIRE(file_description.offset() == 10); - REQUIRE(file_description.write(nullptr, 20) == 20); - REQUIRE(file_description.offset() == 30); - REQUIRE(file_description.read(nullptr, 5) == 5); - REQUIRE(file_description.offset() == 35); - REQUIRE(file_description.write(nullptr, 15) == 15); - REQUIRE(file_description.offset() == 50); + REQUIRE(file_descriptor.read(nullptr, 10) == 10); + REQUIRE(file_descriptor.offset() == 10); + REQUIRE(file_descriptor.write(nullptr, 20) == 20); + REQUIRE(file_descriptor.offset() == 30); + REQUIRE(file_descriptor.read(nullptr, 5) == 5); + REQUIRE(file_descriptor.offset() == 35); + REQUIRE(file_descriptor.write(nullptr, 15) == 15); + REQUIRE(file_descriptor.offset() == 50); } } } -SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, - "Open file description read with real image", "[filesystem][open_file_description][img]") +SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "Open file descriptor read with real image", + "[filesystem][open_file_descriptor][img]") { auto const image_path = std::filesystem::path{KERNEL_TEST_ASSETS_DIR} / "ext2_1KB_fs.img"; - GIVEN("an open file description for a file in a real image") + GIVEN("an open file descriptor for a file in a real image") { REQUIRE(std::filesystem::exists(image_path)); REQUIRE_NOTHROW(setup_modules_from_img_and_init_vfs({"test_img_module"}, {image_path})); @@ -78,7 +77,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, auto & vfs = kernel::filesystem::vfs::get(); auto dentry = vfs.open("/information/info_1.txt"); REQUIRE(dentry != nullptr); - auto ofd = kstd::make_shared<kernel::filesystem::open_file_description>(dentry->get_inode()); + auto ofd = kstd::make_shared<kernel::filesystem::open_file_descriptor>(dentry->get_inode()); THEN("the file can be read and the offset is updated") { diff --git a/kernel/src/filesystem/open_file_table.cpp b/kernel/src/filesystem/open_file_table.cpp new file mode 100644 index 0000000..e47d229 --- /dev/null +++ b/kernel/src/filesystem/open_file_table.cpp @@ -0,0 +1,98 @@ +#include <kernel/filesystem/open_file_table.hpp> + +#include <kernel/filesystem/open_file_descriptor.hpp> + +#include <kapi/system.hpp> + +#include <kstd/memory> + +#include <algorithm> +#include <cstddef> +#include <optional> + +namespace +{ + constinit auto static global_open_file_table = std::optional<kernel::filesystem::open_file_table>{}; +} // namespace + +namespace kernel::filesystem +{ + auto open_file_table::init() -> void + { + if (global_open_file_table) + { + kapi::system::panic("[FILESYSTEM] Open file table has already been initialized."); + } + + global_open_file_table.emplace(open_file_table{}); + } + + auto open_file_table::get() -> open_file_table & |
