Newer
Older
use system::error::{Result, Error, EEXIST, EISDIR, ENOENT, ENOSPC, ENOTDIR, ENOTEMPTY};
use super::{Disk, ExNode, Extent, Header, Node};
for block in 0..4096 {
let mut header = (0, Header::default());
try!(disk.read_at(block + header.0, &mut header.1));
if header.1.valid() {
let mut root = (header.1.root, Node::default());
try!(disk.read_at(block + root.0, &mut root.1));
let mut free = (header.1.free, Node::default());
try!(disk.read_at(block + free.0, &mut free.1));
return Ok(FileSystem {
disk: disk,
block: block,
header: header
});
}
/// Create a file system on a disk
let size = try!(disk.size());
let mut free = (2, Node::new(Node::MODE_FILE, "free", 0));
free.1.extents[0] = Extent::new(4, size - 4 * 512);
let root = (1, Node::new(Node::MODE_DIR, "root", 0));
let header = (0, Header::new(size, root.0, free.0));
fn read_at(&mut self, block: u64, buffer: &mut [u8]) -> Result<usize> {
self.disk.read_at(self.block + block, buffer)
}
fn write_at(&mut self, block: u64, buffer: &[u8]) -> Result<usize> {
self.disk.write_at(self.block + block, buffer)
}
let free_block = self.header.1.free;
let mut free = try!(self.node(free_block));
for mut extent in free.1.extents.iter_mut() {
if extent.length/512 >= length {
extent.length -= length * 512;
try!(self.write_at(free.0, &free.1));
pub fn deallocate(&mut self, block: u64, length: u64) -> Result<()> {
let free_block = self.header.1.free;
pub fn node(&mut self, block: u64) -> Result<(u64, Node)> {
try!(self.read_at(block, &mut node));
Ok((block, node))
pub fn ex_node(&mut self, block: u64) -> Result<(u64, ExNode)> {
let mut node = ExNode::default();
try!(self.read_at(block, &mut node));
Ok((block, node))
}
pub fn child_nodes(&mut self, children: &mut Vec<(u64, Node)>, parent_block: u64) -> Result<()> {
if parent_block == 0 {
return Ok(());
}
let parent = try!(self.node(parent_block));
for extent in parent.1.extents.iter() {
for (block, size) in extent.blocks() {
if size >= 512 {
children.push(try!(self.node(block)));
}
self.child_nodes(children, parent.1.next)
pub fn find_node(&mut self, name: &str, parent_block: u64) -> Result<(u64, Node)> {
if parent_block == 0 {
let parent = try!(self.node(parent_block));
for extent in parent.1.extents.iter() {
for (block, size) in extent.blocks() {
if size >= 512 {
let child = try!(self.node(block));
let mut matches = false;
if let Ok(child_name) = child.1.name() {
if child_name == name {
matches = true;
}
if matches {
return Ok(child);
}
self.find_node(name, parent.1.next)
}
pub fn path_nodes(&mut self, path: &str, nodes: &mut Vec<(u64, Node)>) -> Result<(u64, Node)> {
let mut block = self.header.1.root;
nodes.push(try!(self.node(block)));
if ! part.is_empty() {
let node = try!(self.find_node(part, block));
block = node.0;
nodes.push(node);
}
}
Ok(nodes.pop().unwrap())
}
fn insert_blocks(&mut self, block: u64, length: u64, parent_block: u64) -> Result<()> {
if parent_block == 0 {
}
let mut inserted = false;
let mut parent = try!(self.node(parent_block));
for mut extent in parent.1.extents.iter_mut() {
if extent.length == 0 {
//New extent
inserted = true;
extent.block = block;
} else if length % 512 == 0 && extent.block == block + length/512 {
//At beginning
inserted = true;
extent.block = block;
} else if extent.length % 512 == 0 && extent.block + extent.length/512 == block {
//At end
inserted = true;
break;
}
}
if inserted {
try!(self.write_at(parent.0, &parent.1));
} else {
if parent.1.next == 0 {
try!(self.write_at(parent.0, &parent.1));
try!(self.write_at(parent.1.next, &Node::default()));
pub fn create_node(&mut self, mode: u16, name: &str, parent_block: u64) -> Result<(u64, Node)> {
if self.find_node(name, parent_block).is_ok() {
Err(Error::new(EEXIST))
} else {
let node = (try!(self.allocate(1)), Node::new(mode, name, parent_block));
try!(self.write_at(node.0, &node.1));
try!(self.insert_blocks(node.0, 512, parent_block));
fn remove_blocks(&mut self, block: u64, length: u64, parent_block: u64) -> Result<()> {
}
let mut removed = false;
let mut replace_option = None;
let mut parent = try!(self.node(parent_block));
for mut extent in parent.1.extents.iter_mut() {
if block >= extent.block && block + length <= extent.block + extent.length/512 {
let left = Extent::new(extent.block, (block - extent.block) * 512);
let right = Extent::new(block + length, ((extent.block + extent.length/512) - (block + length)) * 512);
if left.length > 0 {
*extent = left;
if right.length > 0 {
replace_option = Some(right);
}
} else if right.length > 0 {
*extent = right;
} else {
*extent = Extent::default();
}
break;
}
}
if removed {
try!(self.write_at(parent.0, &parent.1));
try!(self.insert_blocks(replace.block, replace.length, parent_block));
try!(self.deallocate(block, 512));
pub fn remove_node(&mut self, mode: u16, name: &str, parent_block: u64) -> Result<()> {
let node = try!(self.find_node(name, parent_block));
if node.1.mode & Node::MODE_TYPE == mode {
if node.1.is_dir() {
let mut children = Vec::new();
try!(self.child_nodes(&mut children, node.0));
if ! children.is_empty() {
return Err(Error::new(ENOTEMPTY));
try!(self.write_at(node.0, &Node::default()));
Ok(())
} else if node.1.is_dir() {
Err(Error::new(EISDIR))
} else {
Err(Error::new(ENOTDIR))
fn node_ensure_len(&mut self, block: u64, mut length: u64) -> Result<()> {
if block == 0 {
return Err(Error::new(ENOENT));
}
let node = try!(self.node(block));
for extent in node.1.extents.iter() {
if extent.length >= length {
length = 0;
break;
} else {
length -= extent.length;
}
}
if length > 0 {
if node.1.next > 0 {
self.node_ensure_len(node.1.next, length)
} else {
let new_block = try!(self.allocate((length + 511)/512));
try!(self.insert_blocks(new_block, length, block));
Ok(())
}
} else {
Ok(())
}
}
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
pub fn node_set_len(&mut self, block: u64, mut length: u64) -> Result<()> {
if block == 0 {
return Err(Error::new(ENOENT));
}
let mut changed = false;
let mut node = try!(self.node(block));
for mut extent in node.1.extents.iter_mut() {
if extent.length > length {
//TODO: try!(self.deallocate(block, 512));
extent.length = length;
changed = true;
length = 0;
} else {
length -= extent.length;
}
}
if changed {
try!(self.write_at(node.0, &node.1));
}
if node.1.next > 0 {
self.node_set_len(node.1.next, length)
} else {
Ok(())
}
}
fn node_extents(&mut self, block: u64, mut offset: u64, mut len: usize, extents: &mut Vec<Extent>) -> Result<()> {
}
let node = try!(self.node(block));
for extent in node.1.extents.iter() {
let mut push_extent = Extent::default();
for (block, size) in extent.blocks() {
if push_extent.block == 0 {
push_extent.block = block;
}
if len >= size {
push_extent.length += size as u64;
len -= size;
} else if len > 0 {
push_extent.length += len as u64;
len = 0;
break;
if push_extent.length > 0 {
extents.push(push_extent);
}
if len == 0 {
break;
}
if len > 0 {
self.node_extents(node.1.next, offset, len, extents)
pub fn read_node(&mut self, block: u64, offset: u64, buf: &mut [u8]) -> Result<usize> {
let mut byte_offset = (offset % 512) as usize;
let mut extents = Vec::new();
try!(self.node_extents(block, block_offset, byte_offset + buf.len(), &mut extents));
for extent in extents.iter() {
for (block, size) in extent.blocks() {
let mut sector = [0; 512];
try!(self.read_at(block, &mut sector));
if byte_offset < size && i < buf.len() {
for (s_b, mut b) in sector[byte_offset..size].iter().zip(buf[i..].iter_mut()) {
*b = *s_b;
i += 1;
}
pub fn write_node(&mut self, block: u64, offset: u64, buf: &[u8]) -> Result<usize> {
let mut byte_offset = (offset % 512) as usize;
try!(self.node_ensure_len(block, block_offset as u64 * 512 + (byte_offset + buf.len()) as u64));
let mut extents = Vec::new();
try!(self.node_extents(block, block_offset, byte_offset + buf.len(), &mut extents));
for extent in extents.iter() {
for (block, size) in extent.blocks() {
let mut sector = [0; 512];
if byte_offset < size && i < buf.len() {
for (mut s_b, b) in sector[byte_offset..size].iter_mut().zip(buf[i..].iter()) {
*s_b = *b;
i += 1;
}
try!(self.write_at(block, §or));
}
pub fn node_len(&mut self, block: u64) -> Result<u64> {
if block == 0 {
return Err(Error::new(ENOENT));
}
let mut size = 0;
let node = try!(self.node(block));
for extent in node.1.extents.iter() {
size += extent.length;
}
if node.1.next > 0 {
size += try!(self.node_len(node.1.next));
Ok(size)
} else {
Ok(size)
}
}