diff options
author | Chuyan Zhang <me@zcy.moe> | 2023-11-29 03:29:34 -0800 |
---|---|---|
committer | Chuyan Zhang <me@zcy.moe> | 2023-11-29 03:29:34 -0800 |
commit | 7af0771f9a3031acc36a6990d07bdb92a61c0c75 (patch) | |
tree | 3db3c79b8d385bc949c8486d97def8dadd4323e6 /src/memory | |
parent | ceb83a7214000ccd048857b40cc0ebfc54290731 (diff) | |
download | myfs-7af0771f9a3031acc36a6990d07bdb92a61c0c75.tar.gz myfs-7af0771f9a3031acc36a6990d07bdb92a61c0c75.zip |
symlink, probably not working
Diffstat (limited to 'src/memory')
-rw-r--r-- | src/memory/cached_block.rs | 13 | ||||
-rw-r--r-- | src/memory/cached_inode.rs | 92 | ||||
-rw-r--r-- | src/memory/dir_entry.rs | 68 | ||||
-rw-r--r-- | src/memory/file_handle.rs | 4 |
4 files changed, 42 insertions, 135 deletions
diff --git a/src/memory/cached_block.rs b/src/memory/cached_block.rs index 002a75b..c3d0338 100644 --- a/src/memory/cached_block.rs +++ b/src/memory/cached_block.rs @@ -1,9 +1,6 @@ use crate::block_device::{BlockDevice, BLOCK_SIZE}; use crate::disk::block::Block; -use crate::disk::inode::Inode; use crate::AyaFS; -use and_then_some::BoolExt; -use log::debug; use lru::LruCache; use std::num::NonZeroUsize; use std::sync::Arc; @@ -15,12 +12,6 @@ pub struct CachedBlock<T: Block> { pub dirty: bool, } -impl<T: Block> CachedBlock<T> { - fn cast<U: Block>(&self) -> CachedBlock<U> { - unsafe { std::mem::transmute_copy(&self) } - } -} - pub fn convert_mut<U: Block, T: Block>(input_block: &mut CachedBlock<U>) -> &mut CachedBlock<T> { let ptr = input_block as *const CachedBlock<U> as *mut u8; let block = ptr.cast::<CachedBlock<T>>(); @@ -108,11 +99,13 @@ impl<T: Block> BlockCache<T> { } } + #[allow(unused)] /// 从 LRU cache 中读取一个 block 的引用, *不会* 影响 LRU cache 的结构, 如果没有在 cache 中不会加载. pub(crate) fn peek_block<U: Block>(&self, index: usize) -> Option<&CachedBlock<U>> { self.cache.peek(&index).map(convert::<T, U>) } + #[allow(unused)] /// 从 LRU cache 中读取一个 block 的可变引用, *不会* 影响 LRU cache 的结构, 如果没有在 cache 中不会加载. pub(crate) fn peek_block_mut<U: Block>(&mut self, index: usize) -> Option<&mut CachedBlock<U>> { self.cache.peek_mut(&index).map(convert_mut::<T, U>) @@ -165,6 +158,7 @@ impl AyaFS { // 返回 None 当且仅当 data_bitmap 中这个 block 为 invalid } + #[allow(unused)] pub(crate) fn peek_block<T: Block>(&self, index: usize) -> Option<&CachedBlock<T>> { self.data_bitmap .query(index) @@ -172,6 +166,7 @@ impl AyaFS { // 返回 None 当且仅当 data_bitmap 中这个 block 为 invalid } + #[allow(unused)] pub(crate) fn peek_block_mut<T: Block>(&mut self, index: usize) -> Option<&mut CachedBlock<T>> { self.data_bitmap .query(index) diff --git a/src/memory/cached_inode.rs b/src/memory/cached_inode.rs index a9c92f5..441d0fb 100644 --- a/src/memory/cached_inode.rs +++ b/src/memory/cached_inode.rs @@ -1,8 +1,14 @@ -use crate::disk::block::{DirectoryBlock, DirectoryEntry, InodeBlock}; +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}; use and_then_some::BoolExt; -use libc::{c_int, EISDIR, ENOENT, ENOTDIR, ENOTEMPTY}; +use fuser::FileType; +use libc::{c_int, EIO, EISDIR, ENOENT, ENOTDIR, ENOTEMPTY}; +use log::{debug, error}; impl AyaFS { pub(crate) fn create_file( @@ -20,6 +26,21 @@ impl AyaFS { }) } + pub(crate) fn create_symlink( + &mut self, + permissions: u16, + uid: u32, + gid: u32, + flags: u32, + ) -> Option<(usize, &Inode)> { + self.inode_bitmap.allocate().map(|inode_index| { + self.get_inode_mut(inode_index).map(|inode| { + *inode = Inode::symlink(permissions, uid, gid, utils::time_now(), flags, 0, 0, 0); + }); + (inode_index, self.get_inode(inode_index).unwrap()) + }) + } + /// 根目录的 parent_inode_number 传入 None, 会直接以自己作为 .. 的 inode number pub(crate) fn create_directory( &mut self, @@ -44,36 +65,6 @@ impl AyaFS { 0x2, ) .unwrap(); - - // // 分配第一个 direct block - // (new_inode.direct[0], _) = self.allocate_block_for(&mut new_inode).unwrap(); - // new_inode.size = 2; - // // 在 direct block 里分配 . 和 .. - // if let Some(directory_block) = - // self.get_block_mut::<DirectoryBlock>(new_inode.direct[0] as usize) - // { - // let dot = '.'.to_ascii_lowercase() as u8; - // // add dot entry - // directory_block.block.entries[0] = DirectoryEntry { - // inode: inode_index as u32, - // record_len: 264, - // name_len: 1, - // file_type: 0x2, - // name: [0; 256], - // }; - // directory_block.block.entries[0].name[0] = dot; - // - // // add dot dot entry - // directory_block.block.entries[1] = DirectoryEntry { - // inode: parent_inode_number.unwrap_or(inode_index as u32), - // record_len: 264, - // name_len: 2, - // file_type: 0x2, - // name: [0; 256], - // }; - // directory_block.block.entries[1].name[0] = dot; - // directory_block.block.entries[1].name[1] = dot; - // } // 把 inode 放到指定位置 self.get_inode_mut(inode_index).map(|inode| { *inode = new_inode; @@ -88,10 +79,16 @@ impl AyaFS { let (block_index, offset) = self.locate_inode(inode_index); if let Some(cached_block) = self.cached_inodes.get_block::<InodeBlock>(block_index) { let inode = cached_block.block.inodes[offset / INODE_SIZE].clone(); - if !inode.is_file() { - return Err(EISDIR); + match inode.file_type() { + FileType::RegularFile => self.deallocate_all_blocks_for(&inode).unwrap(), + FileType::Symlink => { + if inode.size >= 60 { + self.deallocate_all_blocks_for(&inode).unwrap(); + } + }, + FileType::Directory => return Err(EISDIR), + _ => return Err(EIO), } - self.deallocate_all_blocks_for(&inode).unwrap(); } self.inode_bitmap.deallocate(inode_index); Ok(true) @@ -125,27 +122,6 @@ impl AyaFS { } } - pub(crate) fn remove_inode(&mut self, inode_index: usize) -> bool { - if self.inode_bitmap.query(inode_index) { - self.inode_bitmap.deallocate(inode_index); - let (block_index, offset) = self.locate_inode(inode_index); - if let Some(cached_block) = self.cached_inodes.get_block::<InodeBlock>(block_index) { - let inode = &cached_block.block.inodes[offset / INODE_SIZE].clone(); - - if inode.is_file() { - self.deallocate_all_blocks_for(inode).unwrap(); - } else if inode.is_dir() { - // TODO 把 dir 下所有子目录 remove 掉 - } else { - unimplemented!("only file and dir are implemented!"); - } - } - true - } else { - false - } - } - pub(crate) fn update_inode(&mut self, inode_index: usize, inode: Inode) -> bool { if self.inode_bitmap.query(inode_index) { let (block_index, offset) = self.locate_inode(inode_index); @@ -162,6 +138,7 @@ impl AyaFS { pub(crate) fn get_inode(&mut self, inode_index: usize) -> Option<&Inode> { self.inode_bitmap.query(inode_index).and_then(|| { let (block_index, offset) = self.locate_inode(inode_index); + // debug!("get_inode(inode_index: {}) -> block_index: {}, offset: {}", inode_index, block_index, offset); self.cached_inodes .get_block::<InodeBlock>(block_index) .map(|cached_block| &cached_block.block.inodes[offset / INODE_SIZE]) @@ -171,6 +148,7 @@ impl AyaFS { pub(crate) fn get_inode_mut(&mut self, inode_index: usize) -> Option<&mut Inode> { self.inode_bitmap.query(inode_index).and_then(|| { let (block_index, offset) = self.locate_inode(inode_index); + // debug!("get_inode_mut(inode_index: {}) -> block_index: {}, offset: {}", inode_index, block_index, offset); self.cached_inodes .get_block_mut::<InodeBlock>(block_index) .map(|cached_block| { @@ -180,6 +158,7 @@ impl AyaFS { }) } + #[allow(unused)] pub(crate) fn peek_inode(&self, inode_index: usize) -> Option<&Inode> { self.inode_bitmap.query(inode_index).and_then(|| { let (block_index, offset) = self.locate_inode(inode_index); @@ -189,6 +168,7 @@ impl AyaFS { }) } + #[allow(unused)] pub(crate) fn peek_inode_mut(&mut self, inode_index: usize) -> Option<&mut Inode> { self.inode_bitmap.query(inode_index).and_then(|| { let (block_index, offset) = self.locate_inode(inode_index); diff --git a/src/memory/dir_entry.rs b/src/memory/dir_entry.rs index 08a82c5..5e030d3 100644 --- a/src/memory/dir_entry.rs +++ b/src/memory/dir_entry.rs @@ -88,6 +88,7 @@ impl AyaFS { } 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 => { @@ -104,7 +105,7 @@ impl AyaFS { parent_index: usize, parent_inode: &mut Inode, name: &OsStr, - entry_index: u32, + _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) { @@ -116,22 +117,6 @@ impl AyaFS { } } else { Err(ENOENT) - // let block_index_within_inode = (entry_index / 15) as usize; - // let entry_index_within_block = (entry_index % 15) as usize; - // - // match self.access_block_mut::<DirectoryBlock>(parent_inode, block_index_within_inode) { - // Some(directory_block) => { - // if directory_block.block.query(entry_index_within_block) { - // directory_block.block.deallocate(entry_index_within_block); - // // directory_block.block.entries[entry_index_within_block] = - // // DirectoryEntry::default(); - // Ok(()) - // } else { - // Err(ENOENT) - // } - // } - // None => Err(ENOENT), - // } } } @@ -169,41 +154,6 @@ impl AyaFS { } else { Err(ENOENT) } - // // 找到第一个有空闲 DirEntry 的块, 从中分配一个 entry - // let mut block_index_within_inode: usize = 0; - // loop { - // // 所有已经分配的块都用完, 需要额外分配一个块了 - // if block_index_within_inode as u32 == parent_inode.n_blocks { - // if self.allocate_block_for(parent_inode).is_none() { - // return Err(ENOSPC); - // } - // } - // // 寻找当前块里有没有空闲空间 - // if let Some(directory_block) = - // self.access_block_mut::<DirectoryBlock>(parent_inode, block_index_within_inode) - // { - // if let Some(entry_index_within_block) = directory_block.block.allocate() { - // // 如果有空闲空间, 可以分配一个块 - // let name_len = child_inode_name.len() as u8; - // let mut name = [0u8; 256]; - // (&mut name[0..name_len as usize]) - // .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, - // }; - // directory_block.block.entries[entry_index_within_block] = dir_entry; - // let entry_index = block_index_within_inode * 15 + entry_index_within_block; - // parent_inode.size += 1; - // return Ok(entry_index as u32); - // } - // } - // block_index_within_inode += 1; - // } } pub(crate) fn get_direntry( &mut self, @@ -225,23 +175,9 @@ impl AyaFS { .ok_or(ENOENT) } else { Err(ENOENT) - // let block_index_within_inode = (entry_index / 15) as usize; - // let entry_index_within_block = (entry_index % 15) as usize; - // - // match self.access_block::<DirectoryBlock>(parent_inode, block_index_within_inode) { - // Some(directory_block) => { - // if directory_block.block.query(entry_index_within_block) { - // Ok(directory_block.block.entries[entry_index_within_block].clone()) - // } else { - // Err(ENOENT) - // } - // } - // None => Err(ENOENT), - // } } } - // TODO 实现一个带 cache 的版本 /// 返回 inode_index, inode 在 parent 里的 index, inode 本身 pub fn lookup_name( &mut self, diff --git a/src/memory/file_handle.rs b/src/memory/file_handle.rs index 0da2ed2..c821619 100644 --- a/src/memory/file_handle.rs +++ b/src/memory/file_handle.rs @@ -12,8 +12,4 @@ impl AyaFS { self.file_handle_map.insert(fd, (inode_index, read, write)); fd } - - pub(crate) fn get_inode_from_fd(&self, file_descriptor: u64) -> Option<(usize, bool, bool)> { - self.file_handle_map.get(&file_descriptor).copied() - } } |