Add exnode
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
use collections::Vec;
|
||||
|
||||
use core::{fmt, mem, ops, slice};
|
||||
|
||||
use super::Extent;
|
||||
|
||||
/// An extra node
|
||||
#[repr(packed)]
|
||||
pub struct ExNode {
|
||||
pub prev: u64,
|
||||
pub next: u64,
|
||||
pub extents: [Extent; 31],
|
||||
}
|
||||
|
||||
impl ExNode {
|
||||
pub fn default() -> ExNode {
|
||||
ExNode {
|
||||
prev: 0,
|
||||
next: 0,
|
||||
extents: [Extent::default(); 31],
|
||||
}
|
||||
}
|
||||
|
||||
pub fn size(&self) -> u64 {
|
||||
self.extents.iter().fold(0, |size, extent| size + extent.length)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for ExNode {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let extents: Vec<&Extent> = self.extents.iter().filter(|extent| -> bool { extent.length > 0 }).collect();
|
||||
f.debug_struct("ExNode")
|
||||
.field("prev", &self.prev)
|
||||
.field("next", &self.next)
|
||||
.field("extents", &extents)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl ops::Deref for ExNode {
|
||||
type Target = [u8];
|
||||
fn deref(&self) -> &[u8] {
|
||||
unsafe {
|
||||
slice::from_raw_parts(self as *const ExNode as *const u8, mem::size_of::<ExNode>()) as &[u8]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ops::DerefMut for ExNode {
|
||||
fn deref_mut(&mut self) -> &mut [u8] {
|
||||
unsafe {
|
||||
slice::from_raw_parts_mut(self as *mut ExNode as *mut u8, mem::size_of::<ExNode>()) as &mut [u8]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ex_node_size_test(){
|
||||
assert!(mem::size_of::<ExNode>() <= 512);
|
||||
}
|
||||
+40
-12
@@ -88,21 +88,49 @@ impl<E> FileSystem<E> {
|
||||
try!(self.disk.write_at(node.0, &node.1));
|
||||
|
||||
let mut inserted = false;
|
||||
for mut extent in self.root.1.extents.iter_mut() {
|
||||
if extent.length == 0 {
|
||||
inserted = true;
|
||||
extent.length = 512;
|
||||
extent.block = block;
|
||||
break;
|
||||
let mut last_node = (0, Node::default());
|
||||
let mut next_node = (self.header.1.root, Node::default());
|
||||
while ! inserted {
|
||||
if next_node.0 > 0 {
|
||||
try!(self.disk.read_at(next_node.0, &mut next_node.1));
|
||||
}else{
|
||||
if let Some(block) = try!(self.allocate()) {
|
||||
next_node.0 = block;
|
||||
if last_node.0 > 0 {
|
||||
last_node.1.next = block;
|
||||
if last_node.0 == self.root.0 {
|
||||
self.root.1.next = last_node.1.next;
|
||||
}
|
||||
try!(self.disk.write_at(last_node.0, &last_node.1));
|
||||
} else {
|
||||
panic!("last_node was 0");
|
||||
}
|
||||
} else {
|
||||
return Ok(None);
|
||||
}
|
||||
}
|
||||
|
||||
for mut extent in next_node.1.extents.iter_mut() {
|
||||
if extent.length == 0 {
|
||||
inserted = true;
|
||||
extent.length = 512;
|
||||
extent.block = block;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if inserted {
|
||||
if next_node.0 == self.root.0 {
|
||||
self.root.1.extents = next_node.1.extents;
|
||||
}
|
||||
try!(self.disk.write_at(next_node.0, &next_node.1));
|
||||
} else {
|
||||
last_node = next_node;
|
||||
next_node = (last_node.1.next, Node::default());
|
||||
}
|
||||
}
|
||||
if inserted {
|
||||
try!(self.disk.write_at(self.root.0, &self.root.1));
|
||||
|
||||
Ok(Some(node))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
Ok(Some(node))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
@@ -14,12 +14,14 @@ extern crate alloc;
|
||||
extern crate collections;
|
||||
|
||||
pub use self::disk::Disk;
|
||||
pub use self::ex_node::ExNode;
|
||||
pub use self::extent::Extent;
|
||||
pub use self::filesystem::FileSystem;
|
||||
pub use self::header::Header;
|
||||
pub use self::node::Node;
|
||||
|
||||
pub mod disk;
|
||||
pub mod ex_node;
|
||||
pub mod extent;
|
||||
pub mod filesystem;
|
||||
pub mod header;
|
||||
|
||||
Reference in New Issue
Block a user