From 4c34414b26bf71e747ea3ecb2586645bab4aba52 Mon Sep 17 00:00:00 2001 From: Chuyan Zhang Date: Fri, 1 Dec 2023 19:42:13 -0800 Subject: Multiple bugfix, it works! --- ayafs-core/src/lib.rs | 124 ++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 111 insertions(+), 13 deletions(-) (limited to 'ayafs-core/src/lib.rs') diff --git a/ayafs-core/src/lib.rs b/ayafs-core/src/lib.rs index 5ec118a..db3ac28 100644 --- a/ayafs-core/src/lib.rs +++ b/ayafs-core/src/lib.rs @@ -1,3 +1,6 @@ +#[macro_use] +extern crate static_assertions; + pub mod block_device; pub mod disk; pub mod filesystem; @@ -15,17 +18,17 @@ use std::num::NonZeroUsize; use std::sync::atomic::AtomicU64; use std::sync::Arc; use std::time::Duration; +use libc::{gid_t, uid_t}; use crate::disk::block::{DirectoryEntry, InodeBlock, SuperBlock}; use crate::memory::cached_block::BlockCache; use block_device::{BlockDevice, BLOCK_SIZE}; use disk::bitmap::Bitmap; use disk::block::DataBlock; -use disk::inode::INODE_SIZE; -use users::{get_current_gid, get_current_uid}; +use crate::disk::inode::INODE_PER_BLOCK; + const TTL: Duration = Duration::new(0, 0); -const INODE_PER_BLOCK: usize = BLOCK_SIZE / INODE_SIZE; /// The design of MyFS is rather simple: /// +-------------------+ @@ -69,7 +72,7 @@ pub struct AyaFS { } impl AyaFS { - pub fn new(device: Arc, total_block_number: usize) -> Self { + pub fn new(device: Arc, total_block_number: usize, uid: uid_t, gid: gid_t) -> Self { let max_inode_number: usize = 16384; // TODO: remove hard-coded magic number let inode_block_number = max_inode_number / INODE_PER_BLOCK; // == 128 let inode_bitmap_block_number = (inode_block_number + BLOCK_SIZE - 1) / BLOCK_SIZE; @@ -101,40 +104,135 @@ impl AyaFS { inode_bitmap_block_number, inode_block_number, data_block_number, + total_block_number, + 0, + 0 ); - let mut data_bitmap = Bitmap::new(1, data_bitmap_block_number, device.clone()); + let mut data_bitmap = Bitmap::new(1, data_bitmap_block_number, device.clone(), 0); let _ = data_bitmap.allocate().unwrap(); // data block 0 is not usable let mut inode_bitmap = Bitmap::new( data_bitmap_block_number + 1, inode_bitmap_block_number, device.clone(), + 0, ); let _ = inode_bitmap.allocate().unwrap(); // inode block 0 is not usable + let inode_start_block = data_bitmap_block_number + inode_bitmap_block_number + 1; + let data_start_block = inode_start_block + inode_block_number; + let mut fs = Self { device: device.clone(), data_bitmap, inode_bitmap, - inode_start_block: data_bitmap_block_number + inode_bitmap_block_number + 1, - data_start_block: data_bitmap_block_number - + inode_bitmap_block_number - + inode_block_number - + 1, + inode_start_block, + data_start_block, next_file_handle: AtomicU64::new(3), // 0,1,2 are stdin, stdout and stderr file_handle_map: HashMap::new(), dir_entry_map: LruCache::new(NonZeroUsize::new(1024).unwrap()), - cached_inodes: BlockCache::new(device.clone(), 1024), - cached_blocks: BlockCache::new(device.clone(), 8192), + cached_inodes: BlockCache::new(device.clone(), 8192, inode_start_block), + cached_blocks: BlockCache::new(device.clone(), 16384, data_start_block), super_block, }; - fs.create_directory(0o755, get_current_uid(), get_current_gid(), 0, None); + fs.create_directory(0o755, uid, gid, 0, None); fs } + + pub fn load(device: Arc) -> Self { + let mut buffer = [0u8; 4096]; + device.read(0, &mut buffer); + + let super_block: SuperBlock = unsafe { + std::mem::transmute_copy(&buffer) + }; + let data_bitmap_block_number = super_block.data_bitmap_block_number as usize; + let inode_bitmap_block_number = super_block.inode_bitmap_block_number as usize; + let inode_block_number = super_block.inode_block_number as usize; + let data_block_number = super_block.data_block_number as usize; + debug!("data_bitmap_block_number: {}", data_bitmap_block_number); + debug!("inode_bitmap_block_number: {}", inode_bitmap_block_number); + debug!("inode_block_number: {}", inode_block_number); + debug!("data_block_number: {}", data_block_number); + debug!("total_block_number: {}", super_block.total_block_number); + debug!( + "sum: {}", + 1 + data_bitmap_block_number + + inode_bitmap_block_number + + inode_block_number + + data_block_number + ); + + let data_bitmap = Bitmap::load( + 1, + data_bitmap_block_number, + device.clone(), + super_block.used_block_number, + ); + debug!("data_bitmap starting from: {:?}", data_bitmap.peek()); + + let inode_bitmap = Bitmap::load( + data_bitmap_block_number + 1, + inode_bitmap_block_number, + device.clone(), + super_block.used_inode_number, + ); + debug!("inode_bitmap starting from: {:?}", inode_bitmap.peek()); + + let inode_start_block = data_bitmap_block_number + inode_bitmap_block_number + 1; + let data_start_block = inode_start_block + inode_block_number; + + Self { + device: device.clone(), + data_bitmap, + inode_bitmap, + inode_start_block, + data_start_block, + + next_file_handle: AtomicU64::new(3), // 0,1,2 are stdin, stdout and stderr + file_handle_map: HashMap::new(), + + dir_entry_map: LruCache::new(NonZeroUsize::new(1024).unwrap()), + + cached_inodes: BlockCache::new(device.clone(), 1024, inode_start_block), + cached_blocks: BlockCache::new(device.clone(), 8192, data_start_block), + + super_block, + } + } + + pub fn write_back(&mut self) { + self.super_block.used_inode_number = self.inode_bitmap.count; + self.super_block.used_block_number = self.data_bitmap.count; + let super_block_buffer = unsafe { + let ptr = &self.super_block as *const SuperBlock as *const u8; + std::slice::from_raw_parts(ptr, std::mem::size_of::()) + }; + self.device.write(0, super_block_buffer); + + while let Some((inode_index, dir_entry_map)) = self.dir_entry_map.pop_lru() { + debug!("writing back direntry map for inode {}", inode_index); + let mut inode = self.get_inode(inode_index).unwrap().clone(); + self.write_back_direntry( + inode_index, + &mut inode, + dir_entry_map, + ).unwrap(); + self.update_inode(inode_index, inode); + } // dir entry 的 write back 是写回到 block / inode cache 里, 所以要在前面 + + debug!("data_bitmap stopping at: {:?}", self.data_bitmap.peek()); + debug!("inode_bitmap stopping at: {:?}", self.inode_bitmap.peek()); + self.data_bitmap.write_back(); + self.inode_bitmap.write_back(); + + self.cached_blocks.write_back(); + self.cached_inodes.write_back(); + } } -- cgit v1.2.3-70-g09d2