kernel: Add a registry for file system implementations
This commit is contained in:
parent
ba4e807f8e
commit
9c65dba412
@ -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)
|
||||
|
96
kernel/src/fs/FSRegistry.cpp
Normal file
96
kernel/src/fs/FSRegistry.cpp
Normal 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);
|
||||
}
|
||||
}
|
62
kernel/src/fs/FSRegistry.h
Normal file
62
kernel/src/fs/FSRegistry.h
Normal 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);
|
||||
}
|
@ -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!");
|
||||
|
@ -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));
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user