diff --git a/src/fs.rs b/src/fs.rs index 7d67234..c8b63cd 100644 --- a/src/fs.rs +++ b/src/fs.rs @@ -1,6 +1,9 @@ +use alloc::Vec; + use error::Error; use buffer::{Buffer, BufferSlice}; use sys::superblock::Superblock; +use sys::block_group::BlockGroupDescriptor; struct Struct { pub inner: T, @@ -18,6 +21,7 @@ impl From<(T, usize)> for Struct { pub struct Ext2> { buffer: B, superblock: Struct, + block_groups: Struct>, } impl> Ext2 @@ -25,8 +29,26 @@ where Error: From, { pub fn new(buffer: B) -> Result, Error> { - let superblock = Superblock::find(&buffer)?.into(); - Ok(Ext2 { buffer, superblock }) + let superblock = Struct::from(Superblock::find(&buffer)?); + let block_size = superblock.inner.block_size(); + let block_groups_offset = + (superblock.inner.first_data_block as usize + 1) * block_size; + let block_groups_count = superblock + .inner + .block_group_count() + .map(|count| count as usize) + .map_err(|(a, b)| Error::BadBlockGroupCount(a, b))?; + let block_groups = BlockGroupDescriptor::find_descriptor_table( + &buffer, + block_groups_offset, + block_groups_count, + )?; + let block_groups = Struct::from(block_groups); + Ok(Ext2 { + buffer, + superblock, + block_groups, + }) } pub fn update(&mut self) -> Result<(), Error> { @@ -46,6 +68,13 @@ where &mut self.superblock.inner } + pub fn block_group_count(&self) -> Result { + self.superblock() + .block_group_count() + .map(|count| count as usize) + .map_err(|(a, b)| Error::BadBlockGroupCount(a, b)) + } + pub fn total_block_count(&self) -> usize { self.superblock().blocks_count as _ }