[victoriafalls] Move a superblock-based calculations to the block reader
This commit is contained in:
parent
52b4b273b7
commit
150bfd2fd4
|
@ -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<MappedMemoryRegion> Ext2BlockReader::ReadBlock(
|
||||
uint64_t block_number) {
|
||||
return denali_.ReadSectors(block_number * SectorsPerBlock(),
|
||||
|
|
|
@ -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<Ext2BlockReader> 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<MappedMemoryRegion> ReadBlock(uint64_t block_number);
|
||||
glcr::ErrorOr<MappedMemoryRegion> ReadBlocks(uint64_t block_number,
|
||||
|
@ -22,4 +35,6 @@ class Ext2BlockReader {
|
|||
MappedMemoryRegion super_block_region_;
|
||||
|
||||
Ext2BlockReader(ScopedDenaliClient&& denali, MappedMemoryRegion super_block);
|
||||
|
||||
uint64_t SectorsPerBlock();
|
||||
};
|
||||
|
|
|
@ -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<BlockGroupDescriptor*>(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);
|
||||
|
|
|
@ -3,42 +3,30 @@
|
|||
#include <mammoth/debug.h>
|
||||
|
||||
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<Inode*> 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<Inode*>(reinterpret_cast<uint64_t>(root) +
|
||||
local_index * inode_size_);
|
||||
local_index * ext2_reader_.InodeSize());
|
||||
}
|
||||
|
||||
glcr::ErrorOr<Inode*> 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*>(inode_tables_[block_group_num].vaddr());
|
||||
}
|
||||
|
|
|
@ -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<MappedMemoryRegion> inode_tables_;
|
||||
|
||||
|
|
Loading…
Reference in New Issue