diff options
author | Chuyan Zhang <me@zcy.moe> | 2023-11-27 13:30:33 -0800 |
---|---|---|
committer | Chuyan Zhang <me@zcy.moe> | 2023-11-27 13:30:33 -0800 |
commit | dfe7a2b658d31f6032f86ce225a467530860bf77 (patch) | |
tree | b404f2764c4be4c5d2ca4ce028b163194bcc2448 /src/filesystem | |
parent | 51118228f978f8dde956016f4cf3f169d9e21f20 (diff) | |
download | myfs-dfe7a2b658d31f6032f86ce225a467530860bf77.tar.gz myfs-dfe7a2b658d31f6032f86ce225a467530860bf77.zip |
I CAN WRITE!!!
Diffstat (limited to 'src/filesystem')
-rw-r--r-- | src/filesystem/trait_impl.rs | 84 |
1 files changed, 66 insertions, 18 deletions
diff --git a/src/filesystem/trait_impl.rs b/src/filesystem/trait_impl.rs index 2a49eeb..0b73c9b 100644 --- a/src/filesystem/trait_impl.rs +++ b/src/filesystem/trait_impl.rs @@ -647,32 +647,92 @@ impl Filesystem for AyaFS { } } + // 写了多少就返回多少 fn write( &mut self, - _req: &Request<'_>, + req: &Request<'_>, ino: u64, fh: u64, offset: i64, data: &[u8], write_flags: u32, flags: i32, - lock_owner: Option<u64>, + _lock_owner: Option<u64>, reply: ReplyWrite, ) { - todo!() + assert_eq!(self.file_handle_map.get(&fh).unwrap().0, 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, W_OK) { + reply.error(EACCES); + return; + } + debug!("writing inode {:#x} (offset {} size {})", ino, offset, data.len()); + let write_length = data.len(); + let mut write_ptr = 0usize; + + let mut inode = inode.clone(); + + while write_ptr < write_length { + let current_point = offset as usize + write_ptr; + let current_block_index = current_point / BLOCK_SIZE; + let current_offset = current_point % BLOCK_SIZE; + + let write_length_within_block = if BLOCK_SIZE - current_offset < write_length - write_ptr { + BLOCK_SIZE - current_offset // 可以写满 block + } else { + write_length - write_ptr // 写完 buffer 就停下来 + }; + + // 当前块已分配, 直接往里写 + if let Some(block) = self.access_block_mut::<DataBlock>(&inode, current_block_index) { + debug!("writing in block {} within inode", current_block_index); + (block.block.0[ .. 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); + // 能分配, 往里写 + let block = self.access_block_mut::<DataBlock>(&inode, block_index_within_inode).unwrap(); + (block.block.0[ .. 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 { + // 分配不了, 没空间了 + break; + } + } + } + + inode.size = inode.size.max(offset as u32 + write_length as u32); + self.update_inode(ino as usize, inode); + reply.written(write_length as u32); + } else { + reply.error(ENOENT); + } } fn release( &mut self, _req: &Request<'_>, - _ino: u64, - _fh: u64, + ino: u64, + fh: u64, _flags: i32, _lock_owner: Option<u64>, _flush: bool, reply: ReplyEmpty, ) { - todo!() + debug!("release(ino: {:#x?}, fh: {}", ino, fh); + if self.file_handle_map.contains_key(&fh) { + self.file_handle_map.remove(&fh); + reply.ok(); + } else { + reply.error(EBADF); + } } fn opendir(&mut self, req: &Request<'_>, ino: u64, flags: i32, reply: ReplyOpen) { @@ -802,16 +862,4 @@ impl Filesystem for AyaFS { reply.error(ENOENT); } } - - fn lseek( - &mut self, - _req: &Request<'_>, - ino: u64, - fh: u64, - offset: i64, - whence: i32, - reply: ReplyLseek, - ) { - reply.error(ENOSYS); - } } |