port BlockGroupDescriptor table finding to Buffer

This commit is contained in:
Szymon Walter 2018-03-19 18:10:27 +01:00
parent d4348c3177
commit e6acaad9a9

View file

@ -1,7 +1,9 @@
use core::mem; use core::mem;
use core::slice;
use alloc::Vec;
use error::Error; use error::Error;
use buffer::Buffer;
/// The Block Group Descriptor Table contains a descriptor for each block group /// The Block Group Descriptor Table contains a descriptor for each block group
/// within the file system. The number of block groups within the file system, /// within the file system. The number of block groups within the file system,
@ -16,6 +18,7 @@ use error::Error;
/// Remember that blocks are numbered starting at 0, and that block numbers /// Remember that blocks are numbered starting at 0, and that block numbers
/// don't usually correspond to physical block addresses. /// don't usually correspond to physical block addresses.
#[repr(C, packed)] #[repr(C, packed)]
#[derive(Clone, Copy)]
pub struct BlockGroupDescriptor { pub struct BlockGroupDescriptor {
/// Block address of block usage bitmap /// Block address of block usage bitmap
pub block_usage_addr: u32, pub block_usage_addr: u32,
@ -34,21 +37,47 @@ pub struct BlockGroupDescriptor {
} }
impl BlockGroupDescriptor { impl BlockGroupDescriptor {
pub unsafe fn find_descriptor_table<'a>( pub unsafe fn find_descriptor<'a, E>(
haystack: &'a mut [u8], haystack: &'a Buffer<u8, Error = E>,
offset: isize, offset: usize,
) -> Result<(BlockGroupDescriptor, usize), Error>
where
Error: From<E>,
{
let end = offset + mem::size_of::<BlockGroupDescriptor>();
if haystack.len() < end {
return Err(Error::OutOfBounds(end));
}
let descr = haystack
.slice_unchecked(offset..end)
.dynamic_cast::<BlockGroupDescriptor>();
Ok(descr)
}
pub fn find_descriptor_table<'a, E>(
haystack: &'a Buffer<u8, Error = E>,
count: usize, count: usize,
) -> Result<&'a mut [BlockGroupDescriptor], Error> { ) -> Result<(Vec<BlockGroupDescriptor>, usize), Error>
let offset = (2048 + offset) as usize; where
Error: From<E>,
{
let offset = 2048; // TODO: this assumes a block size
let end = offset + count * mem::size_of::<BlockGroupDescriptor>(); let end = offset + count * mem::size_of::<BlockGroupDescriptor>();
if haystack.len() < end { if haystack.len() < end {
return Err(Error::OutOfBounds(end)); return Err(Error::OutOfBounds(end));
} }
let ptr = haystack.as_mut_ptr().offset(offset as isize) let mut vec = Vec::with_capacity(count);
as *mut BlockGroupDescriptor; for i in 0..count {
let slice = slice::from_raw_parts_mut(ptr, count); let offset = offset + i * mem::size_of::<BlockGroupDescriptor>();
Ok(slice) vec.push(unsafe {
BlockGroupDescriptor::find_descriptor(haystack, offset)?.0
});
}
Ok((vec, offset))
} }
} }
@ -58,17 +87,14 @@ mod tests {
#[test] #[test]
fn find() { fn find() {
let mut buffer = vec![0_u8; 4096]; let buffer = vec![0_u8; 4096];
let addr = &buffer[2048] as *const _ as usize; let table = BlockGroupDescriptor::find_descriptor_table(&buffer, 8);
// magic
let table = unsafe {
BlockGroupDescriptor::find_descriptor_table(&mut buffer, 0, 0)
};
assert!( assert!(
table.is_ok(), table.is_ok(),
"Err({:?})", "Err({:?})",
table.err().unwrap_or_else(|| unreachable!()), table.err().unwrap_or_else(|| unreachable!()),
); );
assert_eq!(table.unwrap().as_ptr() as usize, addr); let table = table.unwrap_or_else(|_| unreachable!());
assert_eq!(table.0.len(), 8);
} }
} }