diff --git a/sys/victoriafalls/fs/ext2/ext2.h b/sys/victoriafalls/fs/ext2/ext2.h index 8b841be..7a9c7a2 100644 --- a/sys/victoriafalls/fs/ext2/ext2.h +++ b/sys/victoriafalls/fs/ext2/ext2.h @@ -62,3 +62,11 @@ struct Inode { uint32_t faddr; uint32_t osd2[3]; } __attribute__((__packed__)); + +struct DirEntry { + uint32_t inode; + uint32_t record_length; + uint8_t name_len; + uint8_t file_type; + char name[256]; +} __attribute__((__packed__)); diff --git a/sys/victoriafalls/fs/ext2/ext2_driver.cpp b/sys/victoriafalls/fs/ext2/ext2_driver.cpp index 3fde967..6e468e0 100644 --- a/sys/victoriafalls/fs/ext2/ext2_driver.cpp +++ b/sys/victoriafalls/fs/ext2/ext2_driver.cpp @@ -1,6 +1,8 @@ #include "fs/ext2/ext2_driver.h" +#include #include + glcr::ErrorOr Ext2Driver::Init(ScopedDenaliClient&& denali) { ASSIGN_OR_RETURN(Ext2BlockReader reader, Ext2BlockReader::Init(glcr::Move(denali))); @@ -49,11 +51,46 @@ glcr::ErrorCode Ext2Driver::ProbePartition() { 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 ProbeDirectory(root); +} + +glcr::ErrorCode Ext2Driver::ProbeDirectory(Inode* inode) { + if (!(inode->mode & 0x4000)) { + dbgln("Probing non-directory"); + return glcr::INVALID_ARGUMENT; + } + + // This calculation is cursed. + uint64_t real_block_cnt = + (inode->blocks - 1) / (ext2_reader_.BlockSize() / 512) + 1; + + if (real_block_cnt > 12) { + dbgln("Cant handle indirect blocks yet"); + return glcr::FAILED_PRECONDITION; + } + + 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])); + uint64_t addr = block.vaddr(); + while (addr < block.vaddr() + ext2_reader_.BlockSize()) { + DirEntry* entry = reinterpret_cast(addr); + dbgln("Entry: inode: %x, rec_len %x, name_len %x", entry->inode, + entry->record_length, entry->name_len); + // FIXME: We need a method to construct a string that is *up to* a certain + // length. As illustrated below the provided name_len is 0x2e but the + // first character is \0 since this is the self-referencial inode. + glcr::String name(entry->name, entry->name_len); + dbgln("%x, %x", name.length(), glcr::String(entry->name).length()); + dbgln("%s", name.cstr()); + addr += entry->record_length; + } + } return glcr::OK; } diff --git a/sys/victoriafalls/fs/ext2/ext2_driver.h b/sys/victoriafalls/fs/ext2/ext2_driver.h index 600b281..c1f0ee4 100644 --- a/sys/victoriafalls/fs/ext2/ext2_driver.h +++ b/sys/victoriafalls/fs/ext2/ext2_driver.h @@ -13,6 +13,8 @@ class Ext2Driver { glcr::ErrorCode ProbePartition(); + glcr::ErrorCode ProbeDirectory(Inode* inode); + private: Ext2BlockReader ext2_reader_; glcr::UniquePtr inode_table_;