use crate::disk::block::{DirectoryBlock, DirectoryEntry, InodeBlock}; use crate::disk::inode::{Inode, InodeMode, INODE_SIZE}; use crate::utils::from_filetype; use crate::{utils, AyaFS}; use and_then_some::BoolExt; use fuser::FileType; use log::debug; impl AyaFS { pub(crate) fn create_file( &mut self, permissions: u16, uid: u32, gid: u32, flags: u32, ) -> Option<(usize, &Inode)> { self.inode_bitmap.allocate().map(|inode_index| { self.get_inode_mut(inode_index).map(|inode| { *inode = Inode::file(permissions, uid, gid, utils::time_now(), flags, 0, 0, 0); }); (inode_index, self.get_inode(inode_index).unwrap()) }) } pub(crate) fn create_directory( &mut self, permissions: u16, uid: u32, gid: u32, flags: u32, ) -> Option<(usize, &Inode)> { self.inode_bitmap.allocate().map(|inode_index| { // 创建 Inode let mut new_inode = Inode::directory(permissions, uid, gid, utils::time_now(), flags, 0, 0, 0); // 分配第一个 direct block (new_inode.direct[0], _) = self.allocate_block_for(&mut new_inode).unwrap(); new_inode.size = 2; // 在 direct block 里分配 . 和 .. if let Some(directory_block) = self.get_block_mut::(new_inode.direct[0] as usize) { let dot = '.'.to_ascii_lowercase() as u8; // add dot entry directory_block.block.entries[0] = DirectoryEntry { inode: inode_index as u32, record_len: 264, name_len: 1, file_type: 0x2, name: [0; 256], }; directory_block.block.entries[0].name[0] = dot; // add dot dot entry directory_block.block.entries[1] = DirectoryEntry { inode: 0, // TODO set this as parent inode number record_len: 264, name_len: 2, file_type: 0x2, name: [0; 256], }; directory_block.block.entries[1].name[0] = dot; directory_block.block.entries[1].name[1] = dot; } // 把 inode 放到指定位置 self.get_inode_mut(inode_index).map(|inode| { *inode = new_inode; }); (inode_index, self.get_inode(inode_index).unwrap()) }) } pub(crate) fn create_inode( &mut self, permissions: u16, mode: InodeMode, uid: u32, gid: u32, flags: u32, ) -> Option { self.inode_bitmap.allocate().map(|inode_index| { self.get_inode_mut(inode_index).map(|inode| { *inode = Inode::make_inode( permissions, mode, uid, gid, utils::time_now(), flags, 0, 0, 0, ); }); inode_index }) } pub(crate) fn update_inode(&mut self, inode_index: usize, inode: Inode) -> bool { if self.inode_bitmap.query(inode_index) { let (block_index, offset) = self.locate_inode(inode_index); if let Some(cached_block) = self.cached_inodes.get_block_mut::(block_index) { cached_block.block.inodes[offset / INODE_SIZE] = inode; } true } else { false } } pub(crate) fn get_inode(&mut self, inode_index: usize) -> Option<&Inode> { self.inode_bitmap.query(inode_index).and_then(|| { let (block_index, offset) = self.locate_inode(inode_index); self.cached_inodes .get_block::(block_index) .map(|cached_block| &cached_block.block.inodes[offset / INODE_SIZE]) }) } pub(crate) fn get_inode_mut(&mut self, inode_index: usize) -> Option<&mut Inode> { self.inode_bitmap.query(inode_index).and_then(|| { let (block_index, offset) = self.locate_inode(inode_index); self.cached_inodes .get_block_mut::(block_index) .map(|cached_block| { cached_block.dirty = true; // 保守一些, 只要返回了 &mut Inode 这个页一定标记为脏 &mut cached_block.block.inodes[offset / INODE_SIZE] }) }) } pub(crate) fn peek_inode(&self, inode_index: usize) -> Option<&Inode> { self.inode_bitmap.query(inode_index).and_then(|| { let (block_index, offset) = self.locate_inode(inode_index); self.cached_inodes .peek_block::(block_index) .map(|cached_block| &cached_block.block.inodes[offset / INODE_SIZE]) }) } pub(crate) fn peek_inode_mut(&mut self, inode_index: usize) -> Option<&mut Inode> { self.inode_bitmap.query(inode_index).and_then(|| { let (block_index, offset) = self.locate_inode(inode_index); self.cached_inodes .peek_block_mut::(block_index) .map(|cached_block| { cached_block.dirty = true; // 保守一些, 只要返回了 &mut Inode 这个页一定标记为脏 &mut cached_block.block.inodes[offset / INODE_SIZE] }) }) } }