summaryrefslogtreecommitdiff
path: root/ayafs-core/src/lib.rs
diff options
context:
space:
mode:
authorChuyan Zhang <me@zcy.moe>2023-12-01 19:42:13 -0800
committerChuyan Zhang <me@zcy.moe>2023-12-01 19:42:13 -0800
commit4c34414b26bf71e747ea3ecb2586645bab4aba52 (patch)
treeb569935a94c7fb3e0a23a19207f6545b4d7719c3 /ayafs-core/src/lib.rs
parentfd125947c9db0b33761414e65e919f73d9bf1815 (diff)
downloadmyfs-4c34414b26bf71e747ea3ecb2586645bab4aba52.tar.gz
myfs-4c34414b26bf71e747ea3ecb2586645bab4aba52.zip
Multiple bugfix, it works!
Diffstat (limited to 'ayafs-core/src/lib.rs')
-rw-r--r--ayafs-core/src/lib.rs124
1 files changed, 111 insertions, 13 deletions
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<dyn BlockDevice>, total_block_number: usize) -> Self {
+ pub fn new(device: Arc<dyn BlockDevice>, 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<dyn BlockDevice>) -> 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::<SuperBlock>())
+ };
+ 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();
+ }
}