From 289f627be8f56a99e243d26ef9b8b5b84cb3bbe2 Mon Sep 17 00:00:00 2001 From: Ben Pig Chu Date: Mon, 22 Oct 2018 20:43:39 +0800 Subject: [PATCH] add unlink interface --- src/sfs.rs | 37 +++++++++++++++++++++++++++++++++---- src/vfs.rs | 2 ++ 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/src/sfs.rs b/src/sfs.rs index 5982280..8823159 100644 --- a/src/sfs.rs +++ b/src/sfs.rs @@ -96,16 +96,19 @@ impl INode { } } /// Only for Dir - fn get_file_inode_id(&self, name: &str) -> Option { + fn get_file_inode_and_entry_id(&self, name: &str) -> Option<(INodeId,usize)> { (0..self.disk_inode.blocks) .map(|i| { use vfs::INode; let mut entry: DiskEntry = unsafe { uninitialized() }; self._read_at(i as usize * BLKSIZE, entry.as_buf_mut()).unwrap(); - entry + (entry,i) }) - .find(|entry| entry.name.as_ref() == name) - .map(|entry| entry.id as INodeId) + .find(|(entry,id)| entry.name.as_ref() == name) + .map(|(entry,id)| (entry.id as INodeId,id as usize)) + } + fn get_file_inode_id(&self, name: &str) -> Option { + self.get_file_inode_and_entry_id(name).map(|(inode_id,entry_id)|{inode_id}) } /// Init dir content. Insert 2 init entries. fn init_dir(&mut self, parent: INodeId) -> vfs::Result<()> { @@ -279,6 +282,30 @@ impl vfs::INode for INode { Ok(inode) } + fn unlink(&mut self, name: &str) -> vfs::Result<()> { + let fs = self.fs.upgrade().unwrap(); + let info = self.info().unwrap(); + assert_eq!(info.type_, vfs::FileType::Dir); + + let inode_and_entry_id = self.get_file_inode_and_entry_id(name); + if inode_and_entry_id.is_none() { + return Err(()); + } + let (inode_id,entry_id)=inode_and_entry_id.unwrap(); + let inode = fs.get_inode(inode_id); + + let type_ = inode.borrow().disk_inode.type_; + if(type_==FileType::Dir){ + // only . and .. + assert!(inode.borrow().disk_inode.blocks==2); + } + + //todo: actually unlink: + //1. move the last entry to the original place + //2. free the disc space + + unimplemented!(); + } fn lookup(&self, path: &str) -> vfs::Result> { let fs = self.fs.upgrade().unwrap(); let info = self.info().unwrap(); @@ -322,6 +349,7 @@ impl Drop for INode { fn drop(&mut self) { use vfs::INode; self.sync().expect("failed to sync"); + //TODO: check nlink and atually remove } } @@ -488,6 +516,7 @@ impl vfs::FileSystem for SimpleFileSystem { use vfs::INode; inode.borrow_mut().sync().unwrap(); } + //TODO: drop no ref inode Ok(()) } diff --git a/src/vfs.rs b/src/vfs.rs index ad2b560..14812dd 100644 --- a/src/vfs.rs +++ b/src/vfs.rs @@ -23,6 +23,8 @@ pub trait INode: Debug { // fn reclaim(&mut self) -> Result<()>; fn resize(&mut self, len: usize) -> Result<()>; fn create(&mut self, name: &str, type_: FileType) -> Result; + // since we do not have link, unlink==remove + fn unlink(&mut self, name: &str) -> Result<()>; fn lookup(&self, path: &str) -> Result; fn list(&self) -> Result>; // fn io_ctrl(&mut self, op: u32, data: &[u8]) -> Result<()>;