summaryrefslogtreecommitdiff
path: root/src/memory
diff options
context:
space:
mode:
Diffstat (limited to 'src/memory')
-rw-r--r--src/memory/cached_inode.rs10
-rw-r--r--src/memory/dir_entry.rs100
2 files changed, 102 insertions, 8 deletions
diff --git a/src/memory/cached_inode.rs b/src/memory/cached_inode.rs
index 441d0fb..16c40c2 100644
--- a/src/memory/cached_inode.rs
+++ b/src/memory/cached_inode.rs
@@ -1,7 +1,3 @@
-use std::ffi::OsStr;
-use std::os::unix::ffi::OsStrExt;
-use std::path::Path;
-use std::slice;
use crate::disk::block::InodeBlock;
use crate::disk::inode::{Inode, INODE_SIZE};
use crate::{utils, AyaFS};
@@ -9,6 +5,10 @@ use and_then_some::BoolExt;
use fuser::FileType;
use libc::{c_int, EIO, EISDIR, ENOENT, ENOTDIR, ENOTEMPTY};
use log::{debug, error};
+use std::ffi::OsStr;
+use std::os::unix::ffi::OsStrExt;
+use std::path::Path;
+use std::slice;
impl AyaFS {
pub(crate) fn create_file(
@@ -85,7 +85,7 @@ impl AyaFS {
if inode.size >= 60 {
self.deallocate_all_blocks_for(&inode).unwrap();
}
- },
+ }
FileType::Directory => return Err(EISDIR),
_ => return Err(EIO),
}
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,