From ec2f349a648e4d87fba12d20e338b1cd6d8ef29a Mon Sep 17 00:00:00 2001 From: Chuyan Zhang Date: Mon, 27 Nov 2023 00:11:55 -0800 Subject: Fix directory stuff --- src/memory/cached_inode.rs | 92 ++++++++++++++++++++++++++++------------------ 1 file changed, 56 insertions(+), 36 deletions(-) (limited to 'src/memory/cached_inode.rs') diff --git a/src/memory/cached_inode.rs b/src/memory/cached_inode.rs index aa4f5e3..a9c92f5 100644 --- a/src/memory/cached_inode.rs +++ b/src/memory/cached_inode.rs @@ -2,7 +2,7 @@ use crate::disk::block::{DirectoryBlock, DirectoryEntry, InodeBlock}; use crate::disk::inode::{Inode, INODE_SIZE}; use crate::{utils, AyaFS}; use and_then_some::BoolExt; -use libc::{c_int, EISDIR, ENOENT, ENOTDIR}; +use libc::{c_int, EISDIR, ENOENT, ENOTDIR, ENOTEMPTY}; impl AyaFS { pub(crate) fn create_file( @@ -27,41 +27,53 @@ impl AyaFS { uid: u32, gid: u32, flags: u32, - parent_inode_number: Option, + parent_inode_number: Option, ) -> Option<(usize, &Inode)> { self.inode_bitmap.allocate().map(|inode_index| { // 创建 Inode let mut new_inode = Inode::directory(permissions, uid, gid, utils::time_now(), flags, 0, 0, 0); - // 分配第一个 direct block - (new_inode.direct[0], _) = self.allocate_block_for(&mut new_inode).unwrap(); - new_inode.size = 2; - // 在 direct block 里分配 . 和 .. - if let Some(directory_block) = - self.get_block_mut::(new_inode.direct[0] as usize) - { - let dot = '.'.to_ascii_lowercase() as u8; - // add dot entry - directory_block.block.entries[0] = DirectoryEntry { - inode: inode_index as u32, - record_len: 264, - name_len: 1, - file_type: 0x2, - name: [0; 256], - }; - directory_block.block.entries[0].name[0] = dot; + self.init_direntry_map(inode_index); + self.add_direntry(inode_index, &mut new_inode, inode_index, ".", 0x2) + .unwrap(); + self.add_direntry( + inode_index, + &mut new_inode, + parent_inode_number.unwrap_or(inode_index), + "..", + 0x2, + ) + .unwrap(); - // add dot dot entry - directory_block.block.entries[1] = DirectoryEntry { - inode: parent_inode_number.unwrap_or(inode_index as u32), - record_len: 264, - name_len: 2, - file_type: 0x2, - name: [0; 256], - }; - directory_block.block.entries[1].name[0] = dot; - directory_block.block.entries[1].name[1] = dot; - } + // // 分配第一个 direct block + // (new_inode.direct[0], _) = self.allocate_block_for(&mut new_inode).unwrap(); + // new_inode.size = 2; + // // 在 direct block 里分配 . 和 .. + // if let Some(directory_block) = + // self.get_block_mut::(new_inode.direct[0] as usize) + // { + // let dot = '.'.to_ascii_lowercase() as u8; + // // add dot entry + // directory_block.block.entries[0] = DirectoryEntry { + // inode: inode_index as u32, + // record_len: 264, + // name_len: 1, + // file_type: 0x2, + // name: [0; 256], + // }; + // directory_block.block.entries[0].name[0] = dot; + // + // // add dot dot entry + // directory_block.block.entries[1] = DirectoryEntry { + // inode: parent_inode_number.unwrap_or(inode_index as u32), + // record_len: 264, + // name_len: 2, + // file_type: 0x2, + // name: [0; 256], + // }; + // directory_block.block.entries[1].name[0] = dot; + // directory_block.block.entries[1].name[1] = dot; + // } // 把 inode 放到指定位置 self.get_inode_mut(inode_index).map(|inode| { *inode = new_inode; @@ -70,10 +82,9 @@ impl AyaFS { (inode_index, self.get_inode(inode_index).unwrap()) }) } - + pub(crate) fn remove_file(&mut self, inode_index: usize) -> Result { if self.inode_bitmap.query(inode_index) { - self.inode_bitmap.deallocate(inode_index); let (block_index, offset) = self.locate_inode(inode_index); if let Some(cached_block) = self.cached_inodes.get_block::(block_index) { let inode = cached_block.block.inodes[offset / INODE_SIZE].clone(); @@ -82,23 +93,32 @@ impl AyaFS { } self.deallocate_all_blocks_for(&inode).unwrap(); } + self.inode_bitmap.deallocate(inode_index); Ok(true) } else { Err(ENOENT) } } - + + // 要删除的 inode 一定得是空的 pub(crate) fn remove_dir(&mut self, inode_index: usize) -> Result { if self.inode_bitmap.query(inode_index) { - self.inode_bitmap.deallocate(inode_index); let (block_index, offset) = self.locate_inode(inode_index); if let Some(cached_block) = self.cached_inodes.get_block::(block_index) { - let inode = cached_block.block.inodes[offset / INODE_SIZE].clone(); + let inode = &cached_block.block.inodes[offset / INODE_SIZE].clone(); if !inode.is_dir() { + // 不是 dir -> ENOTDIR return Err(ENOTDIR); } - // TODO 递归删除所有下面的 direntry 里的 inode, 注意排除 . 和 .. + if inode.size > 2 { + // 有 . 和 .. 以外的 entry -> ENOTEMPTY + return Err(ENOTEMPTY); + } + // 销毁 inode 里的所有 block + self.deallocate_all_blocks_for(inode).unwrap(); } + // 销毁 inode + self.inode_bitmap.deallocate(inode_index); Ok(true) } else { Err(ENOENT) -- cgit v1.2.3-70-g09d2