70 lines
2.3 KiB
C++
70 lines
2.3 KiB
C++
#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<u64> 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<SharedPtr<Device>> {
|
|
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<VFS::FileSystem> 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<u64> 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<u64> 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;
|
|
}
|