From f5c92834f79dfdf8007daa019f401c5e51a7596f Mon Sep 17 00:00:00 2001 From: Chuyan Zhang Date: Sat, 2 Dec 2023 17:37:57 -0800 Subject: Fix read/write permissions --- ayafs-core/src/block_device/disk.rs | 6 +- ayafs-core/src/disk/allocation.rs | 30 ++--- ayafs-core/src/filesystem/trait_impl.rs | 189 ++++++++++++++++++++++---------- ayafs-core/src/lib.rs | 4 +- ayafs-core/src/memory/cached_block.rs | 32 +++--- ayafs-core/src/memory/dir_entry.rs | 24 ++-- ayafs-core/src/utils/permissions.rs | 15 +++ 7 files changed, 196 insertions(+), 104 deletions(-) (limited to 'ayafs-core/src') 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 { - 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::(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::(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::(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> { 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> { 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, // 用不到! 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, 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::(&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::(&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 { @@ -43,14 +43,14 @@ impl BlockCache { 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::()) }; 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 BlockCache { 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 BlockCache { /// 这个函数不应该返回 None pub(crate) fn get_block(&mut self, index: usize) -> Option<&CachedBlock> { 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::(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::) } @@ -103,21 +103,21 @@ impl BlockCache { /// 这个函数不应该返回 None pub(crate) fn get_block_mut(&mut self, index: usize) -> Option<&mut CachedBlock> { 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::(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::(block) // }) @@ -159,7 +159,7 @@ impl BlockCache { 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 BlockCache { } fn pop(&mut self, entry: usize) -> Option> { - 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(&mut self, index: usize) -> Option<&CachedBlock> { 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::(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 = IndexMap::new(); let mut entry_index: usize = 0; loop { @@ -38,11 +38,11 @@ impl AyaFS { match self.access_block::(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 { 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 { 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 { 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 } -- cgit v1.2.3-70-g09d2