Create two files and list them.

This commit is contained in:
Yifan Wu 2020-12-19 15:28:42 +08:00
parent 459efec595
commit c351635e2f
7 changed files with 104 additions and 36 deletions

View File

@ -8,3 +8,5 @@ edition = "2018"
[dependencies] [dependencies]
spin = "0.7.0" spin = "0.7.0"
#lazy_static = { version = "1.4.0", features = ["spin_no_std"] }
lazy_static = "1.4.0"

View File

@ -4,7 +4,6 @@ extern crate alloc;
use easy_fs::{ use easy_fs::{
BlockDevice, BlockDevice,
EasyFileSystem, EasyFileSystem,
Inode,
}; };
use std::fs::{File, OpenOptions}; use std::fs::{File, OpenOptions};
use std::io::{Read, Write, Seek, SeekFrom}; use std::io::{Read, Write, Seek, SeekFrom};
@ -54,7 +53,7 @@ fn easy_fs_pack() -> std::io::Result<()> {
root_inode.create("filea"); root_inode.create("filea");
root_inode.create("fileb"); root_inode.create("fileb");
for name in root_inode.ls() { for name in root_inode.ls() {
println!("name"); println!("{}", name);
} }
Ok(()) Ok(())
} }

View File

@ -0,0 +1,86 @@
use super::{
BlockDevice,
BLOCK_SZ,
};
use alloc::sync::{Arc, Weak};
use alloc::collections::BTreeMap;
use lazy_static::*;
use spin::Mutex;
pub struct BlockCache {
cache: [u8; BLOCK_SZ],
block_id: usize,
block_device: Arc<dyn BlockDevice>,
}
impl BlockCache {
pub fn new(block_id: usize, block_device: Arc<dyn BlockDevice>) -> Self {
let mut cache = [0u8; BLOCK_SZ];
block_device.read_block(block_id, &mut cache);
Self {
cache,
block_id,
block_device,
}
}
pub fn start_addr(&self, offset: usize) -> usize {
&self.cache[offset] as *const _ as usize
}
}
impl Drop for BlockCache {
fn drop(&mut self) {
// write back
self.block_device.write_block(self.block_id, &self.cache);
// invalid in block cache manager
BLOCK_CACHE_MANAGER.lock().invalid(self.block_id);
}
}
pub struct BlockCacheManager {
map: BTreeMap<usize, Weak<BlockCache>>,
}
lazy_static! {
static ref BLOCK_CACHE_MANAGER: Mutex<BlockCacheManager> = Mutex::new(
BlockCacheManager::new()
);
}
impl BlockCacheManager {
pub fn new() -> Self {
Self { map: BTreeMap::new() }
}
pub fn get(
&mut self,
block_id: usize,
block_device: Arc<dyn BlockDevice>
) -> Arc<BlockCache> {
if let Some(block_cache) = self.map.get(&block_id) {
// return cloned
block_cache.upgrade().unwrap().clone()
} else {
// fetch from disk
let block_cache = Arc::new(BlockCache::new(
block_id,
block_device.clone()
));
self.map.insert(
block_id,
Arc::downgrade(&block_cache),
);
// return
block_cache
}
}
pub fn invalid(&mut self, block_id: usize) {
assert!(self.map.remove(&block_id).is_some());
}
}
pub fn get_block_cache(
block_id: usize,
block_device: Arc<dyn BlockDevice>
) -> Arc<BlockCache> {
BLOCK_CACHE_MANAGER.lock().get(block_id, block_device)
}

View File

@ -1,45 +1,38 @@
use super::BlockDevice; use super::{
use super::BLOCK_SZ; BlockDevice,
BLOCK_SZ,
BlockCache,
get_block_cache,
};
use alloc::sync::Arc; use alloc::sync::Arc;
use core::marker::PhantomData; use core::marker::PhantomData;
pub struct Dirty<T> { pub struct Dirty<T> {
block_id: usize, block_cache: Arc<BlockCache>,
block_cache: [u8; BLOCK_SZ],
offset: usize, offset: usize,
dirty: bool,
block_device: Arc<dyn BlockDevice>,
phantom: PhantomData<T>, phantom: PhantomData<T>,
} }
impl<T> Dirty<T> where T: Sized { impl<T> Dirty<T> where T: Sized {
pub fn new(block_id: usize, offset: usize, block_device: Arc<dyn BlockDevice>) -> Self { pub fn new(block_id: usize, offset: usize, block_device: Arc<dyn BlockDevice>) -> Self {
Self { Self {
block_id, block_cache: get_block_cache(block_id, block_device.clone()),
block_cache: {
let mut cache = [0u8; BLOCK_SZ];
block_device.read_block(block_id as usize, &mut cache);
cache
},
offset, offset,
dirty: false,
block_device,
phantom: PhantomData, phantom: PhantomData,
} }
} }
pub fn get_mut(&mut self) -> &mut T { pub fn get_mut(&mut self) -> &mut T {
self.dirty = true;
let type_size = core::mem::size_of::<T>(); let type_size = core::mem::size_of::<T>();
// assert that the struct is inside a block // assert that the struct is inside a block
assert!(self.offset + type_size <= BLOCK_SZ); assert!(self.offset + type_size <= BLOCK_SZ);
let start_addr = &self.block_cache[self.offset] as *const _ as usize; let start_addr = self.block_cache.start_addr(self.offset);
unsafe { &mut *(start_addr as *mut T) } unsafe { &mut *(start_addr as *mut T) }
} }
pub fn get_ref(&self) -> &T { pub fn get_ref(&self) -> &T {
let type_size = core::mem::size_of::<T>(); let type_size = core::mem::size_of::<T>();
// assert that the struct is inside a block // assert that the struct is inside a block
assert!(self.offset + type_size <= BLOCK_SZ); assert!(self.offset + type_size <= BLOCK_SZ);
let start_addr = &self.block_cache[self.offset] as *const _ as usize; let start_addr = self.block_cache.start_addr(self.offset);
unsafe { &*(start_addr as *const T) } unsafe { &*(start_addr as *const T) }
} }
pub fn read<V>(&self, f: impl FnOnce(&T) -> V) -> V { pub fn read<V>(&self, f: impl FnOnce(&T) -> V) -> V {
@ -48,16 +41,4 @@ impl<T> Dirty<T> where T: Sized {
pub fn modify(&mut self, f: impl FnOnce(&mut T)) { pub fn modify(&mut self, f: impl FnOnce(&mut T)) {
f(self.get_mut()); f(self.get_mut());
} }
pub fn write_back(&mut self) {
if self.dirty {
self.block_device
.write_block(self.block_id as usize, &self.block_cache);
}
}
}
impl<T> Drop for Dirty<T> {
fn drop(&mut self) {
self.write_back();
}
} }

View File

@ -247,7 +247,7 @@ pub struct DirEntry {
pub const DIRENT_SZ: usize = 32; pub const DIRENT_SZ: usize = 32;
pub type DirentBlock = [DirEntry; BLOCK_SZ / DIRENT_SZ]; //pub type DirentBlock = [DirEntry; BLOCK_SZ / DIRENT_SZ];
pub type DirentBytes = [u8; DIRENT_SZ]; pub type DirentBytes = [u8; DIRENT_SZ];
impl DirEntry { impl DirEntry {

View File

@ -6,6 +6,7 @@ mod efs;
mod dirty; mod dirty;
mod bitmap; mod bitmap;
mod vfs; mod vfs;
mod block_cache;
pub const BLOCK_SZ: usize = 512; pub const BLOCK_SZ: usize = 512;
pub use block_dev::BlockDevice; pub use block_dev::BlockDevice;
@ -14,3 +15,4 @@ pub use vfs::Inode;
use layout::*; use layout::*;
use dirty::Dirty; use dirty::Dirty;
use bitmap::Bitmap; use bitmap::Bitmap;
use block_cache::{BlockCache, get_block_cache};

View File

@ -6,13 +6,11 @@ use super::{
DirEntry, DirEntry,
DirentBytes, DirentBytes,
EasyFileSystem, EasyFileSystem,
BLOCK_SZ,
DIRENT_SZ, DIRENT_SZ,
}; };
use alloc::sync::Arc; use alloc::sync::Arc;
use alloc::string::String; use alloc::string::String;
use alloc::vec::Vec; use alloc::vec::Vec;
use crate::layout::DiskInodeType::Directory;
use spin::{Mutex, MutexGuard}; use spin::{Mutex, MutexGuard};
pub struct Inode { pub struct Inode {