rCore-Tutorial-v3/os/src/fs/inode.rs

105 lines
2.3 KiB
Rust
Raw Normal View History

use easy_fs::{
EasyFileSystem,
Inode,
};
use crate::drivers::BLOCK_DEVICE;
use alloc::sync::Arc;
use lazy_static::*;
use bitflags::*;
use alloc::vec::Vec;
use spin::Mutex;
pub struct OSInode {
readable: bool,
writable: bool,
inner: Mutex<OSInodeInner>,
}
pub struct OSInodeInner {
offset: usize,
inode: Arc<Inode>,
}
impl OSInode {
pub fn new(
readable: bool,
writable: bool,
inode: Arc<Inode>,
) -> Self {
Self {
readable,
writable,
inner: Mutex::new(OSInodeInner {
offset: 0,
inode,
}),
}
}
pub fn read_all(&self) -> Vec<u8> {
let mut inner = self.inner.lock();
let mut buffer = [0u8; 512];
let mut v: Vec<u8> = Vec::new();
loop {
let len = inner.inode.read_at(inner.offset, &mut buffer);
if len == 0 {
break;
}
inner.offset += len;
v.extend_from_slice(&buffer[..len]);
}
v
}
}
lazy_static! {
pub static ref ROOT_INODE: Arc<Inode> = {
let efs = EasyFileSystem::open(BLOCK_DEVICE.clone());
Arc::new(EasyFileSystem::root_inode(&efs))
};
}
pub fn list_apps() {
println!("/**** APPS ****");
for app in ROOT_INODE.ls() {
println!("{}", app);
}
println!("**************/")
}
bitflags! {
pub struct OpenFlags: u32 {
const RDONLY = 0;
const WRONLY = 1 << 0;
const RDWR = 1 << 1;
const CREATE = 1 << 9;
const TRUNC = 1 << 10;
}
}
impl OpenFlags {
/// Do not check validity for simplicity
/// Return (readable, writable)
pub fn read_write(&self) -> (bool, bool) {
if self.is_empty() {
(true, false)
} else if self.contains(Self::WRONLY) {
(false, true)
} else {
(true, true)
}
}
}
pub fn open_file(name: &str, flags: OpenFlags) -> Option<Arc<OSInode>> {
let (readable, writable) = flags.read_write();
// TODO: do not support CREATE or TRUNC flags now
ROOT_INODE.find(name)
.map(|inode| {
Arc::new(OSInode::new(
readable,
writable,
inode
))
})
}