Skip to content

Commit

Permalink
Hash tree implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
BijanRegmi committed Jun 1, 2023
1 parent a202767 commit 43a834d
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 26 deletions.
73 changes: 48 additions & 25 deletions src/disk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@ impl Disk {
let bs: u32 = (2 as u32).pow(10 + sb.s_log_block_size);
let gpf: u16 = (1 as u16) << sb.s_log_groups_per_flex;

dbg!(&sb.s_log_groups_per_flex, bs, gpf);

Disk {
file: f,
super_block: sb,
Expand Down Expand Up @@ -126,39 +124,64 @@ impl Disk {

pub fn read_dir(&mut self, inode_num: u32) {
let inode = self.get_inode(inode_num);
dbg!(&inode);
if inode
.i_flags
.contains(ext4::flags::inode::IFlags::Ext4IndexFl)
{
unimplemented!("Hashed Tree Directory");
}

let extents = self.get_extents(&inode);
if extents.len() > 1 {
/* if extents.len() > 1 {
unimplemented!();
}
} */

let e = &extents[0];
let blk_no: u64 = ((e.ee_start_hi as u64) << 32) | e.ee_start_lo as u64;
let block = self.read_block(blk_no).unwrap();

let mut offset = 0;
let mut entries = Vec::<ext4::structs::dir::Entry2>::new();

while offset < block.len() {
let de = ext4::structs::dir::Entry2::from_buffer(&block, offset);
if de.inode == 0 {
break;
let use_htree = inode
.i_flags
.contains(ext4::flags::inode::IFlags::Ext4IndexFl);
if use_htree {
let dx_root = ext4::structs::dir::DxRoot::from_buffer(&block, 0);
if dx_root.indirect_levels != 0 {
unimplemented!("Support for multi level hash tree is pending")
}
offset = offset + de.rec_len as usize;
entries.push(de);
}
for i in 0..dx_root.count {
let nblock;
if i == 0 {
nblock = blk_no + dx_root.block as u64;
} else {
let dentry = ext4::structs::dir::DxEntry::from_buffer(
&block,
40 + ((i - 1) * 8) as usize,
);
nblock = blk_no + dentry.block as u64;
}
let blk = self.read_block(nblock).unwrap();
let mut off = 0;
while off < blk.len() {
let de = ext4::structs::dir::Entry2::from_buffer(&blk, off);
if de.inode == 0 {
break;
}
off = off + de.rec_len as usize;
let s = std::str::from_utf8(&de.name[0..de.name_len as usize]).unwrap();
println!("{:>10}: {}", de.inode, s);
}
}
} else {
let mut offset = 0;
let mut entries = Vec::<ext4::structs::dir::Entry2>::new();

println!("Reading dir with inode_num {inode_num}");
for ele in entries {
let s = std::str::from_utf8(&ele.name[0..ele.name_len as usize]).unwrap();
println!("{:>10}: {}", ele.inode, s);
while offset < block.len() {
let de = ext4::structs::dir::Entry2::from_buffer(&block, offset);
if de.inode == 0 {
break;
}
offset = offset + de.rec_len as usize;
entries.push(de);
}
println!("Reading dir with inode_num {inode_num}");
for ele in entries {
let s = std::str::from_utf8(&ele.name[0..ele.name_len as usize]).unwrap();
println!("{:>10}: {}", ele.inode, s);
}
}
}

Expand Down
42 changes: 42 additions & 0 deletions src/ext4/directories.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,45 @@ pub struct DirEntryHash {
pub minor_hash: u32,
}
impl LoadAble for DirEntryHash {}

#[allow(dead_code)]
#[derive(Debug)]
#[repr(C)]
pub struct DxEntry {
pub hash: u32,
pub block: u32,
}

#[allow(dead_code)]
#[derive(Debug)]
#[repr(C)]
pub struct DxRoot {
// Dot
pub dotinode: u32,
pub dotrec_len: u16,
pub dotname_len: u8,
pub dotfile_type: FileType,
pub dotname: [u8; 4],

// DotDot
pub dotdotinode: u32,
pub dotdotrec_len: u16,
pub dotdotname_len: u8,
pub dotdotfile_type: FileType,
pub dotdotname: [u8; 4],

// dx_root_info
pub reserved_zero: u32,
pub hash_version: u8,
pub info_length: u8,
pub indirect_levels: u8,
pub unused_flags: u8,

// limits
pub limit: u16,
pub count: u16,
pub block: u32,
// pub entries: [DxEntry],
}
impl LoadAble for DxEntry {}
impl LoadAble for DxRoot {}
2 changes: 1 addition & 1 deletion src/ext4/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ pub mod structs {
pub use crate::ext4::superblock::SuperBlock;
pub mod dir {
pub use crate::ext4::directories::{
DirEntry as Entry, DirEntry2 as Entry2, DirEntryHash as EntryHash,
DirEntry as Entry, DirEntry2 as Entry2, DirEntryHash as EntryHash, DxEntry, DxRoot,
};
}
pub mod extent {
Expand Down

0 comments on commit 43a834d

Please sign in to comment.