From b3db8a5a710aa0890c80241ffb3fd9792bf1cbe7 Mon Sep 17 00:00:00 2001 From: Chuyan Zhang Date: Wed, 29 Nov 2023 13:29:03 -0800 Subject: Add rename --- src/memory/cached_inode.rs | 10 ++--- src/memory/dir_entry.rs | 100 +++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 102 insertions(+), 8 deletions(-) (limited to 'src/memory') 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>( + &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>( &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>( + &mut self, + parent_index: usize, + parent_inode: &mut Inode, + child_inode_name: T, + dir_entry: DirectoryEntry, + ) -> Result { + 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>( &mut self, parent_index: usize, @@ -155,6 +227,28 @@ impl AyaFS { Err(ENOENT) } } + + pub(crate) fn get_direntry_by_name>( + &mut self, + parent_index: usize, + parent_inode: &Inode, + name: T, + ) -> Result { + 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, -- cgit v1.2.3-70-g09d2