summaryrefslogtreecommitdiff
path: root/ayafs-core/src/filesystem
diff options
context:
space:
mode:
authorChuyan Zhang <me@zcy.moe>2023-12-01 19:42:13 -0800
committerChuyan Zhang <me@zcy.moe>2023-12-01 19:42:13 -0800
commit4c34414b26bf71e747ea3ecb2586645bab4aba52 (patch)
treeb569935a94c7fb3e0a23a19207f6545b4d7719c3 /ayafs-core/src/filesystem
parentfd125947c9db0b33761414e65e919f73d9bf1815 (diff)
downloadmyfs-4c34414b26bf71e747ea3ecb2586645bab4aba52.tar.gz
myfs-4c34414b26bf71e747ea3ecb2586645bab4aba52.zip
Multiple bugfix, it works!
Diffstat (limited to 'ayafs-core/src/filesystem')
-rw-r--r--ayafs-core/src/filesystem/trait_impl.rs100
1 files changed, 54 insertions, 46 deletions
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::<DataBlock>(&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 权限