From de6b914cd1f3f2f367ee86ed1d9cd5b1268769fa Mon Sep 17 00:00:00 2001 From: gaotianyu1350 Date: Wed, 10 Apr 2019 16:33:34 +0800 Subject: [PATCH] trick to add device inode --- rcore-fs-sfs/src/lib.rs | 45 ++++++++++++++++++++++++++----------- rcore-fs-sfs/src/structs.rs | 13 +++++++++++ rcore-fs/src/vfs.rs | 1 + 3 files changed, 46 insertions(+), 13 deletions(-) diff --git a/rcore-fs-sfs/src/lib.rs b/rcore-fs-sfs/src/lib.rs index da846f1..16e3a72 100644 --- a/rcore-fs-sfs/src/lib.rs +++ b/rcore-fs-sfs/src/lib.rs @@ -12,6 +12,7 @@ use alloc::{ sync::{Arc, Weak}, vec::Vec, vec, + boxed::Box }; use core::any::Any; use core::fmt::{Debug, Error, Formatter}; @@ -63,6 +64,7 @@ pub struct INodeImpl { disk_inode: RwLock>, /// Weak reference to SFS, used by almost all operations fs: Arc, + device_inode: Option> } impl Debug for INodeImpl { @@ -379,24 +381,36 @@ impl INodeImpl { impl vfs::INode for INodeImpl { fn read_at(&self, offset: usize, buf: &mut [u8]) -> vfs::Result { - if self.disk_inode.read().type_ != FileType::File - && self.disk_inode.read().type_ != FileType::SymLink - { - return Err(FsError::NotFile); + match self.disk_inode.read().type_ { + FileType::File => self._read_at(offset, buf), + FileType::SymLink => self._read_at(offset, buf), + FileType::CharDevice => { + match &self.device_inode { + Some(x) => x.read_at(offset, buf), + None => Err(FsError::NoDevice) + } + }, + _ => Err(FsError::NotFile) } - self._read_at(offset, buf) } fn write_at(&self, offset: usize, buf: &[u8]) -> vfs::Result { let DiskINode { type_, size, .. } = **self.disk_inode.read(); - if type_ != FileType::File && type_ != FileType::SymLink { - return Err(FsError::NotFile); - } - // resize if not large enough - let end_offset = offset + buf.len(); - if (size as usize) < end_offset { - self._resize(end_offset)?; + match type_ { + FileType::File | FileType::SymLink => { + let end_offset = offset + buf.len(); + if (size as usize) < end_offset { + self._resize(end_offset)?; + } + self._write_at(offset, buf) + }, + FileType::CharDevice => { + match &self.device_inode { + Some(x) => x.write_at(offset, buf), + None => Err(FsError::NoDevice) + } + }, + _ => Err(FsError::NotFile) } - self._write_at(offset, buf) } /// the size returned here is logical size(entry num for directory), not the disk space used. fn metadata(&self) -> vfs::Result { @@ -407,6 +421,8 @@ impl vfs::INode for INodeImpl { size: match disk_inode.type_ { FileType::File | FileType::SymLink => disk_inode.size as usize, FileType::Dir => disk_inode.blocks as usize, + FileType::CharDevice => 0, + FileType::BlockDevice => 0, _ => panic!("Unknown file type"), }, mode: 0o777, @@ -786,6 +802,7 @@ impl SimpleFileSystem { id, disk_inode: RwLock::new(disk_inode), fs: self.self_ptr.upgrade().unwrap(), + device_inode: None }); self.inodes.write().insert(id, Arc::downgrade(&inode)); inode @@ -929,6 +946,8 @@ impl From for vfs::FileType { FileType::File => vfs::FileType::File, FileType::SymLink => vfs::FileType::SymLink, FileType::Dir => vfs::FileType::Dir, + FileType::CharDevice => vfs::FileType::CharDevice, + FileType::BlockDevice => vfs::FileType::BlockDevice, _ => panic!("unknown file type"), } } diff --git a/rcore-fs-sfs/src/structs.rs b/rcore-fs-sfs/src/structs.rs index c86cb8e..2f83bfe 100644 --- a/rcore-fs-sfs/src/structs.rs +++ b/rcore-fs-sfs/src/structs.rs @@ -4,7 +4,9 @@ use alloc::str; use core::fmt::{Debug, Error, Formatter}; use core::mem::{size_of, size_of_val}; use core::slice; +use core::any::Any; use static_assertions::const_assert; +use crate::vfs; /// On-disk superblock #[repr(C)] @@ -44,6 +46,15 @@ pub struct DiskINode { pub db_indirect: u32, } +/* +pub trait DeviceINode : Any + Sync + Send{ + fn read_at(&self, _offset: usize, buf: &mut [u8]) -> vfs::Result; + fn write_at(&self, _offset: usize, buf: &[u8]) -> vfs::Result; +} +*/ + +pub type DeviceINode = vfs::INode; + #[repr(C)] pub struct IndirectBlock { pub entries: [u32; BLK_NENTRY], @@ -220,6 +231,8 @@ pub enum FileType { File = 1, Dir = 2, SymLink = 3, + CharDevice = 4, + BlockDevice = 5, } const_assert!(o1; size_of::() <= BLKSIZE); diff --git a/rcore-fs/src/vfs.rs b/rcore-fs/src/vfs.rs index 4b23d4f..530beec 100644 --- a/rcore-fs/src/vfs.rs +++ b/rcore-fs/src/vfs.rs @@ -210,6 +210,7 @@ pub enum FsError { DirNotEmpty, //E_NOTEMPTY WrongFs, //E_INVAL, when we find the content on disk is wrong when opening the device DeviceError, + NoDevice } impl fmt::Display for FsError {