rename dirent

master
Ben Pig Chu 6 years ago
parent 07a4a96b73
commit 9026395afc

@ -374,6 +374,37 @@ impl vfs::INode for INode {
child.nlinks_inc();
Ok(())
}
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);
let inode_and_entry_id = self.get_file_inode_and_entry_id(old_name);
if inode_and_entry_id.is_none() {
return Err(());
}
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;
self._read_at(entry_pos, entry.as_buf_mut()).unwrap();
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<()>{
let fs = self.fs.upgrade().unwrap();
let info = self.info().unwrap();
assert_eq!(info.type_, vfs::FileType::Dir);
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);
unimplemented!()
}
fn find(&self, name: &str) -> vfs::Result<Ptr<vfs::INode>> {
let fs = self.fs.upgrade().unwrap();
let info = self.info().unwrap();

@ -168,6 +168,19 @@ fn kernel_image_file_unlink(){
}
// #[test]
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();
let files_count_after = root.borrow().list().unwrap().len();
assert_eq!(files_count_before, files_count_after);
assert!(root.borrow().lookup("hello").is_err());
sfs.sync().unwrap();
}
#[test]
fn hard_link(){
let sfs = _create_new_sfs();
@ -193,6 +206,9 @@ fn nlinks(){
let dir1 = root.borrow_mut().create("dir1", FileType::Dir).unwrap();
assert_eq!(dir1.borrow().info().unwrap().nlinks,2);
assert_eq!(root.borrow().info().unwrap().nlinks,3);
root.borrow_mut().rename("dir1", "dir_1").unwrap();
assert_eq!(dir1.borrow().info().unwrap().nlinks,2);
assert_eq!(root.borrow().info().unwrap().nlinks,3);
use core::ops::DerefMut;
dir1.borrow_mut().link("file2",file1.borrow_mut().deref_mut()).unwrap();
assert_eq!(dir1.borrow().info().unwrap().nlinks,2);
@ -205,7 +221,7 @@ fn nlinks(){
assert_eq!(file1.borrow().info().unwrap().nlinks,0);
assert_eq!(dir1.borrow().info().unwrap().nlinks,2);
assert_eq!(root.borrow().info().unwrap().nlinks,3);
root.borrow_mut().unlink("dir1").unwrap();
root.borrow_mut().unlink("dir_1").unwrap();
assert_eq!(dir1.borrow().info().unwrap().nlinks,0);
assert_eq!(root.borrow().info().unwrap().nlinks,2);

@ -20,14 +20,14 @@ pub trait INode: Debug + Any {
fn write_at(&self, offset: usize, buf: &[u8]) -> Result<usize>;
fn info(&self) -> Result<FileInfo>;
fn sync(&mut self) -> Result<()>;
// fn name_file(&mut self) -> Result<()>;
// fn reclaim(&mut self) -> Result<()>;
fn resize(&mut self, len: usize) -> Result<()>;
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 lookup(&self, path: &str) -> Result<INodePtr>;
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<()>;
/// lookup with only one layer
fn find(&self, name: &str) -> Result<INodePtr>;
/// like list()[id]

Loading…
Cancel
Save