summaryrefslogtreecommitdiff
path: root/ayafs/src/memory/dir_entry.rs
diff options
context:
space:
mode:
authorChuyan Zhang <me@zcy.moe>2023-11-30 12:01:11 -0800
committerChuyan Zhang <me@zcy.moe>2023-11-30 12:01:11 -0800
commitfd125947c9db0b33761414e65e919f73d9bf1815 (patch)
treec4c66d95ba85601427928aa7f23659590055d464 /ayafs/src/memory/dir_entry.rs
parent1eac97eea4ec0bcef0be061a2cba93a584355283 (diff)
downloadmyfs-fd125947c9db0b33761414e65e919f73d9bf1815.tar.gz
myfs-fd125947c9db0b33761414e65e919f73d9bf1815.zip
Refactor workspace
Diffstat (limited to 'ayafs/src/memory/dir_entry.rs')
-rw-r--r--ayafs/src/memory/dir_entry.rs305
1 files changed, 0 insertions, 305 deletions
diff --git a/ayafs/src/memory/dir_entry.rs b/ayafs/src/memory/dir_entry.rs
deleted file mode 100644
index c013e1e..0000000
--- a/ayafs/src/memory/dir_entry.rs
+++ /dev/null
@@ -1,305 +0,0 @@
-use crate::disk::block::{DirectoryBlock, DirectoryEntry};
-use crate::disk::inode::Inode;
-use crate::AyaFS;
-use indexmap::IndexMap;
-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) {
- let direntry_map: IndexMap<OsString, DirectoryEntry> = IndexMap::new();
- if let Some((old_inode_index, old_dir_entry_map)) =
- self.dir_entry_map.push(index, direntry_map)
- {
- if let Some(old_inode) = self.get_inode(old_inode_index) {
- let mut old_inode = old_inode.clone();
- self.write_back_direntry(old_inode_index, &mut old_inode, old_dir_entry_map)
- .unwrap();
- self.update_inode(old_inode_index, old_inode);
- }
- }
- }
-
- pub(crate) fn load_direntry_map(&mut self, index: usize, inode: &Inode) -> Result<(), c_int> {
- if self.dir_entry_map.contains(&index) {
- debug!("load_direntry_map(ino: {}) already in cache", index);
- return Ok(());
- }
-
- debug!("load_direntry_map(ino: {}) loading", index);
- let mut dir_entry_map: IndexMap<OsString, DirectoryEntry> = IndexMap::new();
- let mut entry_index: usize = 0;
- loop {
- let block_index_within_inode = entry_index / 15;
- let entry_index_within_block = entry_index % 15;
-
- match self.access_block::<DirectoryBlock>(inode, block_index_within_inode) {
- Some(directory_block) => {
- if directory_block.block.query(entry_index_within_block) {
- let dir_entry = &directory_block.block.entries[entry_index_within_block];
- let name = dir_entry.name();
- dir_entry_map.insert(name, dir_entry.clone());
- } else {
- break;
- }
- }
- None => break,
- }
- entry_index += 1;
- }
-
- if let Some((old_inode_index, old_dir_entry_map)) =
- self.dir_entry_map.push(index, dir_entry_map)
- {
- if let Some(old_inode) = self.get_inode(old_inode_index) {
- let mut old_inode = old_inode.clone();
- self.write_back_direntry(old_inode_index, &mut old_inode, old_dir_entry_map)?;
- self.update_inode(old_inode_index, old_inode);
- }
- }
-
- Ok(())
- }
-
- pub(crate) fn write_back_direntry(
- &mut self,
- _parent_index: usize,
- parent_inode: &mut Inode,
- dir_entry_map: IndexMap<OsString, DirectoryEntry>,
- ) -> Result<(), c_int> {
- for (entry_index, (_, dir_entry)) in dir_entry_map.into_iter().enumerate() {
- let block_index_within_inode = entry_index / 15;
- let entry_index_within_block = entry_index % 15;
- // 不够就新分配
- if self
- .get_block_index(parent_inode, block_index_within_inode)
- .is_none()
- {
- match self.allocate_block_for(parent_inode) {
- Some((_, block_index_within)) => {
- assert_eq!(block_index_within, block_index_within_inode);
- }
- None => {
- return Err(ENOSPC);
- }
- }
- }
- match self.access_block_mut::<DirectoryBlock>(parent_inode, block_index_within_inode) {
- Some(directory_block) => {
- directory_block.block.allocate(entry_index_within_block);
- directory_block.block.entries[entry_index_within_block] = dir_entry;
- }
- None => {
- return Err(ENOENT);
- }
- }
- }
- 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<T: AsRef<OsStr>>(
- &mut self,
- parent_index: usize,
- parent_inode: &mut Inode,
- 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.as_ref()).is_some() {
- Ok(())
- } else {
- Err(ENOENT)
- }
- } else {
- Err(ENOENT)
- }
- }
-
- 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,
- parent_inode: &mut Inode,
- child_inode_index: usize,
- child_inode_name: T,
- file_type: u8,
- ) -> 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 name_len = child_inode_name.len() as u8;
- let mut name = [0u8; 256];
- (&mut name[0..child_inode_name.len()]).copy_from_slice(child_inode_name.as_bytes());
-
- let dir_entry = DirectoryEntry {
- inode: child_inode_index as u32,
- record_len: 264,
- name_len,
- file_type,
- name,
- };
-
- 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 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,
- parent_inode: &Inode,
- entry_index: u32,
- ) -> 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: {}, entry_index: {}) using hashmap",
- parent_index, entry_index
- );
- dir_entry_map
- .iter()
- .skip(entry_index as usize)
- .next()
- .map(|entry| entry.1.clone())
- .ok_or(ENOENT)
- } else {
- Err(ENOENT)
- }
- }
-
- /// 返回 inode_index, inode 在 parent 里的 index, inode 本身
- pub fn lookup_name(
- &mut self,
- parent_index: usize,
- parent_inode: &Inode,
- name: &OsStr,
- ) -> Result<(u32, u32, Inode), c_int> {
- self.load_direntry_map(parent_index, parent_inode)?;
- if let Some(dir_entry_map) = self.dir_entry_map.get(&parent_index) {
- if let Some((entry_index, _, dir_entry)) = dir_entry_map.get_full(name) {
- let inode_index = dir_entry.inode;
- let inode = self.get_inode(inode_index as usize).unwrap().clone();
- Ok((inode_index, entry_index as u32, inode))
- } else {
- Err(ENOENT)
- }
- } else {
- let mut entry_index = 0;
- while entry_index < parent_inode.size {
- if let Ok(entry) = self.get_direntry(parent_index, parent_inode, entry_index) {
- if entry.name() == name {
- let inode = self.get_inode(entry.inode as usize).unwrap().clone();
- return Ok((entry.inode, entry_index, inode));
- }
- }
- entry_index += 1;
- }
- Err(ENOENT)
- }
- }
-}