From 9c0c3e0d8306a75c9697208e48e5fd5bd6645773 Mon Sep 17 00:00:00 2001 From: Ben Pig Chu Date: Mon, 29 Oct 2018 16:06:58 +0800 Subject: [PATCH] move the list and lookup implement to the vfs level --- src/sfs.rs | 33 --------------------------------- src/tests.rs | 37 +++++++++++++++++++------------------ src/vfs.rs | 35 +++++++++++++++++++++++++++++++++-- 3 files changed, 52 insertions(+), 53 deletions(-) diff --git a/src/sfs.rs b/src/sfs.rs index e505f28..d9dcabb 100644 --- a/src/sfs.rs +++ b/src/sfs.rs @@ -374,28 +374,6 @@ impl vfs::INode for INode { child.nlinks_inc(); Ok(()) } - fn lookup(&self, path: &str) -> vfs::Result> { - let fs = self.fs.upgrade().unwrap(); - let info = self.info().unwrap(); - assert_eq!(info.type_, vfs::FileType::Dir); - - let (name, rest_path) = match path.find('/') { - None => (path, ""), - Some(pos) => (&path[0..pos], &path[pos + 1..]), - }; - let inode_id = self.get_file_inode_id(name); - if inode_id.is_none() { - return Err(()); - } - let inode = fs.get_inode(inode_id.unwrap()); - - let type_ = inode.borrow().disk_inode.type_; - match type_ { - FileType::File => if rest_path == "" { Ok(inode) } else { Err(()) }, - FileType::Dir => if rest_path == "" { Ok(inode) } else { inode.borrow().lookup(rest_path) }, - _ => unimplemented!(), - } - } fn find(&self, name: &str) -> vfs::Result> { let fs = self.fs.upgrade().unwrap(); let info = self.info().unwrap(); @@ -415,17 +393,6 @@ impl vfs::INode for INode { self._read_at(id as usize * BLKSIZE, entry.as_buf_mut()).unwrap(); Ok(String::from(entry.name.as_ref())) } - fn list(&self) -> vfs::Result> { - assert_eq!(self.disk_inode.type_, FileType::Dir); - - Ok((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(); - String::from(entry.name.as_ref()) - }).collect()) - } fn fs(&self) -> Weak { self.fs.clone() } diff --git a/src/tests.rs b/src/tests.rs index f0a6d9b..f8f4a82 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -128,23 +128,24 @@ fn resize() { #[test] fn create_then_lookup() { let sfs = _create_new_sfs(); - let root = sfs.root_inode(); - - assert!(Rc::ptr_eq(&root.borrow().lookup(".").unwrap(), &root), "failed to find ."); - assert!(Rc::ptr_eq(&root.borrow().lookup("..").unwrap(), &root), "failed to find .."); - - let file1 = root.borrow_mut().create("file1", FileType::File) - .expect("failed to create file1"); - assert!(Rc::ptr_eq(&root.borrow().lookup("file1").unwrap(), &file1), "failed to find file1"); - assert!(root.borrow().lookup("file2").is_err(), "found non-existent file"); - - let dir1 = root.borrow_mut().create("dir1", FileType::Dir) - .expect("failed to create dir1"); - let file2 = dir1.borrow_mut().create("file2", FileType::File) - .expect("failed to create /dir1/file2"); - assert!(Rc::ptr_eq(&root.borrow().lookup("dir1/file2").unwrap(), &file2), "failed to find dir1/file1"); - assert!(Rc::ptr_eq(&dir1.borrow().lookup("..").unwrap(), &root), "failed to find .. from dir1"); - + { + let root = sfs.root_inode(); + + assert!(Rc::ptr_eq(&root.borrow().lookup(".").unwrap(), &root), "failed to find ."); + assert!(Rc::ptr_eq(&root.borrow().lookup("..").unwrap(), &root), "failed to find .."); + + let file1 = root.borrow_mut().create("file1", FileType::File) + .expect("failed to create file1"); + assert!(Rc::ptr_eq(&root.borrow().lookup("file1").unwrap(), &file1), "failed to find file1"); + assert!(root.borrow().lookup("file2").is_err(), "found non-existent file"); + + let dir1 = root.borrow_mut().create("dir1", FileType::Dir) + .expect("failed to create dir1"); + let file2 = dir1.borrow_mut().create("file2", FileType::File) + .expect("failed to create /dir1/file2"); + assert!(Rc::ptr_eq(&root.borrow().lookup("dir1/file2").unwrap(), &file2), "failed to find dir1/file1"); + assert!(Rc::ptr_eq(&dir1.borrow().lookup("..").unwrap(), &root), "failed to find .. from dir1"); + } sfs.sync().unwrap(); } @@ -192,7 +193,7 @@ fn hard_link(){ 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(); - let file2 = root.borrow_mut().lookup("file2").unwrap(); + let file2 = root.borrow().lookup("file2").unwrap(); file1.borrow_mut().resize(100); assert_eq!(file2.borrow().info().unwrap().size,100); diff --git a/src/vfs.rs b/src/vfs.rs index f152941..15c4968 100644 --- a/src/vfs.rs +++ b/src/vfs.rs @@ -27,10 +27,9 @@ pub trait INode: Debug + Any { 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 lookup(&self, path: &str) -> Result; + // fn lookup(&self, path: &str) -> Result; /// lookup with only one layer fn find(&self, name: &str) -> Result; - fn list(&self) -> Result>; /// like list()[id] /// only get one item in list, often faster than list fn get_entry(&self,id: usize) -> Result; @@ -51,10 +50,42 @@ impl INode{ pub fn downcast_mut(&mut self) -> Option<&mut T> { self.as_any_mut().downcast_mut::() } + pub fn list(&self) -> Result> { + let info=self.info().unwrap(); + assert_eq!(info.type_, FileType::Dir); + Ok((0..info.size).map(|i|{ + self.get_entry(i).unwrap() + }).collect()) + } + pub fn lookup(&self, path: &str) -> Result { + if(self.info().unwrap().type_ != FileType::Dir){ + return Err(()) + } + let mut result=self.find(".").unwrap(); + let mut rest_path=path; + while rest_path != "" { + 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..]}, + }; + let found=result.borrow().find(name); + match found { + Err(_) => return Err(()), + Ok(inode) => result=inode, + }; + } + Ok(result) + } } #[derive(Debug, Eq, PartialEq)] pub struct FileInfo { + // Note: for normal file size is the actuate file size + // for directory this is count of dirent. pub size: usize, pub mode: u32, pub type_: FileType,