basic unlink implement

master
Ben Pig Chu 6 years ago
parent 77cea66f7e
commit 36277c5769

@ -271,6 +271,7 @@ impl vfs::INode for INode {
let fs = self.fs.upgrade().unwrap();
let info = self.info().unwrap();
assert_eq!(info.type_, vfs::FileType::Dir);
assert!(info.nlinks>0);
// Ensure the name is not exist
assert!(self.get_file_inode_id(name).is_none(), "file name exist");
@ -297,6 +298,8 @@ impl vfs::INode for INode {
Ok(inode)
}
fn unlink(&mut self, name: &str) -> vfs::Result<()> {
assert!(name!=".");
assert!(name!="..");
let fs = self.fs.upgrade().unwrap();
let info = self.info().unwrap();
assert_eq!(info.type_, vfs::FileType::Dir);
@ -313,12 +316,20 @@ impl vfs::INode for INode {
// only . and ..
assert!(inode.borrow().disk_inode.blocks==2);
}
inode.borrow_mut().nlinks_dec();
if(type_==FileType::Dir){
inode.borrow_mut().nlinks_dec();//for .
self.nlinks_dec();//for ..
}
let old_block_count=self.disk_inode.blocks as usize;
if(entry_id!=old_block_count - 1){//not last entry
let mut entry: DiskEntry = unsafe { uninitialized() };
self._read_at((old_block_count - 1) * BLKSIZE, entry.as_buf_mut()).unwrap();
self._write_at(entry_id * BLKSIZE, entry.as_buf()).unwrap();
}
self._resize((old_block_count - 1) * BLKSIZE).unwrap();
//todo: actually unlink:
//1. move the last entry to the original place
//2. free the disc space
unimplemented!();
Ok(())
}
fn lookup(&self, path: &str) -> vfs::Result<Ptr<vfs::INode>> {
let fs = self.fs.upgrade().unwrap();

@ -29,6 +29,7 @@ pub struct DiskINode {
/// one of SYS_TYPE_* above
pub type_: FileType,
/// number of hard links to this file
/// Note: "." and ".." is counted in this nlinks
pub nlinks: u16,
/// number of blocks
pub blocks: u32,

@ -168,6 +168,18 @@ fn kernel_image_file_create(){
sfs.sync().unwrap();
}
// #[test]
fn kernel_image_file_unlink(){
let sfs = _open_sample_file();
let root = sfs.root_inode();
let files_count_before = root.borrow().list().unwrap().len();
root.borrow_mut().unlink("hello");
let files_count_after = root.borrow().list().unwrap().len();
assert_eq!(files_count_before, files_count_after+1);
sfs.sync().unwrap();
}
#[test]
fn nlinks(){
let sfs = _create_new_sfs();
@ -179,6 +191,12 @@ fn nlinks(){
let dir1 = root.borrow_mut().create("dir1", FileType::Dir).unwrap();
assert_eq!(dir1.borrow().info().unwrap().nlinks,2);
assert_eq!(root.borrow().info().unwrap().nlinks,3);
root.borrow_mut().unlink("file1").unwrap();
assert_eq!(file1.borrow().info().unwrap().nlinks,0);
assert_eq!(root.borrow().info().unwrap().nlinks,3);
root.borrow_mut().unlink("dir1").unwrap();
assert_eq!(dir1.borrow().info().unwrap().nlinks,0);
assert_eq!(root.borrow().info().unwrap().nlinks,2);
sfs.sync().unwrap();
}

@ -37,6 +37,8 @@ pub struct FileInfo {
pub mode: u32,
pub type_: FileType,
pub blocks: usize,
// Note: different from linux, "." and ".." count in nlinks
// this is same as original ucore.
pub nlinks: usize,
}

Loading…
Cancel
Save