diff options
Diffstat (limited to 'kernel/src/filesystem')
| -rw-r--r-- | kernel/src/filesystem/mount.cpp | 22 | ||||
| -rw-r--r-- | kernel/src/filesystem/mount_table.cpp | 5 | ||||
| -rw-r--r-- | kernel/src/filesystem/open_file_descriptor.cpp | 7 | ||||
| -rw-r--r-- | kernel/src/filesystem/open_file_descriptor.tests.cpp | 24 | ||||
| -rw-r--r-- | kernel/src/filesystem/vfs.cpp | 17 |
5 files changed, 60 insertions, 15 deletions
diff --git a/kernel/src/filesystem/mount.cpp b/kernel/src/filesystem/mount.cpp index 749c86a..3016509 100644 --- a/kernel/src/filesystem/mount.cpp +++ b/kernel/src/filesystem/mount.cpp @@ -18,6 +18,7 @@ namespace kernel::filesystem , m_root_dentry(root_dentry) , m_filesystem(fs) , m_parent_mount(parent_mount) + , m_ref_count(0) { if (!m_filesystem) { @@ -53,4 +54,25 @@ namespace kernel::filesystem { return m_parent_mount; } + + auto mount::increment_ref_count() -> void + { + m_ref_count += 1; + } + + auto mount::decrement_ref_count() -> bool + { + if (m_ref_count == 0) + { + return false; + } + + m_ref_count -= 1; + return true; + } + + auto mount::is_ready_to_unmount() const -> bool + { + return m_ref_count == 0; + } } // namespace kernel::filesystem
\ No newline at end of file diff --git a/kernel/src/filesystem/mount_table.cpp b/kernel/src/filesystem/mount_table.cpp index b582fd9..9951590 100644 --- a/kernel/src/filesystem/mount_table.cpp +++ b/kernel/src/filesystem/mount_table.cpp @@ -30,7 +30,6 @@ namespace kernel::filesystem auto mount_table::remove_mount(std::string_view path) -> operation_result { - // TODO BA-FS26 check wheter something is open in this mount auto mount_it = find_mount_iterator(path); if (mount_it == m_mounts.end()) { @@ -38,6 +37,10 @@ namespace kernel::filesystem } auto const & mount = *mount_it; + if (!mount->is_ready_to_unmount()) + { + return operation_result::cannot_be_unmounted; + } if (has_child_mounts(mount)) { return operation_result::has_child_mounts; diff --git a/kernel/src/filesystem/open_file_descriptor.cpp b/kernel/src/filesystem/open_file_descriptor.cpp index 27e6449..ebaabef 100644 --- a/kernel/src/filesystem/open_file_descriptor.cpp +++ b/kernel/src/filesystem/open_file_descriptor.cpp @@ -33,9 +33,14 @@ namespace kernel::filesystem return written_bytes; } - auto open_file_descriptor::offset() const -> size_t + auto open_file_descriptor::get_offset() const -> size_t { return m_offset; } + auto open_file_descriptor::get_dentry() const -> kstd::shared_ptr<dentry> const & + { + return m_dentry; + } + } // namespace kernel::filesystem
\ No newline at end of file diff --git a/kernel/src/filesystem/open_file_descriptor.tests.cpp b/kernel/src/filesystem/open_file_descriptor.tests.cpp index 8c24cf0..1910b8b 100644 --- a/kernel/src/filesystem/open_file_descriptor.tests.cpp +++ b/kernel/src/filesystem/open_file_descriptor.tests.cpp @@ -26,7 +26,7 @@ SCENARIO("Open file descriptor construction", "[filesystem][open_file_descriptor THEN("the initial offset is zero") { - REQUIRE(file_descriptor.offset() == 0); + REQUIRE(file_descriptor.get_offset() == 0); } } } @@ -42,29 +42,29 @@ SCENARIO("Open file descriptor read/write offset management", "[filesystem][open THEN("the offset is updated correctly after reads") { REQUIRE(file_descriptor.read(nullptr, 100) == 100); - REQUIRE(file_descriptor.offset() == 100); + REQUIRE(file_descriptor.get_offset() == 100); REQUIRE(file_descriptor.read(nullptr, 50) == 50); - REQUIRE(file_descriptor.offset() == 150); + REQUIRE(file_descriptor.get_offset() == 150); } THEN("the offset is updated correctly after writes") { REQUIRE(file_descriptor.write(nullptr, 200) == 200); - REQUIRE(file_descriptor.offset() == 200); + REQUIRE(file_descriptor.get_offset() == 200); REQUIRE(file_descriptor.write(nullptr, 25) == 25); - REQUIRE(file_descriptor.offset() == 225); + REQUIRE(file_descriptor.get_offset() == 225); } THEN("reads and writes both update the same offset") { REQUIRE(file_descriptor.read(nullptr, 10) == 10); - REQUIRE(file_descriptor.offset() == 10); + REQUIRE(file_descriptor.get_offset() == 10); REQUIRE(file_descriptor.write(nullptr, 20) == 20); - REQUIRE(file_descriptor.offset() == 30); + REQUIRE(file_descriptor.get_offset() == 30); REQUIRE(file_descriptor.read(nullptr, 5) == 5); - REQUIRE(file_descriptor.offset() == 35); + REQUIRE(file_descriptor.get_offset() == 35); REQUIRE(file_descriptor.write(nullptr, 15) == 15); - REQUIRE(file_descriptor.offset() == 50); + REQUIRE(file_descriptor.get_offset() == 50); } } } @@ -89,7 +89,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "Ope kstd::vector<std::byte> buffer(32); auto bytes_read = ofd->read(buffer.data(), buffer.size()); REQUIRE(bytes_read == 7); - REQUIRE(ofd->offset() == 7); + REQUIRE(ofd->get_offset() == 7); std::string_view buffer_as_str{reinterpret_cast<char *>(buffer.data()), static_cast<size_t>(bytes_read)}; REQUIRE(buffer_as_str == "info_1\n"); @@ -100,11 +100,11 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "Ope kstd::vector<std::byte> buffer(4); auto bytes_read_1 = ofd->read(buffer.data(), buffer.size() / 2); REQUIRE(bytes_read_1 == buffer.size() / 2); - REQUIRE(ofd->offset() == buffer.size() / 2); + REQUIRE(ofd->get_offset() == buffer.size() / 2); auto bytes_read_2 = ofd->read(buffer.data() + buffer.size() / 2, buffer.size() / 2); REQUIRE(bytes_read_2 == buffer.size() / 2); - REQUIRE(ofd->offset() == buffer.size()); + REQUIRE(ofd->get_offset() == buffer.size()); std::string_view buffer_as_str{reinterpret_cast<char *>(buffer.data()), bytes_read_1 + bytes_read_2}; REQUIRE(buffer_as_str == "info"); diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index 77ae015..3b3d6ff 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -89,7 +89,22 @@ namespace kernel::filesystem auto vfs::open(std::string_view path) -> kstd::shared_ptr<dentry> { - return resolve_path(path); + auto [dentry, mount] = resolve_path_internal(path); + mount->increment_ref_count(); + return dentry; + } + + auto vfs::close(kstd::shared_ptr<dentry> const & dentry) -> operation_result + { + if (auto mount = find_mount(dentry->get_absolute_path().view())) + { + if (mount->decrement_ref_count()) + { + return operation_result::success; + } + return operation_result::close_failed; + } + return operation_result::invalid_path; } auto vfs::do_mount(std::string_view source, std::string_view target) -> operation_result |
