#include "Pledge.h" #include "fs/VFS.h" #include "fs/ext2/FileSystem.h" #include "fs/tmpfs/FileSystem.h" #include "memory/MemoryManager.h" #include "sys/Syscall.h" #include "thread/Scheduler.h" Result sys_mount(Registers*, SyscallArgs args) { auto target = TRY(MemoryManager::strdup_from_user(args[0])); auto fstype = TRY(MemoryManager::strdup_from_user(args[1])); auto source = TRY(MemoryManager::strdup_from_user(args[2])); auto* current = Scheduler::current(); TRY(check_pledge(current, Promise::p_mount)); if (current->auth.euid != 0) return err(EPERM); auto get_source = [current, &source]() -> Result> { auto inode = TRY(VFS::resolve_path(source.chars(), current->auth, current->current_directory)); if (inode->type() != VFS::InodeType::BlockDevice) return err(ENOTBLK); dev_t device_id = inode->metadata().devid; return TRY(DeviceRegistry::fetch_special_device(luna_dev_major(device_id), luna_dev_minor(device_id))); }; SharedPtr fs; if (fstype.view() == "tmpfs") fs = TRY(TmpFS::FileSystem::create()); else if (fstype.view() == "devfs") fs = TRY(DeviceRegistry::create_devfs_instance()); else if (fstype.view() == "ext2") { auto source_device = TRY(get_source()); fs = TRY(Ext2::FileSystem::create(source_device)); } else return err(ENODEV); TRY(VFS::mount(target.chars(), fs, current->auth, current->current_directory)); return 0; } Result sys_umount(Registers*, SyscallArgs args) { auto target = TRY(MemoryManager::strdup_from_user(args[0])); auto* current = Scheduler::current(); TRY(check_pledge(current, Promise::p_mount)); if (current->auth.euid != 0) return err(EPERM); TRY(VFS::umount(target.chars(), current->auth, current->current_directory)); return 0; } Result sys_pivot_root(Registers*, SyscallArgs args) { auto new_root = TRY(MemoryManager::strdup_from_user(args[0])); auto put_old = TRY(MemoryManager::strdup_from_user(args[1])); auto* current = Scheduler::current(); TRY(check_pledge(current, Promise::p_mount)); if (current->auth.euid != 0) return err(EPERM); TRY(VFS::pivot_root(new_root.chars(), put_old.chars(), current->current_directory)); return 0; }