summaryrefslogtreecommitdiff
path: root/src/memory
diff options
context:
space:
mode:
authorChuyan Zhang <me@zcy.moe>2023-11-29 03:29:34 -0800
committerChuyan Zhang <me@zcy.moe>2023-11-29 03:29:34 -0800
commit7af0771f9a3031acc36a6990d07bdb92a61c0c75 (patch)
tree3db3c79b8d385bc949c8486d97def8dadd4323e6 /src/memory
parentceb83a7214000ccd048857b40cc0ebfc54290731 (diff)
downloadmyfs-7af0771f9a3031acc36a6990d07bdb92a61c0c75.tar.gz
myfs-7af0771f9a3031acc36a6990d07bdb92a61c0c75.zip
symlink, probably not working
Diffstat (limited to 'src/memory')
-rw-r--r--src/memory/cached_block.rs13
-rw-r--r--src/memory/cached_inode.rs92
-rw-r--r--src/memory/dir_entry.rs68
-rw-r--r--src/memory/file_handle.rs4
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()
- }
}