blob: 2c04c8a439d05f221dddb56b34a4b183bfa92348 [file] [log] [blame]
swissChilief829f32021-06-13 20:00:54 -07001#pragma once
2
3#include <vfs.h>
4
5struct ext2_superblock
6{
swissChilib7ef65d2021-07-17 12:51:52 -07007 /// Total number of inodes
swissChilief829f32021-06-13 20:00:54 -07008 uint total_inodes;
swissChilib7ef65d2021-07-17 12:51:52 -07009
10 /// Total number of blocks
swissChilief829f32021-06-13 20:00:54 -070011 uint total_blocks;
swissChilib7ef65d2021-07-17 12:51:52 -070012
13 /// Number of blocks reserved for superuser
swissChilief829f32021-06-13 20:00:54 -070014 uint blocks_reserved_for_superuser;
swissChilib7ef65d2021-07-17 12:51:52 -070015
16 /// Number of unallocated blocks
swissChilief829f32021-06-13 20:00:54 -070017 uint unallocated_blocks;
swissChilib7ef65d2021-07-17 12:51:52 -070018
19 /// Number of unallocated inodes
swissChilief829f32021-06-13 20:00:54 -070020 uint unallocated_inodes;
swissChilib7ef65d2021-07-17 12:51:52 -070021
22 /// Block number containing the superblock
swissChilief829f32021-06-13 20:00:54 -070023 uint superblock_block_number;
swissChilib7ef65d2021-07-17 12:51:52 -070024
25 /// the number to shift 1024 to the left by to get the block size
swissChilief829f32021-06-13 20:00:54 -070026 uint block_size_shift;
swissChilib7ef65d2021-07-17 12:51:52 -070027
28 /// the number to shift 1024 to the left by to get the fragment size
swissChilief829f32021-06-13 20:00:54 -070029 uint fragment_size_shift;
swissChilib7ef65d2021-07-17 12:51:52 -070030
31 /// Number of blocks in one block group
swissChilief829f32021-06-13 20:00:54 -070032 uint blocks_per_block_group;
swissChilib7ef65d2021-07-17 12:51:52 -070033
34 /// Number of fragments in one block group
swissChilief829f32021-06-13 20:00:54 -070035 uint fragments_per_block_group;
swissChilib7ef65d2021-07-17 12:51:52 -070036
37 /// Number of inodse in one block group
swissChilief829f32021-06-13 20:00:54 -070038 uint inodes_per_block_group;
swissChilib7ef65d2021-07-17 12:51:52 -070039
40 /// UNIX time of last mount
swissChilief829f32021-06-13 20:00:54 -070041 uint last_mount_time;
swissChilib7ef65d2021-07-17 12:51:52 -070042
43 /// UNIX time of last write
swissChilief829f32021-06-13 20:00:54 -070044 uint last_write_time;
swissChilib7ef65d2021-07-17 12:51:52 -070045
46 /// Number of mounts since last consistency check
swissChilief829f32021-06-13 20:00:54 -070047 ushort mounts_since_last_fsck;
swissChilib7ef65d2021-07-17 12:51:52 -070048
49 /// Number of mounts allowed between consistency checks
swissChilief829f32021-06-13 20:00:54 -070050 ushort mounts_allowed_before_fsck;
swissChilib7ef65d2021-07-17 12:51:52 -070051
52 /// EXT2 signature, should be 0xef53
swissChilief829f32021-06-13 20:00:54 -070053 ushort signature;
swissChilib7ef65d2021-07-17 12:51:52 -070054
55 /// File system state, see enum ext2_fs_state
swissChilief829f32021-06-13 20:00:54 -070056 ushort state;
swissChilib7ef65d2021-07-17 12:51:52 -070057
58 /// What to do in case of an error, see enum ext2_error_case
swissChilief829f32021-06-13 20:00:54 -070059 ushort error_case;
swissChilib7ef65d2021-07-17 12:51:52 -070060
61 /// Minor portion of version
swissChilief829f32021-06-13 20:00:54 -070062 ushort version_minor;
swissChilib7ef65d2021-07-17 12:51:52 -070063
64 /// UNIX time of last consistency check
swissChilief829f32021-06-13 20:00:54 -070065 uint last_fsck_time;
swissChilib7ef65d2021-07-17 12:51:52 -070066
67 /// Max time between consistency checks
swissChilief829f32021-06-13 20:00:54 -070068 uint fsck_time_interval;
swissChilib7ef65d2021-07-17 12:51:52 -070069
70 /// Operating system ID of creator
swissChilief829f32021-06-13 20:00:54 -070071 uint creator_os_id;
swissChilib7ef65d2021-07-17 12:51:52 -070072
73 /// Major portion of version
swissChilief829f32021-06-13 20:00:54 -070074 uint version_major;
swissChilib7ef65d2021-07-17 12:51:52 -070075
76 /// User ID that can use reserved blocks
swissChilief829f32021-06-13 20:00:54 -070077 ushort reserved_blocks_uid;
swissChilib7ef65d2021-07-17 12:51:52 -070078
79 /// Group ID that can use reserved blocks
swissChilief829f32021-06-13 20:00:54 -070080 ushort reserved_blocks_gid;
81};
82
83enum ext2_fs_state
84{
85 EXT2_STATE_CLEAN = 1,
86 EXT2_STATE_ERRORS = 2,
87};
88
89enum ext2_error_case
90{
91 EXT2_ERROR_IGNORE = 1,
92 EXT2_ERROR_REMOUNT = 2,
93 EXT2_ERROR_KPANIC = 3,
94};
95
96enum ext2_os_id
97{
98 EXT2_OS_LINUX = 0,
99 EXT2_OS_HURD,
100 EXT2_OS_MASIX,
101 EXT2_OS_FREEBSD,
102 EXT2_OS_OTHER_BSD,
103};
104
swissChili9bd74de2021-06-15 20:30:48 -0700105#define EXT2_SIGNATURE 0xef53
106
swissChilib7ef65d2021-07-17 12:51:52 -0700107struct ext2_block_group_descriptor
108{
109 /// Address of block usage bitmap
110 uint block_bitmap; // 4
111
112 /// Address of inode usage bitmap
113 uint inode_bitmap; // 8
114
115 /// Starting block address of inode table
116 uint inode_table_start_block; // 12
117
118 /// Number of unallocated blocks in this group
119 ushort unallocated_blocks; // 14
120
121 /// Number of unallocated inodes in this group
122 ushort unallocated_inodes; // 16
123
124 /// Number of directories in this group
125 ushort num_dirs; // 18
126
127 ushort padding;
128
129 uchar reserved[12]; // 32
130};
131
132struct ext2_inode
133{
134 /// The format and permissions of the file, see EXT2_S_*
135 ushort mode;
136
137 /// The user id of the owner
138 ushort uid;
139
140 /// The lower 32 bits of the file size
141 uint size;
142
143 /// Last time this was accessed in UNIX time
144 uint access_time;
145
146 /// Time this was created in UNIX time
147 uint created_time;
148
149 /// Time this was last modified in UNIX time
150 uint modified_time;
151
152 /// Time this was deleted in UNIX time
153 uint deleted_time;
154
155 /// Owner group id
156 ushort gid;
157
158 /// Reference count for hard links
159 ushort links_count;
160
161 /// Number of 512 byte blocks storing this files data, NOT EXT2 blocks!
162 uint num_blocks;
163
164 /// Flags describing how this file can be accessed
165 uint flags;
166
167 /// First field reserved for the operating system
168 uint os_reserved_1;
169
170 union
171 {
172 /// The blocks of this file
173 uint blocks[15];
174
175 struct
176 {
177 /// The direct blocks
178 uint direct_blocks[12];
179
180 /// The single indirect block
181 uint ind_block;
182
183 /// The double indirect block
184 uint ind2_block;
185
186 /// The triple indirect block
187 uint ind3_block;
188 };
189 };
190
191 /// Used by NFS to version files
192 uint generation;
193
194 /// File attributes, unused
195 uint file_acl;
196
197 /// Directory attributes, unused
198 uint dir_acl;
199
200 /// Location of file fragment, unused
201 uint faddr;
202
203 /// Second field reserved for the operating system
204 uchar os_reserved_2[12];
205};
206
207enum
208{
209 // File types
210 EXT2_S_IFSOCK = 0xc000,
211 EXT2_S_IFLINK = 0xa000,
212 EXT2_S_IFREG = 0x8000,
213 EXT2_S_IFBLK = 0x6000,
214 EXT2_S_IFDIR = 0x4000,
215 EXT2_S_IFCHR = 0x2000,
216 EXT2_S_IFIFO = 0x1000,
217
218 /// Set UID
219 EXT2_S_ISUID = 0x0800,
220 /// Set GUID
221 EXT2_S_ISGID = 0x0400,
222 /// Sticky
223 EXT2_S_ISVTX = 0x0200,
224
225 // Normal UNIX file permissions
226 EXT2_S_IRUSR = 0x0100,
227 EXT2_S_IWUSR = 0x0080,
228 EXT2_S_IXUSR = 0x0040,
229 EXT2_S_IRGRP = 0x0020,
230 EXT2_S_IWGRP = 0x0010,
231 EXT2_S_IXGRP = 0x0008,
232 EXT2_S_IROTH = 0x0004,
233 EXT2_S_IWOTH = 0x0002,
234 EXT2_S_IXOTH = 0x0001,
235};
236
swissChilicbd43632021-07-17 16:19:44 -0700237/// File type flag (used on inode->mode)
238#define EXT2_F_TYPE 0xf000
239
swissChilib7ef65d2021-07-17 12:51:52 -0700240struct ext2_dirent
241{
242 uint inode;
243 ushort rec_len;
244 uchar name_len;
245 uchar file_type;
246 char name[];
247};
248
249/// Read a file system block (0-indexed), if necessary multiple disk blocks
250/// will be read automatically
251void ext2_read_block(struct ext2_superblock *sb, void *buffer, uint block);
252
swissChili4418ca52021-06-14 17:36:00 -0700253struct ext2_superblock ext2_read_superblock();
swissChilib7ef65d2021-07-17 12:51:52 -0700254
255void ext2_write_superblock(struct ext2_superblock *sb);
256
257// Just for fun, corrupt the superblock (obviously don't actually do this)
258void ext2_corrupt_superblock_for_fun();
259
swissChilief829f32021-06-13 20:00:54 -0700260void ext2_mount(struct fs_node *where);
swissChilib7ef65d2021-07-17 12:51:52 -0700261
swissChili9bd74de2021-06-15 20:30:48 -0700262bool ext2_valid_filesystem();
swissChilib7ef65d2021-07-17 12:51:52 -0700263
264bool ext2_find_inode(struct ext2_superblock *sb, uint number, struct ext2_inode *inode);
265
266/// Load a block group descriptor for a certain block group
267struct ext2_block_group_descriptor ext2_load_block_group_descriptor(
268 struct ext2_superblock *sb, uint block_group);
269
270/// List the contents of a directory dir. Calls `cb` for each item. If `dir` is
271/// not a directory, returns false. Otherwise returns true.
272bool ext2_dir_ls(struct ext2_superblock *sb,
273 struct ext2_inode *dir,
274 void (*cb)(uint inode,
275 const char *name,
276 void *data),
277 void *data);
278
279/// Read a data block for the inode, 0 being the first block of the file.
280bool ext2_read_inode_block(struct ext2_superblock *sb,
281 struct ext2_inode *inode,
282 void *buffer,
283 uint block);
swissChilicbd43632021-07-17 16:19:44 -0700284
285ssize_t ext2_read_inode(struct ext2_superblock *sb, struct ext2_inode *inode, void *buffer, ssize_t size);