aboutsummaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/CMakeLists.txt2
-rw-r--r--kernel/include/kernel/filesystem/devfs/filesystem.hpp6
-rw-r--r--kernel/include/kernel/filesystem/ext2/filesystem.hpp8
-rw-r--r--kernel/include/kernel/filesystem/file_descriptor_table.hpp3
-rw-r--r--kernel/include/kernel/filesystem/filesystem.hpp29
-rw-r--r--kernel/include/kernel/filesystem/rootfs/filesystem.hpp8
-rw-r--r--kernel/include/kernel/filesystem/vfs.hpp15
-rw-r--r--kernel/kapi/filesystem.cpp64
-rw-r--r--kernel/kapi/filesystem.tests.cpp128
-rw-r--r--kernel/src/filesystem/devfs/filesystem.cpp2
-rw-r--r--kernel/src/filesystem/ext2/filesystem.cpp21
-rw-r--r--kernel/src/filesystem/ext2/filesystem.tests.cpp13
-rw-r--r--kernel/src/filesystem/ext2/inode.cpp7
-rw-r--r--kernel/src/filesystem/ext2/inode.tests.cpp13
-rw-r--r--kernel/src/filesystem/file_descriptor_table.cpp8
-rw-r--r--kernel/src/filesystem/filesystem.cpp22
-rw-r--r--kernel/src/filesystem/rootfs/filesystem.cpp4
-rw-r--r--kernel/src/filesystem/vfs.cpp39
-rw-r--r--kernel/src/filesystem/vfs.tests.cpp99
-rw-r--r--kernel/src/main.cpp14
-rw-r--r--kernel/src/test_support/filesystem/test_assets/ext2_1KB_fs.img2
21 files changed, 378 insertions, 129 deletions
diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt
index 2f6113a..e83e529 100644
--- a/kernel/CMakeLists.txt
+++ b/kernel/CMakeLists.txt
@@ -8,6 +8,7 @@ add_library("kernel_objs" OBJECT
"kapi/devices/bus.cpp"
"kapi/devices/cpu.cpp"
"kapi/devices/device.cpp"
+ "kapi/filesystem.cpp"
"kapi/interrupts.cpp"
"kapi/memory.cpp"
"kapi/system.cpp"
@@ -124,6 +125,7 @@ else()
# KAPI Shim Tests
"kapi/cpu.tests.cpp"
"kapi/system.tests.cpp"
+ "kapi/filesystem.tests.cpp"
# KSTD Shim Tests
"kstd/print.tests.cpp"
diff --git a/kernel/include/kernel/filesystem/devfs/filesystem.hpp b/kernel/include/kernel/filesystem/devfs/filesystem.hpp
index 137eca3..3a52403 100644
--- a/kernel/include/kernel/filesystem/devfs/filesystem.hpp
+++ b/kernel/include/kernel/filesystem/devfs/filesystem.hpp
@@ -1,8 +1,6 @@
#ifndef TEACH_OS_KERNEL_FILESYSTEM_DEVFS_FILESYSTEM_HPP
#define TEACH_OS_KERNEL_FILESYSTEM_DEVFS_FILESYSTEM_HPP
-#include "kapi/devices/device.hpp"
-
#include "kernel/filesystem/filesystem.hpp"
#include "kernel/filesystem/inode.hpp"
@@ -23,10 +21,10 @@ namespace kernel::filesystem::devfs
{
/**
@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).
+ @param backing_inode Backing inode passed by the vfs (not required by devfs).
@return The result of the mount operation.
*/
- auto mount(kstd::shared_ptr<kapi::devices::device> const & device) -> operation_result override;
+ auto mount(kstd::shared_ptr<kernel::filesystem::inode> const & backing_inode) -> operation_result override;
/**
@brief Looks up an inode by @p name within a @p parent directory.
diff --git a/kernel/include/kernel/filesystem/ext2/filesystem.hpp b/kernel/include/kernel/filesystem/ext2/filesystem.hpp
index a71385f..9112866 100644
--- a/kernel/include/kernel/filesystem/ext2/filesystem.hpp
+++ b/kernel/include/kernel/filesystem/ext2/filesystem.hpp
@@ -1,8 +1,6 @@
#ifndef TEACH_OS_KERNEL_FILESYSTEM_EXT2_FILESYSTEM_HPP
#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"
@@ -46,11 +44,11 @@ namespace kernel::filesystem::ext2
struct filesystem : kernel::filesystem::filesystem
{
/**
- @brief Initializes the ext2 filesystem with the given @p device.
- @param device The device to mount.
+ @brief Initializes the ext2 filesystem with the given @p backing_inode.
+ @param backing_inode The backing inode to mount.
@return The result of the mount operation.
*/
- auto mount(kstd::shared_ptr<kapi::devices::device> const & device) -> operation_result override;
+ auto mount(kstd::shared_ptr<kernel::filesystem::inode> const & backing_inode) -> operation_result override;
/**
@brief Looks up an inode by @p name within a @p parent directory.
diff --git a/kernel/include/kernel/filesystem/file_descriptor_table.hpp b/kernel/include/kernel/filesystem/file_descriptor_table.hpp
index 5d52c19..5dd91e7 100644
--- a/kernel/include/kernel/filesystem/file_descriptor_table.hpp
+++ b/kernel/include/kernel/filesystem/file_descriptor_table.hpp
@@ -50,8 +50,9 @@ namespace kernel::filesystem
/**
@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) -> void;
+ auto remove_file(int fd) -> int;
private:
file_descriptor_table() = default;
diff --git a/kernel/include/kernel/filesystem/filesystem.hpp b/kernel/include/kernel/filesystem/filesystem.hpp
index ef6929a..099caee 100644
--- a/kernel/include/kernel/filesystem/filesystem.hpp
+++ b/kernel/include/kernel/filesystem/filesystem.hpp
@@ -1,8 +1,6 @@
#ifndef TEACH_OS_KERNEL_FILESYSTEM_FILESYSTEM_HPP
#define TEACH_OS_KERNEL_FILESYSTEM_FILESYSTEM_HPP
-#include "kapi/devices/device.hpp"
-
#include "kernel/filesystem/inode.hpp"
#include <kstd/memory>
@@ -32,22 +30,23 @@ namespace kernel::filesystem
virtual ~filesystem() = default;
/**
- @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.
+ @brief Probes the given @p backing_inode 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 backing inode until the mount was successful or all types have been tried.
+ @param backing_inode The inode 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.
+ is found on the backing inode.
+ @warning Panics if @p backing_inode is null.
*/
- auto static probe_and_mount(kstd::shared_ptr<kapi::devices::device> const & device) -> kstd::shared_ptr<filesystem>;
+ auto static probe_and_mount(kstd::shared_ptr<inode> const & backing_inode) -> kstd::shared_ptr<filesystem>;
/**
- @brief Initializes the filesystem with the given @p device.
- @param device The device to mount.
+ @brief Initializes the filesystem with the given @p backing_inode.
+ @param backing_inode The inode to use as the backing inode for the filesystem. (This is typically the inode
+ representing the block device or another inode which contains the filesystem data.)
@return The result of the mount operation.
*/
- virtual auto mount(kstd::shared_ptr<kapi::devices::device> const & device) -> operation_result;
+ virtual auto mount(kstd::shared_ptr<inode> const & backing_inode) -> operation_result;
/**
@brief Looks up a child inode within the given @p parent inode with the specified @p name. This method must be
@@ -65,13 +64,13 @@ namespace kernel::filesystem
[[nodiscard]] auto root_inode() const -> kstd::shared_ptr<inode> const &;
/**
- @brief Returns a reference to the device associated with the filesystem.
+ @brief Returns a reference to the backing inode of the filesystem.
*/
- [[nodiscard]] auto device() const -> kstd::shared_ptr<kapi::devices::device> const &;
+ [[nodiscard]] auto backing_inode() const -> kstd::shared_ptr<inode> const &;
protected:
kstd::shared_ptr<inode> m_root_inode{};
- kstd::shared_ptr<kapi::devices::device> m_device{};
+ kstd::shared_ptr<inode> m_backing_inode{};
kstd::vector<kstd::shared_ptr<inode>> m_inodes{};
};
diff --git a/kernel/include/kernel/filesystem/rootfs/filesystem.hpp b/kernel/include/kernel/filesystem/rootfs/filesystem.hpp
index 0155c41..e14a1ee 100644
--- a/kernel/include/kernel/filesystem/rootfs/filesystem.hpp
+++ b/kernel/include/kernel/filesystem/rootfs/filesystem.hpp
@@ -1,8 +1,6 @@
#ifndef TEACH_OS_KERNEL_FILESYSTEM_ROOTFS_FILESYSTEM_HPP
#define TEACH_OS_KERNEL_FILESYSTEM_ROOTFS_FILESYSTEM_HPP
-#include "kapi/devices/device.hpp"
-
#include "kernel/filesystem/filesystem.hpp"
#include "kernel/filesystem/inode.hpp"
@@ -23,11 +21,11 @@ namespace kernel::filesystem::rootfs
struct filesystem : kernel::filesystem::filesystem
{
/**
- @brief Initializes the rootfs filesystem with the given @p device.
- @param device The device to mount (not required by rootfs).
+ @brief Initializes the rootfs filesystem with the given @p backing_inode.
+ @param backing_inode The backing inode to mount (not required by rootfs).
@return The result of the mount operation.
*/
- auto mount(kstd::shared_ptr<kapi::devices::device> const & device) -> operation_result override;
+ auto mount(kstd::shared_ptr<kernel::filesystem::inode> const & backing_inode) -> operation_result override;
/**
@brief Looks up an inode by @p name within a @p parent directory.
diff --git a/kernel/include/kernel/filesystem/vfs.hpp b/kernel/include/kernel/filesystem/vfs.hpp
index 4dd2a83..2a9d5f7 100644
--- a/kernel/include/kernel/filesystem/vfs.hpp
+++ b/kernel/include/kernel/filesystem/vfs.hpp
@@ -27,9 +27,10 @@ namespace kernel::filesystem
{
success = 0,
invalid_path = -1,
- mount_point_not_found = -2,
- filesystem_null = -3,
- unmount_failed = -4
+ non_existent_path = -2,
+ mount_point_not_found = -3,
+ unmount_failed = -4,
+ invalid_filesystem = -5,
};
/**
@@ -58,12 +59,12 @@ namespace kernel::filesystem
auto open(std::string_view path) -> kstd::shared_ptr<open_file_description>;
/**
- @brief Mount a @p filesystem at a specific @p path.
- @param path The path where the filesystem should be mounted.
- @param filesystem The filesystem to mount.
+ @brief Mount a @p source path to a specific @p target path.
+ @param source The source of the filesystem to mount.
+ @param target The path where the filesystem should be mounted.
@return The result of the mount operation.
*/
- auto do_mount(std::string_view path, kstd::shared_ptr<filesystem> const & filesystem) -> operation_result;
+ auto do_mount(std::string_view source, std::string_view target) -> operation_result;
/**
@brief Unmount the filesystem mounted at the specified @p path.
diff --git a/kernel/kapi/filesystem.cpp b/kernel/kapi/filesystem.cpp
new file mode 100644
index 0000000..30201b7
--- /dev/null
+++ b/kernel/kapi/filesystem.cpp
@@ -0,0 +1,64 @@
+#include "kapi/filesystem.hpp"
+
+#include "kernel/filesystem/file_descriptor_table.hpp"
+#include "kernel/filesystem/vfs.hpp"
+
+#include <cstddef>
+#include <string_view>
+#include <sys/types.h>
+
+namespace kapi::filesystem
+{
+ auto mount(std::string_view source, std::string_view target) -> int
+ {
+ if (kernel::filesystem::vfs::get().do_mount(source, target) == kernel::filesystem::vfs::operation_result::success)
+ {
+ return 0;
+ }
+ return -1;
+ }
+
+ auto umount(std::string_view target) -> int
+ {
+ if (kernel::filesystem::vfs::get().unmount(target) == kernel::filesystem::vfs::operation_result::success)
+ {
+ return 0;
+ }
+ return -1;
+ }
+
+ auto open(std::string_view path) -> int
+ {
+ if (auto open_file_description = kernel::filesystem::vfs::get().open(path))
+ {
+ return kernel::filesystem::file_descriptor_table::get().add_file(open_file_description);
+ }
+
+ return -1;
+ }
+
+ auto close(int fd) -> int
+ {
+ return kernel::filesystem::file_descriptor_table::get().remove_file(fd);
+ }
+
+ auto read(int fd, void * buffer, size_t size) -> ssize_t
+ {
+ if (auto open_file_description = kernel::filesystem::file_descriptor_table::get().get_file(fd))
+ {
+ return open_file_description->read(buffer, size);
+ }
+
+ return -1;
+ }
+
+ auto write(int fd, void const * buffer, size_t size) -> ssize_t
+ {
+ if (auto open_file_description = kernel::filesystem::file_descriptor_table::get().get_file(fd))
+ {
+ return open_file_description->write(buffer, size);
+ }
+
+ return -1;
+ }
+} // namespace kapi::filesystem \ No newline at end of file
diff --git a/kernel/kapi/filesystem.tests.cpp b/kernel/kapi/filesystem.tests.cpp
new file mode 100644
index 0000000..aa24aed
--- /dev/null
+++ b/kernel/kapi/filesystem.tests.cpp
@@ -0,0 +1,128 @@
+#include "kapi/filesystem.hpp"
+
+#include "kernel/test_support/filesystem/storage_boot_module_vfs_fixture.hpp"
+
+#include <catch2/catch_test_macros.hpp>
+
+#include <algorithm>
+#include <cstddef>
+#include <filesystem>
+#include <string_view>
+#include <vector>
+
+SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "Kapi filesystem with real images",
+ "[kapi][filesystem]")
+{
+ auto const image_path_1 = std::filesystem::path{KERNEL_TEST_ASSETS_DIR} / "ext2_1KB_fs.img";
+ auto const image_path_2 = std::filesystem::path{KERNEL_TEST_ASSETS_DIR} / "ext2_2KB_fs.img";
+
+ GIVEN("a real image file")
+ {
+ REQUIRE(std::filesystem::exists(image_path_1));
+ REQUIRE(std::filesystem::exists(image_path_2));
+ REQUIRE_NOTHROW(
+ setup_modules_from_img_and_init_vfs({"test_img_module_1", "test_img_module_2"}, {image_path_1, image_path_2}));
+
+ THEN("files can be opened, read and closed again")
+ {
+ auto fd = kapi::filesystem::open("/information/info_1.txt");
+ REQUIRE(fd >= 0);
+
+ auto buffer = std::vector<std::byte>(6);
+ auto bytes_read = kapi::filesystem::read(fd, buffer.data(), buffer.size());
+ REQUIRE(bytes_read >= 0);
+
+ std::string_view buffer_as_str{reinterpret_cast<char *>(buffer.data()), static_cast<size_t>(bytes_read)};
+ REQUIRE(buffer_as_str == "info_1");
+
+ REQUIRE(kapi::filesystem::close(fd) == 0);
+ }
+
+ THEN("a filesystem can be mounted, files can be opened, read and closed again and unmounted")
+ {
+ REQUIRE(kapi::filesystem::mount("/dev/ram16", "/information") == 0);
+
+ auto fd = kapi::filesystem::open("/information/monkey_house/monkey_1.txt");
+ REQUIRE(fd >= 0);
+
+ auto buffer = std::vector<std::byte>(8);
+ auto bytes_read = kapi::filesystem::read(fd, buffer.data(), buffer.size());
+ REQUIRE(bytes_read >= 0);
+
+ std::string_view buffer_as_str{reinterpret_cast<char *>(buffer.data()), static_cast<size_t>(bytes_read)};
+ REQUIRE(buffer_as_str == "monkey_1");
+
+ REQUIRE(kapi::filesystem::close(fd) == 0);
+ REQUIRE(kapi::filesystem::umount("/information") == 0);
+ }
+
+ THEN("device can be opened as file and read from")
+ {
+ auto fd = kapi::filesystem::open("/dev/ram0");
+ REQUIRE(fd >= 0);
+
+ auto buffer = std::vector<std::byte>(512);
+ auto bytes_read = kapi::filesystem::read(fd, buffer.data(), buffer.size());
+ REQUIRE(bytes_read >= 0);
+
+ REQUIRE(kapi::filesystem::close(fd) == 0);
+ }
+
+ THEN("device can be opened as file and written to and read from again")
+ {
+ auto read_fd = kapi::filesystem::open("/dev/ram16");
+ REQUIRE(read_fd >= 0);
+
+ auto buffer = std::vector<std::byte>(512, std::byte{0xAB});
+ auto bytes_written = kapi::filesystem::write(read_fd, buffer.data(), buffer.size());
+ REQUIRE(bytes_written >= 0);
+
+ auto write_fd = kapi::filesystem::open("/dev/ram16");
+ REQUIRE(write_fd >= 0);
+
+ auto read_buffer = std::vector<std::byte>(512);
+ auto bytes_read = kapi::filesystem::read(write_fd, read_buffer.data(), read_buffer.size());
+ REQUIRE(bytes_read >= 0);
+
+ REQUIRE(std::equal(buffer.begin(), buffer.end(), read_buffer.begin()));
+
+ REQUIRE(kapi::filesystem::close(write_fd) == 0);
+ REQUIRE(kapi::filesystem::close(read_fd) == 0);
+ }
+
+ THEN("invalid paths cannot be mounted or unmounted")
+ {
+ REQUIRE(kapi::filesystem::mount("/dev/ram16", "invalid_path") < 0);
+ }
+
+ THEN("invalid paths cannot be unmounted")
+ {
+ REQUIRE(kapi::filesystem::umount("invalid_path") < 0);
+ }
+
+ THEN("non existent files cannot be opened")
+ {
+ auto fd = kapi::filesystem::open("/information/non_existent.txt");
+ REQUIRE(fd < 0);
+ }
+
+ THEN("not opened files cannot closed")
+ {
+ REQUIRE(kapi::filesystem::close(999) < 0);
+ }
+
+ THEN("not opened files cannot be read from")
+ {
+ std::vector<std::byte> buffer(10);
+ auto bytes_read = kapi::filesystem::read(999, buffer.data(), buffer.size());
+ REQUIRE(bytes_read < 0);
+ }
+
+ THEN("not opened files cannot be written to")
+ {
+ std::vector<std::byte> buffer(10);
+ auto bytes_written = kapi::filesystem::write(999, buffer.data(), buffer.size());
+ REQUIRE(bytes_written < 0);
+ }
+ }
+}
diff --git a/kernel/src/filesystem/devfs/filesystem.cpp b/kernel/src/filesystem/devfs/filesystem.cpp
index 03b4218..dd60c5d 100644
--- a/kernel/src/filesystem/devfs/filesystem.cpp
+++ b/kernel/src/filesystem/devfs/filesystem.cpp
@@ -14,7 +14,7 @@
namespace kernel::filesystem::devfs
{
- auto filesystem::mount(kstd::shared_ptr<kapi::devices::device> const &) -> operation_result
+ auto filesystem::mount(kstd::shared_ptr<kernel::filesystem::inode> const &) -> operation_result
{
m_root_inode = kstd::make_shared<inode>();
build_device_inode_table();
diff --git a/kernel/src/filesystem/ext2/filesystem.cpp b/kernel/src/filesystem/ext2/filesystem.cpp
index 0ad5c97..c0f97ed 100644
--- a/kernel/src/filesystem/ext2/filesystem.cpp
+++ b/kernel/src/filesystem/ext2/filesystem.cpp
@@ -1,8 +1,5 @@
#include "kernel/filesystem/ext2/filesystem.hpp"
-#include "kapi/devices/device.hpp"
-
-#include "kernel/devices/block_device_utils.hpp"
#include "kernel/filesystem/ext2/block_group_descriptor.hpp"
#include "kernel/filesystem/ext2/inode.hpp"
#include "kernel/filesystem/ext2/linked_directory_entry.hpp"
@@ -32,12 +29,11 @@ namespace kernel::filesystem::ext2
}
} // namespace
- auto filesystem::mount(kstd::shared_ptr<kapi::devices::device> const & device) -> operation_result
+ auto filesystem::mount(kstd::shared_ptr<kernel::filesystem::inode> const & backing_inode) -> operation_result
{
- kernel::filesystem::filesystem::mount(device);
+ kernel::filesystem::filesystem::mount(backing_inode);
- kernel::devices::block_device_utils::read(m_device, &m_superblock, constants::superblock_offset,
- sizeof(m_superblock));
+ m_backing_inode->read(&m_superblock, constants::superblock_offset, sizeof(m_superblock));
if (m_superblock.magic != constants::magic_number)
{
@@ -51,9 +47,8 @@ namespace kernel::filesystem::ext2
m_block_group_descriptors = kstd::vector<block_group_descriptor>(num_block_groups);
auto const block_group_descriptor_table_offset = block_size == 1024 ? 2 * block_size : block_size;
- kernel::devices::block_device_utils::read(m_device, m_block_group_descriptors.data(),
- block_group_descriptor_table_offset,
- num_block_groups * sizeof(block_group_descriptor));
+ m_backing_inode->read(m_block_group_descriptors.data(), block_group_descriptor_table_offset,
+ num_block_groups * sizeof(block_group_descriptor));
m_root_inode = read_inode(constants::root_inode_number);
@@ -86,7 +81,7 @@ namespace kernel::filesystem::ext2
{
auto const global_block_number = map_inode_block_index_to_global_block_number(i, inode_data);
auto const block_offset = global_block_number * block_size;
- kernel::devices::block_device_utils::read(m_device, buffer.data(), block_offset, block_size);
+ m_backing_inode->read(buffer.data(), block_offset, block_size);
auto const * entry = reinterpret_cast<linked_directory_entry const *>(buffer.data());
auto bytes_read = 0uz;
@@ -125,7 +120,7 @@ namespace kernel::filesystem::ext2
auto const inode_offset = inode_table_offset + inode_index_within_group * get_inode_size();
auto new_inode = kstd::make_shared<inode>(this);
- kernel::devices::block_device_utils::read(m_device, &new_inode->m_data, inode_offset, sizeof(inode_data));
+ m_backing_inode->read(&new_inode->m_data, inode_offset, sizeof(inode_data));
// TODO BA-FS26 improve inode_kind really needed? or just map it to the mode bits?
if (S_ISREG(new_inode->m_data.mode))
@@ -209,7 +204,7 @@ namespace kernel::filesystem::ext2
auto const block_start_offset = block_number * get_block_size();
auto const number_start_address = block_start_offset + index * sizeof(uint32_t);
- kernel::devices::block_device_utils::read(m_device, &block_number_buffer, number_start_address, sizeof(uint32_t));
+ m_backing_inode->read(&block_number_buffer, number_start_address, sizeof(uint32_t));
return block_number_buffer;
}
diff --git a/kernel/src/filesystem/ext2/filesystem.tests.cpp b/kernel/src/filesystem/ext2/filesystem.tests.cpp
index b13ebf3..a7b8d5b 100644
--- a/kernel/src/filesystem/ext2/filesystem.tests.cpp
+++ b/kernel/src/filesystem/ext2/filesystem.tests.cpp
@@ -1,6 +1,7 @@
#include "kernel/filesystem/ext2/filesystem.hpp"
#include "kernel/devices/storage/management.hpp"
+#include "kernel/filesystem/device_inode.hpp"
#include "kernel/filesystem/ext2/inode.hpp"
#include "kernel/filesystem/filesystem.hpp"
#include "kernel/test_support/devices/block_device.hpp"
@@ -29,8 +30,10 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_fixture,
auto boot_device = kernel::devices::storage::management::get().determine_boot_device();
REQUIRE(boot_device != nullptr);
+ auto dev_inode = kstd::make_shared<kernel::filesystem::device_inode>(boot_device);
+
auto fs = kernel::filesystem::ext2::filesystem{};
- REQUIRE(fs.mount(boot_device) == kernel::filesystem::filesystem::operation_result::success);
+ REQUIRE(fs.mount(dev_inode) == kernel::filesystem::filesystem::operation_result::success);
THEN("the root inode is available and is a directory")
{
@@ -72,11 +75,13 @@ SCENARIO("Ext2 filesystem rejects invalid magic", "[filesystem][ext2][filesystem
auto device = kstd::make_shared<kernel::tests::devices::block_device>(0, 0, "mock", block_size, 2 * block_size);
REQUIRE(device != nullptr);
+ auto dev_inode = kstd::make_shared<kernel::filesystem::device_inode>(device);
+
auto fs = kernel::filesystem::ext2::filesystem{};
THEN("mount fails with invalid_magic_number")
{
- REQUIRE(fs.mount(device) == kernel::filesystem::filesystem::operation_result::invalid_magic_number);
+ REQUIRE(fs.mount(dev_inode) == kernel::filesystem::filesystem::operation_result::invalid_magic_number);
}
}
}
@@ -92,8 +97,10 @@ SCENARIO("Ext2 block mapping includes direct and all indirect levels", "[filesys
kernel::tests::filesystem::ext2::setup_mock_ext2_layout(*device);
+ auto dev_inode = kstd::make_shared<kernel::filesystem::device_inode>(device);
+
auto fs = kernel::filesystem::ext2::filesystem{};
- REQUIRE(fs.mount(device) == kernel::filesystem::filesystem::operation_result::success);
+ REQUIRE(fs.mount(dev_inode) == kernel::filesystem::filesystem::operation_result::success);
auto inode_data = kernel::filesystem::ext2::inode_data{};
inode_data.block[0] = 7;
diff --git a/kernel/src/filesystem/ext2/inode.cpp b/kernel/src/filesystem/ext2/inode.cpp
index a29bb3b..bf3f0cf 100644
--- a/kernel/src/filesystem/ext2/inode.cpp
+++ b/kernel/src/filesystem/ext2/inode.cpp
@@ -2,7 +2,6 @@
#include "kapi/system.hpp"
-#include "kernel/devices/block_device_utils.hpp"
#include "kernel/filesystem/ext2/filesystem.hpp"
#include "kernel/filesystem/inode.hpp"
@@ -41,8 +40,8 @@ namespace kernel::filesystem::ext2
auto const read_offset = block_start_offset + in_block_offset;
auto const bytes_to_read = std::min(size - bytes_read, m_filesystem->get_block_size() - in_block_offset);
- bytes_read += kernel::devices::block_device_utils::read(
- m_filesystem->device(), static_cast<uint8_t *>(buffer) + bytes_read, read_offset, bytes_to_read);
+ bytes_read +=
+ m_filesystem->backing_inode()->read(static_cast<uint8_t *>(buffer) + bytes_read, read_offset, bytes_to_read);
block_index++;
in_block_offset = 0; // After the first block, we always start at the beginning of the block
@@ -56,4 +55,4 @@ namespace kernel::filesystem::ext2
kapi::system::panic("[EXT2] inode::write is not implemented yet");
return 0;
}
-} // namespace kernel::filesystem::ext2 \ No newline at end of file
+} // namespace kernel::filesystem::ext2
diff --git a/kernel/src/filesystem/ext2/inode.tests.cpp b/kernel/src/filesystem/ext2/inode.tests.cpp
index 795ff10..ae66aff 100644
--- a/kernel/src/filesystem/ext2/inode.tests.cpp
+++ b/kernel/src/filesystem/ext2/inode.tests.cpp
@@ -1,6 +1,7 @@
#include "kernel/filesystem/ext2/inode.hpp"
#include "kernel/devices/storage/management.hpp"
+#include "kernel/filesystem/device_inode.hpp"
#include "kernel/filesystem/ext2/filesystem.hpp"
#include "kernel/filesystem/filesystem.hpp"
#include "kernel/test_support/cpu.hpp"
@@ -54,8 +55,10 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_fixture, "Ext2 in
auto boot_device = kernel::devices::storage::management::get().determine_boot_device();
REQUIRE(boot_device != nullptr);
+ auto dev_inode = kstd::make_shared<kernel::filesystem::device_inode>(boot_device);
+
auto fs = kernel::filesystem::ext2::filesystem{};
- REQUIRE(fs.mount(boot_device) == kernel::filesystem::filesystem::operation_result::success);
+ REQUIRE(fs.mount(dev_inode) == kernel::filesystem::filesystem::operation_result::success);
auto information = fs.lookup(fs.root_inode(), "information");
REQUIRE(information != nullptr);
@@ -94,8 +97,10 @@ SCENARIO("Ext2 inode read stops when block mapping resolves to zero", "[filesyst
REQUIRE(device != nullptr);
kernel::tests::filesystem::ext2::setup_mock_ext2_layout(*device);
+ auto dev_inode = kstd::make_shared<kernel::filesystem::device_inode>(device);
+
auto fs = kernel::filesystem::ext2::filesystem{};
- REQUIRE(fs.mount(device) == kernel::filesystem::filesystem::operation_result::success);
+ REQUIRE(fs.mount(dev_inode) == kernel::filesystem::filesystem::operation_result::success);
auto inode = kernel::filesystem::ext2::inode{&fs};
inode.m_data.blocks = 2;
@@ -120,8 +125,10 @@ SCENARIO("Ext2 inode read across block boundaries", "[filesystem][ext2][inode]")
REQUIRE(device != nullptr);
kernel::tests::filesystem::ext2::setup_mock_ext2_layout(*device);
+ auto dev_inode = kstd::make_shared<kernel::filesystem::device_inode>(device);
+
auto fs = kernel::filesystem::ext2::filesystem{};
- REQUIRE(fs.mount(device) == kernel::filesystem::filesystem::operation_result::success);
+ REQUIRE(fs.mount(dev_inode) == kernel::filesystem::filesystem::operation_result::success);
auto inode = kernel::filesystem::ext2::inode{&fs};
inode.m_data.blocks = 2;
diff --git a/kernel/src/filesystem/file_descriptor_table.cpp b/kernel/src/filesystem/file_descriptor_table.cpp
index 1c062a1..7569cea 100644
--- a/kernel/src/filesystem/file_descriptor_table.cpp
+++ b/kernel/src/filesystem/file_descriptor_table.cpp
@@ -41,7 +41,6 @@ namespace kernel::filesystem
{
if (!file_description)
{
- // TODO BA-FS26 panic or errorcode?
return -1;
}
@@ -72,20 +71,21 @@ namespace kernel::filesystem
return m_open_files.at(index);
}
- auto file_descriptor_table::remove_file(int fd) -> void
+ auto file_descriptor_table::remove_file(int fd) -> int
{
if (fd < 0)
{
- return;
+ return -1;
}
auto const index = static_cast<size_t>(fd);
if (index >= m_open_files.size())
{
- return;
+ return -1;
}
m_open_files.at(index) = nullptr;
+ return 0;
}
} // namespace kernel::filesystem
diff --git a/kernel/src/filesystem/filesystem.cpp b/kernel/src/filesystem/filesystem.cpp
index d8b04eb..99e7456 100644
--- a/kernel/src/filesystem/filesystem.cpp
+++ b/kernel/src/filesystem/filesystem.cpp
@@ -1,6 +1,5 @@
#include "kernel/filesystem/filesystem.hpp"
-#include "kapi/devices/device.hpp"
#include "kapi/system.hpp"
#include "kernel/filesystem/ext2/filesystem.hpp"
@@ -19,18 +18,17 @@ namespace kernel::filesystem
};
} // namespace
- auto filesystem::probe_and_mount(kstd::shared_ptr<kapi::devices::device> const & device)
- -> kstd::shared_ptr<filesystem>
+ auto filesystem::probe_and_mount(kstd::shared_ptr<inode> const & backing_inode) -> kstd::shared_ptr<filesystem>
{
- if (!device)
+ if (!backing_inode)
{
- kapi::system::panic("[FILESYSTEM] cannot mount filesystem: device is null.");
+ kapi::system::panic("[FILESYSTEM] cannot mount filesystem: backing inode is null.");
}
for (auto & factory : filesystem_factories)
{
auto fs = factory();
- if (fs->mount(device) == operation_result::success)
+ if (fs->mount(backing_inode) == operation_result::success)
{
return fs;
}
@@ -39,14 +37,14 @@ namespace kernel::filesystem
return nullptr;
}
- auto filesystem::mount(kstd::shared_ptr<kapi::devices::device> const & device) -> operation_result
+ auto filesystem::mount(kstd::shared_ptr<inode> const & backing_inode) -> operation_result
{
- if (!device)
+ if (!backing_inode)
{
- kapi::system::panic("[FILESYSTEM] cannot mount filesystem: device is null.");
+ kapi::system::panic("[FILESYSTEM] cannot mount filesystem: backing inode is null.");
}
- m_device = device;
+ m_backing_inode = backing_inode;
return operation_result::success;
}
@@ -55,8 +53,8 @@ namespace kernel::filesystem
return m_root_inode;
}
- auto filesystem::device() const -> kstd::shared_ptr<kapi::devices::device> const &
+ auto filesystem::backing_inode() const -> kstd::shared_ptr<inode> const &
{
- return m_device;
+ return m_backing_inode;
}
} // namespace kernel::filesystem \ No newline at end of file
diff --git a/kernel/src/filesystem/rootfs/filesystem.cpp b/kernel/src/filesystem/rootfs/filesystem.cpp
index dffef99..f718c72 100644
--- a/kernel/src/filesystem/rootfs/filesystem.cpp
+++ b/kernel/src/filesystem/rootfs/filesystem.cpp
@@ -1,7 +1,5 @@
#include "kernel/filesystem/rootfs/filesystem.hpp"
-#include "kapi/devices/device.hpp"
-
#include "kernel/filesystem/inode.hpp"
#include "kernel/filesystem/rootfs/inode.hpp"
@@ -11,7 +9,7 @@
namespace kernel::filesystem::rootfs
{
- auto filesystem::mount(kstd::shared_ptr<kapi::devices::device> const &) -> operation_result
+ auto filesystem::mount(kstd::shared_ptr<kernel::filesystem::inode> const &) -> operation_result
{
auto rfs_inode = kstd::make_sha