Reformat code.

master
WangRunji 6 years ago
parent 075ea8469f
commit 3f71a36c66

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

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

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

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

@ -24,16 +24,16 @@ pub trait INode: Debug + Any {
fn create(&mut self, name: &str, type_: FileType) -> Result<INodePtr>;
fn unlink(&mut self, name: &str) -> Result<()>;
/// 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<()>;
// 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
fn find(&self, name: &str) -> Result<INodePtr>;
/// like list()[id]
/// only get one item in list, often faster than list
fn get_entry(&self,id: usize) -> Result<String>;
// fn io_ctrl(&mut self, op: u32, data: &[u8]) -> Result<()>;
fn get_entry(&self, id: usize) -> Result<String>;
// fn io_ctrl(&mut self, op: u32, data: &[u8]) -> Result<()>;
fn fs(&self) -> Weak<FileSystem>;
/// this is used to implement dynamics cast
/// 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;
}
impl INode{
pub fn downcast_ref<T:INode>(&self) -> Option<&T> {
impl INode {
pub fn downcast_ref<T: INode>(&self) -> Option<&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>()
}
pub fn list(&self) -> Result<Vec<String>> {
let info=self.info().unwrap();
let info = self.info().unwrap();
assert_eq!(info.type_, FileType::Dir);
Ok((0..info.size).map(|i|{
Ok((0..info.size).map(|i| {
self.get_entry(i).unwrap()
}).collect())
}
pub fn lookup(&self, path: &str) -> Result<INodePtr> {
if(self.info().unwrap().type_ != FileType::Dir){
return Err(())
if self.info().unwrap().type_ != FileType::Dir {
return Err(());
}
let mut result=self.find(".").unwrap();
let mut rest_path=path;
let mut result = self.find(".").unwrap();
let mut rest_path = path;
while rest_path != "" {
if(result.borrow().info().unwrap().type_ != FileType::Dir){
return Err(())
if result.borrow().info().unwrap().type_ != FileType::Dir {
return Err(());
}
let mut name;
match rest_path.find('/') {
None => {name=rest_path; rest_path=""},
Some(pos) => {name=&rest_path[0..pos]; rest_path=&rest_path[pos + 1..]},
None => {
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 {
Err(_) => return Err(()),
Ok(inode) => result=inode,
Ok(inode) => result = inode,
};
}
Ok(result)
@ -97,7 +103,8 @@ pub struct FileInfo {
#[derive(Debug, Eq, PartialEq)]
pub enum FileType {
File, Dir,
File,
Dir,
}
#[derive(Debug)]

Loading…
Cancel
Save