From cc7d319f3721910fada5ac3e3d02dc487d7fcd9a Mon Sep 17 00:00:00 2001 From: gaotianyu1350 Date: Sun, 7 Apr 2019 23:45:18 +0800 Subject: [PATCH 01/19] add .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index a573d69..9f39509 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ Cargo.lock .idea /*.img +*.iml From 3edc14e317191f06b946c58e522ff3c5c22eb998 Mon Sep 17 00:00:00 2001 From: gaotianyu1350 Date: Sun, 7 Apr 2019 23:51:59 +0800 Subject: [PATCH 02/19] add dev dir --- rcore-fs-sfs/src/lib.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rcore-fs-sfs/src/lib.rs b/rcore-fs-sfs/src/lib.rs index 791eef5..24febdf 100644 --- a/rcore-fs-sfs/src/lib.rs +++ b/rcore-fs-sfs/src/lib.rs @@ -868,7 +868,8 @@ impl vfs::FileSystem for SimpleFileSystem { } fn root_inode(&self) -> Arc { - self.get_inode(BLKN_ROOT) + let root = self.get_inode(BLKN_ROOT); + root.create("dev", vfs::FileType::Dir, 0); } fn info(&self) -> vfs::FsInfo { From 770bbd5aad58542851f8c1573efd5f387c5bdd25 Mon Sep 17 00:00:00 2001 From: Tianyu Gao Date: Tue, 9 Apr 2019 06:50:58 +0000 Subject: [PATCH 03/19] Revert "add .gitignore" This reverts commit cc7d319f3721910fada5ac3e3d02dc487d7fcd9a. --- .gitignore | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitignore b/.gitignore index 9f39509..a573d69 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,3 @@ Cargo.lock .idea /*.img -*.iml From d0a2d9241a9f6a81718a74e160873fe07763209a Mon Sep 17 00:00:00 2001 From: Tianyu Gao Date: Tue, 9 Apr 2019 06:53:42 +0000 Subject: [PATCH 04/19] ignore swp --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index a573d69..6c8eb3e 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ Cargo.lock .idea /*.img +*.swp From 60da95773f2e5d02576935e631efb16c94c8194a Mon Sep 17 00:00:00 2001 From: gaotianyu1350 Date: Tue, 9 Apr 2019 14:59:05 +0800 Subject: [PATCH 05/19] gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 6c8eb3e..da03a14 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ Cargo.lock .idea /*.img *.swp +*.iml From 55a8d350547a351d050a311e7e0ea8dd46b8c3b0 Mon Sep 17 00:00:00 2001 From: Tianyu Gao Date: Tue, 9 Apr 2019 07:02:44 +0000 Subject: [PATCH 06/19] no create dev --- rcore-fs-sfs/src/lib.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/rcore-fs-sfs/src/lib.rs b/rcore-fs-sfs/src/lib.rs index 24febdf..871c611 100644 --- a/rcore-fs-sfs/src/lib.rs +++ b/rcore-fs-sfs/src/lib.rs @@ -868,8 +868,9 @@ impl vfs::FileSystem for SimpleFileSystem { } fn root_inode(&self) -> Arc { - let root = self.get_inode(BLKN_ROOT); - root.create("dev", vfs::FileType::Dir, 0); + self.get_inode(BLKN_ROOT) + // let root = self.get_inode(BLKN_ROOT); + // root.create("dev", vfs::FileType::Dir, 0); } fn info(&self) -> vfs::FsInfo { From d9fa1417fed5c9a28c4a9025d597960075117456 Mon Sep 17 00:00:00 2001 From: gaotianyu1350 Date: Tue, 9 Apr 2019 15:40:13 +0800 Subject: [PATCH 07/19] create dev --- rcore-fs-sfs/src/lib.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/rcore-fs-sfs/src/lib.rs b/rcore-fs-sfs/src/lib.rs index 871c611..be79aac 100644 --- a/rcore-fs-sfs/src/lib.rs +++ b/rcore-fs-sfs/src/lib.rs @@ -868,9 +868,10 @@ impl vfs::FileSystem for SimpleFileSystem { } fn root_inode(&self) -> Arc { - self.get_inode(BLKN_ROOT) - // let root = self.get_inode(BLKN_ROOT); - // root.create("dev", vfs::FileType::Dir, 0); + // self.get_inode(BLKN_ROOT) + let root = self.get_inode(BLKN_ROOT); + root.create("dev", vfs::FileType::Dir, 0); // what's mode? + return root; } fn info(&self) -> vfs::FsInfo { From 56b9db6c8f8a3ffcd193ca9794e4636d65924cd3 Mon Sep 17 00:00:00 2001 From: gaotianyu1350 Date: Tue, 9 Apr 2019 15:41:32 +0800 Subject: [PATCH 08/19] handle result returned by create --- rcore-fs-sfs/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rcore-fs-sfs/src/lib.rs b/rcore-fs-sfs/src/lib.rs index be79aac..b9fc438 100644 --- a/rcore-fs-sfs/src/lib.rs +++ b/rcore-fs-sfs/src/lib.rs @@ -870,7 +870,7 @@ impl vfs::FileSystem for SimpleFileSystem { fn root_inode(&self) -> Arc { // self.get_inode(BLKN_ROOT) let root = self.get_inode(BLKN_ROOT); - root.create("dev", vfs::FileType::Dir, 0); // what's mode? + root.create("dev", vfs::FileType::Dir, 0).expect("fail to create dev"); // what's mode? return root; } From 1cc5fd90bba3615bf108b01ae9a25afa333e6a82 Mon Sep 17 00:00:00 2001 From: Tianyu Gao Date: Tue, 9 Apr 2019 08:00:02 +0000 Subject: [PATCH 09/19] remove creating dev in root_inode --- rcore-fs-sfs/src/lib.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/rcore-fs-sfs/src/lib.rs b/rcore-fs-sfs/src/lib.rs index b9fc438..da846f1 100644 --- a/rcore-fs-sfs/src/lib.rs +++ b/rcore-fs-sfs/src/lib.rs @@ -868,10 +868,10 @@ impl vfs::FileSystem for SimpleFileSystem { } fn root_inode(&self) -> Arc { - // self.get_inode(BLKN_ROOT) - let root = self.get_inode(BLKN_ROOT); - root.create("dev", vfs::FileType::Dir, 0).expect("fail to create dev"); // what's mode? - return root; + self.get_inode(BLKN_ROOT) + // let root = self.get_inode(BLKN_ROOT); + // root.create("dev", vfs::FileType::Dir, 0).expect("fail to create dev"); // what's mode? + // return root; } fn info(&self) -> vfs::FsInfo { From de6b914cd1f3f2f367ee86ed1d9cd5b1268769fa Mon Sep 17 00:00:00 2001 From: gaotianyu1350 Date: Wed, 10 Apr 2019 16:33:34 +0800 Subject: [PATCH 10/19] 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 { From cef08da81299bb8a298e52b77f404d92c1770668 Mon Sep 17 00:00:00 2001 From: gaotianyu1350 Date: Thu, 11 Apr 2019 13:29:10 +0800 Subject: [PATCH 11/19] add device inodes for SFS and device inode id for inodeimpl --- rcore-fs-sfs/src/lib.rs | 46 +++++++++++++++++++++++++++++-------- rcore-fs-sfs/src/structs.rs | 13 +++++++++++ 2 files changed, 49 insertions(+), 10 deletions(-) diff --git a/rcore-fs-sfs/src/lib.rs b/rcore-fs-sfs/src/lib.rs index 16e3a72..b007c40 100644 --- a/rcore-fs-sfs/src/lib.rs +++ b/rcore-fs-sfs/src/lib.rs @@ -19,7 +19,7 @@ use core::fmt::{Debug, Error, Formatter}; use core::mem::uninitialized; use bitvec::BitVec; -use spin::RwLock; +use spin::{RwLock, RwLockReadGuard, RwLockWriteGuard}; use rcore_fs::dev::Device; use rcore_fs::dirty::Dirty; @@ -64,7 +64,7 @@ pub struct INodeImpl { disk_inode: RwLock>, /// Weak reference to SFS, used by almost all operations fs: Arc, - device_inode: Option> + device_inode_id: usize } impl Debug for INodeImpl { @@ -385,15 +385,17 @@ impl vfs::INode for INodeImpl { 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) + let device_inodes = self.fs.device_inodes.read(); + let device_inode = device_inodes.get(&self.device_inode_id); + match device_inode { + Some(device) => device.read().read_at(offset, buf), + None => Err(FsError::DeviceError) } }, _ => Err(FsError::NotFile) } } - fn write_at(&self, offset: usize, buf: &[u8]) -> vfs::Result { + fn write_at(&mut self, offset: usize, buf: &[u8]) -> vfs::Result { let DiskINode { type_, size, .. } = **self.disk_inode.read(); match type_ { FileType::File | FileType::SymLink => { @@ -404,9 +406,11 @@ impl vfs::INode for INodeImpl { self._write_at(offset, buf) }, FileType::CharDevice => { - match &self.device_inode { - Some(x) => x.write_at(offset, buf), - None => Err(FsError::NoDevice) + let device_inodes = self.fs.device_inodes.write(); + let device_inode = device_inodes.get(&self.device_inode_id); + match device_inode { + Some(device) => device.write().write_at(offset, buf), + None => Err(FsError::DeviceError) } }, _ => Err(FsError::NotFile) @@ -691,6 +695,8 @@ pub struct SimpleFileSystem { device: Arc, /// Pointer to self, used by INodes self_ptr: Weak, + /// device inode + device_inodes: RwLock>>> } impl SimpleFileSystem { @@ -711,6 +717,7 @@ impl SimpleFileSystem { inodes: RwLock::new(BTreeMap::new()), device, self_ptr: Weak::default(), + device_inodes: RwLock::new(BTreeMap::new()) } .wrap()) } @@ -742,6 +749,7 @@ impl SimpleFileSystem { inodes: RwLock::new(BTreeMap::new()), device, self_ptr: Weak::default(), + device_inodes: RwLock::new(BTreeMap::new()) } .wrap(); @@ -802,7 +810,18 @@ impl SimpleFileSystem { id, disk_inode: RwLock::new(disk_inode), fs: self.self_ptr.upgrade().unwrap(), - device_inode: None + device_inode_id: NODEVICE + }); + self.inodes.write().insert(id, Arc::downgrade(&inode)); + inode + } + + fn _new_inode_with_device(&self, id: INodeId, disk_inode: Dirty, device_inode_id: usize) -> Arc { + let inode = Arc::new(INodeImpl { + id, + disk_inode: RwLock::new(disk_inode), + fs: self.self_ptr.upgrade().unwrap(), + device_inode_id: device_inode_id }); self.inodes.write().insert(id, Arc::downgrade(&inode)); inode @@ -842,6 +861,13 @@ impl SimpleFileSystem { inode.init_dir_entry(parent)?; Ok(inode) } + /// Create a new INode chardevice + pub fn new_inode_chardevice(&self, device_inode_id: usize) -> vfs::Result> { + let id = self.alloc_block().ok_or(FsError::NoDeviceSpace)?; + let disk_inode = Dirty::new_dirty(DiskINode::new_chardevice()); + let new_inode = self._new_inode_with_device(id, disk_inode, device_inode_id); + Ok(new_inode) + } fn flush_weak_inodes(&self) { let mut inodes = self.inodes.write(); let remove_ids: Vec<_> = inodes diff --git a/rcore-fs-sfs/src/structs.rs b/rcore-fs-sfs/src/structs.rs index 2f83bfe..3bfb15e 100644 --- a/rcore-fs-sfs/src/structs.rs +++ b/rcore-fs-sfs/src/structs.rs @@ -158,6 +158,17 @@ impl DiskINode { db_indirect: 0, } } + pub const fn new_chardevice() -> Self { + DiskINode { + size: 0, + type_: FileType::CharDevice, + nlinks: 0, + blocks: 0, + direct: [0; NDIRECT], + indirect: 0, + db_indirect: 0, + } + } } /// Convert structs to [u8] slice @@ -185,6 +196,8 @@ impl AsBuf for u32 {} pub type BlockId = usize; pub type INodeId = BlockId; +pub const NODEVICE: usize = 100; + /// magic number for sfs pub const MAGIC: u32 = 0x2f8dbe2a; /// size of block From f2e688cc1085ca753dc20852acee7cad6b757cfc Mon Sep 17 00:00:00 2001 From: gaotianyu1350 Date: Thu, 11 Apr 2019 13:46:50 +0800 Subject: [PATCH 12/19] fix device inode bug --- rcore-fs-sfs/src/lib.rs | 8 ++++---- rcore-fs/Cargo.toml | 3 +++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/rcore-fs-sfs/src/lib.rs b/rcore-fs-sfs/src/lib.rs index b007c40..bb7b0fa 100644 --- a/rcore-fs-sfs/src/lib.rs +++ b/rcore-fs-sfs/src/lib.rs @@ -388,14 +388,14 @@ impl vfs::INode for INodeImpl { let device_inodes = self.fs.device_inodes.read(); let device_inode = device_inodes.get(&self.device_inode_id); match device_inode { - Some(device) => device.read().read_at(offset, buf), + Some(device) => device.read_at(offset, buf), None => Err(FsError::DeviceError) } }, _ => Err(FsError::NotFile) } } - fn write_at(&mut self, offset: usize, buf: &[u8]) -> vfs::Result { + fn write_at(&self, offset: usize, buf: &[u8]) -> vfs::Result { let DiskINode { type_, size, .. } = **self.disk_inode.read(); match type_ { FileType::File | FileType::SymLink => { @@ -409,7 +409,7 @@ impl vfs::INode for INodeImpl { let device_inodes = self.fs.device_inodes.write(); let device_inode = device_inodes.get(&self.device_inode_id); match device_inode { - Some(device) => device.write().write_at(offset, buf), + Some(device) => device.write_at(offset, buf), None => Err(FsError::DeviceError) } }, @@ -696,7 +696,7 @@ pub struct SimpleFileSystem { /// Pointer to self, used by INodes self_ptr: Weak, /// device inode - device_inodes: RwLock>>> + device_inodes: RwLock>> } impl SimpleFileSystem { diff --git a/rcore-fs/Cargo.toml b/rcore-fs/Cargo.toml index 1b47bb5..58dbe8a 100644 --- a/rcore-fs/Cargo.toml +++ b/rcore-fs/Cargo.toml @@ -7,5 +7,8 @@ edition = "2018" [dev-dependencies] tempfile = "3" +[dependencies] +spin = "0.4" + [features] std = [] \ No newline at end of file From 6cb05c35a25828d8e1c6185296d9057e6a086fb7 Mon Sep 17 00:00:00 2001 From: gaotianyu1350 Date: Thu, 11 Apr 2019 14:48:13 +0800 Subject: [PATCH 13/19] add inode impl link --- rcore-fs-sfs/src/lib.rs | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/rcore-fs-sfs/src/lib.rs b/rcore-fs-sfs/src/lib.rs index bb7b0fa..cd414ab 100644 --- a/rcore-fs-sfs/src/lib.rs +++ b/rcore-fs-sfs/src/lib.rs @@ -377,6 +377,35 @@ impl INodeImpl { assert!(disk_inode.nlinks > 0); disk_inode.nlinks -= 1; } + + pub fn link_inodeimpl(&self, name: &str, other: &Arc) -> vfs::Result<()> { + let info = self.metadata()?; + if info.type_ != vfs::FileType::Dir { + return Err(FsError::NotDir); + } + if info.nlinks <= 0 { + return Err(FsError::DirRemoved); + } + if !self.get_file_inode_id(name).is_none() { + return Err(FsError::EntryExist); + } + let child = other; + if !Arc::ptr_eq(&self.fs, &child.fs) { + return Err(FsError::NotSameFs); + } + if child.metadata()?.type_ == vfs::FileType::Dir { + return Err(FsError::IsDir); + } + let entry = DiskEntry { + id: child.id as u32, + name: Str256::from(name), + }; + let old_size = self._size(); + self._resize(old_size + BLKSIZE)?; + self._write_at(old_size, entry.as_buf()).unwrap(); + child.nlinks_inc(); + Ok(()) + } } impl vfs::INode for INodeImpl { @@ -803,6 +832,17 @@ impl SimpleFileSystem { trace!("free block {:#x}", block_id); } + pub fn new_device_inode(&self, device_inode_id: usize, device_inode: Arc) { + self.device_inodes.write().insert(device_inode_id, device_inode); + } + + pub fn get_device_inode(&self, device_inode_id: usize) -> vfs::Result> { + match self.device_inodes.read().get(&device_inode_id) { + Some(x) => Ok(Arc::clone(x)), + None => Err(FsError::DeviceError) + } + } + /// Create a new INode struct, then insert it to self.inodes /// Private used for load or create INode fn _new_inode(&self, id: INodeId, disk_inode: Dirty) -> Arc { From 83c218aadb0bd4e3b69e5c69457f724be78863c5 Mon Sep 17 00:00:00 2001 From: gaotianyu1350 Date: Fri, 12 Apr 2019 13:57:31 +0800 Subject: [PATCH 14/19] add device inode id to DiskINode --- rcore-fs-sfs/src/lib.rs | 17 ++++------------- rcore-fs-sfs/src/structs.rs | 8 +++++++- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/rcore-fs-sfs/src/lib.rs b/rcore-fs-sfs/src/lib.rs index cd414ab..0b61166 100644 --- a/rcore-fs-sfs/src/lib.rs +++ b/rcore-fs-sfs/src/lib.rs @@ -846,17 +846,7 @@ impl SimpleFileSystem { /// Create a new INode struct, then insert it to self.inodes /// Private used for load or create INode fn _new_inode(&self, id: INodeId, disk_inode: Dirty) -> Arc { - let inode = Arc::new(INodeImpl { - id, - disk_inode: RwLock::new(disk_inode), - fs: self.self_ptr.upgrade().unwrap(), - device_inode_id: NODEVICE - }); - self.inodes.write().insert(id, Arc::downgrade(&inode)); - inode - } - - fn _new_inode_with_device(&self, id: INodeId, disk_inode: Dirty, device_inode_id: usize) -> Arc { + let device_inode_id = disk_inode.device_inode_id; let inode = Arc::new(INodeImpl { id, disk_inode: RwLock::new(disk_inode), @@ -866,6 +856,7 @@ impl SimpleFileSystem { self.inodes.write().insert(id, Arc::downgrade(&inode)); inode } + /// Get inode by id. Load if not in memory. /// ** Must ensure it's a valid INode ** fn get_inode(&self, id: INodeId) -> Arc { @@ -904,8 +895,8 @@ impl SimpleFileSystem { /// Create a new INode chardevice pub fn new_inode_chardevice(&self, device_inode_id: usize) -> vfs::Result> { let id = self.alloc_block().ok_or(FsError::NoDeviceSpace)?; - let disk_inode = Dirty::new_dirty(DiskINode::new_chardevice()); - let new_inode = self._new_inode_with_device(id, disk_inode, device_inode_id); + let disk_inode = Dirty::new_dirty(DiskINode::new_chardevice(device_inode_id)); + let new_inode = self._new_inode(id, disk_inode); Ok(new_inode) } fn flush_weak_inodes(&self) { diff --git a/rcore-fs-sfs/src/structs.rs b/rcore-fs-sfs/src/structs.rs index 3bfb15e..fd84e98 100644 --- a/rcore-fs-sfs/src/structs.rs +++ b/rcore-fs-sfs/src/structs.rs @@ -44,6 +44,8 @@ pub struct DiskINode { pub indirect: u32, /// double indirect blocks pub db_indirect: u32, + /// device inode id + pub device_inode_id: usize } /* @@ -134,6 +136,7 @@ impl DiskINode { direct: [0; NDIRECT], indirect: 0, db_indirect: 0, + device_inode_id: NODEVICE } } pub const fn new_symlink() -> Self { @@ -145,6 +148,7 @@ impl DiskINode { direct: [0; NDIRECT], indirect: 0, db_indirect: 0, + device_inode_id: NODEVICE } } pub const fn new_dir() -> Self { @@ -156,9 +160,10 @@ impl DiskINode { direct: [0; NDIRECT], indirect: 0, db_indirect: 0, + device_inode_id: NODEVICE } } - pub const fn new_chardevice() -> Self { + pub const fn new_chardevice(device_inode_id: usize) -> Self { DiskINode { size: 0, type_: FileType::CharDevice, @@ -167,6 +172,7 @@ impl DiskINode { direct: [0; NDIRECT], indirect: 0, db_indirect: 0, + device_inode_id: device_inode_id } } } From 4ed2ad696765e610bfeaadab915576fd78df0c06 Mon Sep 17 00:00:00 2001 From: gaotianyu1350 Date: Sat, 13 Apr 2019 16:09:32 +0800 Subject: [PATCH 15/19] add call ioctl for inodeimpl --- rcore-fs-sfs/src/lib.rs | 22 +++++++++++++++------- rcore-fs-sfs/src/structs.rs | 18 +++++++++++++++++- 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/rcore-fs-sfs/src/lib.rs b/rcore-fs-sfs/src/lib.rs index 0b61166..1bd0f0d 100644 --- a/rcore-fs-sfs/src/lib.rs +++ b/rcore-fs-sfs/src/lib.rs @@ -406,6 +406,21 @@ impl INodeImpl { child.nlinks_inc(); Ok(()) } + + pub fn call_ioctl(&self, request: u32, data: *mut u8) -> Result<(), IOCTLError> { + if self.metadata().unwrap().type_ != vfs::FileType::CharDevice { + return Err(IOCTLError::NotCharDevice); + } + let device_inodes = self.fs.device_inodes.read(); + let device_inode = device_inodes.get(&self.device_inode_id); + match device_inode { + Some(x) => { x.ioctl(request, data) } + None => { + warn!("cannot find corresponding device inode in call_inoctl"); + Err(IOCTLError::NotCharDevice) + } + } + } } impl vfs::INode for INodeImpl { @@ -836,13 +851,6 @@ impl SimpleFileSystem { self.device_inodes.write().insert(device_inode_id, device_inode); } - pub fn get_device_inode(&self, device_inode_id: usize) -> vfs::Result> { - match self.device_inodes.read().get(&device_inode_id) { - Some(x) => Ok(Arc::clone(x)), - None => Err(FsError::DeviceError) - } - } - /// Create a new INode struct, then insert it to self.inodes /// Private used for load or create INode fn _new_inode(&self, id: INodeId, disk_inode: Dirty) -> Arc { diff --git a/rcore-fs-sfs/src/structs.rs b/rcore-fs-sfs/src/structs.rs index fd84e98..b8e09e9 100644 --- a/rcore-fs-sfs/src/structs.rs +++ b/rcore-fs-sfs/src/structs.rs @@ -55,7 +55,23 @@ pub trait DeviceINode : Any + Sync + Send{ } */ -pub type DeviceINode = vfs::INode; +// pub type DeviceINode = vfs::INode; +pub trait DeviceINode : vfs::INode { + fn ioctl(&self, request: u32, data: *mut u8) -> Result<(), IOCTLError>; +} + +impl DeviceINode { + fn ioctl(&self, request: u32, data: *mut u8) -> Result<(), IOCTLError> { + Ok(()) + } +} + +pub enum IOCTLError { + NotValidFD = 9, // EBADF + NotValidMemory = 14, // EFAULT + NotValidParam = 22, // EINVAL + NotCharDevice = 25, // ENOTTY +} #[repr(C)] pub struct IndirectBlock { From 0bc5a7dcfdd73710fee93d8b999ab17398e2b0dc Mon Sep 17 00:00:00 2001 From: gaotianyu1350 Date: Sat, 13 Apr 2019 21:19:47 +0800 Subject: [PATCH 16/19] add ioctl --- rcore-fs-sfs/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rcore-fs-sfs/src/lib.rs b/rcore-fs-sfs/src/lib.rs index 1bd0f0d..63d48fc 100644 --- a/rcore-fs-sfs/src/lib.rs +++ b/rcore-fs-sfs/src/lib.rs @@ -26,7 +26,7 @@ use rcore_fs::dirty::Dirty; use rcore_fs::util::*; use rcore_fs::vfs::{self, FileSystem, FsError, INode, Timespec}; -use self::structs::*; +pub use self::structs::*; mod structs; #[cfg(test)] From 958fd0844e4361fdcfb1908d919b3fb8a1e081a4 Mon Sep 17 00:00:00 2001 From: gaotianyu1350 Date: Sat, 13 Apr 2019 23:08:39 +0800 Subject: [PATCH 17/19] fix ioctl bug --- rcore-fs-sfs/src/lib.rs | 30 +++++++++++++++--------------- rcore-fs-sfs/src/structs.rs | 18 +----------------- rcore-fs/src/vfs.rs | 9 +++++++++ 3 files changed, 25 insertions(+), 32 deletions(-) diff --git a/rcore-fs-sfs/src/lib.rs b/rcore-fs-sfs/src/lib.rs index 63d48fc..2355eb4 100644 --- a/rcore-fs-sfs/src/lib.rs +++ b/rcore-fs-sfs/src/lib.rs @@ -406,21 +406,6 @@ impl INodeImpl { child.nlinks_inc(); Ok(()) } - - pub fn call_ioctl(&self, request: u32, data: *mut u8) -> Result<(), IOCTLError> { - if self.metadata().unwrap().type_ != vfs::FileType::CharDevice { - return Err(IOCTLError::NotCharDevice); - } - let device_inodes = self.fs.device_inodes.read(); - let device_inode = device_inodes.get(&self.device_inode_id); - match device_inode { - Some(x) => { x.ioctl(request, data) } - None => { - warn!("cannot find corresponding device inode in call_inoctl"); - Err(IOCTLError::NotCharDevice) - } - } - } } impl vfs::INode for INodeImpl { @@ -707,6 +692,21 @@ impl vfs::INode for INodeImpl { fn as_any_ref(&self) -> &Any { self } + + fn ioctl(&self, request: u32, data: *mut u8) -> Result<(), vfs::IOCTLError> { + if self.metadata().unwrap().type_ != vfs::FileType::CharDevice { + return Err(vfs::IOCTLError::NotCharDevice); + } + let device_inodes = self.fs.device_inodes.read(); + let device_inode = device_inodes.get(&self.device_inode_id); + match device_inode { + Some(x) => { x.ioctl(request, data) } + None => { + warn!("cannot find corresponding device inode in call_inoctl"); + Err(vfs::IOCTLError::NotCharDevice) + } + } + } } impl Drop for INodeImpl { diff --git a/rcore-fs-sfs/src/structs.rs b/rcore-fs-sfs/src/structs.rs index b8e09e9..fd84e98 100644 --- a/rcore-fs-sfs/src/structs.rs +++ b/rcore-fs-sfs/src/structs.rs @@ -55,23 +55,7 @@ pub trait DeviceINode : Any + Sync + Send{ } */ -// pub type DeviceINode = vfs::INode; -pub trait DeviceINode : vfs::INode { - fn ioctl(&self, request: u32, data: *mut u8) -> Result<(), IOCTLError>; -} - -impl DeviceINode { - fn ioctl(&self, request: u32, data: *mut u8) -> Result<(), IOCTLError> { - Ok(()) - } -} - -pub enum IOCTLError { - NotValidFD = 9, // EBADF - NotValidMemory = 14, // EFAULT - NotValidParam = 22, // EINVAL - NotCharDevice = 25, // ENOTTY -} +pub type DeviceINode = vfs::INode; #[repr(C)] pub struct IndirectBlock { diff --git a/rcore-fs/src/vfs.rs b/rcore-fs/src/vfs.rs index 530beec..2c1d91d 100644 --- a/rcore-fs/src/vfs.rs +++ b/rcore-fs/src/vfs.rs @@ -32,6 +32,7 @@ pub trait INode: Any + Sync + Send { /// this is used to implement dynamics cast /// simply return self in the implement of the function fn as_any_ref(&self) -> &Any; + fn ioctl(&self, request: u32, data: *mut u8) -> result::Result<(), IOCTLError>; } impl INode { @@ -111,6 +112,14 @@ impl INode { } Ok(result) } + +} + +pub enum IOCTLError { + NotValidFD = 9, // EBADF + NotValidMemory = 14, // EFAULT + NotValidParam = 22, // EINVAL + NotCharDevice = 25, // ENOTTY } /// Metadata of INode From ab5ae3a447a8a98f8bdbfced6e7852b17180f617 Mon Sep 17 00:00:00 2001 From: Tianyu Gao Date: Sun, 12 May 2019 07:49:09 +0000 Subject: [PATCH 18/19] fix some conflict, pass building --- rcore-fs-sfs/src/lib.rs | 30 ++++++++++++++---------------- rcore-fs/Cargo.toml | 5 +---- rcore-fs/src/vfs.rs | 2 +- 3 files changed, 16 insertions(+), 21 deletions(-) diff --git a/rcore-fs-sfs/src/lib.rs b/rcore-fs-sfs/src/lib.rs index f5ffb76..06be195 100644 --- a/rcore-fs-sfs/src/lib.rs +++ b/rcore-fs-sfs/src/lib.rs @@ -11,8 +11,8 @@ use alloc::{ string::String, sync::{Arc, Weak}, vec, - boxed::Box vec::Vec, + boxed::Box }; use core::any::Any; use core::fmt::{Debug, Error, Formatter}; @@ -392,7 +392,8 @@ impl INodeImpl { id: child.id as u32, name: Str256::from(name), }; - let old_size = self._size(); + let mut disk_inode = self.disk_inode.write(); + let old_size = disk_inode.size as usize; self._resize(old_size + BLKSIZE)?; self._write_at(old_size, entry.as_buf()).unwrap(); child.nlinks_inc(); @@ -457,7 +458,6 @@ impl vfs::INode for INodeImpl { FileType::BlockDevice => 0, _ => panic!("Unknown file type"), }, - size: disk_inode.size as usize, mode: 0o777, type_: vfs::FileType::from(disk_inode.type_.clone()), blocks: disk_inode.blocks as usize, @@ -672,29 +672,27 @@ impl vfs::INode for INodeImpl { Ok(String::from(entry.name.as_ref())) } fn io_control(&self, _cmd: u32, _data: usize) -> vfs::Result<()> { - Err(FsError::NotSupported) - } - fn fs(&self) -> Arc { - self.fs.clone() - } - fn as_any_ref(&self) -> &Any { - self - } - - fn ioctl(&self, request: u32, data: *mut u8) -> Result<(), vfs::IOCTLError> { if self.metadata().unwrap().type_ != vfs::FileType::CharDevice { - return Err(vfs::IOCTLError::NotCharDevice); + return Err(FsError::IOCTLError); } let device_inodes = self.fs.device_inodes.read(); let device_inode = device_inodes.get(&self.device_inode_id); match device_inode { - Some(x) => { x.ioctl(request, data) } + Some(x) => { x.io_control(_cmd, _data) } None => { warn!("cannot find corresponding device inode in call_inoctl"); - Err(vfs::IOCTLError::NotCharDevice) + Err(FsError::IOCTLError) } } + + } + fn fs(&self) -> Arc { + self.fs.clone() } + fn as_any_ref(&self) -> &Any { + self + } + } impl Drop for INodeImpl { diff --git a/rcore-fs/Cargo.toml b/rcore-fs/Cargo.toml index 8e682f2..562137a 100644 --- a/rcore-fs/Cargo.toml +++ b/rcore-fs/Cargo.toml @@ -10,8 +10,5 @@ spin = "0.5" [dev-dependencies] tempfile = "3" -[dependencies] -spin = "0.4" - [features] -std = [] \ No newline at end of file +std = [] diff --git a/rcore-fs/src/vfs.rs b/rcore-fs/src/vfs.rs index fbf739b..96b593f 100644 --- a/rcore-fs/src/vfs.rs +++ b/rcore-fs/src/vfs.rs @@ -59,7 +59,6 @@ pub trait INode: Any + Sync + Send { /// This is used to implement dynamics cast. /// Simply return self in the implement of the function. fn as_any_ref(&self) -> &Any; - fn ioctl(&self, request: u32, data: *mut u8) -> result::Result<(), IOCTLError>; } impl INode { @@ -253,6 +252,7 @@ pub enum FsError { DirNotEmpty, //E_NOTEMPTY WrongFs, //E_INVAL, when we find the content on disk is wrong when opening the device DeviceError, + IOCTLError, NoDevice } From cc4f258ad4c7f4d3bd9fb01697e9f6633c5cf230 Mon Sep 17 00:00:00 2001 From: Tianyu Gao Date: Mon, 13 May 2019 16:05:00 +0800 Subject: [PATCH 19/19] Change size of the directory -> disk_inode.size Co-Authored-By: Wang Runji --- rcore-fs-sfs/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rcore-fs-sfs/src/lib.rs b/rcore-fs-sfs/src/lib.rs index 06be195..967bf56 100644 --- a/rcore-fs-sfs/src/lib.rs +++ b/rcore-fs-sfs/src/lib.rs @@ -453,7 +453,7 @@ impl vfs::INode for INodeImpl { inode: self.id, size: match disk_inode.type_ { FileType::File | FileType::SymLink => disk_inode.size as usize, - FileType::Dir => disk_inode.blocks as usize, + FileType::Dir => disk_inode.size as usize, FileType::CharDevice => 0, FileType::BlockDevice => 0, _ => panic!("Unknown file type"),