diff options
Diffstat (limited to 'kernel/kernel/filesystem/vfs.tests.cpp')
| -rw-r--r-- | kernel/kernel/filesystem/vfs.tests.cpp | 185 |
1 files changed, 89 insertions, 96 deletions
diff --git a/kernel/kernel/filesystem/vfs.tests.cpp b/kernel/kernel/filesystem/vfs.tests.cpp index c5130ef4..59589633 100644 --- a/kernel/kernel/filesystem/vfs.tests.cpp +++ b/kernel/kernel/filesystem/vfs.tests.cpp @@ -1,9 +1,11 @@ #include <kernel/filesystem/vfs.hpp> +#include <kernel/filesystem/error.hpp> #include <kernel/filesystem/open_file_descriptor.hpp> #include <kernel/test_support/filesystem/storage_boot_module_vfs_fixture.hpp> #include <kstd/memory.hpp> +#include <kstd/system_error.hpp> #include <kstd/vector.hpp> #include <catch2/catch_test_macros.hpp> @@ -73,7 +75,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS auto & vfs = kernel::filesystem::vfs::get(); auto image_1 = vfs.open("/dev/image_1.txt"); - REQUIRE(image_1 == nullptr); + REQUIRE(image_1.error() == make_error_condition(kstd::errc::no_such_file_or_directory)); auto dev = vfs.open("/dev/ram0"); REQUIRE(dev != nullptr); @@ -102,16 +104,15 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS THEN("second image can be mounted, data retrieved and unmounted again") { - REQUIRE(vfs.do_mount("/dev/ram16", "/information") == kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.do_mount("/dev/ram16", "/information")); auto mounted_monkey_1 = vfs.open("/information/monkey_house/monkey_1.txt"); REQUIRE(mounted_monkey_1); - REQUIRE(vfs.close(mounted_monkey_1.value()->absolute_path()) == - kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.close(mounted_monkey_1.value()->absolute_path())); - REQUIRE(vfs.unmount("/information") == kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.unmount("/information")); auto unmounted_monkey_1 = vfs.open("/information/monkey_house/monkey_1.txt"); - REQUIRE(unmounted_monkey_1 == nullptr); + REQUIRE(unmounted_monkey_1.error() == make_error_condition(kstd::errc::no_such_file_or_directory)); auto info_1 = vfs.open("/information/info_1.txt"); REQUIRE(info_1 != nullptr); @@ -119,9 +120,8 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS THEN("third image can be mounted in a mounted file system, unmount only if no child mount exists") { - REQUIRE(vfs.do_mount("/dev/ram16", "/information") == kernel::filesystem::vfs::operation_result::success); - REQUIRE(vfs.do_mount("/dev/ram32", "/information/monkey_house/infrastructure") == - kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.do_mount("/dev/ram16", "/information")); + REQUIRE(vfs.do_mount("/dev/ram32", "/information/monkey_house/infrastructure")); auto mounted_monkey_1 = vfs.open("/information/monkey_house/monkey_1.txt"); auto mounted_fish1 = vfs.open("/information/monkey_house/infrastructure/enclosures/aquarium/tank_1/fish_1.txt"); @@ -129,34 +129,31 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS REQUIRE(mounted_monkey_1); REQUIRE(mounted_fish1); - REQUIRE(vfs.close(mounted_monkey_1.value()->absolute_path()) == - kernel::filesystem::vfs::operation_result::success); - REQUIRE(vfs.close(mounted_fish1.value()->absolute_path()) == kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.close(mounted_monkey_1.value()->absolute_path())); + REQUIRE(vfs.close(mounted_fish1.value()->absolute_path())); - REQUIRE(vfs.unmount("/information") == kernel::filesystem::vfs::operation_result::unmount_failed); - REQUIRE(vfs.unmount("/information/monkey_house/infrastructure") == - kernel::filesystem::vfs::operation_result::success); - REQUIRE(vfs.unmount("/information") == kernel::filesystem::vfs::operation_result::success); + REQUIRE(!vfs.unmount("/information")); + REQUIRE(vfs.unmount("/information/monkey_house/infrastructure")); + REQUIRE(vfs.unmount("/information")); } THEN("image can be mounted, unmount only if no files are open") { - REQUIRE(vfs.do_mount("/dev/ram16", "/information") == kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.do_mount("/dev/ram16", "/information")); auto mounted_monkey_1 = vfs.open("/information/monkey_house/monkey_1.txt"); REQUIRE(mounted_monkey_1); - REQUIRE(vfs.unmount("/information") == kernel::filesystem::vfs::operation_result::unmount_failed); + REQUIRE(!vfs.unmount("/information")); - REQUIRE(vfs.close(mounted_monkey_1.value()->absolute_path()) == - kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.close(mounted_monkey_1.value()->absolute_path())); - REQUIRE(vfs.unmount("/information") == kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.unmount("/information")); } THEN("file with invalid path or not opened file cannot be closed") { - REQUIRE(vfs.close("invalid_path") == kernel::filesystem::vfs::operation_result::invalid_path); + REQUIRE(!vfs.close("invalid_path")); REQUIRE_THROWS_AS(vfs.close("/information/info_1.txt"), std::runtime_error); } @@ -165,27 +162,26 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS auto info_1 = vfs.open("/information/info_1.txt"); REQUIRE(info_1); - REQUIRE(vfs.close(info_1.value()->absolute_path()) == kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.close(info_1.value()->absolute_path())); REQUIRE_THROWS_AS(vfs.close(info_1.value()->absolute_path()), std::runtime_error); } THEN("images can be stacked mounted and correct file system is unmounted again") { - REQUIRE(vfs.do_mount("/dev/ram16", "/information") == kernel::filesystem::vfs::operation_result::success); - REQUIRE(vfs.do_mount("/dev/ram32", "/information") == kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.do_mount("/dev/ram16", "/information")); + REQUIRE(vfs.do_mount("/dev/ram32", "/information")); auto mounted_tickets = vfs.open("/information/entrance/tickets.txt"); REQUIRE(mounted_tickets); - REQUIRE(vfs.close(mounted_tickets.value()->absolute_path()) == - kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.close(mounted_tickets.value()->absolute_path())); - REQUIRE(vfs.unmount("/information") == kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.unmount("/information")); mounted_tickets = vfs.open("/information/entrance/tickets.txt"); - REQUIRE(mounted_tickets == nullptr); + REQUIRE(mounted_tickets.error() == make_error_condition(kstd::errc::no_such_file_or_directory)); auto mounted_monkey = vfs.open("/information/monkey_house/monkey_1.txt"); - REQUIRE(mounted_monkey != nullptr); + REQUIRE(mounted_monkey); } THEN("image can be mounted on / file opened and unmounted again") @@ -193,17 +189,17 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS auto info_1 = vfs.open("/information/info_1.txt"); REQUIRE(info_1 != nullptr); - REQUIRE(vfs.do_mount("/dev/ram16", "/") == kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.do_mount("/dev/ram16", "/")); info_1 = vfs.open("/information/info_1.txt"); - REQUIRE(info_1 == nullptr); + REQUIRE(info_1.error() == make_error_condition(kstd::errc::no_such_file_or_directory)); auto water = vfs.open("/monkey_house/infrastructure/water.txt"); REQUIRE(water != nullptr); - REQUIRE(vfs.close(water.value()->absolute_path()) == kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.close(water.value()->absolute_path())); - REQUIRE(vfs.unmount("/") == kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.unmount("/")); info_1 = vfs.open("/information/info_1.txt"); REQUIRE(info_1 != nullptr); @@ -214,22 +210,23 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS auto info_1 = vfs.open("/information/info_1.txt"); REQUIRE(info_1 != nullptr); - REQUIRE(vfs.do_mount("/dev/ram16", "/") == kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.do_mount("/dev/ram16", "/")); info_1 = vfs.open("/information/info_1.txt"); - REQUIRE(info_1 == nullptr); + REQUIRE(info_1.error() == make_error_condition(kstd::errc::no_such_file_or_directory)); auto water = vfs.open("/monkey_house/infrastructure/water.txt"); REQUIRE(water != nullptr); - REQUIRE(vfs.close(water.value()->absolute_path()) == kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.close(water.value()->absolute_path())); auto dev_ram_16 = vfs.open("/dev/ram16"); - REQUIRE(dev_ram_16 == nullptr); + REQUIRE(dev_ram_16.error() == make_error_condition(kstd::errc::no_such_file_or_directory)); - REQUIRE(vfs.do_mount("/dev/ram32", "/") == kernel::filesystem::vfs::operation_result::non_existent_path); + REQUIRE(vfs.do_mount("/dev/ram32", "/").error() == + make_error_code(kernel::filesystem::vfs_errc::non_existent_path)); - REQUIRE(vfs.unmount("/") == kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.unmount("/")); auto dev_ram_32 = vfs.open("/dev/ram32"); REQUIRE(dev_ram_32 != nullptr); @@ -240,58 +237,59 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS auto info_1 = vfs.open("/information/info_1.txt"); REQUIRE(info_1 != nullptr); - REQUIRE(vfs.close(info_1.value()->absolute_path()) == kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.close(info_1.value()->absolute_path())); - REQUIRE(vfs.unmount("/dev") == kernel::filesystem::vfs::operation_result::success); - REQUIRE(vfs.unmount("/") == kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.unmount("/dev")); + REQUIRE(vfs.unmount("/")); info_1 = vfs.open("/information/info_1.txt"); - REQUIRE(info_1 == nullptr); + REQUIRE(info_1.error() == make_error_condition(kstd::errc::no_such_file_or_directory)); - REQUIRE(vfs.do_mount("/dev/ram0", "/") == kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.do_mount("/dev/ram0", "/")); info_1 = vfs.open("/information/info_1.txt"); REQUIRE(info_1 != nullptr); auto dev_ram_0 = vfs.open("/dev/ram0"); - REQUIRE(dev_ram_0 == nullptr); + REQUIRE(dev_ram_0.error() == make_error_condition(kstd::errc::no_such_file_or_directory)); } THEN("mount with null file system fails") { - REQUIRE(vfs.do_mount("/closed.txt", "/information") == - kernel::filesystem::vfs::operation_result::invalid_filesystem); + REQUIRE(vfs.do_mount("/closed.txt", "/information").error() == + make_error_code(kernel::filesystem::vfs_errc::invalid_filesystem)); } THEN("mount with invalid path fails") { - REQUIRE(vfs.do_mount("/dev/ram16", "") == kernel::filesystem::vfs::operation_result::invalid_path); - REQUIRE(vfs.do_mount("/dev/ram16", "information") == - kernel::filesystem::vfs::operation_result::mount_point_not_found); + REQUIRE(vfs.do_mount("/dev/ram16", "").error() == make_error_code(kernel::filesystem::vfs_errc::invalid_path)); + REQUIRE(vfs.do_mount("/dev/ram16", "information").error() == + make_error_code(kernel::filesystem::vfs_errc::mount_point_not_found)); } THEN("mount with non-existent source path fails") { - REQUIRE(vfs.do_mount("/dev/nonexistent", "/information") == - kernel::filesystem::vfs::operation_result::non_existent_path); + REQUIRE(vfs.do_mount("/dev/nonexistent", "/information").error() == + make_error_code(kernel::filesystem::vfs_errc::non_existent_path)); } THEN("mount with non-existent mount point fails") { - REQUIRE(vfs.do_mount("/dev/ram16", "/information/nonexistent") == - kernel::filesystem::vfs::operation_result::mount_point_not_found); + REQUIRE(vfs.do_mount("/dev/ram16", "/information/nonexistent").error() == + make_error_code(kernel::filesystem::vfs_errc::mount_point_not_found)); } THEN("unmount with invalid path fails") { - REQUIRE(vfs.unmount("") == kernel::filesystem::vfs::operation_result::invalid_path); - REQUIRE(vfs.unmount("information") == kernel::filesystem::vfs::operation_result::mount_point_not_found); + REQUIRE(vfs.unmount("").error() == make_error_code(kernel::filesystem::vfs_errc::invalid_path)); + REQUIRE(vfs.unmount("information").error() == + make_error_code(kernel::filesystem::vfs_errc::mount_point_not_found)); } THEN("unmounting non-existent mount point returns expected error code") { - REQUIRE(vfs.unmount("/information/nonexistent") == - kernel::filesystem::vfs::operation_result::mount_point_not_found); + REQUIRE(vfs.unmount("/information/nonexistent").error() == + make_error_code(kernel::filesystem::vfs_errc::mount_point_not_found)); } THEN("a file can be access if . in the path") @@ -311,7 +309,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS THEN("a file can be accessed over multiple mounts if path contains .. or . ") { - REQUIRE(vfs.do_mount("/dev/ram16", "/information") == kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.do_mount("/dev/ram16", "/information")); auto img = vfs.open("/information/monkey_house/caretaker/../../../../../../archiv/2024.img"); REQUIRE(img != nullptr); @@ -325,9 +323,8 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS THEN("a file can be accessed over multiple mounts (device and file) if path contains .. ") { - REQUIRE(vfs.do_mount("/dev/ram16", "/information") == kernel::filesystem::vfs::operation_result::success); - REQUIRE(vfs.do_mount("/archiv/2024.img", "/information/monkey_house/infrastructure") == - kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.do_mount("/dev/ram16", "/information")); + REQUIRE(vfs.do_mount("/archiv/2024.img", "/information/monkey_house/infrastructure")); auto pig_1 = vfs.open("/information/monkey_house/infrastructure/stable/pig_1.txt"); REQUIRE(pig_1 != nullptr); @@ -349,10 +346,10 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS THEN("the file-filesystem in the image can be mounted, files can be read and unmounted again") { auto & vfs = kernel::filesystem::vfs::get(); - REQUIRE(vfs.do_mount("/archiv/2024.img", "/information") == kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.do_mount("/archiv/2024.img", "/information")); auto info_1 = vfs.open("/information/info_1.txt"); - REQUIRE(info_1 == nullptr); + REQUIRE(info_1.error() == make_error_condition(kstd::errc::no_such_file_or_directory)); auto dentry = vfs.open("/information/sheep_1.txt"); REQUIRE(dentry != nullptr); @@ -363,20 +360,19 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS std::string_view buffer_as_str{reinterpret_cast<char *>(buffer.data()), bytes_read}; REQUIRE(buffer_as_str == "sheep_1"); - REQUIRE(vfs.close(dentry.value()->absolute_path()) == kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.close(dentry.value()->absolute_path())); - REQUIRE(vfs.unmount("/information") == kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.unmount("/information")); auto unmounted_sheep_1 = vfs.open("/information/sheep_1.txt"); - REQUIRE(unmounted_sheep_1 == nullptr); + REQUIRE(unmounted_sheep_1.error() == make_error_condition(kstd::errc::no_such_file_or_directory)); } THEN("the file-filesystem in the image can be mounted and in this filesystem can another file-filesystem be " "mounted, files can be read and unmounted again") { auto & vfs = kernel::filesystem::vfs::get(); - REQUIRE(vfs.do_mount("/archiv/2024.img", "/information") == kernel::filesystem::vfs::operation_result::success); - REQUIRE(vfs.do_mount("/archiv/2025.img", "/information/stable") == - kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.do_mount("/archiv/2024.img", "/information")); + REQUIRE(vfs.do_mount("/archiv/2025.img", "/information/stable")); auto sheep_1 = vfs.open("/information/sheep_1.txt"); auto goat_1 = vfs.open("/information/stable/petting_zoo/goat_1.txt"); @@ -396,24 +392,23 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS buffer_as_str = std::string_view{reinterpret_cast<char *>(goat_buffer.data()), bytes_read}; REQUIRE(buffer_as_str == "goat_1"); - REQUIRE(vfs.close(sheep_1.value()->absolute_path()) == kernel::filesystem::vfs::operation_result::success); - REQUIRE(vfs.close(goat_1.value()->absolute_path()) == kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.close(sheep_1.value()->absolute_path())); + REQUIRE(vfs.close(goat_1.value()->absolute_path())); - REQUIRE(vfs.unmount("/information") == kernel::filesystem::vfs::operation_result::unmount_failed); + REQUIRE(vfs.unmount("/information").error() == make_error_code(kernel::filesystem::vfs_errc::unmount_failed)); - REQUIRE(vfs.unmount("/information/stable") == kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.unmount("/information/stable")); auto unmounted_goat_1 = vfs.open("/information/stable/petting_zoo/goat_1.txt"); - REQUIRE(unmounted_goat_1 == nullptr); + REQUIRE(unmounted_goat_1.error() == make_error_condition(kstd::errc::no_such_file_or_directory)); auto still_mounted_sheep_1 = vfs.open("/information/sheep_1.txt"); REQUIRE(still_mounted_sheep_1 != nullptr); - REQUIRE(vfs.close(still_mounted_sheep_1.value()->absolute_path()) == - kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.close(still_mounted_sheep_1.value()->absolute_path())); - REQUIRE(vfs.unmount("/information") == kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.unmount("/information")); auto unmounted_sheep_1 = vfs.open("/information/sheep_1.txt"); - REQUIRE(unmounted_sheep_1 == nullptr); + REQUIRE(unmounted_sheep_1.error() == make_error_condition(kstd::errc::no_such_file_or_directory)); } } @@ -428,23 +423,21 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS THEN("cannot unmount a filesystem if files are mounted") { - REQUIRE(vfs.do_mount("/dev/ram16", "/entrance") == kernel::filesystem::vfs::operation_result::success); - REQUIRE(vfs.do_mount("/entrance/archiv/2024.img", "/enclosures") == - kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.do_mount("/dev/ram16", "/entrance")); + REQUIRE(vfs.do_mount("/entrance/archiv/2024.img", "/enclosures")); - REQUIRE(vfs.unmount("/entrance") == kernel::filesystem::vfs::operation_result::unmount_failed); - REQUIRE(vfs.unmount("/enclosures") == kernel::filesystem::vfs::operation_result::success); - REQUIRE(vfs.unmount("/entrance") == kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.unmount("/entrance").error() == make_error_code(kernel::filesystem::vfs_errc::unmount_failed)); + REQUIRE(vfs.unmount("/enclosures")); + REQUIRE(vfs.unmount("/entrance")); } THEN("can mount filesystem onto the directory that contains it") { - REQUIRE(vfs.do_mount("/dev/ram16", "/entrance") == kernel::filesystem::vfs::operation_result::success); - REQUIRE(vfs.do_mount("/entrance/archiv/2024.img", "/entrance") == - kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.do_mount("/dev/ram16", "/entrance")); + REQUIRE(vfs.do_mount("/entrance/archiv/2024.img", "/entrance")); - REQUIRE(vfs.unmount("/entrance") == kernel::filesystem::vfs::operation_result::success); - REQUIRE(vfs.unmount("/entrance") == kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.unmount("/entrance")); + REQUIRE(vfs.unmount("/entrance")); } } @@ -492,21 +485,21 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS { auto & vfs = kernel::filesystem::vfs::get(); auto invalid_symlink = vfs.open("/symlinks/invalid_absolute"); - REQUIRE(invalid_symlink == nullptr); + REQUIRE(invalid_symlink.error() == make_error_code(kernel::filesystem::vfs_errc::non_existent_path)); } THEN("symbolic link containing an invalid relative path is handled correctly") { auto & vfs = kernel::filesystem::vfs::get(); auto invalid_symlink = vfs.open("/symlinks/invalid_relative"); - REQUIRE(invalid_symlink == nullptr); + REQUIRE(invalid_symlink.error() == make_error_code(kernel::filesystem::vfs_errc::non_existent_path)); } THEN("circular symbolic links are detected and handled correctly") { auto & vfs = kernel::filesystem::vfs::get(); auto circular_symlink = vfs.open("/symlinks/symloop_a"); - REQUIRE(circular_symlink == nullptr); + REQUIRE(circular_symlink.error() == make_error_code(kstd::errc::too_many_symbolic_link_levels)); } } @@ -516,7 +509,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS REQUIRE_NOTHROW(setup_modules_from_img_and_init_vfs({"test_img_module_1"}, {image_path_1})); auto & vfs = kernel::filesystem::vfs::get(); - vfs.do_mount("/archiv/2024.img", "/information"); + REQUIRE(vfs.do_mount("/archiv/2024.img", "/information")); THEN("file can be opened through symbolic link pointing to the parent filesystem") { @@ -533,7 +526,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS setup_modules_from_img_and_init_vfs({"test_img_module_1", "test_img_module_2"}, {image_path_1, image_path_2})); auto & vfs = kernel::filesystem::vfs::get(); - vfs.do_mount("/dev/ram16", "/information"); + REQUIRE(vfs.do_mount("/dev/ram16", "/information")); THEN("file can be opened through symbolic link pointing to the parent filesystem and back into the mounted " "filesystem again") |
