summaryrefslogtreecommitdiff
path: root/ayafs-core
diff options
context:
space:
mode:
Diffstat (limited to 'ayafs-core')
-rw-r--r--ayafs-core/src/block_device/disk.rs6
-rw-r--r--ayafs-core/src/disk/allocation.rs30
-rw-r--r--ayafs-core/src/filesystem/trait_impl.rs189
-rw-r--r--ayafs-core/src/lib.rs4
-rw-r--r--ayafs-core/src/memory/cached_block.rs32
-rw-r--r--ayafs-core/src/memory/dir_entry.rs24
-rw-r--r--ayafs-core/src/utils/permissions.rs15
7 files changed, 196 insertions, 104 deletions
diff --git a/ayafs-core/src/block_device/disk.rs b/ayafs-core/src/block_device/disk.rs
index 9e9b6bc..cc9552c 100644
--- a/ayafs-core/src/block_device/disk.rs
+++ b/ayafs-core/src/block_device/disk.rs
@@ -3,7 +3,7 @@ use std::cell::RefCell;
use std::fs::File;
use std::io::{Read, Seek, SeekFrom, Write};
use std::path::PathBuf;
-use log::debug;
+use log::trace;
pub struct Disk {
#[allow(unused)]
@@ -35,7 +35,7 @@ impl BlockDevice for Disk {
device
.read_exact(buffer)
.expect("Failed to read 4096 bytes!");
- debug!("disk::read block {}", block_id);
+ trace!("disk::read block {}", block_id);
}
fn write(&self, block_id: usize, buffer: &[u8]) {
@@ -47,6 +47,6 @@ impl BlockDevice for Disk {
device
.write_all(buffer)
.expect("Unable to write 4096 bytes!");
- debug!("disk::write block {}", block_id);
+ trace!("disk::write block {}", block_id);
}
}
diff --git a/ayafs-core/src/disk/allocation.rs b/ayafs-core/src/disk/allocation.rs
index 6b7167a..ede7055 100644
--- a/ayafs-core/src/disk/allocation.rs
+++ b/ayafs-core/src/disk/allocation.rs
@@ -5,7 +5,7 @@ use crate::disk::inode::{Inode, DIRECT_NUMBER, ENTRY_PER_BLOCK};
use crate::memory::cached_block::{convert, CachedBlock};
use crate::AyaFS;
use libc::c_int;
-use log::debug;
+use log::trace;
impl AyaFS {
/// 为 Inode 分配新 block, 返回 block 的编号和它在 inode 内的编号
@@ -408,19 +408,19 @@ impl AyaFS {
inode: &Inode,
mut block_index_within_inode: usize,
) -> Option<usize> {
- debug!(
+ trace!(
"get_block_index(block_index_within_inode: {})",
block_index_within_inode
);
// direct block
if block_index_within_inode < DIRECT_NUMBER {
let block_index = inode.direct[block_index_within_inode] as usize;
- debug!(" get_block_index -> direct");
+ trace!(" get_block_index -> direct");
return if self.data_bitmap.query(block_index) {
- debug!(" get_block_index -> direct -> ✓");
+ trace!(" get_block_index -> direct -> ✓");
Some(block_index)
} else {
- debug!(" get_block_index -> direct -> ×");
+ trace!(" get_block_index -> direct -> ×");
None
};
} else {
@@ -433,17 +433,17 @@ impl AyaFS {
return if let Some(indirect_block) =
self.get_block::<IndirectBlock>(inode.single_indirect as usize)
{
- debug!(" get_block_index -> indirect");
+ trace!(" get_block_index -> indirect");
let block_index = indirect_block.block.entries[block_index_within_inode] as usize;
if self.data_bitmap.query(block_index) {
- debug!(" get_block_index -> indirect -> ✓");
+ trace!(" get_block_index -> indirect -> ✓");
Some(block_index)
} else {
- debug!(" get_block_index -> indirect -> ×");
+ trace!(" get_block_index -> indirect -> ×");
None
}
} else {
- debug!(" get_block_index -> indirect -> ×");
+ trace!(" get_block_index -> indirect -> ×");
None
};
} else {
@@ -456,7 +456,7 @@ impl AyaFS {
if let Some(double_indirect_block) =
self.get_block::<DoubleIndirectBlock>(inode.double_indirect as usize)
{
- debug!(" get_block_index -> double_indirect");
+ trace!(" get_block_index -> double_indirect");
// 取出 double indirect block
let indirect_block_index = double_indirect_block.block.indirect
[block_index_within_inode / ENTRY_PER_BLOCK]
@@ -464,16 +464,16 @@ impl AyaFS {
// 要找的 entry 在 double indirect block 中的第几个 indirect block
if let Some(indirect_block) = self.get_block::<IndirectBlock>(indirect_block_index)
{
- debug!(" get_block_index -> double_indirect -> indirect");
+ trace!(" get_block_index -> double_indirect -> indirect");
let block_index = indirect_block.block.entries
[block_index_within_inode % ENTRY_PER_BLOCK]
as usize;
// 拿到 DirectoryBlock 的 index
return if self.data_bitmap.query(block_index) {
- debug!(" get_block_index -> double_indirect -> indirect -> ✓");
+ trace!(" get_block_index -> double_indirect -> indirect -> ✓");
Some(block_index)
} else {
- debug!(" get_block_index -> double_indirect -> indirect -> ×");
+ trace!(" get_block_index -> double_indirect -> indirect -> ×");
None
};
}
@@ -525,7 +525,7 @@ impl AyaFS {
) -> Option<&CachedBlock<T>> {
self.get_block_index(inode, block_index_within_inode)
.map(|block_index| {
- debug!(
+ trace!(
"access_block(index: {}) found with global index {}",
block_index_within_inode,
block_index,
@@ -541,7 +541,7 @@ impl AyaFS {
) -> Option<&mut CachedBlock<T>> {
self.get_block_index(inode, block_index_within_inode)
.map(|block_index| {
- debug!(
+ trace!(
"access_block_mut(index: {}) found with global index {}",
block_index_within_inode,
block_index,
diff --git a/ayafs-core/src/filesystem/trait_impl.rs b/ayafs-core/src/filesystem/trait_impl.rs
index 356cc59..39dba1a 100644
--- a/ayafs-core/src/filesystem/trait_impl.rs
+++ b/ayafs-core/src/filesystem/trait_impl.rs
@@ -5,13 +5,13 @@ use crate::utils::permissions::{check_access, clear_suid_sgid, get_groups};
use crate::utils::{from_filetype, from_systime, time_now, to_fileattr, to_filetype};
use crate::{AyaFS, TTL};
use fuser::TimeOrNow::{Now, SpecificTime};
-use fuser::{FileType, Filesystem, KernelConfig, ReplyAttr, ReplyData, ReplyDirectory, ReplyEmpty, ReplyEntry, ReplyOpen, ReplyWrite, Request, TimeOrNow, ReplyStatfs, FileAttr};
+use fuser::{FileType, Filesystem, KernelConfig, ReplyAttr, ReplyData, ReplyDirectory, ReplyEmpty, ReplyEntry, ReplyOpen, ReplyWrite, Request, TimeOrNow, ReplyStatfs, FileAttr, ReplyCreate};
use libc::{
c_int, EACCES, EBADF, EEXIST, EINVAL, EIO, EISDIR, ENAMETOOLONG, ENOENT, ENOSPC, ENOTDIR,
ENOTEMPTY, EPERM, O_ACCMODE, O_RDONLY, O_RDWR, O_WRONLY, RENAME_EXCHANGE,
RENAME_NOREPLACE, R_OK, S_ISGID, S_ISUID, S_IXGRP, S_IXOTH, S_IXUSR, W_OK,
};
-use log::debug;
+use log::{debug, trace};
use std::ffi::OsStr;
use std::os::unix::ffi::OsStrExt;
use std::path::Path;
@@ -22,12 +22,10 @@ impl AyaFS {}
impl Filesystem for AyaFS {
fn init(&mut self, _req: &Request<'_>, _config: &mut KernelConfig) -> Result<(), c_int> {
- debug!("init()");
Ok(())
}
fn destroy(&mut self) {
- debug!("destroy()");
self.write_back();
}
@@ -65,7 +63,7 @@ impl Filesystem for AyaFS {
fn getattr(&mut self, _req: &Request<'_>, ino: u64, reply: ReplyAttr) {
if let Some(inode) = self.get_inode(ino as usize) {
- debug!(
+ trace!(
"getattr(ino: {}, incoming_uid: {}, inode_uid: {})",
ino, _req.uid(), inode.uid,
);
@@ -96,7 +94,7 @@ impl Filesystem for AyaFS {
if let Some(inode) = self.get_inode_mut(ino as usize) {
// chmod
if let Some(mode) = mode {
- debug!("chmod on inode {:#x?} mode {:o}", ino, mode);
+ trace!("chmod on inode {:#x?} mode {:o}", ino, mode);
if req.uid() != 0 && req.uid() != inode.uid {
reply.error(EPERM);
return;
@@ -118,7 +116,7 @@ impl Filesystem for AyaFS {
// chown
if uid.is_some() || gid.is_some() {
- debug!("chown on inode {:#x?} uid {:?} gid {:?}", ino, uid, gid);
+ trace!("chown on inode {:#x?} uid {:?} gid {:?}", ino, uid, gid);
if let Some(uid) = uid {
// 虽然只有 root 可以 chown 但是 user chown 自己也是不报错的
if req.uid() != 0 && !(uid == inode.uid && uid == req.uid()) {
@@ -164,7 +162,7 @@ impl Filesystem for AyaFS {
// ftruncate
if let Some(size) = size {
// TODO 当大小减小的时候对应 deallocate 块
- debug!("ftruncate on inode {:#x?} size {:?}", ino, size);
+ trace!("ftruncate on inode {:#x?} size {:?}", ino, size);
if let Some(file_handle) = fh {
let mut inode = inode.clone();
let (inode_index, _read, write) =
@@ -192,7 +190,7 @@ impl Filesystem for AyaFS {
if atime.is_some() || mtime.is_some() {
let current_time = time_now();
if let Some(atime) = atime {
- debug!("utimensat on inode {:#x?}, atime {:?}", ino, atime);
+ trace!("utimensat on inode {:#x?}, atime {:?}", ino, atime);
// root 和 user 可以随意修改 atime, 其他用户只能 touch (即 atime == Now)
if req.uid() != 0 && req.uid() != inode.uid && atime != Now {
reply.error(EPERM);
@@ -221,7 +219,7 @@ impl Filesystem for AyaFS {
inode.ctime = current_time;
}
if let Some(mtime) = mtime {
- debug!("utimensat on inode {:#x?}, mtime {:?}", ino, mtime);
+ // debug!("utimensat on inode {:#x?}, mtime {:?}", ino, mtime);
// root 和 user 可以随意修改 mtime, 其他用户只能 mtime == Now
if req.uid() != 0 && req.uid() != inode.uid && mtime != Now {
reply.error(EPERM);
@@ -259,7 +257,7 @@ impl Filesystem for AyaFS {
// 这啥语义啊??
fn readlink(&mut self, req: &Request<'_>, ino: u64, reply: ReplyData) {
- debug!("readlink(ino: {})", ino);
+ // debug!("readlink(ino: {})", ino);
if let Some(inode) = self.get_inode(ino as usize) {
if !inode.is_symlink() {
reply.error(ENOENT);
@@ -272,7 +270,7 @@ impl Filesystem for AyaFS {
let path_length = inode.size as usize;
let mut path = vec![0u8; path_length];
if path_length < 60 {
- debug!(
+ trace!(
"symlink path length is {}, reading directly from inode.direct",
path_length
);
@@ -282,7 +280,7 @@ impl Filesystem for AyaFS {
};
path.as_mut_slice().copy_from_slice(copy_src);
} else {
- debug!(
+ trace!(
"symlink path length is {}, using original read",
path_length
);
@@ -309,7 +307,7 @@ impl Filesystem for AyaFS {
}
}
}
- debug!(
+ trace!(
"readlink path read is {:?}",
OsStr::from_bytes(path.as_slice())
);
@@ -329,10 +327,10 @@ impl Filesystem for AyaFS {
_rdev: u32, // the device number (only valid if created file is a device)
reply: ReplyEntry,
) {
- debug!(
- "mknod(parent: {}, name: {:?}, mode: {}, umask: {})",
- parent, name, mode, _umask
- );
+ // debug!(
+ // "mknod(parent: {}, name: {:?}, mode: {}, umask: {})",
+ // parent, name, mode, _umask
+ // );
let parent = parent as usize;
if let Some(parent_inode) = self.get_inode(parent) {
@@ -469,7 +467,7 @@ impl Filesystem for AyaFS {
}
fn unlink(&mut self, req: &Request<'_>, parent: u64, name: &OsStr, reply: ReplyEmpty) {
- debug!("unlink(parent: {:#x?}, name: {:?})", parent, name);
+ // debug!("unlink(parent: {:#x?}, name: {:?})", parent, name);
let parent = parent as usize;
if let Some(parent_inode) = self.get_inode(parent) {
// 无权限删除 -> EACCES
@@ -510,7 +508,7 @@ impl Filesystem for AyaFS {
if inode.n_links == 0 {
// n_links == 0 -> 整个 inode 都要删除掉
match self.remove_file(inode_index) {
- Ok(flag) => debug!(" unlink {}", flag),
+ Ok(flag) => trace!(" unlink {}", flag),
Err(err_code) => {
reply.error(err_code);
return;
@@ -552,7 +550,7 @@ impl Filesystem for AyaFS {
}
fn rmdir(&mut self, req: &Request<'_>, parent: u64, name: &OsStr, reply: ReplyEmpty) {
- debug!("rmdir(parent: {:#x?}, name: {:?})", parent, name);
+ // debug!("rmdir(parent: {:#x?}, name: {:?})", parent, name);
let parent = parent as usize;
if let Some(parent_inode) = self.get_inode(parent) {
// 无权限删除 -> EACCES
@@ -601,7 +599,7 @@ impl Filesystem for AyaFS {
// directory 没有 hard link, 删了就是删了
match self.remove_dir(inode_index) {
- Ok(flag) => debug!(" rmdir {}", flag),
+ Ok(flag) => trace!(" rmdir {}", flag),
Err(err_code) => {
reply.error(err_code);
return;
@@ -635,10 +633,10 @@ impl Filesystem for AyaFS {
target: &Path,
reply: ReplyEntry,
) {
- debug!(
- "symlink(parent: {}, name: {:?}, target: {:?})",
- parent, link_name, target
- );
+ // debug!(
+ // "symlink(parent: {}, name: {:?}, target: {:?})",
+ // parent, link_name, target
+ // );
let parent = parent as usize;
// let root_inode_index = 1usize;
@@ -698,7 +696,7 @@ impl Filesystem for AyaFS {
let mut child_inode = child_inode.clone();
child_inode.size = target.len() as u64;
if target.len() < 60 {
- debug!("create_symlink: target length < 60, allocating in 'direct' section.");
+ trace!("create_symlink: target length < 60, allocating in 'direct' section.");
let target_path = target.as_bytes();
let copy_dst = unsafe {
let dst = (&mut child_inode.direct) as *mut u32 as *mut u8;
@@ -706,7 +704,7 @@ impl Filesystem for AyaFS {
};
copy_dst.copy_from_slice(target_path);
} else {
- debug!("create_symlink: target length >= 60, using original layout.");
+ trace!("create_symlink: target length >= 60, using original layout.");
let mut write_ptr = 0usize;
while write_ptr < target.len() {
let block_index = write_ptr / BLOCK_SIZE;
@@ -785,10 +783,10 @@ impl Filesystem for AyaFS {
flags: u32,
reply: ReplyEmpty,
) {
- debug!(
- "rename(parent: {}, name: {:?}, new_parent: {}, new_name: {:?})",
- parent, name, new_parent, new_name
- );
+ // debug!(
+ // "rename(parent: {}, name: {:?}, new_parent: {}, new_name: {:?})",
+ // parent, name, new_parent, new_name
+ // );
let parent = parent as usize;
let new_parent = new_parent as usize;
@@ -974,7 +972,7 @@ impl Filesystem for AyaFS {
if let Err(err_code) = self.add_direntry(
new_parent,
&mut parent_inode,
- ino as usize,
+ ino,
new_name,
from_filetype(filetype)
) {
@@ -988,8 +986,78 @@ impl Filesystem for AyaFS {
}
}
+ fn create(
+ &mut self,
+ req: &Request<'_>,
+ parent: u64,
+ name: &OsStr,
+ mode: u32,
+ _umask: u32,
+ _flags: i32,
+ reply: ReplyCreate,
+ ) {
+ let parent = parent as usize;
+ if let Some(parent_inode) = self.get_inode(parent) {
+ if !check_access(
+ req.uid(),
+ req.gid(),
+ parent_inode.uid,
+ parent_inode.gid,
+ parent_inode.mode,
+ W_OK,
+ ) {
+ reply.error(EACCES);
+ return;
+ }
+
+ // parent 不是 IFDIR -> Not a directory
+ if !parent_inode.is_dir() {
+ reply.error(ENOTDIR);
+ return;
+ }
+
+ // 文件名长度超过 255, 返回 filename too long
+ if name.len() > 255 {
+ reply.error(ENAMETOOLONG);
+ return;
+ }
+
+ let mut parent_inode = parent_inode.clone();
+ // 如果已经存在, 返回 already exists
+ if self.lookup_name(parent, &parent_inode, name).is_ok() {
+ reply.error(EEXIST);
+ return;
+ }
+
+ let mode = mode as u16;
+ if let Some((child_inode_index, child_inode)) =
+ self.create_file(mode, req.uid(), req.gid(), 0)
+ {
+ let mode = child_inode.mode;
+ let file_attr = to_fileattr(child_inode_index, child_inode);
+ if let Err(err_code) = self.add_direntry(
+ parent,
+ &mut parent_inode,
+ child_inode_index,
+ name,
+ mode.into(),
+ ) {
+ reply.error(err_code);
+ return;
+ }
+ self.update_inode(parent, parent_inode); // 前面 clone 了, 这里写回
+ let fh = self.allocate_file_descriptor(child_inode_index, true, true);
+ reply.created(&TTL, &file_attr, 0, fh, 0);
+ } else {
+ reply.error(ENOSPC);
+ }
+ } else {
+ reply.error(ENOENT);
+ }
+ }
+
fn open(&mut self, req: &Request<'_>, ino: u64, flags: i32, reply: ReplyOpen) {
- debug!("open(ino: {:#x?}, flags: {:#x?})", ino, flags);
+ // debug!("open(ino: {:#x?}, flags: {:#x?})", ino, flags);
let (access_mask, read, write) = match flags & O_ACCMODE {
O_RDONLY => {
// Behavior is undefined, but most filesystems return EACCES
@@ -1035,7 +1103,7 @@ impl Filesystem for AyaFS {
// - EOF > offset + size -> return size
fn read(
&mut self,
- req: &Request<'_>,
+ _req: &Request<'_>,
ino: u64,
fh: u64,
offset: i64,
@@ -1044,17 +1112,22 @@ impl Filesystem for AyaFS {
_lock_owner: Option<u64>, // 用不到!
reply: ReplyData,
) {
- assert_eq!(self.file_handle_map.get(&fh).unwrap().0, ino as usize);
+ let (inode_num, read_permission, _) = self
+ .file_handle_map
+ .get(&fh)
+ .cloned()
+ .unwrap();
+ assert_eq!(inode_num, ino as usize);
if let Some(inode) = self.get_inode(ino as usize) {
if inode.is_dir() {
reply.error(EISDIR);
return;
}
- if !check_access(req.uid(), req.gid(), inode.uid, inode.gid, inode.mode, R_OK) {
+ if !read_permission {
reply.error(EACCES);
return;
}
- debug!("reading inode {:#x} (offset {} size {})", ino, offset, size);
+ trace!("reading inode {:#x} (offset {} size {})", ino, offset, size);
if offset as u64 >= inode.size {
// offset 在 EOF 后面, 直接返回一个 0 长度的空 buffer
@@ -1109,7 +1182,7 @@ impl Filesystem for AyaFS {
// 写了多少就返回多少
fn write(
&mut self,
- req: &Request<'_>,
+ _req: &Request<'_>,
ino: u64,
fh: u64,
offset: i64,
@@ -1119,17 +1192,22 @@ impl Filesystem for AyaFS {
_lock_owner: Option<u64>,
reply: ReplyWrite,
) {
- assert_eq!(self.file_handle_map.get(&fh).unwrap().0, ino as usize);
- if let Some(inode) = self.get_inode(ino as usize) {
+ let (inode_num, _, write_permission) = self
+ .file_handle_map
+ .get(&fh)
+ .cloned()
+ .unwrap();
+ assert_eq!(inode_num, ino as usize);
+ if let Some(inode) = self.get_inode(inode_num) {
if inode.is_dir() {
reply.error(EISDIR);
return;
}
- if !check_access(req.uid(), req.gid(), inode.uid, inode.gid, inode.mode, W_OK) {
+ if !write_permission {
reply.error(EACCES);
return;
}
- debug!(
+ trace!(
"writing inode {:#x} (offset {} size {})",
ino,
offset,
@@ -1155,7 +1233,7 @@ impl Filesystem for AyaFS {
// 当前块已分配, 直接往里写
if let Some(block) = self.access_block_mut::<DataBlock>(&inode, current_block_index)
{
- debug!(
+ trace!(
"writing {} bytes in block {} within inode",
write_length_within_block, current_block_index
);
@@ -1167,7 +1245,7 @@ impl Filesystem for AyaFS {
if let Some((block_index, block_index_within_inode)) =
self.allocate_block_for(&mut inode)
{
- debug!("writing {} bytes in allocated block {} within inode, block index is {}", write_length_within_block, block_index_within_inode, block_index);
+ trace!("writing {} bytes in allocated block {} within inode, block index is {}", write_length_within_block, block_index_within_inode, block_index);
// 能分配, 往里写
let block = self
.access_block_mut::<DataBlock>(&inode, block_index_within_inode)
@@ -1212,7 +1290,7 @@ impl Filesystem for AyaFS {
}
fn opendir(&mut self, req: &Request<'_>, ino: u64, flags: i32, reply: ReplyOpen) {
- debug!("opendir(ino: {:#x?}, flags: {:#x?})", ino, flags);
+ // debug!("opendir(ino: {:#x?}, flags: {:#x?})", ino, flags);
let (access_mask, read, write) = match flags & O_ACCMODE {
O_RDONLY => {
// Behavior is undefined, but most filesystems return EACCES
@@ -1273,10 +1351,10 @@ impl Filesystem for AyaFS {
return;
}
- debug!(
- "reading dir entries from inode {:#x} with offset {}",
- ino, offset
- );
+ // debug!(
+ // "reading dir entries from inode {:#x} with offset {}",
+ // ino, offset
+ // );
let inode = inode.clone();
self.load_direntry_map(ino as usize, &inode).unwrap();
@@ -1288,10 +1366,10 @@ impl Filesystem for AyaFS {
.enumerate()
.skip(offset as usize)
{
- debug!(
- " entry {} from inode {:#x} with name {:?}",
- entry_index, dir_entry.inode, name
- );
+ // debug!(
+ // " entry {} from inode {:#x} with name {:?}",
+ // entry_index, dir_entry.inode, name
+ // );
if reply.add(
dir_entry.inode as u64,
entry_index as i64 + 1,
@@ -1349,10 +1427,9 @@ impl Filesystem for AyaFS {
// mask:
// - 要么是 libc::F_OK (aka 0), 检查文件是否存在
// - 要么是 libc::R_OK,libc::W_OK,libc::X_OK (aka 4/2/1) 构成的 bitmask, 检查是否有对应权限
- debug!("Filesystem::access(ino: {}, mask: {})", ino, mask);
+ // debug!("Filesystem::access(ino: {}, mask: {})", ino, mask);
if let Some(inode) = self.get_inode(ino as usize) {
- debug!(" uid: {}, gid: {}, incoming_uid: {}, incoming_gid: {}, mask: {}", inode.uid, inode.gid, req.uid(), req.gid(), mask);
if mask == libc::F_OK // 只要检查是否存在
|| check_access(req.uid(), req.gid(), inode.uid, inode.gid, inode.mode, mask)
// 需要检查 rwx 权限
diff --git a/ayafs-core/src/lib.rs b/ayafs-core/src/lib.rs
index d73619b..d3dfd79 100644
--- a/ayafs-core/src/lib.rs
+++ b/ayafs-core/src/lib.rs
@@ -10,7 +10,7 @@ pub mod utils;
use indexmap::IndexMap;
-use log::debug;
+use log::{debug, trace};
use lru::LruCache;
use std::collections::HashMap;
use std::ffi::OsString;
@@ -217,7 +217,7 @@ impl AyaFS {
self.device.write(0, super_block_buffer);
while let Some((inode_index, dir_entry_map)) = self.dir_entry_map.pop_lru() {
- debug!("writing back direntry map for inode {}", inode_index);
+ trace!("writing back direntry map for inode {}", inode_index);
if let Some(inode) = self.get_inode(inode_index) {
let mut inode = inode.clone();
self.write_back_direntry(
diff --git a/ayafs-core/src/memory/cached_block.rs b/ayafs-core/src/memory/cached_block.rs
index 24f08c0..ae0f2a9 100644
--- a/ayafs-core/src/memory/cached_block.rs
+++ b/ayafs-core/src/memory/cached_block.rs
@@ -4,7 +4,7 @@ use crate::AyaFS;
use lru::LruCache;
use std::num::NonZeroUsize;
use std::sync::Arc;
-use log::debug;
+use log::trace;
#[derive(Clone)]
pub struct CachedBlock<T: Block> {
@@ -43,14 +43,14 @@ impl<T: Block> BlockCache<T> {
pub(crate) fn write_back(&self) {
for (_, cached_block) in self.cache.iter() {
if cached_block.dirty {
- debug!("write_back: dirty block {}", self.global_offset + cached_block.index);
+ trace!("write_back: dirty block {}", self.global_offset + cached_block.index);
let block_buffer = unsafe {
let block_ptr = &cached_block.block as *const T as *const u8;
std::slice::from_raw_parts(block_ptr, std::mem::size_of::<T>())
};
self.device.write(self.global_offset + cached_block.index, block_buffer);
} else {
- debug!("write_back: clean block {}", self.global_offset + cached_block.index);
+ trace!("write_back: clean block {}", self.global_offset + cached_block.index);
}
}
}
@@ -68,7 +68,7 @@ impl<T: Block> BlockCache<T> {
if let Some((old_index, old_block)) = self.cache.push(index, cached_block) {
assert_ne!(old_index, index); // 只有 block 不在 cache 里的时候才会插入
if old_block.dirty {
- debug!("write_back: evicted dirty block {} while loading {}", self.global_offset + old_block.index, self.global_offset + index);
+ trace!("write_back: evicted dirty block {} while loading {}", self.global_offset + old_block.index, self.global_offset + index);
let old_block_buffer = unsafe {
let old_block_ptr = &old_block.block as *const T as *mut u8;
std::slice::from_raw_parts(old_block_ptr, BLOCK_SIZE)
@@ -84,18 +84,18 @@ impl<T: Block> BlockCache<T> {
/// 这个函数不应该返回 None
pub(crate) fn get_block<U: Block>(&mut self, index: usize) -> Option<&CachedBlock<U>> {
if !self.cache.contains(&index) {
- debug!("get_block(global_block_id: {}) loading from disk", index + self.global_offset);
+ trace!("get_block(global_block_id: {}) loading from disk", index + self.global_offset);
self.load_block(index);
}
if let Some(block) = self.cache.get(&index) {
- debug!("get_block(global_block_id: {}) found", index + self.global_offset);
+ trace!("get_block(global_block_id: {}) found", index + self.global_offset);
Some(convert::<T, U>(block))
} else {
- debug!("get_block(global_block_id: {}) not found", index + self.global_offset);
+ trace!("get_block(global_block_id: {}) not found", index + self.global_offset);
None
}
- // debug!("get_block(global_block_id: {}) found", index + self.global_offset);
+ // trace!("get_block(global_block_id: {}) found", index + self.global_offset);
// self.cache.get(&index).map(convert::<T, U>)
}
@@ -103,21 +103,21 @@ impl<T: Block> BlockCache<T> {
/// 这个函数不应该返回 None
pub(crate) fn get_block_mut<U: Block>(&mut self, index: usize) -> Option<&mut CachedBlock<U>> {
if !self.cache.contains(&index) {
- debug!("get_block_mut(global_block_id: {}) loading from disk", index + self.global_offset);
+ trace!("get_block_mut(global_block_id: {}) loading from disk", index + self.global_offset);
self.load_block(index);
}
if let Some(block) = self.cache.get_mut(&index) {
- debug!("get_block_mut(global_block_id: {}) found", index + self.global_offset);
+ trace!("get_block_mut(global_block_id: {}) found", index + self.global_offset);
block.dirty = true;
Some(convert_mut::<T, U>(block))
} else {
- debug!("get_block_mut(global_block_id: {}) not found", index + self.global_offset);
+ trace!("get_block_mut(global_block_id: {}) not found", index + self.global_offset);
None
}
// self.cache.get_mut(&index).map(|block| {
- // debug!("get_block_mut(global_block_id: {}) found", index + self.global_offset);
+ // trace!("get_block_mut(global_block_id: {}) found", index + self.global_offset);
// block.dirty = true;
// convert_mut::<T, U>(block)
// })
@@ -159,7 +159,7 @@ impl<T: Block> BlockCache<T> {
data_block.dirty = true; // TODO 需要把显式写回的都标记为 dirty 吗
let (entry, _value) = self.cache.push(block.index, data_block).unwrap();
assert_eq!(entry, block.index);
- debug!("update_block(global_block_id: {})", block.index + self.global_offset);
+ trace!("update_block(global_block_id: {})", block.index + self.global_offset);
true
} else {
false
@@ -167,7 +167,7 @@ impl<T: Block> BlockCache<T> {
}
fn pop(&mut self, entry: usize) -> Option<CachedBlock<T>> {
- debug!("pop_block(global_block_id: {})", entry + self.global_offset);
+ trace!("pop_block(global_block_id: {})", entry + self.global_offset);
self.cache.pop(&entry)
}
}
@@ -179,10 +179,10 @@ impl AyaFS {
pub(crate) fn get_block<T: Block>(&mut self, index: usize) -> Option<&CachedBlock<T>> {
if self.data_bitmap.query(index) {
- debug!("get_block(block_id: {}) found", index);
+ trace!("get_block(block_id: {}) found", index);
Some(self.cached_blocks.get_block::<T>(index).unwrap())
} else {
- debug!("get_block(block_id: {}) not exist", index);
+ trace!("get_block(block_id: {}) not exist", index);
self.cached_blocks.pop(index);
None
}
diff --git a/ayafs-core/src/memory/dir_entry.rs b/ayafs-core/src/memory/dir_entry.rs
index 3880f61..ee363b2 100644
--- a/ayafs-core/src/memory/dir_entry.rs
+++ b/ayafs-core/src/memory/dir_entry.rs
@@ -4,7 +4,7 @@ use crate::AyaFS;
use indexmap::map::Entry::Occupied;
use indexmap::IndexMap;
use libc::{c_int, ENOENT, ENOSPC};
-use log::debug;
+use log::trace;
use std::ffi::{OsStr, OsString};
use std::os::unix::ffi::OsStrExt;
@@ -25,11 +25,11 @@ impl AyaFS {
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);
+ trace!("load_direntry_map(ino: {}) already in cache", index);
return Ok(());
}
- debug!("load_direntry_map(ino: {}) loading", index);
+ trace!("load_direntry_map(ino: {}) loading", index);
let mut dir_entry_map: IndexMap<OsString, DirectoryEntry> = IndexMap::new();
let mut entry_index: usize = 0;
loop {
@@ -38,11 +38,11 @@ impl AyaFS {
match self.access_block::<DirectoryBlock>(inode, block_index_within_inode) {
Some(directory_block) => {
- debug!("bitmap for block is {:#b} {:#b}", directory_block.block.occupancy[0], directory_block.block.occupancy[1]);
+ trace!("bitmap for block is {:#b} {:#b}", directory_block.block.occupancy[0], directory_block.block.occupancy[1]);
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();
- debug!("loaded entry({:?}) for inode {}", name.as_os_str(), index);
+ trace!("loaded entry({:?}) for inode {}", name.as_os_str(), index);
dir_entry_map.insert(name, dir_entry.clone());
} else {
break;
@@ -95,9 +95,9 @@ impl AyaFS {
directory_block.block.reset();
}
directory_block.dirty = true;
- debug!("entry {} (block {} offset {}) for inode {}, name {:?}", entry_index, block_index_within_inode, entry_index_within_block, _parent_index, name);
+ trace!("entry {} (block {} offset {}) for inode {}, name {:?}", entry_index, block_index_within_inode, entry_index_within_block, _parent_index, name);
directory_block.block.allocate(entry_index_within_block);
- debug!("bitmap for block is {:#b} {:#b}", directory_block.block.occupancy[0], directory_block.block.occupancy[1]);
+ trace!("bitmap for block is {:#b} {:#b}", directory_block.block.occupancy[0], directory_block.block.occupancy[1]);
directory_block.block.entries[entry_index_within_block] = dir_entry;
}
None => {
@@ -168,7 +168,7 @@ impl AyaFS {
) -> 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);
+ trace!(" remove_direntry(ino: {}) using hashmap", parent_index);
if dir_entry_map.shift_remove(name.as_ref()).is_some() {
Ok(())
} else {
@@ -191,7 +191,7 @@ 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);
- debug!(
+ trace!(
" add_direntry(ino: {}) using hashmap, entry {}",
parent_index, entry_index
);
@@ -227,7 +227,7 @@ impl AyaFS {
let (entry_index, _) =
dir_entry_map.insert_full(child_inode_name.to_os_string(), dir_entry);
- debug!(
+ trace!(
" add_direntry(ino: {}) using hashmap, entry {}",
parent_index, entry_index
);
@@ -246,7 +246,7 @@ impl AyaFS {
) -> 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!(
+ trace!(
" get_direntry(ino: {}, name: {:?}) using hashmap",
parent_index,
name.as_ref()
@@ -265,7 +265,7 @@ impl AyaFS {
) -> 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!(
+ trace!(
" get_direntry(ino: {}, entry_index: {}) using hashmap",
parent_index, entry_index
);
diff --git a/ayafs-core/src/utils/permissions.rs b/ayafs-core/src/utils/permissions.rs
index 6773511..53205b5 100644
--- a/ayafs-core/src/utils/permissions.rs
+++ b/ayafs-core/src/utils/permissions.rs
@@ -2,6 +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;
pub(crate) fn get_groups(pid: u32) -> Vec<u32> {
let file = File::open(format!("/proc/{pid}/task/{pid}/status"))
@@ -36,6 +37,8 @@ pub(crate) fn check_access(
mode: InodeMode,
mut mask: i32,
) -> bool {
+ let mask_mem = mask;
+ // true
if mask == F_OK {
return true;
}
@@ -58,5 +61,17 @@ pub(crate) fn check_access(
} else {
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,
+ );
+
mask == 0
}