Kernel: Make Ext2 filesystem use BlockDevice instead of Partition

This commit is contained in:
Bananymous 2023-11-21 15:20:24 +02:00
parent 7a8fd6d04a
commit bc5e8add19
3 changed files with 26 additions and 23 deletions

View File

@ -1,7 +1,7 @@
#pragma once
#include <BAN/HashMap.h>
#include <kernel/Storage/Partition.h>
#include <kernel/Device/Device.h>
#include <kernel/FS/FileSystem.h>
#include <kernel/FS/Ext2/Inode.h>
@ -45,13 +45,13 @@ namespace Kernel
};
public:
static BAN::ErrorOr<Ext2FS*> create(Partition&);
static BAN::ErrorOr<Ext2FS*> create(BAN::RefPtr<BlockDevice>);
virtual BAN::RefPtr<Inode> root_inode() override { return m_root_inode; }
private:
Ext2FS(Partition& partition)
: m_partition(partition)
Ext2FS(BAN::RefPtr<BlockDevice> block_device)
: m_block_device(block_device)
{}
BAN::ErrorOr<void> initialize_superblock();
@ -106,7 +106,7 @@ namespace Kernel
private:
RecursiveSpinLock m_lock;
Partition& m_partition;
BAN::RefPtr<BlockDevice> m_block_device;
BAN::RefPtr<Inode> m_root_inode;
BAN::Vector<uint32_t> m_superblock_backups;

View File

@ -9,9 +9,9 @@
namespace Kernel
{
BAN::ErrorOr<Ext2FS*> Ext2FS::create(Partition& partition)
BAN::ErrorOr<Ext2FS*> Ext2FS::create(BAN::RefPtr<BlockDevice> block_device)
{
Ext2FS* ext2fs = new Ext2FS(partition);
Ext2FS* ext2fs = new Ext2FS(block_device);
if (ext2fs == nullptr)
return BAN::Error::from_errno(ENOMEM);
BAN::ScopeGuard guard([ext2fs] { delete ext2fs; });
@ -25,7 +25,7 @@ namespace Kernel
{
// Read superblock from disk
{
const uint32_t sector_size = m_partition.device().sector_size();
const uint32_t sector_size = m_block_device->blksize();
ASSERT(1024 % sector_size == 0);
const uint32_t lba = 1024 / sector_size;
@ -34,7 +34,7 @@ namespace Kernel
BAN::Vector<uint8_t> superblock_buffer;
TRY(superblock_buffer.resize(sector_count * sector_size));
TRY(m_partition.read_sectors(lba, sector_count, superblock_buffer.span()));
TRY(m_block_device->read_blocks(lba, sector_count, superblock_buffer.span()));
memcpy(&m_superblock, superblock_buffer.data(), sizeof(Ext2::Superblock));
}
@ -272,35 +272,35 @@ namespace Kernel
{
LockGuard _(m_lock);
const uint32_t sector_size = m_partition.device().sector_size();
const uint32_t sector_size = m_block_device->blksize();
const uint32_t block_size = this->block_size();
const uint32_t sectors_per_block = block_size / sector_size;
const uint32_t sectors_before = 2048 / sector_size;
ASSERT(block >= 2);
ASSERT(buffer.size() >= block_size);
MUST(m_partition.read_sectors(sectors_before + (block - 2) * sectors_per_block, sectors_per_block, buffer.span()));
MUST(m_block_device->read_blocks(sectors_before + (block - 2) * sectors_per_block, sectors_per_block, buffer.span()));
}
void Ext2FS::write_block(uint32_t block, const BlockBufferWrapper& buffer)
{
LockGuard _(m_lock);
const uint32_t sector_size = m_partition.device().sector_size();
const uint32_t sector_size = m_block_device->blksize();
const uint32_t block_size = this->block_size();
const uint32_t sectors_per_block = block_size / sector_size;
const uint32_t sectors_before = 2048 / sector_size;
ASSERT(block >= 2);
ASSERT(buffer.size() >= block_size);
MUST(m_partition.write_sectors(sectors_before + (block - 2) * sectors_per_block, sectors_per_block, buffer.span()));
MUST(m_block_device->write_blocks(sectors_before + (block - 2) * sectors_per_block, sectors_per_block, buffer.span()));
}
void Ext2FS::sync_superblock()
{
LockGuard _(m_lock);
const uint32_t sector_size = m_partition.device().sector_size();
const uint32_t sector_size = m_block_device->blksize();
ASSERT(1024 % sector_size == 0);
const uint32_t superblock_bytes =
@ -313,11 +313,11 @@ namespace Kernel
auto superblock_buffer = get_block_buffer();
MUST(m_partition.read_sectors(lba, sector_count, superblock_buffer.span()));
MUST(m_block_device->read_blocks(lba, sector_count, superblock_buffer.span()));
if (memcmp(superblock_buffer.data(), &m_superblock, superblock_bytes))
{
memcpy(superblock_buffer.data(), &m_superblock, superblock_bytes);
MUST(m_partition.write_sectors(lba, sector_count, superblock_buffer.span()));
MUST(m_block_device->write_blocks(lba, sector_count, superblock_buffer.span()));
}
}

View File

@ -23,7 +23,9 @@ namespace Kernel
root = root.substring(5);
auto partition_inode = MUST(DevFileSystem::get().root_inode()->find_inode(root));
s_instance->m_root_fs = MUST(Ext2FS::create(*(Partition*)partition_inode.ptr()));
if (!partition_inode->is_device() || !reinterpret_cast<Device*>(partition_inode.ptr())->is_partition())
Kernel::panic("Specified root '/dev/{}' does not name a partition", root);
s_instance->m_root_fs = MUST(Ext2FS::create(reinterpret_cast<BlockDevice*>(partition_inode.ptr())));
Credentials root_creds { 0, 0, 0, 0 };
MUST(s_instance->mount(root_creds, &DevFileSystem::get(), "/dev"sv));
@ -40,17 +42,18 @@ namespace Kernel
return *s_instance;
}
BAN::ErrorOr<void> VirtualFileSystem::mount(const Credentials& credentials, BAN::StringView partition, BAN::StringView target)
BAN::ErrorOr<void> VirtualFileSystem::mount(const Credentials& credentials, BAN::StringView block_device_path, BAN::StringView target)
{
auto partition_file = TRY(file_from_absolute_path(credentials, partition, true));
if (!partition_file.inode->is_device())
auto block_device_file = TRY(file_from_absolute_path(credentials, block_device_path, true));
if (!block_device_file.inode->is_device())
return BAN::Error::from_errno(ENOTBLK);
Device* device = (Device*)partition_file.inode.ptr();
if (!device->is_partition())
auto* device = reinterpret_cast<Device*>(block_device_file.inode.ptr());
if (!device->mode().ifblk())
return BAN::Error::from_errno(ENOTBLK);
auto* file_system = TRY(Ext2FS::create(*(Partition*)device));
auto* block_device = reinterpret_cast<BlockDevice*>(device);
auto* file_system = TRY(Ext2FS::create(block_device));
return mount(credentials, file_system, target);
}