diff --git a/easy-fs/Cargo.toml b/easy-fs/Cargo.toml index 16ffc303..8fd21501 100644 --- a/easy-fs/Cargo.toml +++ b/easy-fs/Cargo.toml @@ -9,4 +9,5 @@ edition = "2018" [dependencies] spin = "0.7.0" #lazy_static = { version = "1.4.0", features = ["spin_no_std"] } -lazy_static = "1.4.0" \ No newline at end of file +lazy_static = "1.4.0" +rand = "0.8.0" \ No newline at end of file diff --git a/easy-fs/src/bin/main.rs b/easy-fs/src/bin/main.rs index c7b313c4..4a91928a 100644 --- a/easy-fs/src/bin/main.rs +++ b/easy-fs/src/bin/main.rs @@ -9,6 +9,7 @@ use std::fs::{File, OpenOptions}; use std::io::{Read, Write, Seek, SeekFrom}; use std::sync::Mutex; use alloc::sync::Arc; +use rand; const BLOCK_SZ: usize = 512; @@ -37,6 +38,11 @@ fn main() { } fn easy_fs_pack() -> std::io::Result<()> { + Ok(()) +} + +#[test] +fn efs_test() -> std::io::Result<()> { let block_file = Arc::new(BlockFile(Mutex::new( OpenOptions::new() .read(true) @@ -55,16 +61,49 @@ fn easy_fs_pack() -> std::io::Result<()> { for name in root_inode.ls() { println!("{}", name); } - { - let filea = root_inode.find("filea").unwrap(); - println!("writing filea!"); - filea.write_at(0, "Hello, world!".as_bytes()); - } - { - let filea = root_inode.find("filea").unwrap(); - let mut buffer = [0u8; 512]; - let len = filea.read_at(0, &mut buffer); - println!("{}", core::str::from_utf8(&buffer[..len]).unwrap()); - } + let filea = root_inode.find("filea").unwrap(); + let greet_str = "Hello, world!"; + filea.write_at(0, greet_str.as_bytes()); + let mut buffer = [0u8; 512]; + let len = filea.read_at(0, &mut buffer); + assert_eq!( + greet_str, + core::str::from_utf8(&buffer[..len]).unwrap(), + ); + + let mut random_str_test = |len: usize| { + filea.clear(); + assert_eq!( + filea.read_at(0, &mut buffer), + 0, + ); + let mut str = String::new(); + // random digit + for _ in 0..len { + str.push(char::from('0' as u8 + rand::random::() % 10)); + } + filea.write_at(0, str.as_bytes()); + let mut read_buffer = [0u8; 127]; + let mut offset = 0usize; + let mut read_str = String::new(); + loop { + let len = filea.read_at(offset, &mut read_buffer); + if len == 0 { + break; + } + offset += len; + read_str.push_str( + core::str::from_utf8(&read_buffer[..len]).unwrap() + ); + } + assert_eq!(str, read_str); + }; + + random_str_test(4 * BLOCK_SZ); + random_str_test(8 * BLOCK_SZ + BLOCK_SZ / 2); + random_str_test(100 * BLOCK_SZ); + random_str_test(70 * BLOCK_SZ + BLOCK_SZ / 7); + random_str_test((12 + 128) * BLOCK_SZ); + Ok(()) } \ No newline at end of file diff --git a/easy-fs/src/bitmap.rs b/easy-fs/src/bitmap.rs index edda5909..87f8d297 100644 --- a/easy-fs/src/bitmap.rs +++ b/easy-fs/src/bitmap.rs @@ -16,7 +16,7 @@ pub struct Bitmap { fn decomposition(mut bit: usize) -> (usize, usize, usize) { let block_pos = bit / BLOCK_BITS; bit = bit % BLOCK_BITS; - (block_pos, bit/64, bit % 64) + (block_pos, bit / 64, bit % 64) } impl Bitmap { @@ -52,7 +52,7 @@ impl Bitmap { pub fn dealloc(&self, block_device: &Arc, bit: usize) { let (block_pos, bits64_pos, inner_pos) = decomposition(bit); let mut dirty_bitmap_block: Dirty = Dirty::new( - block_pos, + block_pos + self.start_block_id, 0, block_device.clone(), ); diff --git a/easy-fs/src/efs.rs b/easy-fs/src/efs.rs index 2a8af448..34c6ad82 100644 --- a/easy-fs/src/efs.rs +++ b/easy-fs/src/efs.rs @@ -145,7 +145,7 @@ impl EasyFileSystem { self.data_bitmap.alloc(&self.block_device).unwrap() as u32 + self.data_area_start_block } - fn dealloc_data(&mut self, block_id: u32) { + pub fn dealloc_data(&mut self, block_id: u32) { self.data_bitmap.dealloc( &self.block_device, (block_id - self.data_area_start_block) as usize diff --git a/easy-fs/src/layout.rs b/easy-fs/src/layout.rs index d173e0b0..99e4abc6 100644 --- a/easy-fs/src/layout.rs +++ b/easy-fs/src/layout.rs @@ -267,6 +267,7 @@ impl DirEntry { pub fn from_bytes(bytes: &DirentBytes) -> &Self { unsafe { &*(bytes.as_ptr() as usize as *const Self) } } + #[allow(unused)] pub fn from_bytes_mut(bytes: &mut DirentBytes) -> &mut Self { unsafe { &mut *(bytes.as_mut_ptr() as usize as *mut Self) diff --git a/easy-fs/src/vfs.rs b/easy-fs/src/vfs.rs index b544ac46..fe42adff 100644 --- a/easy-fs/src/vfs.rs +++ b/easy-fs/src/vfs.rs @@ -12,7 +12,6 @@ use alloc::sync::Arc; use alloc::string::String; use alloc::vec::Vec; use spin::{Mutex, MutexGuard}; -use crate::layout::DiskInodeType::Directory; pub struct Inode { inode_id: u32, @@ -196,4 +195,15 @@ impl Inode { disk_inode.write_at(offset, buf, &self.block_device) }) } + + pub fn clear(&self) { + let mut fs = self.fs.lock(); + let mut inode = self.get_disk_inode(&mut fs); + let data_blocks_dealloc = inode.modify(|disk_inode| { + disk_inode.clear_size(&self.block_device) + }); + for data_block in data_blocks_dealloc.into_iter() { + fs.dealloc_data(data_block); + } + } }