Kernel: Start work on adding support for new filesystems
Old code tried to create ext2 filesystem from all devices.
This commit is contained in:
parent
d4903caafa
commit
766439db6d
|
@ -32,6 +32,7 @@ set(KERNEL_SOURCES
|
||||||
kernel/FS/DevFS/FileSystem.cpp
|
kernel/FS/DevFS/FileSystem.cpp
|
||||||
kernel/FS/Ext2/FileSystem.cpp
|
kernel/FS/Ext2/FileSystem.cpp
|
||||||
kernel/FS/Ext2/Inode.cpp
|
kernel/FS/Ext2/Inode.cpp
|
||||||
|
kernel/FS/FileSystem.cpp
|
||||||
kernel/FS/Inode.cpp
|
kernel/FS/Inode.cpp
|
||||||
kernel/FS/Pipe.cpp
|
kernel/FS/Pipe.cpp
|
||||||
kernel/FS/ProcFS/FileSystem.cpp
|
kernel/FS/ProcFS/FileSystem.cpp
|
||||||
|
|
|
@ -45,7 +45,8 @@ namespace Kernel
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static BAN::ErrorOr<Ext2FS*> create(BAN::RefPtr<BlockDevice>);
|
static BAN::ErrorOr<bool> probe(BAN::RefPtr<BlockDevice>);
|
||||||
|
static BAN::ErrorOr<BAN::RefPtr<Ext2FS>> create(BAN::RefPtr<BlockDevice>);
|
||||||
|
|
||||||
virtual BAN::RefPtr<Inode> root_inode() override { return m_root_inode; }
|
virtual BAN::RefPtr<Inode> root_inode() override { return m_root_inode; }
|
||||||
|
|
||||||
|
@ -120,6 +121,7 @@ namespace Kernel
|
||||||
Ext2::Superblock m_superblock;
|
Ext2::Superblock m_superblock;
|
||||||
|
|
||||||
friend class Ext2Inode;
|
friend class Ext2Inode;
|
||||||
|
friend class BAN::RefPtr<Ext2FS>;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,18 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <kernel/Device/Device.h>
|
||||||
#include <kernel/FS/Inode.h>
|
#include <kernel/FS/Inode.h>
|
||||||
|
|
||||||
namespace Kernel
|
namespace Kernel
|
||||||
{
|
{
|
||||||
|
|
||||||
class FileSystem
|
class FileSystem : public BAN::RefCounted<FileSystem>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~FileSystem() {}
|
virtual ~FileSystem() {}
|
||||||
|
|
||||||
|
static BAN::ErrorOr<BAN::RefPtr<FileSystem>> from_block_device(BAN::RefPtr<BlockDevice>);
|
||||||
|
|
||||||
virtual BAN::RefPtr<Inode> root_inode() = 0;
|
virtual BAN::RefPtr<Inode> root_inode() = 0;
|
||||||
|
|
||||||
virtual dev_t dev() const = 0;
|
virtual dev_t dev() const = 0;
|
||||||
|
|
|
@ -13,7 +13,6 @@ namespace Kernel
|
||||||
public:
|
public:
|
||||||
static void initialize(BAN::StringView);
|
static void initialize(BAN::StringView);
|
||||||
static VirtualFileSystem& get();
|
static VirtualFileSystem& get();
|
||||||
virtual ~VirtualFileSystem() {};
|
|
||||||
|
|
||||||
virtual BAN::RefPtr<Inode> root_inode() override { return m_root_fs->root_inode(); }
|
virtual BAN::RefPtr<Inode> root_inode() override { return m_root_fs->root_inode(); }
|
||||||
|
|
||||||
|
@ -21,7 +20,7 @@ namespace Kernel
|
||||||
virtual dev_t dev() const override { return 0; }
|
virtual dev_t dev() const override { return 0; }
|
||||||
|
|
||||||
BAN::ErrorOr<void> mount(const Credentials&, BAN::StringView, BAN::StringView);
|
BAN::ErrorOr<void> mount(const Credentials&, BAN::StringView, BAN::StringView);
|
||||||
BAN::ErrorOr<void> mount(const Credentials&, FileSystem*, BAN::StringView);
|
BAN::ErrorOr<void> mount(const Credentials&, BAN::RefPtr<FileSystem>, BAN::StringView);
|
||||||
|
|
||||||
struct File
|
struct File
|
||||||
{
|
{
|
||||||
|
@ -35,16 +34,18 @@ namespace Kernel
|
||||||
|
|
||||||
struct MountPoint
|
struct MountPoint
|
||||||
{
|
{
|
||||||
|
BAN::RefPtr<FileSystem> target;
|
||||||
File host;
|
File host;
|
||||||
FileSystem* target;
|
|
||||||
};
|
};
|
||||||
MountPoint* mount_from_host_inode(BAN::RefPtr<Inode>);
|
MountPoint* mount_from_host_inode(BAN::RefPtr<Inode>);
|
||||||
MountPoint* mount_from_root_inode(BAN::RefPtr<Inode>);
|
MountPoint* mount_from_root_inode(BAN::RefPtr<Inode>);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Mutex m_mutex;
|
Mutex m_mutex;
|
||||||
FileSystem* m_root_fs = nullptr;
|
BAN::RefPtr<FileSystem> m_root_fs;
|
||||||
BAN::Vector<MountPoint> m_mount_points;
|
BAN::Vector<MountPoint> m_mount_points;
|
||||||
|
|
||||||
|
friend class BAN::RefPtr<VirtualFileSystem>;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,15 +9,34 @@
|
||||||
namespace Kernel
|
namespace Kernel
|
||||||
{
|
{
|
||||||
|
|
||||||
BAN::ErrorOr<Ext2FS*> Ext2FS::create(BAN::RefPtr<BlockDevice> block_device)
|
BAN::ErrorOr<bool> Ext2FS::probe(BAN::RefPtr<BlockDevice> block_device)
|
||||||
{
|
{
|
||||||
Ext2FS* ext2fs = new Ext2FS(block_device);
|
Ext2::Superblock superblock;
|
||||||
if (ext2fs == nullptr)
|
|
||||||
return BAN::Error::from_errno(ENOMEM);
|
// Read superblock from disk
|
||||||
BAN::ScopeGuard guard([ext2fs] { delete ext2fs; });
|
{
|
||||||
|
const uint32_t sector_size = block_device->blksize();
|
||||||
|
ASSERT(1024 % sector_size == 0);
|
||||||
|
|
||||||
|
const uint32_t lba = 1024 / sector_size;
|
||||||
|
const uint32_t sector_count = BAN::Math::div_round_up<uint32_t>(sizeof(Ext2::Superblock), sector_size);
|
||||||
|
|
||||||
|
BAN::Vector<uint8_t> superblock_buffer;
|
||||||
|
TRY(superblock_buffer.resize(sector_count * sector_size));
|
||||||
|
|
||||||
|
TRY(block_device->read_blocks(lba, sector_count, BAN::ByteSpan(superblock_buffer.span())));
|
||||||
|
|
||||||
|
memcpy(&superblock, superblock_buffer.data(), sizeof(Ext2::Superblock));
|
||||||
|
}
|
||||||
|
|
||||||
|
return superblock.magic == Ext2::Enum::SUPER_MAGIC;
|
||||||
|
}
|
||||||
|
|
||||||
|
BAN::ErrorOr<BAN::RefPtr<Ext2FS>> Ext2FS::create(BAN::RefPtr<BlockDevice> block_device)
|
||||||
|
{
|
||||||
|
auto ext2fs = TRY(BAN::RefPtr<Ext2FS>::create(block_device));
|
||||||
TRY(ext2fs->initialize_superblock());
|
TRY(ext2fs->initialize_superblock());
|
||||||
TRY(ext2fs->initialize_root_inode());
|
TRY(ext2fs->initialize_root_inode());
|
||||||
guard.disable();
|
|
||||||
return ext2fs;
|
return ext2fs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
#include <kernel/FS/Ext2/FileSystem.h>
|
||||||
|
#include <kernel/FS/FileSystem.h>
|
||||||
|
|
||||||
|
namespace Kernel
|
||||||
|
{
|
||||||
|
|
||||||
|
BAN::ErrorOr<BAN::RefPtr<FileSystem>> FileSystem::from_block_device(BAN::RefPtr<BlockDevice> block_device)
|
||||||
|
{
|
||||||
|
if (auto res = Ext2FS::probe(block_device); !res.is_error() && res.value())
|
||||||
|
return BAN::RefPtr<FileSystem>(TRY(Ext2FS::create(block_device)));
|
||||||
|
dprintln("Unsupported filesystem");
|
||||||
|
return BAN::Error::from_errno(ENOTSUP);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,7 +1,6 @@
|
||||||
#include <BAN/ScopeGuard.h>
|
#include <BAN/ScopeGuard.h>
|
||||||
#include <BAN/StringView.h>
|
#include <BAN/StringView.h>
|
||||||
#include <kernel/FS/DevFS/FileSystem.h>
|
#include <kernel/FS/DevFS/FileSystem.h>
|
||||||
#include <kernel/FS/Ext2/FileSystem.h>
|
|
||||||
#include <kernel/FS/ProcFS/FileSystem.h>
|
#include <kernel/FS/ProcFS/FileSystem.h>
|
||||||
#include <kernel/FS/TmpFS/FileSystem.h>
|
#include <kernel/FS/TmpFS/FileSystem.h>
|
||||||
#include <kernel/FS/VirtualFileSystem.h>
|
#include <kernel/FS/VirtualFileSystem.h>
|
||||||
|
@ -11,13 +10,12 @@
|
||||||
namespace Kernel
|
namespace Kernel
|
||||||
{
|
{
|
||||||
|
|
||||||
static VirtualFileSystem* s_instance = nullptr;
|
static BAN::RefPtr<VirtualFileSystem> s_instance;
|
||||||
|
|
||||||
void VirtualFileSystem::initialize(BAN::StringView root)
|
void VirtualFileSystem::initialize(BAN::StringView root)
|
||||||
{
|
{
|
||||||
ASSERT(s_instance == nullptr);
|
ASSERT(!s_instance);
|
||||||
s_instance = new VirtualFileSystem();
|
s_instance = MUST(BAN::RefPtr<VirtualFileSystem>::create());
|
||||||
ASSERT(s_instance);
|
|
||||||
|
|
||||||
ASSERT(root.size() >= 5 && root.substring(0, 5) == "/dev/"sv);;
|
ASSERT(root.size() >= 5 && root.substring(0, 5) == "/dev/"sv);;
|
||||||
root = root.substring(5);
|
root = root.substring(5);
|
||||||
|
@ -25,14 +23,14 @@ namespace Kernel
|
||||||
auto partition_inode = MUST(DevFileSystem::get().root_inode()->find_inode(root));
|
auto partition_inode = MUST(DevFileSystem::get().root_inode()->find_inode(root));
|
||||||
if (!partition_inode->is_device() || !static_cast<Device*>(partition_inode.ptr())->is_partition())
|
if (!partition_inode->is_device() || !static_cast<Device*>(partition_inode.ptr())->is_partition())
|
||||||
Kernel::panic("Specified root '/dev/{}' does not name a partition", root);
|
Kernel::panic("Specified root '/dev/{}' does not name a partition", root);
|
||||||
s_instance->m_root_fs = MUST(Ext2FS::create(static_cast<BlockDevice*>(partition_inode.ptr())));
|
s_instance->m_root_fs = MUST(FileSystem::from_block_device(static_cast<BlockDevice*>(partition_inode.ptr())));
|
||||||
|
|
||||||
Credentials root_creds { 0, 0, 0, 0 };
|
Credentials root_creds { 0, 0, 0, 0 };
|
||||||
MUST(s_instance->mount(root_creds, &DevFileSystem::get(), "/dev"sv));
|
MUST(s_instance->mount(root_creds, &DevFileSystem::get(), "/dev"sv));
|
||||||
|
|
||||||
MUST(s_instance->mount(root_creds, &ProcFileSystem::get(), "/proc"sv));
|
MUST(s_instance->mount(root_creds, &ProcFileSystem::get(), "/proc"sv));
|
||||||
|
|
||||||
auto* tmpfs = MUST(TmpFileSystem::create(1024, 0777, 0, 0));
|
auto tmpfs = MUST(TmpFileSystem::create(1024, 0777, 0, 0));
|
||||||
MUST(s_instance->mount(root_creds, tmpfs, "/tmp"sv));
|
MUST(s_instance->mount(root_creds, tmpfs, "/tmp"sv));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,19 +50,18 @@ namespace Kernel
|
||||||
if (!device->mode().ifblk())
|
if (!device->mode().ifblk())
|
||||||
return BAN::Error::from_errno(ENOTBLK);
|
return BAN::Error::from_errno(ENOTBLK);
|
||||||
|
|
||||||
auto* block_device = static_cast<BlockDevice*>(device);
|
auto file_system = TRY(FileSystem::from_block_device(static_cast<BlockDevice*>(device)));
|
||||||
auto* file_system = TRY(Ext2FS::create(block_device));
|
|
||||||
return mount(credentials, file_system, target);
|
return mount(credentials, file_system, target);
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<void> VirtualFileSystem::mount(const Credentials& credentials, FileSystem* file_system, BAN::StringView path)
|
BAN::ErrorOr<void> VirtualFileSystem::mount(const Credentials& credentials, BAN::RefPtr<FileSystem> file_system, BAN::StringView path)
|
||||||
{
|
{
|
||||||
auto file = TRY(file_from_absolute_path(credentials, path, true));
|
auto file = TRY(file_from_absolute_path(credentials, path, true));
|
||||||
if (!file.inode->mode().ifdir())
|
if (!file.inode->mode().ifdir())
|
||||||
return BAN::Error::from_errno(ENOTDIR);
|
return BAN::Error::from_errno(ENOTDIR);
|
||||||
|
|
||||||
LockGuard _(m_mutex);
|
LockGuard _(m_mutex);
|
||||||
TRY(m_mount_points.push_back({ file, file_system }));
|
TRY(m_mount_points.push_back({ file_system, file }));
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue