diff --git a/src/sfs.rs b/src/sfs.rs index 8823159..e7eda15 100644 --- a/src/sfs.rs +++ b/src/sfs.rs @@ -111,17 +111,18 @@ impl INode { 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<()> { + /// This do not init nlinks, please modify the nlinks in the invoker. + fn init_dir_entry(&mut self, parent: INodeId) -> vfs::Result<()> { use vfs::INode; + let fs = self.fs.upgrade().unwrap(); // Insert entries: '.' '..' self._resize(BLKSIZE * 2).unwrap(); self._write_at(BLKSIZE * 1, DiskEntry { id: parent as u32, name: Str256::from(".."), }.as_buf()).unwrap(); - let id = self.id as u32; self._write_at(BLKSIZE * 0, DiskEntry { - id, + id: self.id as u32, name: Str256::from("."), }.as_buf()).unwrap(); Ok(()) @@ -220,6 +221,13 @@ impl INode { }).unwrap(); Ok(()) } + fn nlinks_inc(&mut self) { + self.disk_inode.nlinks+=1; + } + fn nlinks_dec(&mut self) { + assert!(self.disk_inode.nlinks>0); + self.disk_inode.nlinks-=1; + } } impl vfs::INode for INode { @@ -244,6 +252,7 @@ impl vfs::INode for INode { mode: 0, type_: vfs::FileType::from(self.disk_inode.type_.clone()), blocks: self.disk_inode.blocks as usize, + nlinks: self.disk_inode.nlinks as usize, }) } fn sync(&mut self) -> vfs::Result<()> { @@ -279,6 +288,11 @@ impl vfs::INode for INode { }; self._resize(info.size + BLKSIZE).unwrap(); self._write_at(info.size, entry.as_buf()).unwrap(); + inode.borrow_mut().nlinks_inc(); + if(type_==vfs::FileType::Dir){ + inode.borrow_mut().nlinks_inc();//for . + self.nlinks_inc();//for .. + } Ok(inode) } @@ -421,7 +435,9 @@ impl SimpleFileSystem { { use vfs::INode; let root = sfs._new_inode(BLKN_ROOT, Dirty::new_dirty(DiskINode::new_dir())); - root.borrow_mut().init_dir(BLKN_ROOT).unwrap(); + root.borrow_mut().init_dir_entry(BLKN_ROOT).unwrap(); + root.borrow_mut().nlinks_inc();//for . + root.borrow_mut().nlinks_inc();//for ..(root's parent is itself) root.borrow_mut().sync().unwrap(); } @@ -490,7 +506,7 @@ impl SimpleFileSystem { let id = self.alloc_block().unwrap(); let disk_inode = Dirty::new_dirty(DiskINode::new_dir()); let inode = self._new_inode(id, disk_inode); - inode.borrow_mut().init_dir(parent).unwrap(); + inode.borrow_mut().init_dir_entry(parent).unwrap(); Ok(inode) } } diff --git a/src/tests.rs b/src/tests.rs index f09e89f..6abffb1 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -51,6 +51,7 @@ fn open_sample_file() { #[test] fn create_new_sfs() { let sfs = _create_new_sfs(); + let root = sfs.root_inode(); } //#[test] @@ -74,6 +75,7 @@ fn create_file() { type_: FileType::File, mode: 0, blocks: 0, + nlinks: 1, }); sfs.sync().unwrap(); @@ -158,10 +160,25 @@ fn rc_layout() { fn kernel_image_file_create(){ let sfs = _open_sample_file(); let root = sfs.root_inode(); - let files_count_before = root.borrow().list().unwrap(); + let files_count_before = root.borrow().list().unwrap().len(); root.borrow_mut().create("hello2",FileType::File).unwrap(); - let files_count_after = root.borrow().list().unwrap(); - assert_eq!(files_count_before+1, files_count_after) + let files_count_after = root.borrow().list().unwrap().len(); + assert_eq!(files_count_before+1, files_count_after); + + sfs.sync().unwrap(); +} + +#[test] +fn nlinks(){ + let sfs = _create_new_sfs(); + let root = sfs.root_inode(); + assert_eq!(root.borrow().info().unwrap().nlinks,2); + let file1 = root.borrow_mut().create("file1", FileType::File).unwrap(); + assert_eq!(file1.borrow().info().unwrap().nlinks,1); + assert_eq!(root.borrow().info().unwrap().nlinks,2); + 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); sfs.sync().unwrap(); } \ No newline at end of file diff --git a/src/vfs.rs b/src/vfs.rs index 14812dd..e9b8375 100644 --- a/src/vfs.rs +++ b/src/vfs.rs @@ -37,6 +37,7 @@ pub struct FileInfo { pub mode: u32, pub type_: FileType, pub blocks: usize, + pub nlinks: usize, } #[derive(Debug, Eq, PartialEq)]