aboutsummaryrefslogtreecommitdiff
path: root/kernel/src/filesystem/vfs.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/src/filesystem/vfs.cpp')
-rw-r--r--kernel/src/filesystem/vfs.cpp45
1 files changed, 30 insertions, 15 deletions
diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp
index 2578036..45ae053 100644
--- a/kernel/src/filesystem/vfs.cpp
+++ b/kernel/src/filesystem/vfs.cpp
@@ -7,6 +7,7 @@
#include "kernel/filesystem/devfs/filesystem.hpp"
#include "kernel/filesystem/filesystem.hpp"
#include "kernel/filesystem/mount.hpp"
+#include "kernel/filesystem/mount_table.hpp"
#include "kernel/filesystem/open_file_description.hpp"
#include "kernel/filesystem/rootfs/filesystem.hpp"
@@ -21,11 +22,6 @@ namespace kernel::filesystem
namespace
{
constinit auto static active_vfs = std::optional<vfs>{};
-
- // Error codes
- constexpr int INVALID_PATH = -1;
- constexpr int MOUNT_POINT_NOT_FOUND = -2;
- constexpr int FILESYSTEM_NULL = -3;
} // namespace
auto vfs::init() -> void
@@ -45,7 +41,7 @@ namespace kernel::filesystem
root_fs->mount(nullptr);
auto root_fs_root_dentry = kstd::make_shared<dentry>(nullptr, root_fs->root_inode());
- m_mount_table.add_mount(kstd::make_shared<mount>(nullptr, root_fs_root_dentry, root_fs, ""));
+ m_mount_table.add_mount(kstd::make_shared<mount>(nullptr, root_fs_root_dentry, root_fs, "", nullptr));
auto storage_mgmt = devices::storage::management::get();
if (auto boot_device = storage_mgmt.determine_boot_device())
@@ -79,36 +75,55 @@ namespace kernel::filesystem
return nullptr;
}
- // TODO BA-FS26 implement unmount
- auto vfs::do_mount(std::string_view path, kstd::shared_ptr<filesystem> const & filesystem) -> int
+ auto vfs::do_mount(std::string_view path, kstd::shared_ptr<filesystem> const & filesystem) -> operation_result
{
if (!filesystem)
{
- return FILESYSTEM_NULL;
+ return operation_result::filesystem_null;
}
if (path.empty() || path.front() != '/' || (path.size() > 1 && path.back() == '/'))
{
- return INVALID_PATH;
+ return operation_result::invalid_path;
}
if (auto mount_point_dentry = resolve_path(path))
{
do_mount_internal(path, mount_point_dentry, filesystem);
- return 0;
+ return operation_result::success;
+ }
+
+ return operation_result::mount_point_not_found;
+ }
+
+ auto vfs::unmount(std::string_view path) -> operation_result
+ {
+ if (path.empty() || path.front() != '/' || (path.size() > 1 && path.back() == '/'))
+ {
+ return operation_result::invalid_path;
+ }
+
+ auto remove_result = m_mount_table.remove_mount(path);
+ if (remove_result == mount_table::operation_result::removed)
+ {
+ return operation_result::success;
+ }
+
+ if (remove_result == mount_table::operation_result::has_child_mounts)
+ {
+ return operation_result::unmount_failed;
}
- return MOUNT_POINT_NOT_FOUND;
+ return operation_result::mount_point_not_found;
}
auto vfs::do_mount_internal(std::string_view path, kstd::shared_ptr<dentry> const & mount_point_dentry,
kstd::shared_ptr<filesystem> const & fs) -> void
{
- // TODO BA-FS26 check if mount point is already mounted and handle it (unmount old fs, fail, etc.)
+ auto parent_mount = m_mount_table.find_longest_prefix_mount(path);
auto new_fs_root = kstd::make_shared<dentry>(mount_point_dentry, fs->root_inode());
- auto new_mount = kstd::make_shared<mount>(mount_point_dentry, new_fs_root, fs, path);
+ auto new_mount = kstd::make_shared<mount>(mount_point_dentry, new_fs_root, fs, path, parent_mount);
m_mount_table.add_mount(new_mount);
- mount_point_dentry->set_flag(dentry::dentry_flags::dcache_mounted);
}
auto vfs::resolve_path(std::string_view path) -> kstd::shared_ptr<dentry>