From e5259d58496466f6239fda40949c25f53e7ef6a1 Mon Sep 17 00:00:00 2001 From: apio Date: Tue, 20 Jun 2023 21:39:41 +0200 Subject: [PATCH] kernel+libc+apps: Add a source parameter to the mount() system call --- apps/init.cpp | 2 +- apps/mount.cpp | 4 +++- initrd/sbin/mount-tmpfs | 2 +- kernel/CMakeLists.txt | 1 + kernel/src/fs/ext2/FileSystem.cpp | 1 + kernel/src/fs/ext2/FileSystem.h | 1 + kernel/src/sys/mount.cpp | 14 ++++++++++++++ libc/include/sys/mount.h | 2 +- libc/src/sys/mount.cpp | 4 ++-- libluna/include/luna/SharedPtr.h | 6 ++++++ 10 files changed, 31 insertions(+), 6 deletions(-) diff --git a/apps/init.cpp b/apps/init.cpp index afc47547..2bec17ac 100644 --- a/apps/init.cpp +++ b/apps/init.cpp @@ -279,7 +279,7 @@ static void mount_devfs() { if (mkdir("/dev", 0755) < 0 && errno != EEXIST) exit(255); - if (mount("/dev", "devfs") < 0) exit(255); + if (mount("/dev", "devfs", "devfs") < 0) exit(255); } int main() diff --git a/apps/mount.cpp b/apps/mount.cpp index b5762219..1f9b48c0 100644 --- a/apps/mount.cpp +++ b/apps/mount.cpp @@ -6,15 +6,17 @@ Result luna_main(int argc, char** argv) { StringView target; StringView fstype { "auto" }; + StringView source; os::ArgumentParser parser; parser.add_description("Mount a file system."); parser.add_system_program_info("mount"_sv); parser.add_positional_argument(target, "mountpoint"_sv, true); + parser.add_positional_argument(source, "source"_sv, true); parser.add_value_argument(fstype, 't', "type"_sv, "the file system type to use"); parser.parse(argc, argv); - if (mount(target.chars(), fstype.chars()) < 0) + if (mount(target.chars(), fstype.chars(), source.chars()) < 0) { perror("mount"); return 1; diff --git a/initrd/sbin/mount-tmpfs b/initrd/sbin/mount-tmpfs index 7625ebd7..a86562e7 100644 --- a/initrd/sbin/mount-tmpfs +++ b/initrd/sbin/mount-tmpfs @@ -1,5 +1,5 @@ #!/bin/sh mkdir -p /tmp -mount -t tmpfs /tmp +mount -t tmpfs /tmp tmpfs chmod 1777 /tmp diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index eae441b3..31b8b940 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -47,6 +47,7 @@ set(SOURCES src/fs/GPT.cpp src/fs/tmpfs/FileSystem.cpp src/fs/tmpfs/Inode.cpp + src/fs/ext2/FileSystem.cpp src/fs/devices/DeviceRegistry.cpp src/fs/devices/NullDevice.cpp src/fs/devices/ZeroDevice.cpp diff --git a/kernel/src/fs/ext2/FileSystem.cpp b/kernel/src/fs/ext2/FileSystem.cpp index d77af270..b4cf7862 100644 --- a/kernel/src/fs/ext2/FileSystem.cpp +++ b/kernel/src/fs/ext2/FileSystem.cpp @@ -11,6 +11,7 @@ namespace Ext2 auto maybe_inode = m_inode_cache.try_get(inode); if (maybe_inode.has_value()) return maybe_inode.value(); + // TODO: Locate the inode's block group descriptor and find it in the block group's inode table. return err(ENOENT); } diff --git a/kernel/src/fs/ext2/FileSystem.h b/kernel/src/fs/ext2/FileSystem.h index 157edf2e..c6801f61 100644 --- a/kernel/src/fs/ext2/FileSystem.h +++ b/kernel/src/fs/ext2/FileSystem.h @@ -34,6 +34,7 @@ namespace Ext2 u32 major_version; u16 reserved_block_uid; u16 reserved_block_gid; + // TODO: Add extended superblock fields. u8 padding[1024 - 84]; }; diff --git a/kernel/src/sys/mount.cpp b/kernel/src/sys/mount.cpp index e9e6a6c5..b8e210a3 100644 --- a/kernel/src/sys/mount.cpp +++ b/kernel/src/sys/mount.cpp @@ -1,4 +1,5 @@ #include "fs/VFS.h" +#include "fs/ext2/FileSystem.h" #include "fs/tmpfs/FileSystem.h" #include "memory/MemoryManager.h" #include "sys/Syscall.h" @@ -8,15 +9,28 @@ 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(); 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->device_id(); + 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); diff --git a/libc/include/sys/mount.h b/libc/include/sys/mount.h index 2711e287..618e6cc9 100644 --- a/libc/include/sys/mount.h +++ b/libc/include/sys/mount.h @@ -9,7 +9,7 @@ extern "C" #endif /* Mount a file system on target. */ - int mount(const char* target, const char* fstype); + int mount(const char* target, const char* fstype, const char* source); /* Unmount the file system mounted on target. */ int umount(const char* target); diff --git a/libc/src/sys/mount.cpp b/libc/src/sys/mount.cpp index cf8384ee..99e2deb6 100644 --- a/libc/src/sys/mount.cpp +++ b/libc/src/sys/mount.cpp @@ -5,9 +5,9 @@ extern "C" { - int mount(const char* target, const char* fstype) + int mount(const char* target, const char* fstype, const char* source) { - long rc = syscall(SYS_mount, target, fstype); + long rc = syscall(SYS_mount, target, fstype, source); __errno_return(rc, int); } diff --git a/libluna/include/luna/SharedPtr.h b/libluna/include/luna/SharedPtr.h index 020c37a5..a71f372c 100644 --- a/libluna/include/luna/SharedPtr.h +++ b/libluna/include/luna/SharedPtr.h @@ -1,6 +1,7 @@ #pragma once #include #include +#include #include #include #include @@ -84,6 +85,11 @@ template class SharedPtr return *this; } + bool operator==(const SharedPtr& other) + { + return m_ptr == other.m_ptr && m_ref_count == other.m_ref_count; + } + T* ptr() const { return m_ptr;