From 4c34414b26bf71e747ea3ecb2586645bab4aba52 Mon Sep 17 00:00:00 2001 From: Chuyan Zhang Date: Fri, 1 Dec 2023 19:42:13 -0800 Subject: Multiple bugfix, it works! --- ayafs-core/src/filesystem/trait_impl.rs | 100 +++++++++++++++++--------------- 1 file changed, 54 insertions(+), 46 deletions(-) (limited to 'ayafs-core/src/filesystem') diff --git a/ayafs-core/src/filesystem/trait_impl.rs b/ayafs-core/src/filesystem/trait_impl.rs index b551cf7..78673ba 100644 --- a/ayafs-core/src/filesystem/trait_impl.rs +++ b/ayafs-core/src/filesystem/trait_impl.rs @@ -1,17 +1,14 @@ use crate::block_device::BLOCK_SIZE; use crate::disk::block::DataBlock; -use crate::disk::inode::InodeMode; +use crate::disk::inode::{INODE_PER_BLOCK, InodeMode}; 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, ReplyStatfs, ReplyWrite, ReplyXattr, Request, TimeOrNow, -}; +use fuser::{FileType, Filesystem, KernelConfig, ReplyAttr, ReplyData, ReplyDirectory, ReplyEmpty, ReplyEntry, ReplyOpen, ReplyWrite, Request, TimeOrNow, ReplyStatfs}; use libc::{ c_int, EACCES, EBADF, EEXIST, EINVAL, EIO, EISDIR, ENAMETOOLONG, ENOENT, ENOSPC, ENOTDIR, - ENOTEMPTY, EPERM, IPOPT_OFFSET, O_ACCMODE, O_RDONLY, O_RDWR, O_WRONLY, RENAME_EXCHANGE, + 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; @@ -25,13 +22,13 @@ impl AyaFS {} impl Filesystem for AyaFS { fn init(&mut self, _req: &Request<'_>, _config: &mut KernelConfig) -> Result<(), c_int> { - debug!("`init()"); + debug!("init()"); Ok(()) } fn destroy(&mut self) { debug!("destroy()"); - // TODO 写回 + self.write_back(); } fn lookup(&mut self, req: &Request<'_>, parent: u64, name: &OsStr, reply: ReplyEntry) { @@ -66,8 +63,24 @@ impl Filesystem for AyaFS { } } + // fn getxattr(&mut self, _req: &Request<'_>, ino: u64, name: &OsStr, size: u32, reply: ReplyXattr) { + // if let Some(inode) = self.get_inode(ino as usize) { + // debug!( + // "getattr(ino: {}, incoming_uid: {}, inode_uid: {})", + // ino, _req.uid(), inode.uid, + // ); + // reply.error(ENOENT); + // } else { + // reply.error(ENOENT); + // } + // } + fn getattr(&mut self, _req: &Request<'_>, ino: u64, reply: ReplyAttr) { if let Some(inode) = self.get_inode(ino as usize) { + debug!( + "getattr(ino: {}, incoming_uid: {}, inode_uid: {})", + ino, _req.uid(), inode.uid, + ); reply.attr(&TTL, &to_fileattr(ino as usize, inode)); } else { reply.error(ENOENT); @@ -172,7 +185,7 @@ impl Filesystem for AyaFS { if !write { reply.error(EACCES); } else { - inode.size = size as u32; + inode.size = size; reply.attr(&TTL, &to_fileattr(*inode_index, &inode)); self.update_inode(*inode_index, inode); } @@ -180,7 +193,7 @@ impl Filesystem for AyaFS { if !check_access(req.uid(), req.gid(), inode.uid, inode.gid, inode.mode, W_OK) { reply.error(EACCES); } else { - inode.size = size as u32; + inode.size = size; reply.attr(&TTL, &to_fileattr(ino as usize, &inode)); } } @@ -689,7 +702,7 @@ impl Filesystem for AyaFS { self.create_symlink(0o777, req.uid(), req.gid(), 0) { let mut child_inode = child_inode.clone(); - child_inode.size = target.len() as u32; + child_inode.size = target.len() as u64; if target.len() < 60 { debug!("create_symlink: target length < 60, allocating in 'direct' section."); let target_path = target.as_bytes(); @@ -805,7 +818,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, entry_index, _inode)) => { if let Some(new_parent_inode) = self.get_inode(new_parent) { if !check_access( req.uid(), @@ -825,7 +838,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_entry_index, _new_inode)) => { // 新文件存在 if flags & RENAME_NOREPLACE != 0 { // 指定 noreplace 之后不允许覆盖文件 @@ -993,7 +1006,7 @@ impl Filesystem for AyaFS { } debug!("reading inode {:#x} (offset {} size {})", ino, offset, size); - if offset as u32 >= inode.size { + if offset as u64 >= inode.size { // offset 在 EOF 后面, 直接返回一个 0 长度的空 buffer reply.data(&Vec::new()); return; @@ -1001,10 +1014,12 @@ impl Filesystem for AyaFS { // let read_length = size.min(inode.size.saturating_sub(offset as u32)) as usize; // 这和下面那个是等同的但是不利于让人看懂…… - let read_length = if offset as u32 + size <= inode.size { + + let size = size as u64; + let read_length = if size.checked_add_signed(offset).unwrap() <= inode.size { size // 没有越过 EOF, 读取 size 个 byte } else { - inode.size - offset as u32 // 越过了 EOF, 读取 inode.size - offset 个 byte + inode.size - offset as u64 // 越过了 EOF, 读取 inode.size - offset 个 byte } as usize; let mut read_buffer = vec![0u8; read_length]; @@ -1094,7 +1109,7 @@ impl Filesystem for AyaFS { "writing {} bytes in block {} within inode", write_length_within_block, current_block_index ); - (block.block.0[current_offset..current_offset + write_length_within_block]) + block.block.0[current_offset..current_offset + write_length_within_block] .copy_from_slice(&data[write_ptr..write_ptr + write_length_within_block]); write_ptr += write_length_within_block; } else { @@ -1107,7 +1122,7 @@ impl Filesystem for AyaFS { let block = self .access_block_mut::(&inode, block_index_within_inode) .unwrap(); - (block.block.0[current_offset..current_offset + write_length_within_block]) + block.block.0[current_offset..current_offset + write_length_within_block] .copy_from_slice( &data[write_ptr..write_ptr + write_length_within_block], ); @@ -1119,7 +1134,7 @@ impl Filesystem for AyaFS { } } - inode.size = inode.size.max(offset as u32 + write_length as u32); + inode.size = inode.size.max(offset as u64 + write_length as u64); self.update_inode(ino as usize, inode); reply.written(write_length as u32); } else { @@ -1127,30 +1142,6 @@ impl Filesystem for AyaFS { } } - // fn getxattr( - // &mut self, - // _req: &Request<'_>, - // ino: u64, - // name: &OsStr, - // size: u32, - // reply: ReplyXattr, - // ) { - // todo!() - // } - // - // fn setxattr( - // &mut self, - // _req: &Request<'_>, - // ino: u64, - // name: &OsStr, - // _value: &[u8], - // flags: i32, - // position: u32, - // reply: ReplyEmpty, - // ) { - // todo!() - // } - fn release( &mut self, _req: &Request<'_>, @@ -1284,9 +1275,25 @@ impl Filesystem for AyaFS { } } - // fn statfs(&mut self, _req: &Request<'_>, _ino: u64, reply: ReplyStatfs) { - // todo!() - // } + fn statfs(&mut self, _req: &Request<'_>, ino: u64, reply: ReplyStatfs) { + if let Some(_) = self.get_inode(ino as usize) { + self.super_block.used_inode_number = self.inode_bitmap.count; + self.super_block.used_block_number = self.data_bitmap.count; + + reply.statfs( + self.super_block.used_block_number, + self.super_block.data_block_number - self.super_block.used_block_number, + self.super_block.data_block_number - self.super_block.used_block_number, + self.super_block.used_inode_number, + self.super_block.inode_block_number * INODE_PER_BLOCK as u64 - self.super_block.used_inode_number, + BLOCK_SIZE as u32, + 255, + BLOCK_SIZE as u32, + ); + } else { + reply.error(ENOENT); + } + } fn access(&mut self, req: &Request<'_>, ino: u64, mask: i32, reply: ReplyEmpty) { // mask: @@ -1295,6 +1302,7 @@ impl Filesystem for AyaFS { 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 权限 -- cgit v1.2.3-70-g09d2