diff --git a/sys/victoriafalls/fs/ext2/ext2_block_reader.cpp b/sys/victoriafalls/fs/ext2/ext2_block_reader.cpp index 06a0454..a128bbb 100644 --- a/sys/victoriafalls/fs/ext2/ext2_block_reader.cpp +++ b/sys/victoriafalls/fs/ext2/ext2_block_reader.cpp @@ -1,11 +1,12 @@ #include "fs/ext2/ext2_block_reader.h" -glcr::ErrorOr Ext2BlockReader::Init( +glcr::ErrorOr> 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); + return glcr::SharedPtr( + new Ext2BlockReader(glcr::Move(denali), superblock)); } Superblock* Ext2BlockReader::GetSuperblock() { diff --git a/sys/victoriafalls/fs/ext2/ext2_block_reader.h b/sys/victoriafalls/fs/ext2/ext2_block_reader.h index 2fb8347..f149d8d 100644 --- a/sys/victoriafalls/fs/ext2/ext2_block_reader.h +++ b/sys/victoriafalls/fs/ext2/ext2_block_reader.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include @@ -13,7 +14,8 @@ * */ class Ext2BlockReader { public: - static glcr::ErrorOr Init(ScopedDenaliClient&& denali); + static glcr::ErrorOr> Init( + ScopedDenaliClient&& denali); // TODO: Consider creating a new class wrapper with these computations. Superblock* GetSuperblock(); diff --git a/sys/victoriafalls/fs/ext2/ext2_driver.cpp b/sys/victoriafalls/fs/ext2/ext2_driver.cpp index 6a83d3c..68eeb3a 100644 --- a/sys/victoriafalls/fs/ext2/ext2_driver.cpp +++ b/sys/victoriafalls/fs/ext2/ext2_driver.cpp @@ -4,14 +4,21 @@ #include glcr::ErrorOr Ext2Driver::Init(ScopedDenaliClient&& denali) { - ASSIGN_OR_RETURN(Ext2BlockReader reader, + ASSIGN_OR_RETURN(glcr::SharedPtr reader, Ext2BlockReader::Init(glcr::Move(denali))); - Superblock* superblock = reader.GetSuperblock(); - return Ext2Driver(glcr::Move(reader)); + + ASSIGN_OR_RETURN( + MappedMemoryRegion bgdt, + reader->ReadBlocks(reader->BgdtBlockNum(), reader->BgdtBlockSize())); + BlockGroupDescriptor* bgds = + reinterpret_cast(bgdt.vaddr()); + glcr::UniquePtr inode_table(new InodeTable(reader, bgds)); + + return Ext2Driver(reader, glcr::Move(inode_table)); } glcr::ErrorCode Ext2Driver::ProbePartition() { - Superblock* superblock = ext2_reader_.GetSuperblock(); + Superblock* superblock = ext2_reader_->GetSuperblock(); if (superblock->magic != 0xEF53) { dbgln("Invalid EXT2 magic code: %x"); return glcr::INVALID_ARGUMENT; @@ -30,28 +37,11 @@ glcr::ErrorCode Ext2Driver::ProbePartition() { dbgln("Created by: %x", superblock->creator_os); - ASSIGN_OR_RETURN(MappedMemoryRegion bgdt, - ext2_reader_.ReadBlocks(ext2_reader_.BgdtBlockNum(), - ext2_reader_.BgdtBlockSize())); - BlockGroupDescriptor* bgds = - reinterpret_cast(bgdt.vaddr()); + return glcr::OK; +} - uint64_t num_block_groups = ext2_reader_.NumberOfBlockGroups(); - for (uint64_t i = 0; i < num_block_groups; i++) { - dbgln("BGD %x", i); - dbgln("Block Bitmap: %x", bgds[i].block_bitmap); - dbgln("Inode Bitmap: %x", bgds[i].inode_bitmap); - dbgln("Inode Table: %x", bgds[i].inode_table); - dbgln("Free blocks: %x", bgds[i].free_blocks_count); - dbgln("Free inodes: %x", bgds[i].free_inodes_count); - } - - // FIXME: Move this to initialization. - inode_table_ = - glcr::UniquePtr(new InodeTable(ext2_reader_, bgds)); - - ASSIGN_OR_RETURN(Inode * root, inode_table_->GetInode(2)); - return ProbeDirectory(root); +glcr::ErrorOr Ext2Driver::GetInode(uint32_t inode_number) { + return inode_table_->GetInode(inode_number); } glcr::ErrorCode Ext2Driver::ProbeDirectory(Inode* inode) { @@ -62,7 +52,7 @@ glcr::ErrorCode Ext2Driver::ProbeDirectory(Inode* inode) { // This calculation is cursed. uint64_t real_block_cnt = - (inode->blocks - 1) / (ext2_reader_.BlockSize() / 512) + 1; + (inode->blocks - 1) / (ext2_reader_->BlockSize() / 512) + 1; if (real_block_cnt > 12) { dbgln("Cant handle indirect blocks yet"); @@ -72,9 +62,9 @@ glcr::ErrorCode Ext2Driver::ProbeDirectory(Inode* inode) { for (uint64_t i = 0; i < real_block_cnt; i++) { dbgln("Getting block %lx", inode->block[i]); ASSIGN_OR_RETURN(MappedMemoryRegion block, - ext2_reader_.ReadBlock(inode->block[i])); + ext2_reader_->ReadBlock(inode->block[i])); uint64_t addr = block.vaddr(); - while (addr < block.vaddr() + ext2_reader_.BlockSize()) { + while (addr < block.vaddr() + ext2_reader_->BlockSize()) { DirEntry* entry = reinterpret_cast(addr); glcr::String name(entry->name, entry->name_len); switch (entry->file_type) { diff --git a/sys/victoriafalls/fs/ext2/ext2_driver.h b/sys/victoriafalls/fs/ext2/ext2_driver.h index c1f0ee4..77fe877 100644 --- a/sys/victoriafalls/fs/ext2/ext2_driver.h +++ b/sys/victoriafalls/fs/ext2/ext2_driver.h @@ -13,11 +13,14 @@ class Ext2Driver { glcr::ErrorCode ProbePartition(); + glcr::ErrorOr GetInode(uint32_t inode_number); glcr::ErrorCode ProbeDirectory(Inode* inode); private: - Ext2BlockReader ext2_reader_; + glcr::SharedPtr ext2_reader_; glcr::UniquePtr inode_table_; - Ext2Driver(Ext2BlockReader&& reader) : ext2_reader_(glcr::Move(reader)) {} + Ext2Driver(const glcr::SharedPtr& reader, + glcr::UniquePtr inode_table) + : ext2_reader_(reader), inode_table_(glcr::Move(inode_table)) {} }; diff --git a/sys/victoriafalls/fs/ext2/inode_table.cpp b/sys/victoriafalls/fs/ext2/inode_table.cpp index 4528a89..e729d7e 100644 --- a/sys/victoriafalls/fs/ext2/inode_table.cpp +++ b/sys/victoriafalls/fs/ext2/inode_table.cpp @@ -2,31 +2,32 @@ #include -InodeTable::InodeTable(Ext2BlockReader& reader, BlockGroupDescriptor* bgdt) +InodeTable::InodeTable(const glcr::SharedPtr& reader, + BlockGroupDescriptor* bgdt) : ext2_reader_(reader), bgdt_(bgdt) { - inode_tables_.Resize(ext2_reader_.NumberOfBlockGroups()); + inode_tables_.Resize(ext2_reader_->NumberOfBlockGroups()); } -glcr::ErrorOr InodeTable::GetInode(uint64_t inode_num) { - uint64_t inodes_per_group = ext2_reader_.GetSuperblock()->inodes_per_group; +glcr::ErrorOr InodeTable::GetInode(uint32_t inode_num) { + uint64_t inodes_per_group = ext2_reader_->GetSuperblock()->inodes_per_group; uint64_t block_group_num = (inode_num - 1) / inodes_per_group; ASSIGN_OR_RETURN(Inode * root, GetRootOfInodeTable(block_group_num)); uint64_t local_index = (inode_num - 1) % inodes_per_group; return reinterpret_cast(reinterpret_cast(root) + - local_index * ext2_reader_.InodeSize()); + local_index * ext2_reader_->InodeSize()); } glcr::ErrorOr InodeTable::GetRootOfInodeTable( uint64_t block_group_num) { - if (block_group_num > ext2_reader_.NumberOfBlockGroups()) { + if (block_group_num > ext2_reader_->NumberOfBlockGroups()) { return glcr::INVALID_ARGUMENT; } if (!inode_tables_[block_group_num]) { ASSIGN_OR_RETURN( inode_tables_[block_group_num], - ext2_reader_.ReadBlocks(bgdt_[block_group_num].inode_table, - ext2_reader_.InodeTableBlockSize())); + ext2_reader_->ReadBlocks(bgdt_[block_group_num].inode_table, + ext2_reader_->InodeTableBlockSize())); } return reinterpret_cast(inode_tables_[block_group_num].vaddr()); } diff --git a/sys/victoriafalls/fs/ext2/inode_table.h b/sys/victoriafalls/fs/ext2/inode_table.h index 6b53f51..f72350f 100644 --- a/sys/victoriafalls/fs/ext2/inode_table.h +++ b/sys/victoriafalls/fs/ext2/inode_table.h @@ -7,12 +7,13 @@ class InodeTable { public: - InodeTable(Ext2BlockReader& driver, BlockGroupDescriptor* bgdt); + InodeTable(const glcr::SharedPtr& driver, + BlockGroupDescriptor* bgdt); - glcr::ErrorOr GetInode(uint64_t inode_num); + glcr::ErrorOr GetInode(uint32_t inode_num); private: - Ext2BlockReader& ext2_reader_; + glcr::SharedPtr ext2_reader_; BlockGroupDescriptor* bgdt_; glcr::Vector inode_tables_; diff --git a/sys/victoriafalls/victoriafalls.cpp b/sys/victoriafalls/victoriafalls.cpp index e8d6c33..3b0a293 100644 --- a/sys/victoriafalls/victoriafalls.cpp +++ b/sys/victoriafalls/victoriafalls.cpp @@ -13,7 +13,8 @@ uint64_t main(uint64_t init_cap) { ASSIGN_OR_RETURN(ScopedDenaliClient denali, yellowstone.GetDenali()); ASSIGN_OR_RETURN(Ext2Driver ext2, Ext2Driver::Init(glcr::Move(denali))); - check(ext2.ProbePartition()); + ASSIGN_OR_RETURN(Inode * root, ext2.GetInode(2)); + check(ext2.ProbeDirectory(root)); return 0; }