[victoriafalls] Add InodeTable class to cache Inode info
This commit is contained in:
parent
21c1a001ea
commit
52b4b273b7
|
@ -5,3 +5,4 @@
|
||||||
[[nodiscard]] void* operator new[](uint64_t size) { return malloc(size); }
|
[[nodiscard]] void* operator new[](uint64_t size) { return malloc(size); }
|
||||||
|
|
||||||
void operator delete(void*, uint64_t) {}
|
void operator delete(void*, uint64_t) {}
|
||||||
|
void operator delete[](void*, uint64_t) {}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
add_executable(victoriafalls
|
add_executable(victoriafalls
|
||||||
fs/ext2/ext2_block_reader.cpp
|
fs/ext2/ext2_block_reader.cpp
|
||||||
fs/ext2/ext2_driver.cpp
|
fs/ext2/ext2_driver.cpp
|
||||||
|
fs/ext2/inode_table.cpp
|
||||||
victoriafalls.cpp)
|
victoriafalls.cpp)
|
||||||
|
|
||||||
target_include_directories(victoriafalls
|
target_include_directories(victoriafalls
|
||||||
|
|
|
@ -28,6 +28,8 @@ struct Superblock {
|
||||||
uint32_t rev_level;
|
uint32_t rev_level;
|
||||||
uint16_t def_resuid;
|
uint16_t def_resuid;
|
||||||
uint16_t def_resgid;
|
uint16_t def_resgid;
|
||||||
|
uint32_t first_ino;
|
||||||
|
uint16_t inode_size;
|
||||||
} __attribute__((__packed__));
|
} __attribute__((__packed__));
|
||||||
|
|
||||||
struct BlockGroupDescriptor {
|
struct BlockGroupDescriptor {
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
glcr::ErrorOr<Ext2Driver> Ext2Driver::Init(ScopedDenaliClient&& denali) {
|
glcr::ErrorOr<Ext2Driver> Ext2Driver::Init(ScopedDenaliClient&& denali) {
|
||||||
ASSIGN_OR_RETURN(Ext2BlockReader reader,
|
ASSIGN_OR_RETURN(Ext2BlockReader reader,
|
||||||
Ext2BlockReader::Init(glcr::Move(denali)));
|
Ext2BlockReader::Init(glcr::Move(denali)));
|
||||||
|
Superblock* superblock = reader.GetSuperblock();
|
||||||
return Ext2Driver(glcr::Move(reader));
|
return Ext2Driver(glcr::Move(reader));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,6 +20,7 @@ glcr::ErrorCode Ext2Driver::ProbePartition() {
|
||||||
superblock->blocks_per_group);
|
superblock->blocks_per_group);
|
||||||
dbgln("Inodes: 0x%x (0x%x per group)", superblock->inodes_count,
|
dbgln("Inodes: 0x%x (0x%x per group)", superblock->inodes_count,
|
||||||
superblock->inodes_per_group);
|
superblock->inodes_per_group);
|
||||||
|
dbgln("Inode size: 0x%x", superblock->inode_size);
|
||||||
|
|
||||||
dbgln("Mounts: 0x%x out of 0x%x", superblock->mnt_count,
|
dbgln("Mounts: 0x%x out of 0x%x", superblock->mnt_count,
|
||||||
superblock->max_mnt_count);
|
superblock->max_mnt_count);
|
||||||
|
@ -46,5 +48,16 @@ glcr::ErrorCode Ext2Driver::ProbePartition() {
|
||||||
dbgln("Free inodes: %x", bgds[i].free_inodes_count);
|
dbgln("Free inodes: %x", bgds[i].free_inodes_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: Move this to initialization.
|
||||||
|
inode_table_ =
|
||||||
|
glcr::UniquePtr<InodeTable>(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;
|
return glcr::OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
#include "fs/ext2/ext2.h"
|
#include "fs/ext2/ext2.h"
|
||||||
#include "fs/ext2/ext2_block_reader.h"
|
#include "fs/ext2/ext2_block_reader.h"
|
||||||
|
#include "fs/ext2/inode_table.h"
|
||||||
|
|
||||||
class Ext2Driver {
|
class Ext2Driver {
|
||||||
public:
|
public:
|
||||||
|
@ -14,6 +15,7 @@ class Ext2Driver {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ext2BlockReader ext2_reader_;
|
Ext2BlockReader ext2_reader_;
|
||||||
|
glcr::UniquePtr<InodeTable> inode_table_;
|
||||||
|
|
||||||
Ext2Driver(Ext2BlockReader&& reader) : ext2_reader_(glcr::Move(reader)) {}
|
Ext2Driver(Ext2BlockReader&& reader) : ext2_reader_(glcr::Move(reader)) {}
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
#include "fs/ext2/inode_table.h"
|
||||||
|
|
||||||
|
#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;
|
||||||
|
}
|
||||||
|
|
||||||
|
glcr::ErrorOr<Inode*> 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<Inode*>(reinterpret_cast<uint64_t>(root) +
|
||||||
|
local_index * inode_size_);
|
||||||
|
}
|
||||||
|
|
||||||
|
glcr::ErrorOr<Inode*> 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*>(inode_tables_[block_group_num].vaddr());
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <glacier/container/vector.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "fs/ext2/ext2_block_reader.h"
|
||||||
|
|
||||||
|
class InodeTable {
|
||||||
|
public:
|
||||||
|
InodeTable(Ext2BlockReader& driver, BlockGroupDescriptor* bgdt);
|
||||||
|
|
||||||
|
glcr::ErrorOr<Inode*> 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<MappedMemoryRegion> inode_tables_;
|
||||||
|
|
||||||
|
glcr::ErrorOr<Inode*> GetRootOfInodeTable(uint64_t block_group_num);
|
||||||
|
};
|
Loading…
Reference in New Issue