diff options
Diffstat (limited to 'src')
-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); - } } |