Reformat code.

master
WangRunji 6 years ago
parent 075ea8469f
commit 3f71a36c66

@ -18,7 +18,7 @@ fn main() -> Result<()> {
_ => { _ => {
println!("USAGE: <zip|unzip> <PATH> <IMG>"); println!("USAGE: <zip|unzip> <PATH> <IMG>");
panic!("Invalid command: {}", cmd); panic!("Invalid command: {}", cmd);
}, }
} }
} }

@ -32,6 +32,7 @@ trait DeviceExt: Device {
s s
} }
} }
impl DeviceExt for Device {} impl DeviceExt for Device {}
type Ptr<T> = Rc<RefCell<T>>; type Ptr<T> = Rc<RefCell<T>>;
@ -97,19 +98,19 @@ impl INode {
} }
} }
/// Only for Dir /// Only for Dir
fn get_file_inode_and_entry_id(&self, name: &str) -> Option<(INodeId,usize)> { fn get_file_inode_and_entry_id(&self, name: &str) -> Option<(INodeId, usize)> {
(0..self.disk_inode.blocks) (0..self.disk_inode.blocks)
.map(|i| { .map(|i| {
use vfs::INode; use vfs::INode;
let mut entry: DiskEntry = unsafe { uninitialized() }; let mut entry: DiskEntry = unsafe { uninitialized() };
self._read_at(i as usize * BLKSIZE, entry.as_buf_mut()).unwrap(); self._read_at(i as usize * BLKSIZE, entry.as_buf_mut()).unwrap();
(entry,i) (entry, i)
}) })
.find(|(entry,id)| entry.name.as_ref() == name) .find(|(entry, id)| entry.name.as_ref() == name)
.map(|(entry,id)| (entry.id as INodeId,id as usize)) .map(|(entry, id)| (entry.id as INodeId, id as usize))
} }
fn get_file_inode_id(&self, name: &str) -> Option<INodeId> { fn get_file_inode_id(&self, name: &str) -> Option<INodeId> {
self.get_file_inode_and_entry_id(name).map(|(inode_id,entry_id)|{inode_id}) self.get_file_inode_and_entry_id(name).map(|(inode_id, entry_id)| { inode_id })
} }
/// Init dir content. Insert 2 init entries. /// Init dir content. Insert 2 init entries.
/// This do not init nlinks, please modify the nlinks in the invoker. /// This do not init nlinks, please modify the nlinks in the invoker.
@ -133,11 +134,11 @@ impl INode {
fn remove_dirent_page(&mut self, id: usize) -> vfs::Result<()> { fn remove_dirent_page(&mut self, id: usize) -> vfs::Result<()> {
assert!(id < self.disk_inode.blocks as usize); assert!(id < self.disk_inode.blocks as usize);
let fs = self.fs.upgrade().unwrap(); let fs = self.fs.upgrade().unwrap();
let to_remove=self.get_disk_block_id(id).unwrap(); let to_remove = self.get_disk_block_id(id).unwrap();
let current_last=self.get_disk_block_id(self.disk_inode.blocks as usize -1).unwrap(); let current_last = self.get_disk_block_id(self.disk_inode.blocks as usize - 1).unwrap();
self.set_disk_block_id(id,current_last).unwrap(); self.set_disk_block_id(id, current_last).unwrap();
self.disk_inode.blocks -= 1; self.disk_inode.blocks -= 1;
let new_size=self.disk_inode.blocks as usize * BLKSIZE; let new_size = self.disk_inode.blocks as usize * BLKSIZE;
self._set_size(new_size); self._set_size(new_size);
fs.free_block(to_remove); fs.free_block(to_remove);
Ok(()) Ok(())
@ -196,8 +197,8 @@ impl INode {
} }
/// Set the ucore compat size of this inode, /// Set the ucore compat size of this inode,
/// Size in inode for dir is size of entries /// Size in inode for dir is size of entries
fn _set_size(&mut self,len: usize) { fn _set_size(&mut self, len: usize) {
self.disk_inode.size=match self.disk_inode.type_ { self.disk_inode.size = match self.disk_inode.type_ {
FileType::Dir => self.disk_inode.blocks as usize * DIRENT_SIZE, FileType::Dir => self.disk_inode.blocks as usize * DIRENT_SIZE,
FileType::File => len, FileType::File => len,
_ => unimplemented!(), _ => unimplemented!(),
@ -246,11 +247,11 @@ impl INode {
Ok(()) Ok(())
} }
fn nlinks_inc(&mut self) { fn nlinks_inc(&mut self) {
self.disk_inode.nlinks+=1; self.disk_inode.nlinks += 1;
} }
fn nlinks_dec(&mut self) { fn nlinks_dec(&mut self) {
assert!(self.disk_inode.nlinks>0); assert!(self.disk_inode.nlinks > 0);
self.disk_inode.nlinks-=1; self.disk_inode.nlinks -= 1;
} }
} }
@ -300,7 +301,7 @@ impl vfs::INode for INode {
let fs = self.fs.upgrade().unwrap(); let fs = self.fs.upgrade().unwrap();
let info = self.info().unwrap(); let info = self.info().unwrap();
assert_eq!(info.type_, vfs::FileType::Dir); assert_eq!(info.type_, vfs::FileType::Dir);
assert!(info.nlinks>0); assert!(info.nlinks > 0);
// Ensure the name is not exist // Ensure the name is not exist
assert!(self.get_file_inode_id(name).is_none(), "file name exist"); assert!(self.get_file_inode_id(name).is_none(), "file name exist");
@ -316,11 +317,11 @@ impl vfs::INode for INode {
id: inode.borrow().id as u32, id: inode.borrow().id as u32,
name: Str256::from(name), name: Str256::from(name),
}; };
let old_size=self._size(); let old_size = self._size();
self._resize(old_size + BLKSIZE).unwrap(); self._resize(old_size + BLKSIZE).unwrap();
self._write_at(old_size, entry.as_buf()).unwrap(); self._write_at(old_size, entry.as_buf()).unwrap();
inode.borrow_mut().nlinks_inc(); inode.borrow_mut().nlinks_inc();
if(type_==vfs::FileType::Dir){ if (type_ == vfs::FileType::Dir) {
inode.borrow_mut().nlinks_inc();//for . inode.borrow_mut().nlinks_inc();//for .
self.nlinks_inc();//for .. self.nlinks_inc();//for ..
} }
@ -328,8 +329,8 @@ impl vfs::INode for INode {
Ok(inode) Ok(inode)
} }
fn unlink(&mut self, name: &str) -> vfs::Result<()> { fn unlink(&mut self, name: &str) -> vfs::Result<()> {
assert!(name!="."); assert!(name != ".");
assert!(name!=".."); assert!(name != "..");
let fs = self.fs.upgrade().unwrap(); let fs = self.fs.upgrade().unwrap();
let info = self.info().unwrap(); let info = self.info().unwrap();
assert_eq!(info.type_, vfs::FileType::Dir); assert_eq!(info.type_, vfs::FileType::Dir);
@ -338,16 +339,16 @@ impl vfs::INode for INode {
if inode_and_entry_id.is_none() { if inode_and_entry_id.is_none() {
return Err(()); return Err(());
} }
let (inode_id,entry_id)=inode_and_entry_id.unwrap(); let (inode_id, entry_id) = inode_and_entry_id.unwrap();
let inode = fs.get_inode(inode_id); let inode = fs.get_inode(inode_id);
let type_ = inode.borrow().disk_inode.type_; let type_ = inode.borrow().disk_inode.type_;
if(type_==FileType::Dir){ if (type_ == FileType::Dir) {
// only . and .. // only . and ..
assert!(inode.borrow().disk_inode.blocks==2); assert!(inode.borrow().disk_inode.blocks == 2);
} }
inode.borrow_mut().nlinks_dec(); inode.borrow_mut().nlinks_dec();
if(type_==FileType::Dir){ if (type_ == FileType::Dir) {
inode.borrow_mut().nlinks_dec();//for . inode.borrow_mut().nlinks_dec();//for .
self.nlinks_dec();//for .. self.nlinks_dec();//for ..
} }
@ -355,29 +356,29 @@ impl vfs::INode for INode {
Ok(()) Ok(())
} }
fn link(&mut self, name: &str, other:&mut vfs::INode) -> vfs::Result<()> { fn link(&mut self, name: &str, other: &mut vfs::INode) -> vfs::Result<()> {
let fs = self.fs.upgrade().unwrap(); let fs = self.fs.upgrade().unwrap();
let info = self.info().unwrap(); let info = self.info().unwrap();
assert_eq!(info.type_, vfs::FileType::Dir); assert_eq!(info.type_, vfs::FileType::Dir);
assert!(info.nlinks>0); assert!(info.nlinks > 0);
assert!(self.get_file_inode_id(name).is_none(), "file name exist"); assert!(self.get_file_inode_id(name).is_none(), "file name exist");
let child = other.downcast_mut::<INode>().unwrap(); let child = other.downcast_mut::<INode>().unwrap();
assert!(Rc::ptr_eq(&fs,&child.fs.upgrade().unwrap())); assert!(Rc::ptr_eq(&fs, &child.fs.upgrade().unwrap()));
assert!(child.info().unwrap().type_!=vfs::FileType::Dir); assert!(child.info().unwrap().type_ != vfs::FileType::Dir);
let entry = DiskEntry { let entry = DiskEntry {
id: child.id as u32, id: child.id as u32,
name: Str256::from(name), name: Str256::from(name),
}; };
let old_size=self._size(); let old_size = self._size();
self._resize(old_size + BLKSIZE).unwrap(); self._resize(old_size + BLKSIZE).unwrap();
self._write_at(old_size, entry.as_buf()).unwrap(); self._write_at(old_size, entry.as_buf()).unwrap();
child.nlinks_inc(); child.nlinks_inc();
Ok(()) Ok(())
} }
fn rename(&mut self, old_name: &str, new_name: &str) -> vfs::Result<()>{ fn rename(&mut self, old_name: &str, new_name: &str) -> vfs::Result<()> {
let info = self.info().unwrap(); let info = self.info().unwrap();
assert_eq!(info.type_, vfs::FileType::Dir); assert_eq!(info.type_, vfs::FileType::Dir);
assert!(info.nlinks>0); assert!(info.nlinks > 0);
assert!(self.get_file_inode_id(new_name).is_none(), "file name exist"); assert!(self.get_file_inode_id(new_name).is_none(), "file name exist");
@ -385,26 +386,26 @@ impl vfs::INode for INode {
if inode_and_entry_id.is_none() { if inode_and_entry_id.is_none() {
return Err(()); return Err(());
} }
let (_,entry_id)=inode_and_entry_id.unwrap(); let (_, entry_id) = inode_and_entry_id.unwrap();
// in place modify name // in place modify name
let mut entry: DiskEntry = unsafe { uninitialized() }; let mut entry: DiskEntry = unsafe { uninitialized() };
let entry_pos=entry_id as usize * BLKSIZE; let entry_pos = entry_id as usize * BLKSIZE;
self._read_at(entry_pos, entry.as_buf_mut()).unwrap(); self._read_at(entry_pos, entry.as_buf_mut()).unwrap();
entry.name=Str256::from(new_name); entry.name = Str256::from(new_name);
self._write_at(entry_pos, entry.as_buf()).unwrap(); self._write_at(entry_pos, entry.as_buf()).unwrap();
Ok(()) Ok(())
} }
fn move_(&mut self, old_name: &str,target:&mut vfs::INode, new_name: &str) -> vfs::Result<()>{ fn move_(&mut self, old_name: &str, target: &mut vfs::INode, new_name: &str) -> vfs::Result<()> {
let fs = self.fs.upgrade().unwrap(); let fs = self.fs.upgrade().unwrap();
let info = self.info().unwrap(); let info = self.info().unwrap();
assert_eq!(info.type_, vfs::FileType::Dir); assert_eq!(info.type_, vfs::FileType::Dir);
assert!(info.nlinks>0); assert!(info.nlinks > 0);
let dest = target.downcast_mut::<INode>().unwrap(); let dest = target.downcast_mut::<INode>().unwrap();
assert!(Rc::ptr_eq(&fs,&dest.fs.upgrade().unwrap())); assert!(Rc::ptr_eq(&fs, &dest.fs.upgrade().unwrap()));
assert!(dest.info().unwrap().type_==vfs::FileType::Dir); assert!(dest.info().unwrap().type_ == vfs::FileType::Dir);
assert!(dest.info().unwrap().nlinks>0); assert!(dest.info().unwrap().nlinks > 0);
assert!(dest.get_file_inode_id(new_name).is_none(), "file name exist"); assert!(dest.get_file_inode_id(new_name).is_none(), "file name exist");
@ -412,20 +413,20 @@ impl vfs::INode for INode {
if inode_and_entry_id.is_none() { if inode_and_entry_id.is_none() {
return Err(()); return Err(());
} }
let (inode_id,entry_id)=inode_and_entry_id.unwrap(); let (inode_id, entry_id) = inode_and_entry_id.unwrap();
let inode = fs.get_inode(inode_id); let inode = fs.get_inode(inode_id);
let entry = DiskEntry { let entry = DiskEntry {
id: inode_id as u32, id: inode_id as u32,
name: Str256::from(new_name), name: Str256::from(new_name),
}; };
let old_size=dest._size(); let old_size = dest._size();
dest._resize(old_size + BLKSIZE).unwrap(); dest._resize(old_size + BLKSIZE).unwrap();
dest._write_at(old_size, entry.as_buf()).unwrap(); dest._write_at(old_size, entry.as_buf()).unwrap();
self.remove_dirent_page(entry_id); self.remove_dirent_page(entry_id);
if(inode.borrow().info().unwrap().type_==vfs::FileType::Dir){ if (inode.borrow().info().unwrap().type_ == vfs::FileType::Dir) {
self.nlinks_dec(); self.nlinks_dec();
dest.nlinks_inc(); dest.nlinks_inc();
} }
@ -443,9 +444,9 @@ impl vfs::INode for INode {
let inode = fs.get_inode(inode_id.unwrap()); let inode = fs.get_inode(inode_id.unwrap());
Ok(inode) Ok(inode)
} }
fn get_entry(&self,id: usize) -> vfs::Result<String> { fn get_entry(&self, id: usize) -> vfs::Result<String> {
assert_eq!(self.disk_inode.type_, FileType::Dir); assert_eq!(self.disk_inode.type_, FileType::Dir);
assert!(id<self.disk_inode.blocks as usize); assert!(id < self.disk_inode.blocks as usize);
use vfs::INode; use vfs::INode;
let mut entry: DiskEntry = unsafe { uninitialized() }; let mut entry: DiskEntry = unsafe { uninitialized() };
self._read_at(id as usize * BLKSIZE, entry.as_buf_mut()).unwrap(); self._read_at(id as usize * BLKSIZE, entry.as_buf_mut()).unwrap();
@ -467,7 +468,7 @@ impl Drop for INode {
fn drop(&mut self) { fn drop(&mut self) {
use vfs::INode; use vfs::INode;
self.sync().expect("failed to sync"); self.sync().expect("failed to sync");
if(self.disk_inode.nlinks<=0){ if (self.disk_inode.nlinks <= 0) {
let fs = self.fs.upgrade().unwrap(); let fs = self.fs.upgrade().unwrap();
self._resize(0); self._resize(0);
self.disk_inode.sync(); self.disk_inode.sync();
@ -560,8 +561,8 @@ impl SimpleFileSystem {
let fs = Rc::new(self); let fs = Rc::new(self);
let weak = Rc::downgrade(&fs); let weak = Rc::downgrade(&fs);
let ptr = Rc::into_raw(fs) as *mut Self; let ptr = Rc::into_raw(fs) as *mut Self;
unsafe{ (*ptr).self_ptr = weak; } unsafe { (*ptr).self_ptr = weak; }
unsafe{ Rc::from_raw(ptr) } unsafe { Rc::from_raw(ptr) }
} }
/// Allocate a block, return block id /// Allocate a block, return block id
@ -570,7 +571,7 @@ impl SimpleFileSystem {
if id.is_some() { if id.is_some() {
self.super_block.borrow_mut().unused_blocks -= 1; // will panic if underflow self.super_block.borrow_mut().unused_blocks -= 1; // will panic if underflow
id id
}else{ } else {
self.flush_unreachable_inodes(); self.flush_unreachable_inodes();
let id = self.free_map.borrow_mut().alloc(); let id = self.free_map.borrow_mut().alloc();
if id.is_some() { if id.is_some() {
@ -625,22 +626,22 @@ impl SimpleFileSystem {
inode.borrow_mut().init_dir_entry(parent).unwrap(); inode.borrow_mut().init_dir_entry(parent).unwrap();
Ok(inode) Ok(inode)
} }
fn flush_unreachable_inodes(&self){ fn flush_unreachable_inodes(&self) {
let mut inodes = self.inodes.borrow_mut(); let mut inodes = self.inodes.borrow_mut();
let ids: Vec<_> = inodes.keys().cloned().collect(); let ids: Vec<_> = inodes.keys().cloned().collect();
for id in ids.iter() { for id in ids.iter() {
let mut should_remove=false; let mut should_remove = false;
// Since non-lexical-lifetime is not stable... // Since non-lexical-lifetime is not stable...
{ {
let inodeRc=inodes.get(&id).unwrap(); let inodeRc = inodes.get(&id).unwrap();
if Rc::strong_count(inodeRc)<=1 { if Rc::strong_count(inodeRc) <= 1 {
use vfs::INode; use vfs::INode;
if inodeRc.borrow().info().unwrap().nlinks==0 { if inodeRc.borrow().info().unwrap().nlinks == 0 {
should_remove=true; should_remove = true;
} }
} }
} }
if(should_remove){ if (should_remove) {
inodes.remove(&id); inodes.remove(&id);
} }
} }

@ -58,6 +58,7 @@ pub struct DiskEntry {
#[repr(C)] #[repr(C)]
pub struct Str256(pub [u8; 256]); pub struct Str256(pub [u8; 256]);
#[repr(C)] #[repr(C)]
pub struct Str32(pub [u8; 32]); pub struct Str32(pub [u8; 32]);
@ -67,22 +68,26 @@ impl AsRef<str> for Str256 {
str::from_utf8(&self.0[0..len]).unwrap() str::from_utf8(&self.0[0..len]).unwrap()
} }
} }
impl AsRef<str> for Str32 { impl AsRef<str> for Str32 {
fn as_ref(&self) -> &str { fn as_ref(&self) -> &str {
let len = self.0.iter().enumerate().find(|(_, &b)| b == 0).unwrap().0; let len = self.0.iter().enumerate().find(|(_, &b)| b == 0).unwrap().0;
str::from_utf8(&self.0[0..len]).unwrap() str::from_utf8(&self.0[0..len]).unwrap()
} }
} }
impl Debug for Str256 { impl Debug for Str256 {
fn fmt(&self, f: &mut Formatter) -> Result<(), Error> { fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
write!(f, "{}", self.as_ref()) write!(f, "{}", self.as_ref())
} }
} }
impl Debug for Str32 { impl Debug for Str32 {
fn fmt(&self, f: &mut Formatter) -> Result<(), Error> { fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
write!(f, "{}", self.as_ref()) write!(f, "{}", self.as_ref())
} }
} }
impl<'a> From<&'a str> for Str256 { impl<'a> From<&'a str> for Str256 {
fn from(s: &'a str) -> Self { fn from(s: &'a str) -> Self {
let mut ret = [0u8; 256]; let mut ret = [0u8; 256];
@ -90,6 +95,7 @@ impl<'a> From<&'a str> for Str256 {
Str256(ret) Str256(ret)
} }
} }
impl<'a> From<&'a str> for Str32 { impl<'a> From<&'a str> for Str32 {
fn from(s: &'a str) -> Self { fn from(s: &'a str) -> Self {
let mut ret = [0u8; 32]; let mut ret = [0u8; 32];
@ -132,16 +138,19 @@ impl DiskINode {
/// Convert structs to [u8] slice /// Convert structs to [u8] slice
pub trait AsBuf { pub trait AsBuf {
fn as_buf(&self) -> &[u8] { fn as_buf(&self) -> &[u8] {
unsafe{ slice::from_raw_parts(self as *const _ as *const u8, size_of_val(self)) } unsafe { slice::from_raw_parts(self as *const _ as *const u8, size_of_val(self)) }
} }
fn as_buf_mut(&mut self) -> &mut [u8] { fn as_buf_mut(&mut self) -> &mut [u8] {
unsafe{ slice::from_raw_parts_mut(self as *mut _ as *mut u8, size_of_val(self)) } unsafe { slice::from_raw_parts_mut(self as *mut _ as *mut u8, size_of_val(self)) }
} }
} }
impl AsBuf for SuperBlock {} impl AsBuf for SuperBlock {}
impl AsBuf for DiskINode {} impl AsBuf for DiskINode {}
impl AsBuf for DiskEntry {} impl AsBuf for DiskEntry {}
impl AsBuf for u32 {} impl AsBuf for u32 {}
/* /*
@ -184,7 +193,10 @@ pub const DIRENT_SIZE: usize = MAX_FNAME_LEN + 1;
#[repr(u16)] #[repr(u16)]
#[derive(Debug, Eq, PartialEq, Copy, Clone)] #[derive(Debug, Eq, PartialEq, Copy, Clone)]
pub enum FileType { pub enum FileType {
Invalid = 0, File = 1, Dir = 2, Link = 3, Invalid = 0,
File = 1,
Dir = 2,
Link = 3,
} }
const_assert!(o1; size_of::<SuperBlock>() <= BLKSIZE); const_assert!(o1; size_of::<SuperBlock>() <= BLKSIZE);

@ -10,7 +10,7 @@ use std::mem::uninitialized;
use super::structs::{DiskEntry, AsBuf}; use super::structs::{DiskEntry, AsBuf};
fn _open_sample_file() -> Rc<SimpleFileSystem> { fn _open_sample_file() -> Rc<SimpleFileSystem> {
fs::copy("sfs.img","test.img").expect("failed to open sfs.img"); fs::copy("sfs.img", "test.img").expect("failed to open sfs.img");
let file = OpenOptions::new() let file = OpenOptions::new()
.read(true).write(true).open("test.img") .read(true).write(true).open("test.img")
.expect("failed to open test.img"); .expect("failed to open test.img");
@ -44,7 +44,7 @@ fn print_root() {
let files = root.borrow().list().unwrap(); let files = root.borrow().list().unwrap();
println!("{:?}", files); println!("{:?}", files);
assert_eq!(files[3],root.borrow().get_entry(3).unwrap()); assert_eq!(files[3], root.borrow().get_entry(3).unwrap());
sfs.sync().unwrap(); sfs.sync().unwrap();
} }
@ -77,7 +77,7 @@ fn resize() {
const SIZE2: usize = 0x1250; const SIZE2: usize = 0x1250;
file1.borrow_mut().resize(SIZE1).unwrap(); file1.borrow_mut().resize(SIZE1).unwrap();
assert_eq!(file1.borrow().info().unwrap().size, SIZE1, "wrong size after resize"); assert_eq!(file1.borrow().info().unwrap().size, SIZE1, "wrong size after resize");
let mut data1: [u8; SIZE2] = unsafe{uninitialized()}; let mut data1: [u8; SIZE2] = unsafe { uninitialized() };
impl AsBuf for [u8; SIZE2] {} impl AsBuf for [u8; SIZE2] {}
let len = file1.borrow().read_at(0, data1.as_buf_mut()).unwrap(); let len = file1.borrow().read_at(0, data1.as_buf_mut()).unwrap();
assert_eq!(len, SIZE1, "wrong size returned by read_at()"); assert_eq!(len, SIZE1, "wrong size returned by read_at()");
@ -137,32 +137,32 @@ fn rc_layout() {
// ^ start ^ Rc::into_raw // ^ start ^ Rc::into_raw
let p = Rc::new([2u8; 5]); let p = Rc::new([2u8; 5]);
let ptr = Rc::into_raw(p); let ptr = Rc::into_raw(p);
let start = unsafe{ (ptr as *const usize).offset(-2) }; let start = unsafe { (ptr as *const usize).offset(-2) };
let ns = unsafe{ &*(start as *const [usize; 2]) }; let ns = unsafe { &*(start as *const [usize; 2]) };
assert_eq!(ns, &[1usize, 1]); assert_eq!(ns, &[1usize, 1]);
} }
// #[test] // #[test]
fn kernel_image_file_create(){ fn kernel_image_file_create() {
let sfs = _open_sample_file(); let sfs = _open_sample_file();
let root = sfs.root_inode(); let root = sfs.root_inode();
let files_count_before = root.borrow().list().unwrap().len(); let files_count_before = root.borrow().list().unwrap().len();
root.borrow_mut().create("hello2",FileType::File).unwrap(); root.borrow_mut().create("hello2", FileType::File).unwrap();
let files_count_after = root.borrow().list().unwrap().len(); let files_count_after = root.borrow().list().unwrap().len();
assert_eq!(files_count_before+1, files_count_after); assert_eq!(files_count_before + 1, files_count_after);
assert!(root.borrow().lookup("hello2").is_ok()); assert!(root.borrow().lookup("hello2").is_ok());
sfs.sync().unwrap(); sfs.sync().unwrap();
} }
// #[test] // #[test]
fn kernel_image_file_unlink(){ fn kernel_image_file_unlink() {
let sfs = _open_sample_file(); let sfs = _open_sample_file();
let root = sfs.root_inode(); let root = sfs.root_inode();
let files_count_before = root.borrow().list().unwrap().len(); let files_count_before = root.borrow().list().unwrap().len();
root.borrow_mut().unlink("hello").unwrap(); root.borrow_mut().unlink("hello").unwrap();
let files_count_after = root.borrow().list().unwrap().len(); let files_count_after = root.borrow().list().unwrap().len();
assert_eq!(files_count_before, files_count_after+1); assert_eq!(files_count_before, files_count_after + 1);
assert!(root.borrow().lookup("hello").is_err()); assert!(root.borrow().lookup("hello").is_err());
sfs.sync().unwrap(); sfs.sync().unwrap();
@ -170,11 +170,11 @@ fn kernel_image_file_unlink(){
// #[test] // #[test]
fn kernel_image_file_rename(){ fn kernel_image_file_rename() {
let sfs = _open_sample_file(); let sfs = _open_sample_file();
let root = sfs.root_inode(); let root = sfs.root_inode();
let files_count_before = root.borrow().list().unwrap().len(); let files_count_before = root.borrow().list().unwrap().len();
root.borrow_mut().rename("hello","hello2").unwrap(); root.borrow_mut().rename("hello", "hello2").unwrap();
let files_count_after = root.borrow().list().unwrap().len(); let files_count_after = root.borrow().list().unwrap().len();
assert_eq!(files_count_before, files_count_after); assert_eq!(files_count_before, files_count_after);
assert!(root.borrow().lookup("hello").is_err()); assert!(root.borrow().lookup("hello").is_err());
@ -184,16 +184,16 @@ fn kernel_image_file_rename(){
} }
// #[test] // #[test]
fn kernel_image_file_move(){ fn kernel_image_file_move() {
use core::ops::DerefMut; use core::ops::DerefMut;
let sfs = _open_sample_file(); let sfs = _open_sample_file();
let root = sfs.root_inode(); let root = sfs.root_inode();
let files_count_before = root.borrow().list().unwrap().len(); let files_count_before = root.borrow().list().unwrap().len();
root.borrow_mut().unlink("divzero").unwrap(); root.borrow_mut().unlink("divzero").unwrap();
let rust_dir = root.borrow_mut().create("rust", FileType::Dir).unwrap(); let rust_dir = root.borrow_mut().create("rust", FileType::Dir).unwrap();
root.borrow_mut().move_("hello",rust_dir.borrow_mut().deref_mut(),"hello_world").unwrap(); root.borrow_mut().move_("hello", rust_dir.borrow_mut().deref_mut(), "hello_world").unwrap();
let files_count_after = root.borrow().list().unwrap().len(); let files_count_after = root.borrow().list().unwrap().len();
assert_eq!(files_count_before, files_count_after+1); assert_eq!(files_count_before, files_count_after + 1);
assert!(root.borrow().lookup("hello").is_err()); assert!(root.borrow().lookup("hello").is_err());
assert!(root.borrow().lookup("divzero").is_err()); assert!(root.borrow().lookup("divzero").is_err());
assert!(root.borrow().lookup("rust").is_ok()); assert!(root.borrow().lookup("rust").is_ok());
@ -203,55 +203,55 @@ fn kernel_image_file_move(){
} }
#[test] #[test]
fn hard_link(){ fn hard_link() {
let sfs = _create_new_sfs(); let sfs = _create_new_sfs();
let root = sfs.root_inode(); let root = sfs.root_inode();
let file1 = root.borrow_mut().create("file1", FileType::File).unwrap(); let file1 = root.borrow_mut().create("file1", FileType::File).unwrap();
use core::ops::DerefMut; use core::ops::DerefMut;
root.borrow_mut().link("file2",file1.borrow_mut().deref_mut()).unwrap(); root.borrow_mut().link("file2", file1.borrow_mut().deref_mut()).unwrap();
let file2 = root.borrow().lookup("file2").unwrap(); let file2 = root.borrow().lookup("file2").unwrap();
file1.borrow_mut().resize(100); file1.borrow_mut().resize(100);
assert_eq!(file2.borrow().info().unwrap().size,100); assert_eq!(file2.borrow().info().unwrap().size, 100);
sfs.sync().unwrap(); sfs.sync().unwrap();
} }
#[test] #[test]
fn nlinks(){ fn nlinks() {
use core::ops::DerefMut; use core::ops::DerefMut;
let sfs = _create_new_sfs(); let sfs = _create_new_sfs();
let root = sfs.root_inode(); let root = sfs.root_inode();
// -root // -root
assert_eq!(root.borrow().info().unwrap().nlinks,2); assert_eq!(root.borrow().info().unwrap().nlinks, 2);
let file1 = root.borrow_mut().create("file1", FileType::File).unwrap(); let file1 = root.borrow_mut().create("file1", FileType::File).unwrap();
// -root // -root
// `-file1 <f1> // `-file1 <f1>
assert_eq!(file1.borrow().info().unwrap().nlinks,1); assert_eq!(file1.borrow().info().unwrap().nlinks, 1);
assert_eq!(root.borrow().info().unwrap().nlinks,2); assert_eq!(root.borrow().info().unwrap().nlinks, 2);
let dir1 = root.borrow_mut().create("dir1", FileType::Dir).unwrap(); let dir1 = root.borrow_mut().create("dir1", FileType::Dir).unwrap();
// -root // -root
// +-dir1 // +-dir1
// `-file1 <f1> // `-file1 <f1>
assert_eq!(dir1.borrow().info().unwrap().nlinks,2); assert_eq!(dir1.borrow().info().unwrap().nlinks, 2);
assert_eq!(root.borrow().info().unwrap().nlinks,3); assert_eq!(root.borrow().info().unwrap().nlinks, 3);
root.borrow_mut().rename("dir1", "dir_1").unwrap(); root.borrow_mut().rename("dir1", "dir_1").unwrap();
// -root // -root
// +-dir_1 // +-dir_1
// `-file1 <f1> // `-file1 <f1>
assert_eq!(dir1.borrow().info().unwrap().nlinks,2); assert_eq!(dir1.borrow().info().unwrap().nlinks, 2);
assert_eq!(root.borrow().info().unwrap().nlinks,3); assert_eq!(root.borrow().info().unwrap().nlinks, 3);
dir1.borrow_mut().link("file1_",file1.borrow_mut().deref_mut()).unwrap(); dir1.borrow_mut().link("file1_", file1.borrow_mut().deref_mut()).unwrap();
// -root // -root
// +-dir_1 // +-dir_1
// | `-file1_ <f1> // | `-file1_ <f1>
// `-file1 <f1> // `-file1 <f1>
assert_eq!(dir1.borrow().info().unwrap().nlinks,2); assert_eq!(dir1.borrow().info().unwrap().nlinks, 2);
assert_eq!(root.borrow().info().unwrap().nlinks,3); assert_eq!(root.borrow().info().unwrap().nlinks, 3);
assert_eq!(file1.borrow().info().unwrap().nlinks,2); assert_eq!(file1.borrow().info().unwrap().nlinks, 2);
let dir2 = root.borrow_mut().create("dir2", FileType::Dir).unwrap(); let dir2 = root.borrow_mut().create("dir2", FileType::Dir).unwrap();
// -root // -root
@ -259,77 +259,77 @@ fn nlinks(){
// | `-file1_ <f1> // | `-file1_ <f1>
// +-dir2 // +-dir2
// `-file1 <f1> // `-file1 <f1>
assert_eq!(dir1.borrow().info().unwrap().nlinks,2); assert_eq!(dir1.borrow().info().unwrap().nlinks, 2);
assert_eq!(dir2.borrow().info().unwrap().nlinks,2); assert_eq!(dir2.borrow().info().unwrap().nlinks, 2);
assert_eq!(root.borrow().info().unwrap().nlinks,4); assert_eq!(root.borrow().info().unwrap().nlinks, 4);
assert_eq!(file1.borrow().info().unwrap().nlinks,2); assert_eq!(file1.borrow().info().unwrap().nlinks, 2);
root.borrow_mut().rename("file1","file_1").unwrap(); root.borrow_mut().rename("file1", "file_1").unwrap();
// -root // -root
// +-dir_1 // +-dir_1
// | `-file1_ <f1> // | `-file1_ <f1>
// +-dir2 // +-dir2
// `-file_1 <f1> // `-file_1 <f1>
assert_eq!(dir1.borrow().info().unwrap().nlinks,2); assert_eq!(dir1.borrow().info().unwrap().nlinks, 2);
assert_eq!(dir2.borrow().info().unwrap().nlinks,2); assert_eq!(dir2.borrow().info().unwrap().nlinks, 2);
assert_eq!(root.borrow().info().unwrap().nlinks,4); assert_eq!(root.borrow().info().unwrap().nlinks, 4);
assert_eq!(file1.borrow().info().unwrap().nlinks,2); assert_eq!(file1.borrow().info().unwrap().nlinks, 2);
root.borrow_mut().move_("file_1",dir2.borrow_mut().deref_mut(),"file__1").unwrap(); root.borrow_mut().move_("file_1", dir2.borrow_mut().deref_mut(), "file__1").unwrap();
// -root // -root
// +-dir_1 // +-dir_1
// | `-file1_ <f1> // | `-file1_ <f1>
// `-dir2 // `-dir2
// `-file__1 <f1> // `-file__1 <f1>
assert_eq!(dir1.borrow().info().unwrap().nlinks,2); assert_eq!(dir1.borrow().info().unwrap().nlinks, 2);
assert_eq!(dir2.borrow().info().unwrap().nlinks,2); assert_eq!(dir2.borrow().info().unwrap().nlinks, 2);
assert_eq!(root.borrow().info().unwrap().nlinks,4); assert_eq!(root.borrow().info().unwrap().nlinks, 4);
assert_eq!(file1.borrow().info().unwrap().nlinks,2); assert_eq!(file1.borrow().info().unwrap().nlinks, 2);
root.borrow_mut().move_("dir_1",dir2.borrow_mut().deref_mut(),"dir__1").unwrap(); root.borrow_mut().move_("dir_1", dir2.borrow_mut().deref_mut(), "dir__1").unwrap();
// -root // -root
// `-dir2 // `-dir2
// +-dir__1 // +-dir__1
// | `-file1_ <f1> // | `-file1_ <f1>
// `-file__1 <f1> // `-file__1 <f1>
assert_eq!(dir1.borrow().info().unwrap().nlinks,2); assert_eq!(dir1.borrow().info().unwrap().nlinks, 2);
assert_eq!(dir2.borrow().info().unwrap().nlinks,3); assert_eq!(dir2.borrow().info().unwrap().nlinks, 3);
assert_eq!(root.borrow().info().unwrap().nlinks,3); assert_eq!(root.borrow().info().unwrap().nlinks, 3);
assert_eq!(file1.borrow().info().unwrap().nlinks,2); assert_eq!(file1.borrow().info().unwrap().nlinks, 2);
dir2.borrow_mut().unlink("file__1").unwrap(); dir2.borrow_mut().unlink("file__1").unwrap();
// -root // -root
// `-dir2 // `-dir2
// `-dir__1 // `-dir__1
// `-file1_ <f1> // `-file1_ <f1>
assert_eq!(file1.borrow().info().unwrap().nlinks,1); assert_eq!(file1.borrow().info().unwrap().nlinks, 1);
assert_eq!(dir1.borrow().info().unwrap().nlinks,2); assert_eq!(dir1.borrow().info().unwrap().nlinks, 2);
assert_eq!(dir2.borrow().info().unwrap().nlinks,3); assert_eq!(dir2.borrow().info().unwrap().nlinks, 3);
assert_eq!(root.borrow().info().unwrap().nlinks,3); assert_eq!(root.borrow().info().unwrap().nlinks, 3);
dir1.borrow_mut().unlink("file1_").unwrap(); dir1.borrow_mut().unlink("file1_").unwrap();
// -root // -root
// `-dir2 // `-dir2
// `-dir__1 // `-dir__1
assert_eq!(file1.borrow().info().unwrap().nlinks,0); assert_eq!(file1.borrow().info().unwrap().nlinks, 0);
assert_eq!(dir1.borrow().info().unwrap().nlinks,2); assert_eq!(dir1.borrow().info().unwrap().nlinks, 2);
assert_eq!(dir2.borrow().info().unwrap().nlinks,3); assert_eq!(dir2.borrow().info().unwrap().nlinks, 3);
assert_eq!(root.borrow().info().unwrap().nlinks,3); assert_eq!(root.borrow().info().unwrap().nlinks, 3);
dir2.borrow_mut().unlink("dir__1").unwrap(); dir2.borrow_mut().unlink("dir__1").unwrap();
// -root // -root
// `-dir2 // `-dir2
assert_eq!(file1.borrow().info().unwrap().nlinks,0); assert_eq!(file1.borrow().info().unwrap().nlinks, 0);
assert_eq!(dir1.borrow().info().unwrap().nlinks,0); assert_eq!(dir1.borrow().info().unwrap().nlinks, 0);
assert_eq!(root.borrow().info().unwrap().nlinks,3); assert_eq!(root.borrow().info().unwrap().nlinks, 3);
assert_eq!(dir2.borrow().info().unwrap().nlinks,2); assert_eq!(dir2.borrow().info().unwrap().nlinks, 2);
root.borrow_mut().unlink("dir2").unwrap(); root.borrow_mut().unlink("dir2").unwrap();
// -root // -root
assert_eq!(file1.borrow().info().unwrap().nlinks,0); assert_eq!(file1.borrow().info().unwrap().nlinks, 0);
assert_eq!(dir1.borrow().info().unwrap().nlinks,0); assert_eq!(dir1.borrow().info().unwrap().nlinks, 0);
assert_eq!(root.borrow().info().unwrap().nlinks,2); assert_eq!(root.borrow().info().unwrap().nlinks, 2);
assert_eq!(dir2.borrow().info().unwrap().nlinks,0); assert_eq!(dir2.borrow().info().unwrap().nlinks, 0);
sfs.sync().unwrap(); sfs.sync().unwrap();
} }

@ -24,16 +24,16 @@ pub trait INode: Debug + Any {
fn create(&mut self, name: &str, type_: FileType) -> Result<INodePtr>; fn create(&mut self, name: &str, type_: FileType) -> Result<INodePtr>;
fn unlink(&mut self, name: &str) -> Result<()>; fn unlink(&mut self, name: &str) -> Result<()>;
/// user of the vfs api should call borrow_mut by itself /// user of the vfs api should call borrow_mut by itself
fn link(&mut self, name: &str, other:&mut INode) -> Result<()>; fn link(&mut self, name: &str, other: &mut INode) -> Result<()>;
fn rename(&mut self, old_name: &str, new_name: &str) -> Result<()>; fn rename(&mut self, old_name: &str, new_name: &str) -> Result<()>;
// when self==target use rename instead since it's not possible to have two mut_ref at the same time. // when self==target use rename instead since it's not possible to have two mut_ref at the same time.
fn move_(&mut self, old_name: &str,target:&mut INode, new_name: &str) -> Result<()>; fn move_(&mut self, old_name: &str, target: &mut INode, new_name: &str) -> Result<()>;
/// lookup with only one layer /// lookup with only one layer
fn find(&self, name: &str) -> Result<INodePtr>; fn find(&self, name: &str) -> Result<INodePtr>;
/// like list()[id] /// like list()[id]
/// only get one item in list, often faster than list /// only get one item in list, often faster than list
fn get_entry(&self,id: usize) -> Result<String>; fn get_entry(&self, id: usize) -> Result<String>;
// fn io_ctrl(&mut self, op: u32, data: &[u8]) -> Result<()>; // fn io_ctrl(&mut self, op: u32, data: &[u8]) -> Result<()>;
fn fs(&self) -> Weak<FileSystem>; fn fs(&self) -> Weak<FileSystem>;
/// this is used to implement dynamics cast /// this is used to implement dynamics cast
/// simply return self in the implement of the function /// simply return self in the implement of the function
@ -43,39 +43,45 @@ pub trait INode: Debug + Any {
fn as_any_mut(&mut self) -> &mut Any; fn as_any_mut(&mut self) -> &mut Any;
} }
impl INode{ impl INode {
pub fn downcast_ref<T:INode>(&self) -> Option<&T> { pub fn downcast_ref<T: INode>(&self) -> Option<&T> {
self.as_any_ref().downcast_ref::<T>() self.as_any_ref().downcast_ref::<T>()
} }
pub fn downcast_mut<T:INode>(&mut self) -> Option<&mut T> { pub fn downcast_mut<T: INode>(&mut self) -> Option<&mut T> {
self.as_any_mut().downcast_mut::<T>() self.as_any_mut().downcast_mut::<T>()
} }
pub fn list(&self) -> Result<Vec<String>> { pub fn list(&self) -> Result<Vec<String>> {
let info=self.info().unwrap(); let info = self.info().unwrap();
assert_eq!(info.type_, FileType::Dir); assert_eq!(info.type_, FileType::Dir);
Ok((0..info.size).map(|i|{ Ok((0..info.size).map(|i| {
self.get_entry(i).unwrap() self.get_entry(i).unwrap()
}).collect()) }).collect())
} }
pub fn lookup(&self, path: &str) -> Result<INodePtr> { pub fn lookup(&self, path: &str) -> Result<INodePtr> {
if(self.info().unwrap().type_ != FileType::Dir){ if self.info().unwrap().type_ != FileType::Dir {
return Err(()) return Err(());
} }
let mut result=self.find(".").unwrap(); let mut result = self.find(".").unwrap();
let mut rest_path=path; let mut rest_path = path;
while rest_path != "" { while rest_path != "" {
if(result.borrow().info().unwrap().type_ != FileType::Dir){ if result.borrow().info().unwrap().type_ != FileType::Dir {
return Err(()) return Err(());
} }
let mut name; let mut name;
match rest_path.find('/') { match rest_path.find('/') {
None => {name=rest_path; rest_path=""}, None => {
Some(pos) => {name=&rest_path[0..pos]; rest_path=&rest_path[pos + 1..]}, name = rest_path;
rest_path = ""
}
Some(pos) => {
name = &rest_path[0..pos];
rest_path = &rest_path[pos + 1..]
}
}; };
let found=result.borrow().find(name); let found = result.borrow().find(name);
match found { match found {
Err(_) => return Err(()), Err(_) => return Err(()),
Ok(inode) => result=inode, Ok(inode) => result = inode,
}; };
} }
Ok(result) Ok(result)
@ -97,7 +103,8 @@ pub struct FileInfo {
#[derive(Debug, Eq, PartialEq)] #[derive(Debug, Eq, PartialEq)]
pub enum FileType { pub enum FileType {
File, Dir, File,
Dir,
} }
#[derive(Debug)] #[derive(Debug)]

Loading…
Cancel
Save