Skip to content

Commit e326b98

Browse files
ext2: file creation
* file creation * block allocation * inode allocation * fix wrong offset being set in the page cache * appending a block to the inode Signed-off-by: Andy-Python-Programmer <andypythonappdeveloper@gmail.com>
1 parent 13acc92 commit e326b98

File tree

4 files changed

+574
-316
lines changed

4 files changed

+574
-316
lines changed

src/aero_kernel/src/fs/block/mod.rs

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ impl Cache<PageCacheKey, CachedPage> {
107107
return page;
108108
}
109109

110-
let page = CachedPage::new(device.clone(), offset);
110+
let page = CachedPage::new(device.clone(), cache_offset);
111111
let device = device.upgrade().expect("page_cache: device dropped");
112112

113113
let aligned_offset = align_down(offset as u64, Size4KiB::SIZE) as usize;
@@ -145,8 +145,10 @@ pub trait CachedAccess: BlockDeviceInterface {
145145
let data = &page.data_mut()[page_offset..page_offset + size];
146146
dest[loc..loc + size].copy_from_slice(data);
147147

148+
core::mem::forget(page);
149+
148150
loc += size;
149-
offset += align_down(offset as u64 + Size4KiB::SIZE, Size4KiB::SIZE) as usize;
151+
offset = align_down(offset as u64 + Size4KiB::SIZE, Size4KiB::SIZE) as usize;
150152
}
151153

152154
Some(loc)
@@ -172,8 +174,10 @@ pub trait CachedAccess: BlockDeviceInterface {
172174
&buffer[loc..loc + size],
173175
);
174176

177+
core::mem::forget(page);
178+
175179
loc += size;
176-
offset += align_down(offset as u64 + Size4KiB::SIZE, Size4KiB::SIZE) as usize;
180+
offset = align_down(offset as u64 + Size4KiB::SIZE, Size4KiB::SIZE) as usize;
177181
}
178182

179183
Some(loc)
@@ -305,12 +309,6 @@ impl BlockDeviceInterface for PartitionBlockDevice {
305309
}
306310
}
307311

308-
impl CachedAccess for PartitionBlockDevice {
309-
fn sref(&self) -> Weak<dyn CachedAccess> {
310-
self.sref.clone()
311-
}
312-
}
313-
314312
pub fn launch() -> Result<()> {
315313
let mut blocks_copy = Vec::<Arc<BlockDevice>>::new();
316314

src/aero_kernel/src/fs/ext2/disk.rs

Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
use crate::utils::CeilDiv;
2+
3+
use super::FileType;
4+
5+
#[derive(Debug, Copy, Clone)]
6+
#[repr(C, packed)]
7+
pub struct SuperBlock {
8+
pub inodes_count: u32,
9+
pub blocks_count: u32,
10+
pub r_blocks_count: u32,
11+
pub free_blocks_count: u32,
12+
pub free_inodes_count: u32,
13+
pub first_data_block: u32,
14+
pub log_block_size: u32,
15+
pub log_frag_size: u32,
16+
pub blocks_per_group: u32,
17+
pub frags_per_group: u32,
18+
pub inodes_per_group: u32,
19+
pub mtime: u32,
20+
pub wtime: u32,
21+
pub mnt_count: u16,
22+
pub max_mnt_count: u16,
23+
pub magic: u16,
24+
pub state: u16,
25+
pub errors: u16,
26+
pub minor_rev_level: u16,
27+
pub lastcheck: u32,
28+
pub checkinterval: u32,
29+
pub creator_os: u32,
30+
pub rev_level: u32,
31+
pub def_resuid: u16,
32+
pub def_gid: u16,
33+
34+
// Extended Superblock fields
35+
//
36+
// XXX: If version number >= 1, we have to use the ext2 extended superblock as well :)
37+
pub first_ino: u32,
38+
pub inode_size: u16,
39+
pub block_group_nr: u16,
40+
pub feature_compat: u32,
41+
pub feature_incompat: u32,
42+
pub feature_ro_compat: u32,
43+
pub uuid: [u64; 2usize],
44+
pub volume_name: [u8; 16usize],
45+
pub last_mounted: [u64; 8usize],
46+
pub compression_info: u32,
47+
pub prealloc_blocks: u8,
48+
pub prealloc_dir_blocks: u8,
49+
pub reserved_gdt_blocks: u16,
50+
pub journal_uuid: [u8; 16usize],
51+
pub journal_inum: u32,
52+
pub journal_dev: u32,
53+
pub last_orphan: u32,
54+
pub hash_seed: [u32; 4usize],
55+
pub def_hash_version: u8,
56+
pub jnl_backup_type: u8,
57+
pub group_desc_size: u16,
58+
pub default_mount_opts: u32,
59+
pub first_meta_bg: u32,
60+
pub mkfs_time: u32,
61+
pub jnl_blocks: [u32; 17usize],
62+
}
63+
64+
impl SuperBlock {
65+
pub const MAGIC: u16 = 0xef53;
66+
67+
/// Returns the number of entries per block.
68+
pub fn entries_per_block(&self) -> usize {
69+
self.block_size() / core::mem::size_of::<u32>()
70+
}
71+
72+
/// Returns the size of a block in bytes.
73+
pub fn block_size(&self) -> usize {
74+
1024usize << self.log_block_size
75+
}
76+
77+
/// Returns the length of the BGDT.
78+
pub fn bgdt_len(&self) -> usize {
79+
self.blocks_count.ceil_div(self.blocks_per_group) as usize
80+
}
81+
82+
pub fn bgdt_block(&self) -> usize {
83+
// XXX: The block group descriptors are always located in the block immediately
84+
// following the superblock.
85+
let block_size = self.block_size();
86+
87+
if block_size >= 2048 {
88+
block_size
89+
} else {
90+
block_size * 2
91+
}
92+
}
93+
}
94+
95+
#[repr(C)]
96+
#[derive(Debug, Copy, Clone)]
97+
pub struct GroupDescriptor {
98+
pub block_bitmap: u32,
99+
pub inode_bitmap: u32,
100+
pub inode_table: u32,
101+
pub free_blocks_count: u16,
102+
pub free_inodes_count: u16,
103+
pub used_dirs_count: u16,
104+
pub pad: u16,
105+
pub reserved: [u8; 12usize],
106+
}
107+
108+
const_assert_eq!(core::mem::size_of::<GroupDescriptor>(), 32);
109+
110+
#[derive(Debug, Copy, Clone)]
111+
#[repr(C, packed)]
112+
pub struct DirEntry {
113+
pub inode: u32,
114+
pub entry_size: u16,
115+
pub name_size: u8,
116+
pub file_type: u8,
117+
}
118+
119+
impl DirEntry {
120+
pub fn set_name(&mut self, name: &str) {
121+
assert!(name.len() < u8::MAX as usize);
122+
123+
self.name_size = name.len() as u8;
124+
125+
// SAFETY: Above we have verified that the name will fit in the entry.
126+
let name_ptr = unsafe { (self as *mut _ as *mut u8).add(core::mem::size_of::<Self>()) };
127+
let name_bytes = unsafe { core::slice::from_raw_parts_mut(name_ptr, name.len()) };
128+
129+
name_bytes.copy_from_slice(name.as_bytes());
130+
}
131+
132+
pub fn avaliable_size(&self) -> usize {
133+
if self.inode == 0 {
134+
self.entry_size as usize
135+
} else {
136+
0
137+
}
138+
}
139+
140+
pub fn as_bytes(&self) -> &[u8] {
141+
unsafe {
142+
core::slice::from_raw_parts(self as *const Self as *const u8, self.entry_size as usize)
143+
}
144+
}
145+
}
146+
147+
#[repr(C)]
148+
#[derive(Debug, Default, Copy, Clone)]
149+
pub struct INode {
150+
type_and_perm: u16,
151+
pub user_id: u16,
152+
pub size_lower: u32,
153+
pub last_access: u32,
154+
pub creation_time: u32,
155+
pub last_modification: u32,
156+
pub deletion_time: u32,
157+
pub group_id: u16,
158+
pub hl_count: u16,
159+
pub block_count: u32,
160+
pub flags: u32,
161+
pub os_specific: u32,
162+
pub data_ptr: [u32; 15],
163+
pub gen_number: u32,
164+
pub ext_attr_block: u32,
165+
pub size_or_acl: u32,
166+
pub fragment_address: u32,
167+
pub os_specific2: [u8; 12],
168+
}
169+
170+
impl INode {
171+
pub fn file_type(&self) -> FileType {
172+
let ty = self.type_and_perm >> 12;
173+
174+
match ty {
175+
0x1 => FileType::Fifo,
176+
0x2 => FileType::CharDev,
177+
0x4 => FileType::Directory,
178+
0x6 => FileType::BlockDev,
179+
0x8 => FileType::File,
180+
0xa => FileType::Symlink,
181+
0xc => FileType::Socket,
182+
_ => FileType::Unknown,
183+
}
184+
}
185+
}
186+
187+
const_assert_eq!(core::mem::size_of::<INode>(), 128);

0 commit comments

Comments
 (0)