aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--kapi/include/kapi/filesystem.hpp58
-rw-r--r--kernel/CMakeLists.txt8
-rw-r--r--kernel/include/kernel/filesystem/file_descriptor_table.hpp64
-rw-r--r--kernel/include/kernel/filesystem/open_file_descriptor.hpp (renamed from kernel/include/kernel/filesystem/open_file_description.hpp)24
-rw-r--r--kernel/include/kernel/filesystem/open_file_table.hpp63
-rw-r--r--kernel/include/kernel/filesystem/vfs.hpp1
-rw-r--r--kernel/include/kernel/test_support/filesystem/file_descriptor_table.hpp10
-rw-r--r--kernel/include/kernel/test_support/filesystem/open_file_table.hpp10
-rw-r--r--kernel/kapi/filesystem.cpp24
-rw-r--r--kernel/src/filesystem/file_descriptor_table.cpp98
-rw-r--r--kernel/src/filesystem/file_descriptor_table.tests.cpp113
-rw-r--r--kernel/src/filesystem/open_file_descriptor.cpp (renamed from kernel/src/filesystem/open_file_description.cpp)13
-rw-r--r--kernel/src/filesystem/open_file_descriptor.tests.cpp (renamed from kernel/src/filesystem/open_file_description.tests.cpp)57
-rw-r--r--kernel/src/filesystem/open_file_table.cpp98
-rw-r--r--kernel/src/filesystem/open_file_table.tests.cpp113
-rw-r--r--kernel/src/filesystem/vfs.tests.cpp8
-rw-r--r--kernel/src/main.cpp89
-rw-r--r--kernel/src/test_support/state_reset_listener.cpp8
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 &
+ {
+ if (!global_open_file_table)
+ {
+ kapi::system::panic("[FILESYSTEM] Open file table has not been initialized.");
+ }
+
+ return *global_open_file_table;
+ }
+
+ auto open_file_table::add_file(kstd::shared_ptr<open_file_descriptor> const & file_descriptor) -> int
+ {
+ if (!file_descriptor)
+ {
+ 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_descriptor;
+ return static_cast<int>(it - m_open_files.begin());
+ }
+
+ m_open_files.push_back(file_descriptor);
+ return static_cast<int>(m_open_