From fd125947c9db0b33761414e65e919f73d9bf1815 Mon Sep 17 00:00:00 2001 From: Chuyan Zhang Date: Thu, 30 Nov 2023 12:01:11 -0800 Subject: Refactor workspace --- ayafs-core/src/lib.rs | 140 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100644 ayafs-core/src/lib.rs (limited to 'ayafs-core/src/lib.rs') diff --git a/ayafs-core/src/lib.rs b/ayafs-core/src/lib.rs new file mode 100644 index 0000000..5ec118a --- /dev/null +++ b/ayafs-core/src/lib.rs @@ -0,0 +1,140 @@ +pub mod block_device; +pub mod disk; +pub mod filesystem; +pub mod memory; +pub mod tests; +pub mod utils; + + +use indexmap::IndexMap; +use log::debug; +use lru::LruCache; +use std::collections::HashMap; +use std::ffi::OsString; +use std::num::NonZeroUsize; +use std::sync::atomic::AtomicU64; +use std::sync::Arc; +use std::time::Duration; + +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}; + +const TTL: Duration = Duration::new(0, 0); +const INODE_PER_BLOCK: usize = BLOCK_SIZE / INODE_SIZE; + +/// The design of MyFS is rather simple: +/// +-------------------+ +/// | Super Block | +/// +-------------------+ +/// | Inode Bitmap | +/// +-------------------+ +/// | ... | +/// +-------------------+ +/// | Data Block Bitmap | +/// +-------------------+ +/// | ... | +/// +-------------------+ +/// | Inode Block | +/// +-------------------+ +/// | ... | +/// +-------------------+ +/// | Data Block | +/// +-------------------+ +/// With each block 4KiB, each Inode entry 128B + +#[repr(C)] +pub struct AyaFS { + device: Arc, + data_bitmap: Bitmap, + inode_bitmap: Bitmap, + inode_start_block: usize, + data_start_block: usize, + + next_file_handle: AtomicU64, + // file descriptor -> (inode index, read, write) + file_handle_map: HashMap, + + // inode index -> (index aware) hashmap that maps dir entry name to inode index + dir_entry_map: LruCache>, + + cached_inodes: BlockCache, + cached_blocks: BlockCache, + + super_block: SuperBlock, +} + +impl AyaFS { + pub fn new(device: Arc, total_block_number: usize) -> 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; + + let blocks_remaining = + total_block_number - inode_block_number - inode_bitmap_block_number - 1; + // let number of data blocks be x, the remaining block number be C, + // the corresponding data bitmap length should be ceil(x / BLK_SIZE), + // thus we have BLK_SIZE * (C-1) / (BLK_SIZE+1) <= x <= BLK_SIZE * C / (BLK_SIZE+1) + // the difference of the two bounds is less than 1, + // meaning only 1 integer could be in between. + // Thus we have x = floor(BLK_SIZE * C / (BLK_SIZE + 1)) + let data_block_number = BLOCK_SIZE * blocks_remaining / (BLOCK_SIZE + 1); + let data_bitmap_block_number = blocks_remaining - data_block_number; + 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!( + "sum: {}", + 1 + data_bitmap_block_number + + inode_bitmap_block_number + + inode_block_number + + data_block_number + ); + + let super_block = SuperBlock::new( + data_bitmap_block_number, + inode_bitmap_block_number, + inode_block_number, + data_block_number, + ); + + let mut data_bitmap = Bitmap::new(1, data_bitmap_block_number, device.clone()); + 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(), + ); + let _ = inode_bitmap.allocate().unwrap(); // inode block 0 is not usable + + 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, + + 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), + + super_block, + }; + + fs.create_directory(0o755, get_current_uid(), get_current_gid(), 0, None); + + fs + } +} -- cgit v1.2.3-70-g09d2