diff options
Diffstat (limited to 'src/memory/dir_entry.rs')
-rw-r--r-- | src/memory/dir_entry.rs | 100 |
1 files changed, 97 insertions, 3 deletions
diff --git a/src/memory/dir_entry.rs b/src/memory/dir_entry.rs index 5e030d3..c013e1e 100644 --- a/src/memory/dir_entry.rs +++ b/src/memory/dir_entry.rs @@ -6,6 +6,7 @@ use libc::{c_int, ENOENT, ENOSPC}; use log::debug; use std::ffi::{OsStr, OsString}; use std::os::unix::ffi::OsStrExt; +use indexmap::map::Entry::Occupied; impl AyaFS { pub(crate) fn init_direntry_map(&mut self, index: usize) { @@ -99,18 +100,66 @@ impl AyaFS { Ok(()) } + pub(crate) fn exchange_direntry<T: AsRef<OsStr>>( + &mut self, + parent_index: usize, + parent_inode: &mut Inode, + name: T, + new_parent_index: usize, + new_parent_inode: &mut Inode, + new_name: T, + ) -> Result<(), c_int> { + self.load_direntry_map(parent_index, parent_inode)?; + self.load_direntry_map(new_parent_index, new_parent_inode)?; + + let dir_entry = self.dir_entry_map + .get(&parent_index) + .ok_or(ENOENT)? + .get(name.as_ref()) + .cloned() + .ok_or(ENOENT)?; + let new_dir_entry = self.dir_entry_map + .get(&new_parent_index) + .ok_or(ENOENT)? + .get(new_name.as_ref()) + .cloned() + .ok_or(ENOENT)?; + + let name: &OsStr = name.as_ref(); + let new_name: &OsStr = new_name.as_ref(); + + self.dir_entry_map + .get_mut(&parent_index) + .map(|dir_entry_map| { + if let Occupied(mut entry) = dir_entry_map.entry(name.to_os_string()) { + *entry.get_mut() = new_dir_entry.clone(); + } + }) + .ok_or(ENOENT)?; + self.dir_entry_map + .get_mut(&new_parent_index) + .map(|new_dir_entry_map| { + if let Occupied(mut entry) = new_dir_entry_map.entry(new_name.to_os_string()) { + *entry.get_mut() = dir_entry.clone(); + } + }) + .ok_or(ENOENT)?; + + Ok(()) + } + /// 删除第 entry_index 个 dir entry - pub(crate) fn remove_direntry( + pub(crate) fn remove_direntry<T: AsRef<OsStr>>( &mut self, parent_index: usize, parent_inode: &mut Inode, - name: &OsStr, + name: T, _entry_index: u32, ) -> Result<(), c_int> { self.load_direntry_map(parent_index, parent_inode)?; if let Some(dir_entry_map) = self.dir_entry_map.get_mut(&parent_index) { debug!(" remove_direntry(ino: {}) using hashmap", parent_index); - if dir_entry_map.shift_remove(name).is_some() { + if dir_entry_map.shift_remove(name.as_ref()).is_some() { Ok(()) } else { Err(ENOENT) @@ -120,6 +169,29 @@ impl AyaFS { } } + pub(crate) fn add_direntry_2<T: AsRef<OsStr>>( + &mut self, + parent_index: usize, + parent_inode: &mut Inode, + child_inode_name: T, + dir_entry: DirectoryEntry, + ) -> Result<u32, c_int> { + let child_inode_name = child_inode_name.as_ref(); + self.load_direntry_map(parent_index, parent_inode)?; + if let Some(dir_entry_map) = self.dir_entry_map.get_mut(&parent_index) { + let (entry_index, _) = + dir_entry_map.insert_full(child_inode_name.to_os_string(), dir_entry); + debug!( + " add_direntry(ino: {}) using hashmap, entry {}", + parent_index, entry_index + ); + parent_inode.size += 1; + Ok(entry_index as u32) + } else { + Err(ENOENT) + } + } + pub(crate) fn add_direntry<T: AsRef<OsStr>>( &mut self, parent_index: usize, @@ -155,6 +227,28 @@ impl AyaFS { Err(ENOENT) } } + + pub(crate) fn get_direntry_by_name<T: AsRef<OsStr>>( + &mut self, + parent_index: usize, + parent_inode: &Inode, + name: T, + ) -> Result<DirectoryEntry, c_int> { + self.load_direntry_map(parent_index, parent_inode)?; + if let Some(dir_entry_map) = self.dir_entry_map.get(&parent_index) { + debug!( + " get_direntry(ino: {}, name: {:?}) using hashmap", + parent_index, name.as_ref() + ); + dir_entry_map + .get(name.as_ref()) + .cloned() + .ok_or(ENOENT) + } else { + Err(ENOENT) + } + } + pub(crate) fn get_direntry( &mut self, parent_index: usize, |