From ceb83a7214000ccd048857b40cc0ebfc54290731 Mon Sep 17 00:00:00 2001 From: Chuyan Zhang Date: Mon, 27 Nov 2023 13:50:18 -0800 Subject: fix write & fix setattr --- src/filesystem/trait_impl.rs | 51 ++++++++++++++++++++++++++++++-------------- 1 file changed, 35 insertions(+), 16 deletions(-) diff --git a/src/filesystem/trait_impl.rs b/src/filesystem/trait_impl.rs index 0b73c9b..78916ed 100644 --- a/src/filesystem/trait_impl.rs +++ b/src/filesystem/trait_impl.rs @@ -5,8 +5,7 @@ use crate::utils::{from_systime, time_now, to_fileattr, to_filetype}; use crate::{AyaFS, TTL}; use fuser::TimeOrNow::{Now, SpecificTime}; use fuser::{ - Filesystem, KernelConfig, ReplyAttr, ReplyData, ReplyDirectory, ReplyEmpty, ReplyEntry, - ReplyLseek, ReplyOpen, ReplyWrite, Request, TimeOrNow, + Filesystem, KernelConfig, ReplyAttr, ReplyData, ReplyDirectory, ReplyEmpty, ReplyEntry, ReplyOpen, ReplyWrite, Request, TimeOrNow, }; use libc::{c_int, EACCES, EBADF, EEXIST, EINVAL, EIO, EISDIR, ENAMETOOLONG, ENOENT, ENOSPC, ENOSYS, ENOTDIR, ENOTEMPTY, EPERM, O_ACCMODE, O_RDONLY, O_RDWR, O_WRONLY, R_OK, S_ISGID, S_ISUID, S_IXGRP, S_IXOTH, S_IXUSR, W_OK}; use log::debug; @@ -75,11 +74,11 @@ impl Filesystem for AyaFS { mode: Option, uid: Option, gid: Option, - size: Option, // TODO 当 setattr 被 ftruncate invoke 时会设置 size + size: Option, // 当 setattr 被 ftruncate invoke 时会设置 size atime: Option, mtime: Option, _ctime: Option, - fh: Option, // TODO 当 setattr 被 ftruncate invoke 时会提供 fh + fh: Option, // 当 setattr 被 ftruncate invoke 时会提供 fh _crtime: Option, // 忽略 _chgtime: Option, // 忽略 _bkuptime: Option, // 忽略 @@ -158,12 +157,32 @@ impl Filesystem for AyaFS { if let Some(size) = size { debug!("ftruncate on inode {:#x?} size {:?}", ino, size); if let Some(file_handle) = fh { - // 有 file handle 的 - todo!() + let mut inode = inode.clone(); + let (inode_index, _read, write) = self.file_handle_map.get(&file_handle).unwrap(); + assert_eq!(ino as usize, *inode_index); + if !write { + reply.error(EACCES); + } else { + inode.size = size as u32; + reply.attr(&TTL, &to_fileattr(*inode_index, &inode)); + self.update_inode(*inode_index, inode); + } } else { - // 没有 file handle 基于 inode 的 - todo!() + if !check_access( + req.uid(), + req.gid(), + inode.uid, + inode.gid, + inode.mode, + W_OK, + ) { + reply.error(EACCES); + } else { + inode.size = size as u32; + reply.attr(&TTL, &to_fileattr(ino as usize, &inode)); + } } + return; } // time 相关 @@ -541,7 +560,7 @@ impl Filesystem for AyaFS { O_RDONLY => { // Behavior is undefined, but most filesystems return EACCES if flags & libc::O_TRUNC != 0 { - reply.error(libc::EACCES); + reply.error(EACCES); return; } (R_OK, true, false) @@ -655,8 +674,8 @@ impl Filesystem for AyaFS { fh: u64, offset: i64, data: &[u8], - write_flags: u32, - flags: i32, + _write_flags: u32, + _flags: i32, _lock_owner: Option, reply: ReplyWrite, ) { @@ -689,16 +708,16 @@ impl Filesystem for AyaFS { // 当前块已分配, 直接往里写 if let Some(block) = self.access_block_mut::(&inode, current_block_index) { - debug!("writing in block {} within inode", current_block_index); - (block.block.0[ .. current_offset + write_length_within_block]) + debug!("writing {} bytes in block {} within inode", write_length_within_block, current_block_index); + (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 { // 当前块未分配,尝试分配 if let Some((block_index, block_index_within_inode)) = self.allocate_block_for(&mut inode) { - debug!("allocating block {} within inode, block index is {}", block_index_within_inode, block_index); + debug!("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).unwrap(); - (block.block.0[ .. 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 { @@ -741,7 +760,7 @@ impl Filesystem for AyaFS { O_RDONLY => { // Behavior is undefined, but most filesystems return EACCES if flags & libc::O_TRUNC != 0 { - reply.error(libc::EACCES); + reply.error(EACCES); return; } (R_OK, true, false) -- cgit v1.2.3-70-g09d2