diff --git a/sys/victoriafalls/fs/ext2/ext2_block_reader.cpp b/sys/victoriafalls/fs/ext2/ext2_block_reader.cpp index fbeee8e..06a0454 100644 --- a/sys/victoriafalls/fs/ext2/ext2_block_reader.cpp +++ b/sys/victoriafalls/fs/ext2/ext2_block_reader.cpp @@ -16,6 +16,36 @@ uint64_t Ext2BlockReader::SectorsPerBlock() { return 1 << (GetSuperblock()->log_block_size + 1); } +uint64_t Ext2BlockReader::BlockSize() { + return 1024 << (GetSuperblock()->log_block_size); +} + +uint64_t Ext2BlockReader::NumberOfBlockGroups() { + return ((GetSuperblock()->blocks_count - 1) / + GetSuperblock()->blocks_per_group) + + 1; +} + +uint64_t Ext2BlockReader::BgdtBlockNum() { + return (BlockSize() == 1024) ? 2 : 1; +} + +uint64_t Ext2BlockReader::BgdtBlockSize() { + return ((NumberOfBlockGroups() * sizeof(BlockGroupDescriptor) - 1) / + BlockSize()) + + 1; +} + +uint64_t Ext2BlockReader::InodeSize() { + constexpr uint64_t kDefaultInodeSize = 0x80; + return GetSuperblock()->rev_level >= 1 ? GetSuperblock()->inode_size + : kDefaultInodeSize; +} + +uint64_t Ext2BlockReader::InodeTableBlockSize() { + return (InodeSize() * GetSuperblock()->inodes_per_group) / BlockSize(); +} + glcr::ErrorOr Ext2BlockReader::ReadBlock( uint64_t block_number) { return denali_.ReadSectors(block_number * SectorsPerBlock(), diff --git a/sys/victoriafalls/fs/ext2/ext2_block_reader.h b/sys/victoriafalls/fs/ext2/ext2_block_reader.h index 9913ba7..2fb8347 100644 --- a/sys/victoriafalls/fs/ext2/ext2_block_reader.h +++ b/sys/victoriafalls/fs/ext2/ext2_block_reader.h @@ -6,12 +6,25 @@ #include "fs/ext2/ext2.h" +/* Simple Wrapper class around the denali client to translate blocks to sectors. + * + * By necessity contains the Ext Superblock (to make the translation + * calculation). + * */ class Ext2BlockReader { public: static glcr::ErrorOr Init(ScopedDenaliClient&& denali); + // TODO: Consider creating a new class wrapper with these computations. Superblock* GetSuperblock(); - uint64_t SectorsPerBlock(); + uint64_t BlockSize(); + uint64_t NumberOfBlockGroups(); + uint64_t BgdtBlockNum(); + uint64_t BgdtBlockSize(); + uint64_t InodeSize(); + // FIXME: This probably needs to take into account the block group number + // because the last table will likely be smaller. + uint64_t InodeTableBlockSize(); glcr::ErrorOr ReadBlock(uint64_t block_number); glcr::ErrorOr ReadBlocks(uint64_t block_number, @@ -22,4 +35,6 @@ class Ext2BlockReader { MappedMemoryRegion super_block_region_; Ext2BlockReader(ScopedDenaliClient&& denali, MappedMemoryRegion super_block); + + uint64_t SectorsPerBlock(); }; diff --git a/sys/victoriafalls/fs/ext2/ext2_driver.cpp b/sys/victoriafalls/fs/ext2/ext2_driver.cpp index 74b24eb..3fde967 100644 --- a/sys/victoriafalls/fs/ext2/ext2_driver.cpp +++ b/sys/victoriafalls/fs/ext2/ext2_driver.cpp @@ -28,17 +28,13 @@ glcr::ErrorCode Ext2Driver::ProbePartition() { dbgln("Created by: %x", superblock->creator_os); - uint64_t num_block_groups = - 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; ASSIGN_OR_RETURN(MappedMemoryRegion bgdt, - ext2_reader_.ReadBlocks(bgdt_block, bgdt_bytes)) - + ext2_reader_.ReadBlocks(ext2_reader_.BgdtBlockNum(), + ext2_reader_.BgdtBlockSize())); BlockGroupDescriptor* bgds = reinterpret_cast(bgdt.vaddr()); + 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); diff --git a/sys/victoriafalls/fs/ext2/inode_table.cpp b/sys/victoriafalls/fs/ext2/inode_table.cpp index 7b7aba0..4528a89 100644 --- a/sys/victoriafalls/fs/ext2/inode_table.cpp +++ b/sys/victoriafalls/fs/ext2/inode_table.cpp @@ -3,42 +3,30 @@ #include InodeTable::InodeTable(Ext2BlockReader& reader, BlockGroupDescriptor* bgdt) - : ext2_reader_(reader), - bgdt_(bgdt), - num_block_groups_(((reader.GetSuperblock()->blocks_count - 1) / - reader.GetSuperblock()->blocks_per_group) + - 1), - inodes_per_group_(reader.GetSuperblock()->inodes_per_group) { - inode_tables_.Resize(num_block_groups_); - dbgln("EXT rev: %x", reader.GetSuperblock()->rev_level); - inode_size_ = reader.GetSuperblock()->rev_level >= 1 - ? reader.GetSuperblock()->inode_size - : 0x80; + : ext2_reader_(reader), bgdt_(bgdt) { + inode_tables_.Resize(ext2_reader_.NumberOfBlockGroups()); } glcr::ErrorOr InodeTable::GetInode(uint64_t inode_num) { - uint64_t block_group_num = (inode_num - 1) / inodes_per_group_; + 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_; + uint64_t local_index = (inode_num - 1) % inodes_per_group; return reinterpret_cast(reinterpret_cast(root) + - local_index * inode_size_); + local_index * ext2_reader_.InodeSize()); } glcr::ErrorOr InodeTable::GetRootOfInodeTable( uint64_t block_group_num) { - if (block_group_num > num_block_groups_) { + if (block_group_num > ext2_reader_.NumberOfBlockGroups()) { return glcr::INVALID_ARGUMENT; } if (!inode_tables_[block_group_num]) { - // FIXME: Don't hardcode block and inode size here. - uint64_t inode_table_size = - ((inodes_per_group_ * inode_size_ - 1) / 1024) + 1; - dbgln("Reading %lx, %lx", bgdt_[block_group_num].inode_table, - inode_table_size); - ASSIGN_OR_RETURN(inode_tables_[block_group_num], - ext2_reader_.ReadBlocks(bgdt_[block_group_num].inode_table, - inode_table_size)); + ASSIGN_OR_RETURN( + inode_tables_[block_group_num], + 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 8494253..6b53f51 100644 --- a/sys/victoriafalls/fs/ext2/inode_table.h +++ b/sys/victoriafalls/fs/ext2/inode_table.h @@ -14,9 +14,6 @@ class InodeTable { private: Ext2BlockReader& ext2_reader_; BlockGroupDescriptor* bgdt_; - uint64_t num_block_groups_; - uint64_t inodes_per_group_; - uint64_t inode_size_; glcr::Vector inode_tables_;