use port_block_device::BlockDevice; use super::io::{read_block, write_block, read_u32, write_u32, read_u16, write_u16}; pub struct BlockGroupDescriptor { pub block_bitmap: u32, pub inode_bitmap: u32, pub inode_table: u32, pub free_blocks_count: u16, pub free_inodes_count: u16, } impl BlockGroupDescriptor { pub fn read(device: &mut B, gdt_block: u32, bg: u32, spb: usize) -> Option { let mut buf = [0u8; 4096]; if !read_block(device, gdt_block as u64, spb, &mut buf) { return None; } let off = (bg as usize) * 32; if off + 32 > buf.len() { return None; } Some(Self { block_bitmap: read_u32(&buf, off), inode_bitmap: read_u32(&buf, off + 4), inode_table: read_u32(&buf, off + 8), free_blocks_count: read_u16(&buf, off + 12), free_inodes_count: read_u16(&buf, off + 14), }) } pub fn write_back(&self, device: &mut B, gdt_block: u32, bg: u32, spb: usize) -> bool { let mut buf = [0u8; 4096]; if !read_block(device, gdt_block as u64, spb, &mut buf) { return false; } let off = (bg as usize) * 32; if off + 32 > buf.len() { return false; } write_u32(&mut buf, off, self.block_bitmap); write_u32(&mut buf, off + 4, self.inode_bitmap); write_u32(&mut buf, off + 8, self.inode_table); write_u16(&mut buf, off + 12, self.free_blocks_count); write_u16(&mut buf, off + 14, self.free_inodes_count); write_block(device, gdt_block as u64, spb, &buf) } }