From 52b4b273b7de302502929463e6a572772e3c8454 Mon Sep 17 00:00:00 2001 From: Drew Galbraith Date: Thu, 6 Jul 2023 09:39:17 -0700 Subject: [PATCH] [victoriafalls] Add InodeTable class to cache Inode info --- lib/mammoth/src/new.cpp | 1 + sys/victoriafalls/CMakeLists.txt | 1 + sys/victoriafalls/fs/ext2/ext2.h | 2 ++ sys/victoriafalls/fs/ext2/ext2_driver.cpp | 13 +++++++ sys/victoriafalls/fs/ext2/ext2_driver.h | 2 ++ sys/victoriafalls/fs/ext2/inode_table.cpp | 44 +++++++++++++++++++++++ sys/victoriafalls/fs/ext2/inode_table.h | 24 +++++++++++++ 7 files changed, 87 insertions(+) create mode 100644 sys/victoriafalls/fs/ext2/inode_table.cpp create mode 100644 sys/victoriafalls/fs/ext2/inode_table.h diff --git a/lib/mammoth/src/new.cpp b/lib/mammoth/src/new.cpp index d58fcd3..fa06e2e 100644 --- a/lib/mammoth/src/new.cpp +++ b/lib/mammoth/src/new.cpp @@ -5,3 +5,4 @@ [[nodiscard]] void* operator new[](uint64_t size) { return malloc(size); } void operator delete(void*, uint64_t) {} +void operator delete[](void*, uint64_t) {} diff --git a/sys/victoriafalls/CMakeLists.txt b/sys/victoriafalls/CMakeLists.txt index c62d58d..b848b39 100644 --- a/sys/victoriafalls/CMakeLists.txt +++ b/sys/victoriafalls/CMakeLists.txt @@ -1,6 +1,7 @@ add_executable(victoriafalls fs/ext2/ext2_block_reader.cpp fs/ext2/ext2_driver.cpp + fs/ext2/inode_table.cpp victoriafalls.cpp) target_include_directories(victoriafalls diff --git a/sys/victoriafalls/fs/ext2/ext2.h b/sys/victoriafalls/fs/ext2/ext2.h index 3e6fac4..8b841be 100644 --- a/sys/victoriafalls/fs/ext2/ext2.h +++ b/sys/victoriafalls/fs/ext2/ext2.h @@ -28,6 +28,8 @@ struct Superblock { uint32_t rev_level; uint16_t def_resuid; uint16_t def_resgid; + uint32_t first_ino; + uint16_t inode_size; } __attribute__((__packed__)); struct BlockGroupDescriptor { diff --git a/sys/victoriafalls/fs/ext2/ext2_driver.cpp b/sys/victoriafalls/fs/ext2/ext2_driver.cpp index 89d2a53..74b24eb 100644 --- a/sys/victoriafalls/fs/ext2/ext2_driver.cpp +++ b/sys/victoriafalls/fs/ext2/ext2_driver.cpp @@ -4,6 +4,7 @@ glcr::ErrorOr Ext2Driver::Init(ScopedDenaliClient&& denali) { ASSIGN_OR_RETURN(Ext2BlockReader reader, Ext2BlockReader::Init(glcr::Move(denali))); + Superblock* superblock = reader.GetSuperblock(); return Ext2Driver(glcr::Move(reader)); } @@ -19,6 +20,7 @@ glcr::ErrorCode Ext2Driver::ProbePartition() { superblock->blocks_per_group); dbgln("Inodes: 0x%x (0x%x per group)", superblock->inodes_count, superblock->inodes_per_group); + dbgln("Inode size: 0x%x", superblock->inode_size); dbgln("Mounts: 0x%x out of 0x%x", superblock->mnt_count, superblock->max_mnt_count); @@ -46,5 +48,16 @@ glcr::ErrorCode Ext2Driver::ProbePartition() { 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)); + + dbgln("Inode %lx", root); + dbgln("Mode: %x", root->mode); + dbgln("Blocks: %x", root->blocks); + dbgln("Size: %x", root->size); + return glcr::OK; } diff --git a/sys/victoriafalls/fs/ext2/ext2_driver.h b/sys/victoriafalls/fs/ext2/ext2_driver.h index f6d5cea..600b281 100644 --- a/sys/victoriafalls/fs/ext2/ext2_driver.h +++ b/sys/victoriafalls/fs/ext2/ext2_driver.h @@ -5,6 +5,7 @@ #include "fs/ext2/ext2.h" #include "fs/ext2/ext2_block_reader.h" +#include "fs/ext2/inode_table.h" class Ext2Driver { public: @@ -14,6 +15,7 @@ class Ext2Driver { private: Ext2BlockReader ext2_reader_; + glcr::UniquePtr inode_table_; Ext2Driver(Ext2BlockReader&& reader) : ext2_reader_(glcr::Move(reader)) {} }; diff --git a/sys/victoriafalls/fs/ext2/inode_table.cpp b/sys/victoriafalls/fs/ext2/inode_table.cpp new file mode 100644 index 0000000..7b7aba0 --- /dev/null +++ b/sys/victoriafalls/fs/ext2/inode_table.cpp @@ -0,0 +1,44 @@ +#include "fs/ext2/inode_table.h" + +#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; +} + +glcr::ErrorOr InodeTable::GetInode(uint64_t inode_num) { + 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 * inode_size_); +} + +glcr::ErrorOr InodeTable::GetRootOfInodeTable( + uint64_t block_group_num) { + if (block_group_num > num_block_groups_) { + 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)); + } + 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 new file mode 100644 index 0000000..8494253 --- /dev/null +++ b/sys/victoriafalls/fs/ext2/inode_table.h @@ -0,0 +1,24 @@ +#pragma once + +#include +#include + +#include "fs/ext2/ext2_block_reader.h" + +class InodeTable { + public: + InodeTable(Ext2BlockReader& driver, BlockGroupDescriptor* bgdt); + + glcr::ErrorOr GetInode(uint64_t inode_num); + + private: + Ext2BlockReader& ext2_reader_; + BlockGroupDescriptor* bgdt_; + uint64_t num_block_groups_; + uint64_t inodes_per_group_; + uint64_t inode_size_; + + glcr::Vector inode_tables_; + + glcr::ErrorOr GetRootOfInodeTable(uint64_t block_group_num); +};