port BlockGroupDescriptor table finding to Buffer
This commit is contained in:
parent
d4348c3177
commit
e6acaad9a9
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Reference in a new issue