summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChuyan Zhang <me@zcy.moe>2023-11-27 13:30:33 -0800
committerChuyan Zhang <me@zcy.moe>2023-11-27 13:30:33 -0800
commitdfe7a2b658d31f6032f86ce225a467530860bf77 (patch)
treeb404f2764c4be4c5d2ca4ce028b163194bcc2448
parent51118228f978f8dde956016f4cf3f169d9e21f20 (diff)
downloadmyfs-dfe7a2b658d31f6032f86ce225a467530860bf77.tar.gz
myfs-dfe7a2b658d31f6032f86ce225a467530860bf77.zip
I CAN WRITE!!!
-rw-r--r--src/filesystem/trait_impl.rs84
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);
- }
}