mirror of
https://github.com/rcore-os/rCore-Tutorial-v3.git
synced 2024-11-22 17:36:25 +04:00
Create two files and list them.
This commit is contained in:
parent
459efec595
commit
c351635e2f
@ -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"
|
@ -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(())
|
||||||
}
|
}
|
86
easy-fs/src/block_cache.rs
Normal file
86
easy-fs/src/block_cache.rs
Normal 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)
|
||||||
|
}
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -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 {
|
||||||
|
@ -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};
|
@ -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 {
|
||||||
|
Loading…
Reference in New Issue
Block a user