summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChuyan Zhang <me@zcy.moe>2023-12-03 00:44:48 -0800
committerChuyan Zhang <me@zcy.moe>2023-12-03 00:44:48 -0800
commit21a9ce8e53224100f331d9a666bc00c630964724 (patch)
treea57b71974becd920120241b6e947f1082870fee6
parentf5c92834f79dfdf8007daa019f401c5e51a7596f (diff)
downloadmyfs-21a9ce8e53224100f331d9a666bc00c630964724.tar.gz
myfs-21a9ce8e53224100f331d9a666bc00c630964724.zip
fix directory entry counting
-rw-r--r--ayafs-core/src/filesystem/trait_impl.rs21
-rw-r--r--ayafs-core/src/memory/cached_inode.rs4
-rw-r--r--ayafs-core/src/memory/dir_entry.rs38
-rw-r--r--ayafs-core/src/utils/permissions.rs27
4 files changed, 45 insertions, 45 deletions
diff --git a/ayafs-core/src/filesystem/trait_impl.rs b/ayafs-core/src/filesystem/trait_impl.rs
index 39dba1a..48afac3 100644
--- a/ayafs-core/src/filesystem/trait_impl.rs
+++ b/ayafs-core/src/filesystem/trait_impl.rs
@@ -497,7 +497,7 @@ impl Filesystem for AyaFS {
let mut parent_inode = parent_inode.clone();
// 不存在 -> No such file or directory
- if let Ok((inode_index, entry_index, mut inode)) =
+ if let Ok((inode_index, _, mut inode)) =
self.lookup_name(parent, &parent_inode, name)
{
let inode_index = inode_index as usize;
@@ -533,12 +533,11 @@ impl Filesystem for AyaFS {
// 删除 dir entry
if let Err(err_code) =
- self.remove_direntry(parent, &mut parent_inode, name, entry_index)
+ self.remove_direntry(parent, &mut parent_inode, name)
{
reply.error(err_code);
return;
}
- parent_inode.size -= 1;
self.update_inode(parent, parent_inode);
reply.ok();
} else {
@@ -580,7 +579,7 @@ impl Filesystem for AyaFS {
let mut parent_inode = parent_inode.clone();
// 不存在 -> No such file or directory
- if let Ok((inode_index, entry_index, inode)) =
+ if let Ok((inode_index, _, inode)) =
self.lookup_name(parent, &parent_inode, name)
{
let inode_index = inode_index as usize;
@@ -592,7 +591,9 @@ impl Filesystem for AyaFS {
// 一定有 . 和 .. 所以 size == 2 就是空目录
// 目录非空 -> ENOTEMPTY
- if inode.size > 2 {
+ let direntry_map = self.dir_entry_map.get(&inode_index).unwrap();
+ if direntry_map.len() > 2 {
+ trace!("deleting inode {} failed, having {} directory entries", inode_index, direntry_map.len());
reply.error(ENOTEMPTY);
return;
}
@@ -608,13 +609,12 @@ impl Filesystem for AyaFS {
// 删除 dir entry
if let Err(err_code) =
- self.remove_direntry(parent, &mut parent_inode, name, entry_index)
+ self.remove_direntry(parent, &mut parent_inode, name)
{
reply.error(err_code);
return;
}
- parent_inode.size -= 1;
self.update_inode(parent, parent_inode);
reply.ok();
} else {
@@ -810,7 +810,7 @@ impl Filesystem for AyaFS {
let mut parent_inode = parent_inode.clone();
match self.lookup_name(parent, &parent_inode, name) {
- Ok((_inode_index, entry_index, _inode)) => {
+ Ok((_inode_index, _, _inode)) => {
if let Some(new_parent_inode) = self.get_inode(new_parent) {
if !check_access(
req.uid(),
@@ -830,7 +830,7 @@ impl Filesystem for AyaFS {
let mut new_parent_inode = new_parent_inode.clone();
match self.lookup_name(new_parent, &new_parent_inode, new_name) {
- Ok((_new_inode_index, new_entry_index, _new_inode)) => {
+ Ok((_new_inode_index, _, _new_inode)) => {
// 新文件存在
if flags & RENAME_NOREPLACE != 0 {
// 指定 noreplace 之后不允许覆盖文件
@@ -859,7 +859,6 @@ impl Filesystem for AyaFS {
parent,
&mut parent_inode,
name,
- entry_index,
) {
reply.error(err_code);
return;
@@ -868,7 +867,6 @@ impl Filesystem for AyaFS {
new_parent,
&mut new_parent_inode,
new_name,
- new_entry_index,
) {
reply.error(err_code);
return;
@@ -894,7 +892,6 @@ impl Filesystem for AyaFS {
parent,
&mut parent_inode,
name,
- entry_index,
) {
reply.error(err_code);
return;
diff --git a/ayafs-core/src/memory/cached_inode.rs b/ayafs-core/src/memory/cached_inode.rs
index 70579c7..c1e1909 100644
--- a/ayafs-core/src/memory/cached_inode.rs
+++ b/ayafs-core/src/memory/cached_inode.rs
@@ -4,6 +4,7 @@ use crate::{utils, AyaFS};
use and_then_some::BoolExt;
use fuser::FileType;
use libc::{c_int, EIO, EISDIR, ENOENT, ENOTDIR, ENOTEMPTY};
+use log::debug;
impl AyaFS {
pub(crate) fn create_file(
@@ -103,7 +104,10 @@ impl AyaFS {
// 不是 dir -> ENOTDIR
return Err(ENOTDIR);
}
+
+ let direntry_map = self.dir_entry_map.get(&inode_index).unwrap();
if inode.size > 2 {
+ debug!("deleting inode {} failed, having {} directory entries", inode_index, direntry_map.len());
// 有 . 和 .. 以外的 entry -> ENOTEMPTY
return Err(ENOTEMPTY);
}
diff --git a/ayafs-core/src/memory/dir_entry.rs b/ayafs-core/src/memory/dir_entry.rs
index ee363b2..9a11d2a 100644
--- a/ayafs-core/src/memory/dir_entry.rs
+++ b/ayafs-core/src/memory/dir_entry.rs
@@ -72,6 +72,7 @@ impl AyaFS {
parent_inode: &mut Inode,
dir_entry_map: IndexMap<OsString, DirectoryEntry>,
) -> Result<(), c_int> {
+ parent_inode.size = dir_entry_map.len() as u64;
for (entry_index, (name, 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;
@@ -117,32 +118,36 @@ impl AyaFS {
new_parent_inode: &mut Inode,
new_name: T,
) -> Result<(), c_int> {
+ let name: &OsStr = name.as_ref();
+ let new_name: &OsStr = new_name.as_ref();
self.load_direntry_map(parent_index, parent_inode)?;
self.load_direntry_map(new_parent_index, new_parent_inode)?;
+ if parent_index != new_parent_index {
+ parent_inode.size -= 1;
+ new_parent_inode.size += 1;
+ }
+
let dir_entry = self
.dir_entry_map
.get(&parent_index)
.ok_or(ENOENT)?
- .get(name.as_ref())
+ .get(name)
.cloned()
.ok_or(ENOENT)?;
let new_dir_entry = self
.dir_entry_map
.get(&new_parent_index)
.ok_or(ENOENT)?
- .get(new_name.as_ref())
+ .get(new_name)
.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();
+ *entry.get_mut() = new_dir_entry;
}
})
.ok_or(ENOENT)?;
@@ -150,7 +155,7 @@ impl AyaFS {
.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();
+ *entry.get_mut() = dir_entry;
}
})
.ok_or(ENOENT)?;
@@ -164,12 +169,12 @@ impl AyaFS {
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) {
- trace!(" remove_direntry(ino: {}) using hashmap", parent_index);
if dir_entry_map.shift_remove(name.as_ref()).is_some() {
+ parent_inode.size = dir_entry_map.len() as u64;
+ // trace!("remove_direntry(parent: {:#x}, name: {:?}), parent inode size is {}, direntry_map size is {}", parent_index, name.as_ref(), parent_inode.size, dir_entry_map.len());
Ok(())
} else {
Err(ENOENT)
@@ -191,11 +196,9 @@ impl AyaFS {
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);
- trace!(
- " add_direntry(ino: {}) using hashmap, entry {}",
- parent_index, entry_index
- );
- parent_inode.size += 1;
+ // trace!("parent inode size {} before +1", parent_inode.size);
+ parent_inode.size = dir_entry_map.len() as u64;
+ // trace!("add_direntry_2(parent: {:#x}, name: {:?}), parent inode size is {}, direntry_map size is {}", parent_index, child_inode_name, parent_inode.size, dir_entry_map.len());
Ok(entry_index as u32)
} else {
Err(ENOENT)
@@ -227,11 +230,8 @@ impl AyaFS {
let (entry_index, _) =
dir_entry_map.insert_full(child_inode_name.to_os_string(), dir_entry);
- trace!(
- " add_direntry(ino: {}) using hashmap, entry {}",
- parent_index, entry_index
- );
- parent_inode.size += 1;
+ parent_inode.size = dir_entry_map.len() as u64;
+ trace!("add_direntry(parent: {:#x}, name: {:?}), parent inode size is {}, direntry_map size is {}", parent_index, child_inode_name, parent_inode.size, dir_entry_map.len());
Ok(entry_index as u32)
} else {
Err(ENOENT)
diff --git a/ayafs-core/src/utils/permissions.rs b/ayafs-core/src/utils/permissions.rs
index 53205b5..756ca95 100644
--- a/ayafs-core/src/utils/permissions.rs
+++ b/ayafs-core/src/utils/permissions.rs
@@ -2,7 +2,7 @@ use crate::disk::inode::InodeMode;
use libc::{F_OK, S_ISGID, S_ISUID, S_IXGRP, X_OK};
use std::fs::File;
use std::io::BufRead;
-use log::debug;
+use log::trace;
pub(crate) fn get_groups(pid: u32) -> Vec<u32> {
let file = File::open(format!("/proc/{pid}/task/{pid}/status"))
@@ -37,8 +37,16 @@ pub(crate) fn check_access(
mode: InodeMode,
mut mask: i32,
) -> bool {
- let mask_mem = mask;
- // true
+ trace!(
+ "check_access(incoming_uid: {}, incoming_gid: {}, uid: {}, gid: {}, mode: {:#o}, mask: {:#x})",
+ incoming_uid,
+ incoming_gid,
+ uid,
+ gid,
+ mode.0,
+ mask,
+ );
+
if mask == F_OK {
return true;
}
@@ -51,6 +59,7 @@ pub(crate) fn check_access(
mask -= mask & (perm >> 6);
mask -= mask & (perm >> 3);
mask -= mask & perm;
+ trace!("check_access -> {}", mask == 0);
return mask == 0;
}
@@ -62,16 +71,6 @@ pub(crate) fn check_access(
mask -= mask & perm;
}
- debug!(
- "check_access(incoming_uid: {}, incoming_gid: {}, uid: {}, gid: {}, mode: {:#o}, mask: {:#x}) -> {}",
- incoming_uid,
- incoming_gid,
- uid,
- gid,
- mode.0,
- mask_mem,
- mask == 0,
- );
-
+ trace!("check_access -> {}", mask == 0);
mask == 0
}