Kernel: Make Ext2 filesystem use BlockDevice instead of Partition
This commit is contained in:
parent
7a8fd6d04a
commit
bc5e8add19
|
@ -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;
|
||||||
|
|
|
@ -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()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue