kernel: Add a registry for file system implementations

This commit is contained in:
apio 2023-10-23 22:47:49 +02:00
parent ba4e807f8e
commit 9c65dba412
Signed by: apio
GPG Key ID: B8A7D06E42258954
5 changed files with 172 additions and 10 deletions

View File

@ -57,6 +57,7 @@ set(SOURCES
src/fs/GPT.cpp
src/fs/StorageCache.cpp
src/fs/OpenFileDescription.cpp
src/fs/FSRegistry.cpp
src/net/UnixSocket.cpp
src/fs/tmpfs/FileSystem.cpp
src/fs/tmpfs/Inode.cpp
@ -119,7 +120,7 @@ target_link_libraries(moon luna-freestanding)
target_compile_definitions(moon PRIVATE IN_MOON)
target_compile_options(moon PRIVATE ${COMMON_FLAGS})
target_compile_options(moon PRIVATE -nostdlib -mcmodel=kernel -ffreestanding)
target_compile_options(moon PRIVATE -nostdlib -mcmodel=kernel -ffreestanding -fno-threadsafe-statics)
if("${LUNA_ARCH}" MATCHES "x86_64")
target_compile_options(moon PRIVATE -mno-red-zone)

View File

@ -0,0 +1,96 @@
/**
* @file FSRegistry.cpp
* @author apio (cloudapio.eu)
* @brief Kernel registry of available file system implementations.
*
* @copyright Copyright (c) 2023, the Luna authors.
*
*/
#include "fs/FSRegistry.h"
#include "fs/devpts/FileSystem.h"
#include "fs/ext2/FileSystem.h"
#include "fs/tmpfs/FileSystem.h"
#include "lib/Mutex.h"
struct VirtualFileSystemDescriptor
{
StringView name;
VirtualFileSystemFactoryFunction factory_function;
};
struct PhysicalFileSystemDescriptor
{
StringView name;
PhysicalFileSystemFactoryFunction factory_function;
};
Vector<VirtualFileSystemDescriptor> g_virtual_filesystems;
Vector<PhysicalFileSystemDescriptor> g_physical_filesystems;
static Mutex g_lock;
namespace FSRegistry
{
Result<void> init()
{
TRY(register_virtual_filesystem(TmpFS::FileSystem::create, "tmpfs"));
TRY(register_virtual_filesystem(DevPTS::FileSystem::create, "devpts"));
TRY(register_virtual_filesystem(DeviceRegistry::create_devfs_instance, "devfs"));
TRY(register_physical_filesystem(Ext2::FileSystem::create, "ext2"));
return {};
}
Result<void> register_virtual_filesystem(VirtualFileSystemFactoryFunction factory_function, StringView name)
{
ScopedMutexLock lock(g_lock);
for (const auto& descriptor : g_virtual_filesystems)
{
if (descriptor.name == name) return err(EEXIST);
}
auto descriptor = VirtualFileSystemDescriptor { .name = name, .factory_function = factory_function };
return g_virtual_filesystems.try_append(move(descriptor));
}
Result<void> register_physical_filesystem(PhysicalFileSystemFactoryFunction factory_function, StringView name)
{
ScopedMutexLock lock(g_lock);
for (const auto& descriptor : g_physical_filesystems)
{
if (descriptor.name == name) return err(EEXIST);
}
auto descriptor = PhysicalFileSystemDescriptor { .name = name, .factory_function = factory_function };
return g_physical_filesystems.try_append(move(descriptor));
}
Result<VirtualFileSystemFactoryFunction> lookup_virtual_filesystem(StringView name)
{
ScopedMutexLock lock(g_lock);
for (const auto& descriptor : g_virtual_filesystems)
{
if (descriptor.name == name) return descriptor.factory_function;
}
return err(ENODEV);
}
Result<PhysicalFileSystemFactoryFunction> lookup_physical_filesystem(StringView name)
{
ScopedMutexLock lock(g_lock);
for (const auto& descriptor : g_physical_filesystems)
{
if (descriptor.name == name) return descriptor.factory_function;
}
return err(ENODEV);
}
}

View File

@ -0,0 +1,62 @@
/**
* @file FSRegistry.h
* @author apio (cloudapio.eu)
* @brief Kernel registry of available file system implementations.
*
* @copyright Copyright (c) 2023, the Luna authors.
*
*/
#pragma once
#include "fs/VFS.h"
#include "fs/devices/Device.h"
typedef Result<SharedPtr<VFS::FileSystem>> (*VirtualFileSystemFactoryFunction)(void);
typedef Result<SharedPtr<VFS::FileSystem>> (*PhysicalFileSystemFactoryFunction)(SharedPtr<Device>);
namespace FSRegistry
{
/**
* @brief Register the built-in file system implementations.
*
* @return Result<void> Whether the operation succeeded.
*/
Result<void> init();
/**
* @brief Register a "virtual" (in-memory) file system implementation, associating a name to it.
*
* @param factory_function The factory function to use to create new instances of this file system.
* @param name The name to associate with this file system implementation.
* @return Result<void> Whether the operation succeeded.
*/
Result<void> register_virtual_filesystem(VirtualFileSystemFactoryFunction factory_function, StringView name);
/**
* @brief Register a "physical" (mounted from a device) file system implementation, associating a name
* to it.
*
* @param factory_function The factory function to use to create new instances of this file system.
* @param name The name to associate with this file system implementation.
* @return Result<void> Whether the operation succeeded.
*/
Result<void> register_physical_filesystem(PhysicalFileSystemFactoryFunction factory_function, StringView name);
/**
* @brief Find a "virtual" (in-memory) file system implementation by name.
*
* @param name The name to look for.
* @return Result<VirtualFileSystemFactoryFunction> An error, or the factory function to create file systems of this
* type.
*/
Result<VirtualFileSystemFactoryFunction> lookup_virtual_filesystem(StringView name);
/**
* @brief Find a "physical" (mounted from a device) file system implementation by name.
*
* @param name The name to look for.
* @return Result<PhysicalFileSystemFactoryFunction> An error, or the factory function to create file systems of
* this type.
*/
Result<PhysicalFileSystemFactoryFunction> lookup_physical_filesystem(StringView name);
}

View File

@ -5,6 +5,7 @@
#include "binfmt/BinaryFormat.h"
#include "boot/Init.h"
#include "config.h"
#include "fs/FSRegistry.h"
#include "fs/InitRD.h"
#include "fs/devices/DeviceRegistry.h"
#include "fs/devices/PTYMultiplexer.h"
@ -62,6 +63,7 @@ void oom_thread()
mark_critical(DeviceRegistry::init(), "Failed to register initial devices");
mark_critical(BinaryFormat::init(), "Failed to register initial binary formats");
mark_critical(FSRegistry::init(), "Failed to register initial file systems");
auto init =
mark_critical(VFS::resolve_path("/bin/preinit", Credentials {}), "Can't find init in the initial ramfs!");

View File

@ -1,4 +1,5 @@
#include "Pledge.h"
#include "fs/FSRegistry.h"
#include "fs/VFS.h"
#include "fs/devpts/FileSystem.h"
#include "fs/ext2/FileSystem.h"
@ -26,18 +27,18 @@ Result<u64> sys_mount(Registers*, SyscallArgs args)
SharedPtr<VFS::FileSystem> fs;
if (fstype.view() == "tmpfs") fs = TRY(TmpFS::FileSystem::create());
else if (fstype.view() == "devpts")
fs = TRY(DevPTS::FileSystem::create());
else if (fstype.view() == "devfs")
fs = TRY(DeviceRegistry::create_devfs_instance());
else if (fstype.view() == "ext2")
auto maybe_virtual = FSRegistry::lookup_virtual_filesystem(fstype.view());
if (maybe_virtual.has_value())
{
auto source_device = TRY(get_source());
fs = TRY(Ext2::FileSystem::create(source_device));
auto factory = maybe_virtual.release_value();
fs = TRY(factory());
}
else
return err(ENODEV);
{
auto factory = TRY(FSRegistry::lookup_physical_filesystem(fstype.view()));
auto device = TRY(get_source());
fs = TRY(factory(device));
}
TRY(VFS::mount(target.chars(), fs, current->auth, current->current_directory));