feat(ext4): mkdir and nested directory support
This commit is contained in:
@@ -586,5 +586,60 @@ impl<B: BlockDevice> FileSystem for Ext4<B> {
|
||||
self.open_files[handle.raw() as usize].as_ref().map(|f| f.size)
|
||||
}
|
||||
|
||||
fn mkdir(&mut self, _path: &[u8]) -> bool { false }
|
||||
fn mkdir(&mut self, path: &[u8]) -> bool {
|
||||
let (parent_inode_num, dirname) = match self.resolve_parent(path) {
|
||||
Some(v) => v,
|
||||
None => return false,
|
||||
};
|
||||
let parent_inode = match self.read_inode(parent_inode_num) {
|
||||
Some(i) => i,
|
||||
None => return false,
|
||||
};
|
||||
if !parent_inode.is_dir() { return false; }
|
||||
|
||||
if dir::find_entry(&mut self.device, &self.sb, self.gdt_block, &parent_inode, dirname).is_some() {
|
||||
return false;
|
||||
}
|
||||
|
||||
let new_inode_num = match self.alloc_inode() {
|
||||
Some(n) => n,
|
||||
None => return false,
|
||||
};
|
||||
let new_block = match self.alloc_block() {
|
||||
Some(b) => b,
|
||||
None => { self.free_inode(new_inode_num); return false; }
|
||||
};
|
||||
|
||||
let mut new_inode = Self::init_empty_inode(0x4000 | 0o755);
|
||||
new_inode.links_count = 2;
|
||||
new_inode.size = self.sb.block_size as u64;
|
||||
new_inode.blocks_count = (self.sb.block_size / 512) as u32;
|
||||
if !Self::append_extent(&mut new_inode.block_data, 0, new_block as u64, 1) {
|
||||
self.free_block(new_block);
|
||||
self.free_inode(new_inode_num);
|
||||
return false;
|
||||
}
|
||||
self.write_inode(new_inode_num, &new_inode);
|
||||
|
||||
let mut dir_block = [0u8; 4096];
|
||||
dir::init_dir_block(&mut dir_block, new_inode_num, parent_inode_num, self.sb.block_size);
|
||||
io::write_block(&mut self.device, new_block as u64, self.sb.sectors_per_block(), &dir_block);
|
||||
|
||||
let parent_inode = match self.read_inode(parent_inode_num) {
|
||||
Some(i) => i,
|
||||
None => return false,
|
||||
};
|
||||
if !dir::add_entry(&mut self.device, &self.sb, self.gdt_block, &parent_inode, dirname, new_inode_num, 2) {
|
||||
self.free_block(new_block);
|
||||
self.free_inode(new_inode_num);
|
||||
return false;
|
||||
}
|
||||
|
||||
if let Some(mut pi) = self.read_inode(parent_inode_num) {
|
||||
pi.links_count += 1;
|
||||
self.write_inode(parent_inode_num, &pi);
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user