Skip to content
Snippets Groups Projects
Commit 556c842e authored by Jeremy Soller's avatar Jeremy Soller
Browse files

Add exnode

parent d51e891f
No related branches found
No related tags found
No related merge requests found
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);
}
...@@ -88,21 +88,49 @@ impl<E> FileSystem<E> { ...@@ -88,21 +88,49 @@ impl<E> FileSystem<E> {
try!(self.disk.write_at(node.0, &node.1)); try!(self.disk.write_at(node.0, &node.1));
let mut inserted = false; let mut inserted = false;
for mut extent in self.root.1.extents.iter_mut() { let mut last_node = (0, Node::default());
if extent.length == 0 { let mut next_node = (self.header.1.root, Node::default());
inserted = true; while ! inserted {
extent.length = 512; if next_node.0 > 0 {
extent.block = block; try!(self.disk.read_at(next_node.0, &mut next_node.1));
break; }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 {
try!(self.disk.write_at(self.root.0, &self.root.1));
Ok(Some(node)) if inserted {
} else { if next_node.0 == self.root.0 {
Ok(None) 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());
}
} }
Ok(Some(node))
} else { } else {
Ok(None) Ok(None)
} }
......
...@@ -14,12 +14,14 @@ extern crate alloc; ...@@ -14,12 +14,14 @@ extern crate alloc;
extern crate collections; extern crate collections;
pub use self::disk::Disk; pub use self::disk::Disk;
pub use self::ex_node::ExNode;
pub use self::extent::Extent; pub use self::extent::Extent;
pub use self::filesystem::FileSystem; pub use self::filesystem::FileSystem;
pub use self::header::Header; pub use self::header::Header;
pub use self::node::Node; pub use self::node::Node;
pub mod disk; pub mod disk;
pub mod ex_node;
pub mod extent; pub mod extent;
pub mod filesystem; pub mod filesystem;
pub mod header; pub mod header;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment