Merge branch 'ch8' into main
This commit is contained in:
commit
fbacac0585
65 changed files with 1998 additions and 660 deletions
|
@ -17,7 +17,7 @@ pub struct BlockCache {
|
|||
impl BlockCache {
|
||||
/// Load a new BlockCache from disk.
|
||||
pub fn new(
|
||||
block_id: usize,
|
||||
block_id: usize,
|
||||
block_device: Arc<dyn BlockDevice>
|
||||
) -> Self {
|
||||
let mut cache = [0u8; BLOCK_SZ];
|
||||
|
@ -125,4 +125,11 @@ pub fn get_block_cache(
|
|||
block_device: Arc<dyn BlockDevice>
|
||||
) -> Arc<Mutex<BlockCache>> {
|
||||
BLOCK_CACHE_MANAGER.lock().get_block_cache(block_id, block_device)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn block_cache_sync_all() {
|
||||
let manager = BLOCK_CACHE_MANAGER.lock();
|
||||
for (_, cache) in manager.queue.iter() {
|
||||
cache.lock().sync();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ use super::{
|
|||
DiskInodeType,
|
||||
Inode,
|
||||
get_block_cache,
|
||||
block_cache_sync_all,
|
||||
};
|
||||
use crate::BLOCK_SZ;
|
||||
|
||||
|
@ -50,7 +51,7 @@ impl EasyFileSystem {
|
|||
// clear all blocks
|
||||
for i in 0..total_blocks {
|
||||
get_block_cache(
|
||||
i as usize,
|
||||
i as usize,
|
||||
Arc::clone(&block_device)
|
||||
)
|
||||
.lock()
|
||||
|
@ -82,6 +83,7 @@ impl EasyFileSystem {
|
|||
.modify(root_inode_offset, |disk_inode: &mut DiskInode| {
|
||||
disk_inode.initialize(DiskInodeType::Directory);
|
||||
});
|
||||
block_cache_sync_all();
|
||||
Arc::new(Mutex::new(efs))
|
||||
}
|
||||
|
||||
|
@ -107,7 +109,7 @@ impl EasyFileSystem {
|
|||
data_area_start_block: 1 + inode_total_blocks + super_block.data_bitmap_blocks,
|
||||
};
|
||||
Arc::new(Mutex::new(efs))
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
pub fn root_inode(efs: &Arc<Mutex<Self>>) -> Inode {
|
||||
|
|
|
@ -211,6 +211,49 @@ impl DiskInode {
|
|||
Arc::clone(block_device)
|
||||
)
|
||||
.lock()
|
||||
.modify(0, |indirect2: &mut IndirectBlock| {
|
||||
while (a0 < a1) || (a0 == a1 && b0 < b1) {
|
||||
if b0 == 0 {
|
||||
indirect2[a0] = new_blocks.next().unwrap();
|
||||
}
|
||||
// fill current
|
||||
get_block_cache(
|
||||
indirect2[a0] as usize,
|
||||
Arc::clone(block_device)
|
||||
)
|
||||
.lock()
|
||||
.modify(0, |indirect1: &mut IndirectBlock| {
|
||||
indirect1[b0] = new_blocks.next().unwrap();
|
||||
});
|
||||
// move to next
|
||||
b0 += 1;
|
||||
if b0 == INODE_INDIRECT1_COUNT {
|
||||
b0 = 0;
|
||||
a0 += 1;
|
||||
}
|
||||
}
|
||||
});
|
||||
// alloc indirect2
|
||||
if total_blocks > INODE_INDIRECT1_COUNT as u32 {
|
||||
if current_blocks == INODE_INDIRECT1_COUNT as u32 {
|
||||
self.indirect2 = new_blocks.next().unwrap();
|
||||
}
|
||||
current_blocks -= INODE_INDIRECT1_COUNT as u32;
|
||||
total_blocks -= INODE_INDIRECT1_COUNT as u32;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
// fill indirect2 from (a0, b0) -> (a1, b1)
|
||||
let mut a0 = current_blocks as usize / INODE_INDIRECT1_COUNT;
|
||||
let mut b0 = current_blocks as usize % INODE_INDIRECT1_COUNT;
|
||||
let a1 = total_blocks as usize / INODE_INDIRECT1_COUNT;
|
||||
let b1 = total_blocks as usize % INODE_INDIRECT1_COUNT;
|
||||
// alloc low-level indirect1
|
||||
get_block_cache(
|
||||
self.indirect2 as usize,
|
||||
Arc::clone(block_device)
|
||||
)
|
||||
.lock()
|
||||
.modify(0, |indirect2: &mut IndirectBlock| {
|
||||
while (a0 < a1) || (a0 == a1 && b0 < b1) {
|
||||
if b0 == 0 {
|
||||
|
@ -416,7 +459,7 @@ impl DirEntry {
|
|||
}
|
||||
pub fn new(name: &str, inode_number: u32) -> Self {
|
||||
let mut bytes = [0u8; NAME_LENGTH_LIMIT + 1];
|
||||
&mut bytes[..name.len()].copy_from_slice(name.as_bytes());
|
||||
bytes[..name.len()].copy_from_slice(name.as_bytes());
|
||||
Self {
|
||||
name: bytes,
|
||||
inode_number,
|
||||
|
|
|
@ -15,4 +15,4 @@ pub use efs::EasyFileSystem;
|
|||
pub use vfs::Inode;
|
||||
use layout::*;
|
||||
use bitmap::Bitmap;
|
||||
use block_cache::get_block_cache;
|
||||
use block_cache::{get_block_cache, block_cache_sync_all};
|
|
@ -6,6 +6,7 @@ use super::{
|
|||
EasyFileSystem,
|
||||
DIRENT_SZ,
|
||||
get_block_cache,
|
||||
block_cache_sync_all,
|
||||
};
|
||||
use alloc::sync::Arc;
|
||||
use alloc::string::String;
|
||||
|
@ -145,6 +146,7 @@ impl Inode {
|
|||
});
|
||||
|
||||
let (block_id, block_offset) = fs.get_disk_inode_pos(new_inode_id);
|
||||
block_cache_sync_all();
|
||||
// return inode
|
||||
Some(Arc::new(Self::new(
|
||||
block_id,
|
||||
|
@ -185,10 +187,12 @@ impl Inode {
|
|||
|
||||
pub fn write_at(&self, offset: usize, buf: &[u8]) -> usize {
|
||||
let mut fs = self.fs.lock();
|
||||
self.modify_disk_inode(|disk_inode| {
|
||||
let size = self.modify_disk_inode(|disk_inode| {
|
||||
self.increase_size((offset + buf.len()) as u32, disk_inode, &mut fs);
|
||||
disk_inode.write_at(offset, buf, &self.block_device)
|
||||
})
|
||||
});
|
||||
block_cache_sync_all();
|
||||
size
|
||||
}
|
||||
|
||||
pub fn clear(&self) {
|
||||
|
@ -201,5 +205,6 @@ impl Inode {
|
|||
fs.dealloc_data(data_block);
|
||||
}
|
||||
});
|
||||
block_cache_sync_all();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue