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

View File

@ -9,9 +9,9 @@
namespace Kernel 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) if (ext2fs == nullptr)
return BAN::Error::from_errno(ENOMEM); return BAN::Error::from_errno(ENOMEM);
BAN::ScopeGuard guard([ext2fs] { delete ext2fs; }); BAN::ScopeGuard guard([ext2fs] { delete ext2fs; });
@ -25,7 +25,7 @@ namespace Kernel
{ {
// Read superblock from disk // 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); ASSERT(1024 % sector_size == 0);
const uint32_t lba = 1024 / sector_size; const uint32_t lba = 1024 / sector_size;
@ -34,7 +34,7 @@ namespace Kernel
BAN::Vector<uint8_t> superblock_buffer; BAN::Vector<uint8_t> superblock_buffer;
TRY(superblock_buffer.resize(sector_count * sector_size)); 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)); memcpy(&m_superblock, superblock_buffer.data(), sizeof(Ext2::Superblock));
} }
@ -272,35 +272,35 @@ namespace Kernel
{ {
LockGuard _(m_lock); 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 block_size = this->block_size();
const uint32_t sectors_per_block = block_size / sector_size; const uint32_t sectors_per_block = block_size / sector_size;
const uint32_t sectors_before = 2048 / sector_size; const uint32_t sectors_before = 2048 / sector_size;
ASSERT(block >= 2); ASSERT(block >= 2);
ASSERT(buffer.size() >= block_size); 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) void Ext2FS::write_block(uint32_t block, const BlockBufferWrapper& buffer)
{ {
LockGuard _(m_lock); 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 block_size = this->block_size();
const uint32_t sectors_per_block = block_size / sector_size; const uint32_t sectors_per_block = block_size / sector_size;
const uint32_t sectors_before = 2048 / sector_size; const uint32_t sectors_before = 2048 / sector_size;
ASSERT(block >= 2); ASSERT(block >= 2);
ASSERT(buffer.size() >= block_size); 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() void Ext2FS::sync_superblock()
{ {
LockGuard _(m_lock); 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); ASSERT(1024 % sector_size == 0);
const uint32_t superblock_bytes = const uint32_t superblock_bytes =
@ -313,11 +313,11 @@ namespace Kernel
auto superblock_buffer = get_block_buffer(); 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)) if (memcmp(superblock_buffer.data(), &m_superblock, superblock_bytes))
{ {
memcpy(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); root = root.substring(5);
auto partition_inode = MUST(DevFileSystem::get().root_inode()->find_inode(root)); 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 }; 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));
@ -40,17 +42,18 @@ namespace Kernel
return *s_instance; 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)); auto block_device_file = TRY(file_from_absolute_path(credentials, block_device_path, true));
if (!partition_file.inode->is_device()) if (!block_device_file.inode->is_device())
return BAN::Error::from_errno(ENOTBLK); return BAN::Error::from_errno(ENOTBLK);
Device* device = (Device*)partition_file.inode.ptr(); auto* device = reinterpret_cast<Device*>(block_device_file.inode.ptr());
if (!device->is_partition()) if (!device->mode().ifblk())
return BAN::Error::from_errno(ENOTBLK); 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); return mount(credentials, file_system, target);
} }