summaryrefslogtreecommitdiff
path: root/src/memory/dir_entry.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/memory/dir_entry.rs')
-rw-r--r--src/memory/dir_entry.rs100
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,