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")
             }
         }
     }