[victoriafalls] Move the block to lba translation to a small wrapper.

Abstract this away into a thin wrapper over the denali client such that
it can be called from other helper classes.
This commit is contained in:
Drew Galbraith 2023-07-05 23:19:25 -07:00
parent a49d13f1d1
commit 21c1a001ea
6 changed files with 83 additions and 35 deletions

View File

@ -1,4 +1,5 @@
add_executable(victoriafalls
fs/ext2/ext2_block_reader.cpp
fs/ext2/ext2_driver.cpp
victoriafalls.cpp)

View File

@ -0,0 +1,32 @@
#include "fs/ext2/ext2_block_reader.h"
glcr::ErrorOr<Ext2BlockReader> Ext2BlockReader::Init(
ScopedDenaliClient&& denali) {
// Read 1024 bytes from 1024 offset.
// FIXME: Don't assume 512 byte sectors somehow.
ASSIGN_OR_RETURN(MappedMemoryRegion superblock, denali.ReadSectors(2, 2));
return Ext2BlockReader(glcr::Move(denali), superblock);
}
Superblock* Ext2BlockReader::GetSuperblock() {
return reinterpret_cast<Superblock*>(super_block_region_.vaddr());
}
uint64_t Ext2BlockReader::SectorsPerBlock() {
return 1 << (GetSuperblock()->log_block_size + 1);
}
glcr::ErrorOr<MappedMemoryRegion> Ext2BlockReader::ReadBlock(
uint64_t block_number) {
return denali_.ReadSectors(block_number * SectorsPerBlock(),
SectorsPerBlock());
}
glcr::ErrorOr<MappedMemoryRegion> Ext2BlockReader::ReadBlocks(
uint64_t block_number, uint64_t num_blocks) {
return denali_.ReadSectors(block_number * SectorsPerBlock(),
num_blocks * SectorsPerBlock());
}
Ext2BlockReader::Ext2BlockReader(ScopedDenaliClient&& denali,
MappedMemoryRegion super_block)
: denali_(glcr::Move(denali)), super_block_region_(super_block) {}

View File

@ -0,0 +1,25 @@
#pragma once
#include <denali/denali_client.h>
#include <glacier/status/error_or.h>
#include <mammoth/memory_region.h>
#include "fs/ext2/ext2.h"
class Ext2BlockReader {
public:
static glcr::ErrorOr<Ext2BlockReader> Init(ScopedDenaliClient&& denali);
Superblock* GetSuperblock();
uint64_t SectorsPerBlock();
glcr::ErrorOr<MappedMemoryRegion> ReadBlock(uint64_t block_number);
glcr::ErrorOr<MappedMemoryRegion> ReadBlocks(uint64_t block_number,
uint64_t num_blocks);
private:
ScopedDenaliClient denali_;
MappedMemoryRegion super_block_region_;
Ext2BlockReader(ScopedDenaliClient&& denali, MappedMemoryRegion super_block);
};

View File

@ -1,37 +1,38 @@
#include "fs/ext2/ext2_driver.h"
#include <mammoth/debug.h>
glcr::ErrorOr<Ext2Driver> Ext2Driver::Init(ScopedDenaliClient&& denali) {
ASSIGN_OR_RETURN(Ext2BlockReader reader,
Ext2BlockReader::Init(glcr::Move(denali)));
return Ext2Driver(glcr::Move(reader));
}
glcr::ErrorCode Ext2Driver::ProbePartition() {
// Read 1024 bytes from 1024 offset.
// FIXME: Don't assume 512 byte sectors somehow.
ASSIGN_OR_RETURN(MappedMemoryRegion superblock, denali_.ReadSectors(2, 2));
superblock_ = reinterpret_cast<Superblock*>(superblock.vaddr());
if (superblock_->magic != 0xEF53) {
Superblock* superblock = ext2_reader_.GetSuperblock();
if (superblock->magic != 0xEF53) {
dbgln("Invalid EXT2 magic code: %x");
return glcr::INVALID_ARGUMENT;
}
dbgln("Block size: 0x%x", 1024 << superblock_->log_block_size);
dbgln("Block size: 0x%x", 1024 << superblock->log_block_size);
dbgln("Blocks: 0x%x (0x%x per group)", superblock_->blocks_count,
superblock_->blocks_per_group);
dbgln("Inodes: 0x%x (0x%x per group)", superblock_->inodes_count,
superblock_->inodes_per_group);
dbgln("Blocks: 0x%x (0x%x per group)", superblock->blocks_count,
superblock->blocks_per_group);
dbgln("Inodes: 0x%x (0x%x per group)", superblock->inodes_count,
superblock->inodes_per_group);
dbgln("Mounts: 0x%x out of 0x%x", superblock_->mnt_count,
superblock_->max_mnt_count);
dbgln("State: %x", superblock_->state);
dbgln("Mounts: 0x%x out of 0x%x", superblock->mnt_count,
superblock->max_mnt_count);
dbgln("State: %x", superblock->state);
dbgln("Created by: %x", superblock_->creator_os);
dbgln("Created by: %x", superblock->creator_os);
uint64_t num_block_groups =
superblock_->blocks_count / superblock_->blocks_per_group;
superblock->blocks_count / superblock->blocks_per_group;
dbgln("\nReading %u blocks groups", num_block_groups);
uint64_t bgdt_bytes = sizeof(BlockGroupDescriptor) * num_block_groups;
uint64_t bgdt_block = (superblock_->log_block_size == 0) ? 2 : 1;
uint64_t bgdt_block = (superblock->log_block_size == 0) ? 2 : 1;
ASSIGN_OR_RETURN(MappedMemoryRegion bgdt,
ReadBlocks(bgdt_block, BytesToBlockCount(bgdt_bytes)));
ext2_reader_.ReadBlocks(bgdt_block, bgdt_bytes))
BlockGroupDescriptor* bgds =
reinterpret_cast<BlockGroupDescriptor*>(bgdt.vaddr());
@ -45,6 +46,5 @@ glcr::ErrorCode Ext2Driver::ProbePartition() {
dbgln("Free inodes: %x", bgds[i].free_inodes_count);
}
uint64_t root_inode = 2;
return glcr::OK;
}

View File

@ -4,26 +4,16 @@
#include <glacier/memory/move.h>
#include "fs/ext2/ext2.h"
#include "fs/ext2/ext2_block_reader.h"
class Ext2Driver {
public:
Ext2Driver(ScopedDenaliClient&& denali) : denali_(glcr::Move(denali)) {}
static glcr::ErrorOr<Ext2Driver> Init(ScopedDenaliClient&& denali);
glcr::ErrorCode ProbePartition();
glcr::ErrorOr<MappedMemoryRegion> ReadBlocks(uint64_t block_num,
uint64_t num_blocks) {
return denali_.ReadSectors(SectorsPerBlock() * block_num,
SectorsPerBlock() * num_blocks);
}
uint64_t SectorsPerBlock() { return 1 << (superblock_->log_block_size + 1); }
uint64_t BlockToLba(uint64_t block) { return block * SectorsPerBlock(); }
uint64_t BytesToBlockCount(uint64_t bytes) {
return (bytes - 1) / (1024 << superblock_->log_block_size) + 1;
}
private:
ScopedDenaliClient denali_;
Superblock* superblock_;
Ext2BlockReader ext2_reader_;
Ext2Driver(Ext2BlockReader&& reader) : ext2_reader_(glcr::Move(reader)) {}
};

View File

@ -11,7 +11,7 @@ uint64_t main(uint64_t init_cap) {
YellowstoneStub yellowstone(gInitEndpointCap);
ASSIGN_OR_RETURN(ScopedDenaliClient denali, yellowstone.GetDenali());
Ext2Driver ext2(glcr::Move(denali));
ASSIGN_OR_RETURN(Ext2Driver ext2, Ext2Driver::Init(glcr::Move(denali)));
check(ext2.ProbePartition());