diff --git a/src/filesystem.rs b/src/filesystem.rs index 63a0e55b3fbba39235870ddaa4d8b30d0ad62084..9e474990309c7348ce7d23f6756d8f0725feb5de 100644 --- a/src/filesystem.rs +++ b/src/filesystem.rs @@ -35,27 +35,41 @@ impl<E> FileSystem<E> { } /// Create a file system on a disk - pub fn create(mut disk: Box<Disk<E>>) -> Result<Self, E> { + pub fn create(mut disk: Box<Disk<E>>) -> Result<Option<Self>, E> { let size = try!(disk.size()); - assert!(size > 4); + if size >= 4 * 512 { + let mut free = (3, Node::new("free", Node::MODE_FILE)); + free.1.extents[0] = Extent::new(4, (size - 4 * 512)); + try!(disk.write_at(free.0, &free.1)); - let mut free = (3, Node::new("free", Node::MODE_DIR)); - free.1.extents[0] = Extent::new(4, (size - 4 * 512)); - try!(disk.write_at(free.0, &free.1)); + let root = (2, Node::new("root", Node::MODE_DIR)); + try!(disk.write_at(root.0, &root.1)); - let root = (2, Node::new("root", Node::MODE_DIR)); - try!(disk.write_at(root.0, &root.1)); + let header = (1, Header::new(size, root.0, free.0)); + try!(disk.write_at(header.0, &header.1)); - let header = (1, Header::new(size, root.0, free.0)); - try!(disk.write_at(header.0, &header.1)); + Ok(Some(FileSystem { + disk: disk, + header: header, + root: root, + free: free + })) + } else { + Ok(None) + } + } - Ok(FileSystem { - disk: disk, - header: header, - root: root, - free: free - }) + 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; + try!(self.disk.write_at(self.free.0, &self.free.1)); + Ok(Some(block)) + } else { + Ok(None) + } } pub fn node(&mut self, block: u64) -> Result<Node, E> { @@ -63,4 +77,14 @@ impl<E> FileSystem<E> { try!(self.disk.read_at(block, &mut node)); Ok(node) } + + pub fn touch(&mut self, name: &str) -> Result<Option<(u64, Node)>, E> { + if let Some(block) = try!(self.allocate()) { + let node = (block, Node::new(name, Node::MODE_FILE)); + try!(self.disk.write_at(node.0, &node.1)); + Ok(Some(node)) + } else { + Ok(None) + } + } } diff --git a/utility/main.rs b/utility/main.rs index 8e75a88267dfa779760f56806ec224430d9324ce..1ac9925fdecd91a5df3f90b7d983398ad501834a 100644 --- a/utility/main.rs +++ b/utility/main.rs @@ -64,6 +64,19 @@ fn shell<E: Display>(mut fs: FileSystem<E>){ */ println!("TODO: ls"); }, + "touch" => { + if let Some(arg) = args.next() { + match fs.touch(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) + } + } else { + println!("touch <file>"); + } + }, _ => println!("unknown command: {}", command) } } @@ -90,11 +103,15 @@ fn main() { } }else{ //Create a 1 GB disk image - match Image::create(&path, 1024 * 1024 * 1024) { + let size = 1024 * 1024 * 1024; + match Image::create(&path, size) { Ok(disk) => match FileSystem::create(Box::new(disk)) { - Ok(filesystem) => { - println!("redoxfs: created filesystem {}", path); - shell(filesystem); + Ok(filesystem_option) => match filesystem_option { + Some(filesystem) => { + println!("redoxfs: created filesystem {}", path); + shell(filesystem); + }, + None => println!("redoxfs: not enough space for filesystem on {}", path) }, Err(err) => println!("redoxfs: failed to create filesystem {}: {}", path, err) },