diff options
author | Chuyan Zhang <me@zcy.moe> | 2023-11-26 02:33:01 -0800 |
---|---|---|
committer | Chuyan Zhang <me@zcy.moe> | 2023-11-26 02:33:01 -0800 |
commit | 9d1368b0ea380a9446b4697af668d1685464b6c7 (patch) | |
tree | 2103af418264cc70addc9cfc6ed7acac640f5151 /src/disk | |
parent | 777d5e01a34b8ebe6f1a5751b593266f93e88499 (diff) | |
download | myfs-9d1368b0ea380a9446b4697af668d1685464b6c7.tar.gz myfs-9d1368b0ea380a9446b4697af668d1685464b6c7.zip |
more code idk what they are im so tired ohno
Diffstat (limited to 'src/disk')
-rw-r--r-- | src/disk/allocation.rs | 164 | ||||
-rw-r--r-- | src/disk/block.rs | 9 | ||||
-rw-r--r-- | src/disk/inode.rs | 26 |
3 files changed, 168 insertions, 31 deletions
diff --git a/src/disk/allocation.rs b/src/disk/allocation.rs index 57cca0e..b88e7d5 100644 --- a/src/disk/allocation.rs +++ b/src/disk/allocation.rs @@ -1,7 +1,10 @@ -use crate::disk::block::{Block, DataBlock, DoubleIndirectBlock, IndirectBlock, TripleIndirectBlock}; -use crate::disk::inode::{DIRECT_NUMBER, Inode}; -use crate::memory::cached_block::{CachedBlock, convert}; +use crate::disk::block::{ + Block, DataBlock, DoubleIndirectBlock, IndirectBlock, TripleIndirectBlock, +}; +use crate::disk::inode::{Inode, DIRECT_NUMBER}; +use crate::memory::cached_block::{convert, CachedBlock}; use crate::{AyaFS, INODE_PER_BLOCK}; +use libc::c_int; impl AyaFS { /// 为 Inode 分配新 block, 返回 block 的编号和它在 inode 内的编号 @@ -13,6 +16,8 @@ impl AyaFS { // println!("allocating {} for direct", block_index); *index = block_index; inode.n_blocks += 1; + // 初始化这个 block + self.init_block(block_index as usize); // 当调用 get_inode_mut 拿出 &mut Inode 的时候对应的 block 在 cache 里已经脏了 return Some((block_index, index_within_direct)); } @@ -24,12 +29,16 @@ impl AyaFS { .data_bitmap .allocate() .expect("No free space for new block") as u32; + self.init_block(inode.single_indirect as usize); // println!("allocating {} for indirect", inode.single_indirect); } // 在 indirect block 里尝试分配 - if let Some((block_index, index_within_indirect)) = self.allocate_in_indirect(inode.single_indirect) { + if let Some((block_index, index_within_indirect)) = + self.allocate_in_indirect(inode.single_indirect) + { // println!("allocating {} in indirect", block_index); inode.n_blocks += 1; + let index_within_block = DIRECT_NUMBER + index_within_indirect; return Some((block_index, index_within_block)); } @@ -40,10 +49,13 @@ impl AyaFS { .data_bitmap .allocate() .expect("No free space for new block") as u32; + self.init_block(inode.double_indirect as usize); // println!("allocating {} for double indirect", inode.double_indirect); } // 在 double indirect block 里尝试分配 - if let Some((block_index, index_within_double)) = self.alloc_in_double_indirect(inode.double_indirect) { + if let Some((block_index, index_within_double)) = + self.alloc_in_double_indirect(inode.double_indirect) + { // println!("allocating {} in double indirect", block_index); inode.n_blocks += 1; let index_within_block = DIRECT_NUMBER + INODE_PER_BLOCK + index_within_double; @@ -56,13 +68,19 @@ impl AyaFS { .data_bitmap .allocate() .expect("No free space for new block") as u32; + self.init_block(inode.triple_indirect as usize); // println!("allocating {} for triple indirect", inode.triple_indirect); } // 在 double indirect block 里尝试分配 - if let Some((block_index, index_within_triple)) = self.alloc_in_triple_indirect(inode.triple_indirect) { + if let Some((block_index, index_within_triple)) = + self.alloc_in_triple_indirect(inode.triple_indirect) + { // println!("allocating {} in triple indirect", block_index); inode.n_blocks += 1; - let index_within_block = DIRECT_NUMBER + INODE_PER_BLOCK + INODE_PER_BLOCK * INODE_PER_BLOCK + index_within_triple; + let index_within_block = DIRECT_NUMBER + + INODE_PER_BLOCK + + INODE_PER_BLOCK * INODE_PER_BLOCK + + index_within_triple; return Some((block_index, index_within_block)); } None @@ -79,10 +97,13 @@ impl AyaFS { { // println!("found indirect block with number {}", indirect_entry); let mut indirect_block = block.clone(); - for (index_within_indirect, entry) in indirect_block.block.entries.iter_mut().enumerate() { + for (index_within_indirect, entry) in + indirect_block.block.entries.iter_mut().enumerate() + { if self.data_bitmap.query(*entry as usize) == false { indirect_block.dirty = true; // 把这个块标记为 dirty let block_index = self.data_bitmap.allocate().expect("No free space") as u32; + self.init_block(block_index as usize); *entry = block_index; self.update_block(indirect_block); return Some((block_index, index_within_indirect)); @@ -101,18 +122,26 @@ impl AyaFS { { let mut double_indirect_block = block.clone(); let mut double_indirect_modified = false; - for (index_within_double_indirect, indirect_entry) in double_indirect_block.block.indirect.iter_mut().enumerate() { + for (index_within_double_indirect, indirect_entry) in + double_indirect_block.block.indirect.iter_mut().enumerate() + { if self.data_bitmap.query(*indirect_entry as usize) == false { double_indirect_block.dirty = true; double_indirect_modified = true; - *indirect_entry = self.data_bitmap.allocate().expect("No free space") as u32; + + let indirect_index = self.data_bitmap.allocate().expect("No free space"); + *indirect_entry = indirect_index as u32; + self.init_block(indirect_index); } - if let Some((block_index, index_within_indirect)) = self.allocate_in_indirect(*indirect_entry) { + if let Some((block_index, index_within_indirect)) = + self.allocate_in_indirect(*indirect_entry) + { if double_indirect_modified { self.update_block(double_indirect_block); } - let index_within_double = index_within_double_indirect * INODE_PER_BLOCK + index_within_indirect; + let index_within_double = + index_within_double_indirect * INODE_PER_BLOCK + index_within_indirect; return Some((block_index, index_within_double)); } } @@ -129,18 +158,29 @@ impl AyaFS { { let mut triple_indirect_block = block.clone(); let mut triple_indirect_modified = false; - for (index_within_triple_indirect, double_indirect_entry) in triple_indirect_block.block.double_indirect.iter_mut().enumerate() { + for (index_within_triple_indirect, double_indirect_entry) in triple_indirect_block + .block + .double_indirect + .iter_mut() + .enumerate() + { if self.data_bitmap.query(*double_indirect_entry as usize) == false { triple_indirect_block.dirty = true; triple_indirect_modified = true; - *double_indirect_entry = - self.data_bitmap.allocate().expect("No free space") as u32; + + let double_indirect_index = self.data_bitmap.allocate().expect("No free space"); + *double_indirect_entry = double_indirect_index as u32; + self.init_block(double_indirect_index) } - if let Some((block_index, index_within_double_indirect)) = self.alloc_in_double_indirect(*double_indirect_entry) { + if let Some((block_index, index_within_double_indirect)) = + self.alloc_in_double_indirect(*double_indirect_entry) + { if triple_indirect_modified { self.update_block(triple_indirect_block); } - let index_within_triple = index_within_triple_indirect * INODE_PER_BLOCK * INODE_PER_BLOCK + index_within_double_indirect; + let index_within_triple = + index_within_triple_indirect * INODE_PER_BLOCK * INODE_PER_BLOCK + + index_within_double_indirect; return Some((block_index, index_within_triple)); } } @@ -150,6 +190,70 @@ impl AyaFS { } impl AyaFS { + pub(crate) fn deallocate_all_blocks_for(&mut self, inode: &Inode) -> Result<(), c_int> { + // 遍历 direct block 并删除 + for block_index in inode.direct { + self.data_bitmap.deallocate(block_index as usize); + } + + // 遍历 indirect block 并删除 + if self.data_bitmap.query(inode.single_indirect as usize) { + let indirect = self + .get_block::<IndirectBlock>(inode.single_indirect as usize) + .unwrap(); + for block_index in indirect.block.entries { + self.data_bitmap.deallocate(block_index as usize); + } + self.data_bitmap.deallocate(inode.single_indirect as usize); + } + + // 遍历 double indirect block 并删除 + if self.data_bitmap.query(inode.double_indirect as usize) { + let double_indirect = self + .get_block::<DoubleIndirectBlock>(inode.double_indirect as usize) + .unwrap(); + for indirect_block_index in double_indirect.block.indirect { + if let Some(indirect) = + self.get_block::<IndirectBlock>(indirect_block_index as usize) + { + for block_index in indirect.block.entries { + self.data_bitmap.deallocate(block_index as usize); + } + self.data_bitmap.deallocate(indirect_block_index as usize); + } + } + self.data_bitmap.deallocate(inode.double_indirect as usize); + } + + // 遍历 triple indirect block 并删除 + if self.data_bitmap.query(inode.triple_indirect as usize) { + let triple_indirect = self + .get_block::<TripleIndirectBlock>(inode.triple_indirect as usize) + .unwrap(); + for double_indirect_block_index in triple_indirect.block.double_indirect { + if let Some(double_indirect) = + self.get_block::<DoubleIndirectBlock>(double_indirect_block_index as usize) + { + for indirect_block_index in double_indirect.block.indirect { + if let Some(indirect) = + self.get_block::<IndirectBlock>(indirect_block_index as usize) + { + for block_index in indirect.block.entries { + self.data_bitmap.deallocate(block_index as usize); + } + self.data_bitmap.deallocate(indirect_block_index as usize); + } + } + self.data_bitmap + .deallocate(double_indirect_block_index as usize); + } + } + self.data_bitmap.deallocate(inode.triple_indirect as usize); + } + + Ok(()) + } + /// 从 inode 中删去最后一个 block pub(crate) fn deallocate_block_for(&mut self, inode: &mut Inode) -> Option<u32> { // 如果 triple indirect 块存在, 则尝试从中销毁一个块 @@ -294,7 +398,11 @@ impl AyaFS { } impl AyaFS { - fn get_block_index(&mut self, inode: &Inode, mut block_index_within_inode: usize) -> Option<usize> { + fn get_block_index( + &mut self, + inode: &Inode, + mut block_index_within_inode: usize, + ) -> Option<usize> { // direct block if block_index_within_inode < DIRECT_NUMBER { let block_index = inode.direct[block_index_within_inode] as usize; @@ -335,7 +443,7 @@ impl AyaFS { [block_index_within_inode % INODE_PER_BLOCK] as usize; // 拿到 DirectoryBlock 的 index - return Some(block_index) + return Some(block_index); } } return None; @@ -358,7 +466,7 @@ impl AyaFS { // 取出 double indirect block let indirect_block_index = double_indirect_block.block.indirect [block_index_within_inode % (INODE_PER_BLOCK * INODE_PER_BLOCK) - / INODE_PER_BLOCK] as usize; + / INODE_PER_BLOCK] as usize; // 要找的 entry 在 double indirect block 中的第几个 indirect block if let Some(indirect_block) = self.get_block::<IndirectBlock>(indirect_block_index) { @@ -366,7 +474,7 @@ impl AyaFS { [block_index_within_inode % INODE_PER_BLOCK] as usize; // DirectoryBlock 的 index - return Some(block_index) + return Some(block_index); } } } @@ -374,17 +482,25 @@ impl AyaFS { None } - pub(crate) fn access_block<T: Block>(&mut self, inode: &Inode, block_index_within_inode: usize) -> Option<&CachedBlock<T>> { + pub(crate) fn access_block<T: Block>( + &mut self, + inode: &Inode, + block_index_within_inode: usize, + ) -> Option<&CachedBlock<T>> { self.get_block_index(inode, block_index_within_inode) .map(|block_index| { self.get_block::<T>(block_index).unwrap() // 可以 unwrap 吧这里 ?? }) } - pub(crate) fn access_block_mut<T: Block>(&mut self, inode: &Inode, block_index_within_inode: usize) -> Option<&mut CachedBlock<T>> { + pub(crate) fn access_block_mut<T: Block>( + &mut self, + inode: &Inode, + block_index_within_inode: usize, + ) -> Option<&mut CachedBlock<T>> { self.get_block_index(inode, block_index_within_inode) .map(|block_index| { self.get_block_mut::<T>(block_index).unwrap() // 可以 unwrap 吧这里 ?? }) } -}
\ No newline at end of file +} diff --git a/src/disk/block.rs b/src/disk/block.rs index be3d85a..26a7ec5 100644 --- a/src/disk/block.rs +++ b/src/disk/block.rs @@ -120,10 +120,12 @@ impl DirectoryBlock { } pub(crate) fn query(&self, mut index: usize) -> bool { - if index < 7 { // 0-6, first u8 + if index < 7 { + // 0-6, first u8 index = index + 1; self.occupancy[0] & (1 << (7 - index)) as u8 != 0 - } else if index < 15 { // 7-14, second u8 + } else if index < 15 { + // 7-14, second u8 index = index - 7; self.occupancy[1] & (1 << (7 - index)) as u8 != 0 } else { @@ -149,7 +151,8 @@ impl DirectoryBlock { if index < 7 { index = index + 1; self.occupancy[0] &= !((1 << (7 - index)) as u8); - } else if index < 15 { // 7-14, second u8 + } else if index < 15 { + // 7-14, second u8 index = index - 7; self.occupancy[1] &= !((1 << (7 - index)) as u8); } diff --git a/src/disk/inode.rs b/src/disk/inode.rs index 256d2f5..6f9d338 100644 --- a/src/disk/inode.rs +++ b/src/disk/inode.rs @@ -1,6 +1,6 @@ +use crate::utils; use bitflags::bitflags; use fuser::{FileAttr, FileType}; -use crate::utils; pub const DIRECT_NUMBER: usize = 15; @@ -103,7 +103,6 @@ impl From<InodeMode> for u8 { } } - /// Pretty much the same with ext2, with minor changes: /// - removed OS dependent attributes (osd1 & osd2) /// - removed i_faddr since fragmentation is not supported @@ -153,7 +152,7 @@ impl Inode { mtime: time, crtime: time, gid, - n_links: 0, + n_links: 1, n_blocks: 0, flags, direct: [0; DIRECT_NUMBER], @@ -242,7 +241,26 @@ impl Inode { } pub fn empty() -> Self { - Self::new(InodeMode(0), 0, 0, 0, 0, 0, 0, 0) + Self { + mode: InodeMode(0), + uid: 0, + size: 0, + atime: 0, + ctime: 0, + mtime: 0, + crtime: 0, + gid: 0, + n_links: 0, + n_blocks: 0, + flags: 0, + direct: [0; 15], + single_indirect: 0, + double_indirect: 0, + triple_indirect: 0, + generation: 0, + file_acl: 0, + dir_acl: 0, + } } } pub const INODE_SIZE: usize = std::mem::size_of::<Inode>(); |