summaryrefslogtreecommitdiff
path: root/src/disk
diff options
context:
space:
mode:
Diffstat (limited to 'src/disk')
-rw-r--r--src/disk/allocation.rs164
-rw-r--r--src/disk/block.rs9
-rw-r--r--src/disk/inode.rs26
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>();