diff --git a/src/filesystem.rs b/src/filesystem.rs index 9e474990309c7348ce7d23f6756d8f0725feb5de..22008949e4b825106fc56dbdf4ef9ef5c7c663b2 100644 --- a/src/filesystem.rs +++ b/src/filesystem.rs @@ -61,15 +61,19 @@ impl<E> FileSystem<E> { } pub fn allocate(&mut self) -> Result<Option<u64>, E> { - if self.free.1.extents[0].length >= 512 { - let block = self.free.1.extents[0].block; - self.free.1.extents[0].length -= 512; - self.free.1.extents[0].block += 1; + let mut block = None; + for mut extent in self.free.1.extents.iter_mut() { + if extent.length >= 512 { + block = Some(extent.block); + extent.length -= 512; + extent.block += 1; + break; + } + } + if block.is_some() { try!(self.disk.write_at(self.free.0, &self.free.1)); - Ok(Some(block)) - } else { - Ok(None) } + Ok(block) } pub fn node(&mut self, block: u64) -> Result<Node, E> { @@ -78,13 +82,37 @@ impl<E> FileSystem<E> { Ok(node) } - pub fn touch(&mut self, name: &str) -> Result<Option<(u64, Node)>, E> { + fn create_node(&mut self, name: &str, mode: u64) -> Result<Option<(u64, Node)>, E> { if let Some(block) = try!(self.allocate()) { - let node = (block, Node::new(name, Node::MODE_FILE)); + let node = (block, Node::new(name, mode)); try!(self.disk.write_at(node.0, &node.1)); - Ok(Some(node)) + + 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; + } + } + if inserted { + try!(self.disk.write_at(self.root.0, &self.root.1)); + + Ok(Some(node)) + } else { + Ok(None) + } } else { Ok(None) } } + + pub fn create_dir(&mut self, name: &str) -> Result<Option<(u64, Node)>, E> { + self.create_node(name, Node::MODE_DIR) + } + + pub fn create_file(&mut self, name: &str) -> Result<Option<(u64, Node)>, E> { + self.create_node(name, Node::MODE_FILE) + } } diff --git a/utility/main.rs b/utility/main.rs index 1ac9925fdecd91a5df3f90b7d983398ad501834a..1105121cd5824a447c562877796a2ff4fe402d70 100644 --- a/utility/main.rs +++ b/utility/main.rs @@ -35,7 +35,7 @@ fn shell<E: Display>(mut fs: FileSystem<E>){ match arg.parse::<u64>() { Ok(block) => { match fs.node(block) { - Ok(node) => println!("{:#?}", node), + Ok(node) => println!("{}: {:#?}", block, node), Err(err) => println!("node: failed to read {}: {}", block, err) } }, @@ -46,38 +46,46 @@ fn shell<E: Display>(mut fs: FileSystem<E>){ } }, "ls" => { - /* - let path = args.next().unwrap_or("/"); - for (node_block, node) in filesystem.nodes.iter() { - let mut name = "/".to_string(); - for &b in node.name.iter() { - if b == 0 { - break; - } else { - unsafe { name.as_mut_vec().push(b); } - } + let mut blocks = Vec::new(); + for extent in fs.root.1.extents.iter() { + for i in 0 .. extent.length/512 { + blocks.push(extent.block + i); } - if name.starts_with(&path) { - println!("{}: {}", node_block, name); + } + for &block in blocks.iter() { + match fs.node(block) { + Ok(node) => println!("{}: {:#?}", block, node), + Err(err) => println!("ls: failed to read {}: {}", block, err) } } - */ - println!("TODO: ls"); + }, + "mkdir" => { + if let Some(arg) = args.next() { + match fs.create_dir(arg) { + Ok(node_option) => match node_option { + Some(node) => println!("{}: {:#?}", node.0, node.1), + None => println!("mkdir: not enough space for {}", arg) + }, + Err(err) => println!("mkdir: failed to create {}: {}", arg, err) + } + } else { + println!("mkdir <file>"); + } }, "touch" => { if let Some(arg) = args.next() { - match fs.touch(arg) { + match fs.create_file(arg) { Ok(node_option) => match node_option { Some(node) => println!("{}: {:#?}", node.0, node.1), None => println!("touch: not enough space for {}", arg) }, - Err(err) => println!("touch: failed to touch {}: {}", arg, err) + Err(err) => println!("touch: failed to create {}: {}", arg, err) } } else { println!("touch <file>"); } }, - _ => println!("unknown command: {}", command) + _ => println!("commands: exit header node ls mkdir touch") } } }