WIP: Remove
This commit is contained in:
@@ -7,6 +7,13 @@ pub struct Extent {
|
||||
}
|
||||
|
||||
impl Extent {
|
||||
pub fn default() -> Extent {
|
||||
Extent {
|
||||
block: 0,
|
||||
length: 0
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new(block: u64, length: u64) -> Extent {
|
||||
Extent {
|
||||
block: block,
|
||||
|
||||
+72
-6
@@ -60,19 +60,19 @@ impl<E> FileSystem<E> {
|
||||
}
|
||||
|
||||
pub fn allocate(&mut self) -> Result<Option<u64>, E> {
|
||||
let mut block = None;
|
||||
let mut block_option = None;
|
||||
for mut extent in self.free.1.extents.iter_mut() {
|
||||
if extent.length >= 512 {
|
||||
block = Some(extent.block);
|
||||
block_option = Some(extent.block);
|
||||
extent.length -= 512;
|
||||
extent.block += 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if block.is_some() {
|
||||
if block_option.is_some() {
|
||||
try!(self.disk.write_at(self.free.0, &self.free.1));
|
||||
}
|
||||
Ok(block)
|
||||
Ok(block_option)
|
||||
}
|
||||
|
||||
pub fn deallocate(&mut self, _block: u64) -> Result<bool, E> {
|
||||
@@ -178,7 +178,9 @@ impl<E> FileSystem<E> {
|
||||
}
|
||||
|
||||
pub fn create_node(&mut self, mode: u16, name: &str, parent_block: u64) -> Result<Option<(u64, Node)>, E> {
|
||||
if let Some(block) = try!(self.allocate()) {
|
||||
if try!(self.find_node(name, parent_block)).is_some() {
|
||||
Ok(None)
|
||||
} else if let Some(block) = try!(self.allocate()) {
|
||||
let node = (block, Node::new(mode, name, parent_block));
|
||||
try!(self.disk.write_at(node.0, &node.1));
|
||||
|
||||
@@ -192,7 +194,71 @@ impl<E> FileSystem<E> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn remove_node(&mut self, _name: &str) -> Result<bool, E> {
|
||||
fn remove_block(&mut self, block: u64, parent_block: u64) -> Result<bool, E> {
|
||||
if parent_block == 0 {
|
||||
return Ok(false);
|
||||
}
|
||||
|
||||
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 < extent.block + extent.length/512 {
|
||||
//Inside
|
||||
removed = true;
|
||||
|
||||
let left = Extent::new(extent.block, (block - extent.block) * 512);
|
||||
let right = Extent::new(block + 1, ((extent.block + extent.length/512) - (block + 1)) * 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 let Some(_replace) = replace_option {
|
||||
//do it!
|
||||
}
|
||||
|
||||
if removed {
|
||||
try!(self.disk.write_at(parent.0, &parent.1));
|
||||
Ok(true)
|
||||
} else {
|
||||
if parent.1.next == 0 {
|
||||
if let Some(block) = try!(self.allocate()) {
|
||||
parent.1.next = block;
|
||||
try!(self.disk.write_at(parent.0, &parent.1));
|
||||
try!(self.disk.write_at(parent.1.next, &Node::default()));
|
||||
} else {
|
||||
return Ok(false);
|
||||
}
|
||||
}
|
||||
|
||||
self.remove_block(block, parent.1.next)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn remove_node(&mut self, mode: u16, name: &str, parent_block: u64) -> Result<bool, E> {
|
||||
if let Some(mut node) = try!(self.find_node(name, parent_block)) {
|
||||
if node.1.mode & Node::MODE_TYPE == mode {
|
||||
if try!(self.remove_block(node.0, parent_block)) {
|
||||
node.1 = Node::default();
|
||||
try!(self.disk.write_at(node.0, &node.1));
|
||||
|
||||
return Ok(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(false)
|
||||
}
|
||||
}
|
||||
|
||||
+37
-9
@@ -137,6 +137,19 @@ fn shell<E: Display>(mut fs: FileSystem<E>){
|
||||
Err(err) => println!("ls: failed to read {}: {}", block, err)
|
||||
}
|
||||
},
|
||||
"mk" => {
|
||||
if let Some(arg) = args.next() {
|
||||
match fs.create_node(Node::MODE_FILE, arg, block) {
|
||||
Ok(node_option) => match node_option {
|
||||
Some(node) => println!("{}: {:#?}", node.0, node.1),
|
||||
None => println!("mk: not enough space for {}", arg)
|
||||
},
|
||||
Err(err) => println!("mk: failed to create {}: {}", arg, err)
|
||||
}
|
||||
} else {
|
||||
println!("mk <file>");
|
||||
}
|
||||
},
|
||||
"mkdir" => {
|
||||
if let Some(arg) = args.next() {
|
||||
match fs.create_node(Node::MODE_DIR, arg, block) {
|
||||
@@ -147,23 +160,38 @@ fn shell<E: Display>(mut fs: FileSystem<E>){
|
||||
Err(err) => println!("mkdir: failed to create {}: {}", arg, err)
|
||||
}
|
||||
} else {
|
||||
println!("mkdir <file>");
|
||||
println!("mkdir <dir>");
|
||||
}
|
||||
},
|
||||
"touch" => {
|
||||
"rm" => {
|
||||
if let Some(arg) = args.next() {
|
||||
match fs.create_node(Node::MODE_FILE, arg, block) {
|
||||
Ok(node_option) => match node_option {
|
||||
Some(node) => println!("{}: {:#?}", node.0, node.1),
|
||||
None => println!("touch: not enough space for {}", arg)
|
||||
match fs.remove_node(Node::MODE_FILE, arg, block) {
|
||||
Ok(found) => if found {
|
||||
println!("rm {}", arg);
|
||||
}else{
|
||||
println!("rm: did not find {}", arg);
|
||||
},
|
||||
Err(err) => println!("touch: failed to create {}: {}", arg, err)
|
||||
Err(err) => println!("rm: failed to remove {}: {}", arg, err)
|
||||
}
|
||||
} else {
|
||||
println!("touch <file>");
|
||||
println!("rm <file>");
|
||||
}
|
||||
},
|
||||
_ => println!("commands: exit header node root free find ls mkdir touch")
|
||||
"rmdir" => {
|
||||
if let Some(arg) = args.next() {
|
||||
match fs.remove_node(Node::MODE_DIR, arg, block) {
|
||||
Ok(found) => if found {
|
||||
println!("rmdir {}", arg);
|
||||
}else{
|
||||
println!("rmdir: did not find {}", arg);
|
||||
},
|
||||
Err(err) => println!("rmdir: failed to remove {}: {}", arg, err)
|
||||
}
|
||||
} else {
|
||||
println!("rmdir <dir>");
|
||||
}
|
||||
},
|
||||
_ => println!("commands: exit header node root free find ls mk mkdir rm rmdir")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user