summaryrefslogtreecommitdiff
path: root/src/memory/cached_inode.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/memory/cached_inode.rs')
-rw-r--r--src/memory/cached_inode.rs92
1 files changed, 56 insertions, 36 deletions
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<u32>,
+ parent_inode_number: Option<usize>,
) -> 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::<DirectoryBlock>(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::<DirectoryBlock>(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<bool, c_int> {
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::<InodeBlock>(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<bool, c_int> {
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::<InodeBlock>(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)