feat(ext4): inode read/write, init_empty_inode, multi-extent read
This commit is contained in:
@@ -16,6 +16,8 @@ pub struct Inode {
|
||||
pub mode: u16,
|
||||
pub size: u64,
|
||||
pub flags: u32,
|
||||
pub links_count: u16,
|
||||
pub blocks_count: u32,
|
||||
pub block_data: [u8; 60],
|
||||
}
|
||||
|
||||
@@ -111,10 +113,66 @@ impl<B: BlockDevice> Ext4<B> {
|
||||
mode: read_u16(d, 0x00),
|
||||
size,
|
||||
flags: read_u32(d, 0x20),
|
||||
links_count: read_u16(d, 0x1A),
|
||||
blocks_count: read_u32(d, 0x1C),
|
||||
block_data,
|
||||
})
|
||||
}
|
||||
|
||||
fn write_inode(&mut self, inode_num: u32, inode: &Inode) -> bool {
|
||||
let bgd = match BlockGroupDescriptor::read(
|
||||
&mut self.device, self.gdt_block,
|
||||
self.sb.inode_block_group(inode_num),
|
||||
self.sb.sectors_per_block(),
|
||||
) {
|
||||
Some(b) => b,
|
||||
None => return false,
|
||||
};
|
||||
let index = self.sb.inode_index_in_group(inode_num);
|
||||
let inode_offset = (index as usize) * (self.sb.inode_size as usize);
|
||||
let block_offset = inode_offset / self.sb.block_size;
|
||||
let offset_in_block = inode_offset % self.sb.block_size;
|
||||
|
||||
let mut block_buf = [0u8; 4096];
|
||||
let block_num = (bgd.inode_table + block_offset as u32) as u64;
|
||||
read_block(&mut self.device, block_num, self.sb.sectors_per_block(), &mut block_buf);
|
||||
|
||||
let d = &mut block_buf[offset_in_block..];
|
||||
io::write_u16(d, 0x00, inode.mode);
|
||||
io::write_u32(d, 0x04, inode.size as u32);
|
||||
io::write_u16(d, 0x1A, inode.links_count);
|
||||
io::write_u32(d, 0x1C, inode.blocks_count);
|
||||
io::write_u32(d, 0x20, inode.flags);
|
||||
d[0x28..0x64].copy_from_slice(&inode.block_data);
|
||||
io::write_u32(d, 0x6C, (inode.size >> 32) as u32);
|
||||
|
||||
io::write_block(&mut self.device, block_num, self.sb.sectors_per_block(), &block_buf)
|
||||
}
|
||||
|
||||
pub fn init_empty_inode(mode: u16) -> Inode {
|
||||
let mut block_data = [0u8; 60];
|
||||
io::write_u16(&mut block_data, 0, EXTENT_MAGIC);
|
||||
io::write_u16(&mut block_data, 2, 0); // entries = 0
|
||||
io::write_u16(&mut block_data, 4, 4); // max = 4
|
||||
io::write_u16(&mut block_data, 6, 0); // depth = 0
|
||||
Inode {
|
||||
mode,
|
||||
size: 0,
|
||||
flags: 0x80000,
|
||||
links_count: 1,
|
||||
blocks_count: 0,
|
||||
block_data,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn read_inode_pub(&mut self, inode_num: u32) -> Option<Inode> {
|
||||
self.read_inode(inode_num)
|
||||
}
|
||||
|
||||
pub fn write_inode_pub(&mut self, inode_num: u32, inode: &Inode) -> bool {
|
||||
self.write_inode(inode_num, inode)
|
||||
}
|
||||
|
||||
fn read_extents(&self, inode: &Inode) -> Option<Extent> {
|
||||
if !inode.uses_extents() { return None; }
|
||||
let hdr = &inode.block_data;
|
||||
@@ -232,6 +290,8 @@ impl<B: BlockDevice> FileSystem for Ext4<B> {
|
||||
mode: 0,
|
||||
size: file.size as u64,
|
||||
flags: 0x80000,
|
||||
links_count: 0,
|
||||
blocks_count: 0,
|
||||
block_data: file.block_data,
|
||||
};
|
||||
let phys_block = self.map_logical_block(&inode, logical_block)?;
|
||||
|
||||
Reference in New Issue
Block a user