Rev 4066 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 4066 | Rev 4850 | ||
---|---|---|---|
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
2 | ;; ;; |
2 | ;; ;; |
3 | ;; Contains ext2 inode handling code. ;; |
3 | ;; Contains ext2 inode handling code. ;; |
4 | ;; ;; |
4 | ;; ;; |
5 | ;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;; |
5 | ;; Copyright (C) KolibriOS team 2013-2014. All rights reserved. ;; |
6 | ;; Distributed under the terms of the new BSD license. ;; |
6 | ;; Distributed under the terms of the new BSD license. ;; |
7 | ;; ;; |
7 | ;; ;; |
8 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
8 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
- | 9 | ||
- | 10 | $Revision: 4850 $ |
|
- | 11 | ||
9 | 12 | ||
10 | ;--------------------------------------------------------------------- |
13 | ;--------------------------------------------------------------------- |
11 | ; Receives block number from extent-based inode. |
14 | ; Receives block number from extent-based inode. |
12 | ; Input: ecx = number of block in inode |
15 | ; Input: ecx = number of block in inode |
13 | ; esi = address of extent header |
16 | ; esi = address of extent header |
14 | ; ebp = pointer to EXTFS |
17 | ; ebp = pointer to EXTFS |
15 | ; Output: ecx = address of next block, if successful |
18 | ; Output: ecx = address of next block, if successful |
16 | ; eax = error code (0 implies no error) |
19 | ; eax = error code (0 implies no error) |
17 | ;--------------------------------------------------------------------- |
20 | ;--------------------------------------------------------------------- |
18 | ext4_block_recursive_search: |
21 | ext4_block_recursive_search: |
19 | cmp word [esi + EXT4_EXTENT_HEADER.eh_magic], 0xF30A ;EXT4_EXT_MAGIC |
22 | cmp word [esi + EXT4_EXTENT_HEADER.eh_magic], 0xF30A ;EXT4_EXT_MAGIC |
20 | jne .fail |
23 | jne .fail |
21 | 24 | ||
22 | movzx ebx, [esi + EXT4_EXTENT_HEADER.eh_entries] |
25 | movzx ebx, [esi + EXT4_EXTENT_HEADER.eh_entries] |
23 | add esi, sizeof.EXT4_EXTENT_HEADER |
26 | add esi, sizeof.EXT4_EXTENT_HEADER |
24 | cmp word [esi - sizeof.EXT4_EXTENT_HEADER + EXT4_EXTENT_HEADER.eh_depth], 0 |
27 | cmp word [esi - sizeof.EXT4_EXTENT_HEADER + EXT4_EXTENT_HEADER.eh_depth], 0 |
25 | je .leaf_block ;листовой ли это блок? |
28 | je .leaf_block ;листовой ли это блок? |
26 | 29 | ||
27 | ;не листовой блок, а индексный ; eax - ext4_extent_idx |
30 | ;не листовой блок, а индексный ; eax - ext4_extent_idx |
28 | test ebx, ebx |
31 | test ebx, ebx |
29 | jz .fail ;пустой индексный блок -> ошибка |
32 | jz .fail ;пустой индексный блок -> ошибка |
30 | 33 | ||
31 | ;цикл по индексам экстентов |
34 | ;цикл по индексам экстентов |
32 | @@: |
35 | @@: |
33 | cmp ebx, 1 ;у индексов не хранится длина, |
36 | cmp ebx, 1 ;у индексов не хранится длина, |
34 | je .end_search_index ;поэтому, если остался последний - то это нужный |
37 | je .end_search_index ;поэтому, если остался последний - то это нужный |
35 | 38 | ||
36 | cmp ecx, [esi + EXT4_EXTENT_IDX.ei_block] |
39 | cmp ecx, [esi + EXT4_EXTENT_IDX.ei_block] |
37 | jb .fail |
40 | jb .fail |
38 | 41 | ||
39 | cmp ecx, [esi + sizeof.EXT4_EXTENT_IDX + EXT4_EXTENT_IDX.ei_block] ;блок слeдующего индекса |
42 | cmp ecx, [esi + sizeof.EXT4_EXTENT_IDX + EXT4_EXTENT_IDX.ei_block] ;блок слeдующего индекса |
40 | jb .end_search_index ;следующий дальше - значит текущий, то что нам нужен |
43 | jb .end_search_index ;следующий дальше - значит текущий, то что нам нужен |
41 | 44 | ||
42 | add esi, sizeof.EXT4_EXTENT_IDX |
45 | add esi, sizeof.EXT4_EXTENT_IDX |
43 | dec ebx |
46 | dec ebx |
44 | jmp @B |
47 | jmp @B |
45 | 48 | ||
46 | .end_search_index: |
49 | .end_search_index: |
47 | ;ebp указывает на нужный extent_idx, считываем следующий блок |
50 | ;ebp указывает на нужный extent_idx, считываем следующий блок |
48 | mov ebx, [ebp + EXTFS.ext2_temp_block] |
51 | mov ebx, [ebp + EXTFS.ext2_temp_block] |
49 | mov eax, [esi + EXT4_EXTENT_IDX.ei_leaf_lo] |
52 | mov eax, [esi + EXT4_EXTENT_IDX.ei_leaf_lo] |
50 | call ext2_block_read |
53 | call ext2_block_read |
51 | test eax, eax |
54 | test eax, eax |
52 | jnz .fail |
55 | jnz .fail |
53 | mov esi, ebx |
56 | mov esi, ebx |
54 | jmp ext4_block_recursive_search ;рекурсивно прыгаем в начало |
57 | jmp ext4_block_recursive_search ;рекурсивно прыгаем в начало |
55 | 58 | ||
56 | .leaf_block: ;листовой блок esi - ext4_extent |
59 | .leaf_block: ;листовой блок esi - ext4_extent |
57 | ;цикл по экстентам |
60 | ;цикл по экстентам |
58 | @@: |
61 | @@: |
59 | test ebx, ebx |
62 | test ebx, ebx |
60 | jz .fail ;ни один узел не подошел - ошибка |
63 | jz .fail ;ни один узел не подошел - ошибка |
61 | 64 | ||
62 | mov edx, [esi + EXT4_EXTENT.ee_block] |
65 | mov edx, [esi + EXT4_EXTENT.ee_block] |
63 | cmp ecx, edx |
66 | cmp ecx, edx |
64 | jb .fail ;если меньше, значит он был в предыдущих блоках -> ошибка |
67 | jb .fail ;если меньше, значит он был в предыдущих блоках -> ошибка |
65 | 68 | ||
66 | movzx edi, [esi + EXT4_EXTENT.ee_len] |
69 | movzx edi, [esi + EXT4_EXTENT.ee_len] |
67 | add edx, edi |
70 | add edx, edi |
68 | cmp ecx, edx |
71 | cmp ecx, edx |
69 | jb .end_search_extent ;нашли нужный блок |
72 | jb .end_search_extent ;нашли нужный блок |
70 | 73 | ||
71 | add esi, sizeof.EXT4_EXTENT |
74 | add esi, sizeof.EXT4_EXTENT |
72 | dec ebx |
75 | dec ebx |
73 | jmp @B |
76 | jmp @B |
74 | 77 | ||
75 | .end_search_extent: |
78 | .end_search_extent: |
76 | mov edx, [esi + EXT4_EXTENT.ee_start_lo] |
79 | mov edx, [esi + EXT4_EXTENT.ee_start_lo] |
77 | sub ecx, [esi + EXT4_EXTENT.ee_block] ;разница в ext4 блоках |
80 | sub ecx, [esi + EXT4_EXTENT.ee_block] ;разница в ext4 блоках |
78 | add ecx, edx |
81 | add ecx, edx |
79 | xor eax, eax |
82 | xor eax, eax |
80 | ret |
83 | ret |
81 | 84 | ||
82 | .fail: |
85 | .fail: |
83 | mov eax, ERROR_FS_FAIL |
86 | mov eax, ERROR_FS_FAIL |
84 | ret |
87 | ret |
85 | 88 | ||
86 | ;--------------------------------------------------------------------- |
89 | ;--------------------------------------------------------------------- |
87 | ; Frees triply indirect block. |
90 | ; Frees triply indirect block. |
88 | ; Input: eax = triply indirect block. |
91 | ; Input: eax = triply indirect block. |
89 | ; [ebp + EXTFS.ext2_save_inode] = the inode. |
92 | ; [ebp + EXTFS.ext2_save_inode] = the inode. |
90 | ; Output: eax = error code. |
93 | ; Output: eax = error code. |
91 | ;--------------------------------------------------------------------- |
94 | ;--------------------------------------------------------------------- |
92 | ext2_inode_free_triply_indirect: |
95 | ext2_inode_free_triply_indirect: |
93 | push ebx edx |
96 | push ebx edx |
94 | 97 | ||
95 | test eax, eax |
98 | test eax, eax |
96 | jz .success |
99 | jz .success |
97 | push eax |
100 | push eax |
98 | ; Read the triple indirect block. |
101 | ; Read the triple indirect block. |
99 | mov ebx, [ebp + EXTFS.ext2_temp_block] |
102 | mov ebx, [ebp + EXTFS.ext2_temp_block] |
100 | call ext2_block_read |
103 | call ext2_block_read |
101 | test eax, eax |
104 | test eax, eax |
102 | pop eax |
105 | pop eax |
103 | jnz .fail |
106 | jnz .fail |
104 | 107 | ||
105 | ; Free the triple indirect block. |
108 | ; Free the triple indirect block. |
106 | call ext2_block_free |
109 | call ext2_block_free |
107 | test eax, eax |
110 | test eax, eax |
108 | jnz .fail |
111 | jnz .fail |
109 | 112 | ||
110 | mov edx, ebx |
113 | mov edx, ebx |
111 | add edx, [ebp + EXTFS.block_size] |
114 | add edx, [ebp + EXTFS.block_size] |
112 | 115 | ||
113 | @@: |
116 | @@: |
114 | mov eax, [ebx] |
117 | mov eax, [ebx] |
115 | test eax, eax |
118 | test eax, eax |
116 | jz .success |
119 | jz .success |
117 | 120 | ||
118 | call ext2_inode_free_doubly_indirect |
121 | call ext2_inode_free_doubly_indirect |
119 | cmp eax, 1 |
122 | cmp eax, 1 |
120 | je .success |
123 | je .success |
121 | cmp eax, 0xFFFFFFFF |
124 | cmp eax, 0xFFFFFFFF |
122 | je .fail |
125 | je .fail |
123 | 126 | ||
124 | add ebx, 4 |
127 | add ebx, 4 |
125 | cmp ebx, edx |
128 | cmp ebx, edx |
126 | jb @B |
129 | jb @B |
127 | 130 | ||
128 | .success: |
131 | .success: |
129 | xor eax, eax |
132 | xor eax, eax |
130 | .ret: |
133 | .ret: |
131 | pop edx ebx |
134 | pop edx ebx |
132 | ret |
135 | ret |
133 | 136 | ||
134 | .fail: |
137 | .fail: |
135 | xor eax, eax |
138 | xor eax, eax |
136 | not eax |
139 | not eax |
137 | jmp .ret |
140 | jmp .ret |
138 | 141 | ||
139 | ;--------------------------------------------------------------------- |
142 | ;--------------------------------------------------------------------- |
140 | ; Frees double indirect block. |
143 | ; Frees double indirect block. |
141 | ; Input: eax = double indirect block. |
144 | ; Input: eax = double indirect block. |
142 | ; [ebp + EXTFS.ext2_save_inode] = the inode. |
145 | ; [ebp + EXTFS.ext2_save_inode] = the inode. |
143 | ; Output: eax = error code, 1 implies finished, ~0 implies error |
146 | ; Output: eax = error code, 1 implies finished, ~0 implies error |
144 | ;--------------------------------------------------------------------- |
147 | ;--------------------------------------------------------------------- |
145 | ext2_inode_free_doubly_indirect: |
148 | ext2_inode_free_doubly_indirect: |
146 | push ebx edx |
149 | push ebx edx |
147 | 150 | ||
148 | test eax, eax |
151 | test eax, eax |
149 | jz .complete |
152 | jz .complete |
150 | push eax |
153 | push eax |
151 | ; Read the double indirect block. |
154 | ; Read the double indirect block. |
152 | mov ebx, [ebp + EXTFS.ext2_temp_block] |
155 | mov ebx, [ebp + EXTFS.ext2_temp_block] |
153 | call ext2_block_read |
156 | call ext2_block_read |
154 | test eax, eax |
157 | test eax, eax |
155 | pop eax |
158 | pop eax |
156 | jnz .fail |
159 | jnz .fail |
157 | 160 | ||
158 | call ext2_block_free |
161 | call ext2_block_free |
159 | test eax, eax |
162 | test eax, eax |
160 | jnz .fail |
163 | jnz .fail |
161 | 164 | ||
162 | mov edx, ebx |
165 | mov edx, ebx |
163 | add edx, [ebp + EXTFS.block_size] |
166 | add edx, [ebp + EXTFS.block_size] |
164 | 167 | ||
165 | @@: |
168 | @@: |
166 | mov eax, [ebx] |
169 | mov eax, [ebx] |
167 | test eax, eax |
170 | test eax, eax |
168 | jz .complete |
171 | jz .complete |
169 | 172 | ||
170 | call ext2_block_free |
173 | call ext2_block_free |
171 | test eax, eax |
174 | test eax, eax |
172 | jnz .fail |
175 | jnz .fail |
173 | 176 | ||
174 | add ebx, 4 |
177 | add ebx, 4 |
175 | cmp ebx, edx |
178 | cmp ebx, edx |
176 | jb @B |
179 | jb @B |
177 | 180 | ||
178 | .success: |
181 | .success: |
179 | xor eax, eax |
182 | xor eax, eax |
180 | .ret: |
183 | .ret: |
181 | pop edx ebx |
184 | pop edx ebx |
182 | ret |
185 | ret |
183 | 186 | ||
184 | .complete: |
187 | .complete: |
185 | xor eax, eax |
188 | xor eax, eax |
186 | inc eax |
189 | inc eax |
187 | jmp .ret |
190 | jmp .ret |
188 | 191 | ||
189 | .fail: |
192 | .fail: |
190 | xor eax, eax |
193 | xor eax, eax |
191 | not eax |
194 | not eax |
192 | jmp .ret |
195 | jmp .ret |
193 | 196 | ||
194 | ;--------------------------------------------------------------------- |
197 | ;--------------------------------------------------------------------- |
195 | ; Frees all indirect blocks. |
198 | ; Frees all indirect blocks. |
196 | ; Input: ebp = pointer to EXTFS. |
199 | ; Input: ebp = pointer to EXTFS. |
197 | ; [ebp + EXTFS.ext2_save_inode] = the inode. |
200 | ; [ebp + EXTFS.ext2_save_inode] = the inode. |
198 | ; Output: eax = error code (0 implies no error) |
201 | ; Output: eax = error code (0 implies no error) |
199 | ;--------------------------------------------------------------------- |
202 | ;--------------------------------------------------------------------- |
200 | ext2_inode_free_indirect_blocks: |
203 | ext2_inode_free_indirect_blocks: |
201 | push edi |
204 | push edi |
202 | 205 | ||
203 | mov edi, [ebp + EXTFS.ext2_save_inode] |
206 | mov edi, [ebp + EXTFS.ext2_save_inode] |
204 | 207 | ||
205 | ; Free indirect block. |
208 | ; Free indirect block. |
206 | mov eax, [edi + EXT2_INODE_STRUC.i_block + 12*4] |
209 | mov eax, [edi + EXT2_INODE_STRUC.i_block + 12*4] |
207 | test eax, eax |
210 | test eax, eax |
208 | jz .success |
211 | jz .success |
209 | 212 | ||
210 | call ext2_block_free |
213 | call ext2_block_free |
211 | test eax, eax |
214 | test eax, eax |
212 | jnz .fail |
215 | jnz .fail |
213 | 216 | ||
214 | mov eax, [edi + EXT2_INODE_STRUC.i_block + 13*4] |
217 | mov eax, [edi + EXT2_INODE_STRUC.i_block + 13*4] |
215 | call ext2_inode_free_doubly_indirect |
218 | call ext2_inode_free_doubly_indirect |
216 | cmp eax, 1 |
219 | cmp eax, 1 |
217 | je .success |
220 | je .success |
218 | cmp eax, 0xFFFFFFFF |
221 | cmp eax, 0xFFFFFFFF |
219 | je .fail |
222 | je .fail |
220 | 223 | ||
221 | mov eax, [edi + EXT2_INODE_STRUC.i_block + 14*4] |
224 | mov eax, [edi + EXT2_INODE_STRUC.i_block + 14*4] |
222 | call ext2_inode_free_triply_indirect |
225 | call ext2_inode_free_triply_indirect |
223 | test eax, eax |
226 | test eax, eax |
224 | jnz .fail |
227 | jnz .fail |
225 | 228 | ||
226 | .success: |
229 | .success: |
227 | xor eax, eax |
230 | xor eax, eax |
228 | .ret: |
231 | .ret: |
229 | pop edi |
232 | pop edi |
230 | ret |
233 | ret |
231 | 234 | ||
232 | .fail: |
235 | .fail: |
233 | xor eax, eax |
236 | xor eax, eax |
234 | not eax |
237 | not eax |
235 | jmp .ret |
238 | jmp .ret |
236 | 239 | ||
237 | ;--------------------------------------------------------------------- |
240 | ;--------------------------------------------------------------------- |
238 | ; Allocates block for inode. |
241 | ; Allocates block for inode. |
239 | ; Input: esi = address of inode |
242 | ; Input: esi = address of inode |
240 | ; ebp = pointer to EXTFS. |
243 | ; ebp = pointer to EXTFS. |
241 | ; Output: eax = error code (0 implies no error) |
244 | ; Output: eax = error code (0 implies no error) |
242 | ;--------------------------------------------------------------------- |
245 | ;--------------------------------------------------------------------- |
243 | ext2_inode_calloc_block: |
246 | ext2_inode_calloc_block: |
244 | push ecx |
247 | push ecx |
245 | 248 | ||
246 | ; TODO: fix to have correct preference. |
249 | ; TODO: fix to have correct preference. |
247 | mov eax, EXT2_ROOT_INO |
250 | mov eax, EXT2_ROOT_INO |
248 | call ext2_block_calloc |
251 | call ext2_block_calloc |
249 | test eax, eax |
252 | test eax, eax |
250 | jnz .fail |
253 | jnz .fail |
251 | 254 | ||
252 | mov ecx, [ebp + EXTFS.superblock + EXT2_SB_STRUC.log_block_size] |
255 | mov ecx, [ebp + EXTFS.superblock + EXT2_SB_STRUC.log_block_size] |
253 | mov eax, 2 |
256 | mov eax, 2 |
254 | shl eax, cl |
257 | shl eax, cl |
255 | add [esi + EXT2_INODE_STRUC.i_blocks], eax |
258 | add [esi + EXT2_INODE_STRUC.i_blocks], eax |
256 | 259 | ||
257 | .success: |
260 | .success: |
258 | xor eax, eax |
261 | xor eax, eax |
259 | .ret: |
262 | .ret: |
260 | pop ecx |
263 | pop ecx |
261 | ret |
264 | ret |
262 | 265 | ||
263 | .fail: |
266 | .fail: |
264 | xor eax, eax |
267 | xor eax, eax |
265 | not eax |
268 | not eax |
266 | jmp .ret |
269 | jmp .ret |
267 | 270 | ||
268 | ;--------------------------------------------------------------------- |
271 | ;--------------------------------------------------------------------- |
269 | ; Sets block ID for indirect-addressing inode. |
272 | ; Sets block ID for indirect-addressing inode. |
270 | ; Input: ecx = index of block in inode |
273 | ; Input: ecx = index of block in inode |
271 | ; edi = block ID to set to |
274 | ; edi = block ID to set to |
272 | ; esi = address of inode |
275 | ; esi = address of inode |
273 | ; ebp = pointer to EXTFS. |
276 | ; ebp = pointer to EXTFS. |
274 | ; Output: eax = error code (0 implies no error) |
277 | ; Output: eax = error code (0 implies no error) |
275 | ;--------------------------------------------------------------------- |
278 | ;--------------------------------------------------------------------- |
276 | ext2_inode_set_block: |
279 | ext2_inode_set_block: |
277 | push ebx ecx edx |
280 | push ebx ecx edx |
278 | 281 | ||
279 | ; 0 to 11: direct blocks. |
282 | ; 0 to 11: direct blocks. |
280 | cmp ecx, 12 |
283 | cmp ecx, 12 |
281 | jb .direct_block |
284 | jb .direct_block |
282 | 285 | ||
283 | ; Indirect blocks |
286 | ; Indirect blocks |
284 | sub ecx, 12 |
287 | sub ecx, 12 |
285 | cmp ecx, [ebp + EXTFS.count_pointer_in_block] |
288 | cmp ecx, [ebp + EXTFS.count_pointer_in_block] |
286 | jb .indirect_block |
289 | jb .indirect_block |
287 | 290 | ||
288 | ; Double indirect blocks. |
291 | ; Double indirect blocks. |
289 | sub ecx, [ebp + EXTFS.count_pointer_in_block] |
292 | sub ecx, [ebp + EXTFS.count_pointer_in_block] |
290 | cmp ecx, [ebp + EXTFS.count_pointer_in_block_square] |
293 | cmp ecx, [ebp + EXTFS.count_pointer_in_block_square] |
291 | jb .double_indirect_block |
294 | jb .double_indirect_block |
292 | 295 | ||
293 | ; Triple indirect blocks. |
296 | ; Triple indirect blocks. |
294 | sub ecx, [ebp + EXTFS.count_pointer_in_block_square] |
297 | sub ecx, [ebp + EXTFS.count_pointer_in_block_square] |
295 | 298 | ||
296 | ; Get triply-indirect block in temp_block. |
299 | ; Get triply-indirect block in temp_block. |
297 | mov eax, [esi + EXT2_INODE_STRUC.i_block + 14*4] |
300 | mov eax, [esi + EXT2_INODE_STRUC.i_block + 14*4] |
298 | test eax, eax |
301 | test eax, eax |
299 | jnz @F |
302 | jnz @F |
300 | 303 | ||
301 | call ext2_inode_calloc_block |
304 | call ext2_inode_calloc_block |
302 | test eax, eax |
305 | test eax, eax |
303 | jnz .fail_alloc |
306 | jnz .fail_alloc |
304 | 307 | ||
305 | mov [esi + EXT2_INODE_STRUC.i_block + 14*4], ebx |
308 | mov [esi + EXT2_INODE_STRUC.i_block + 14*4], ebx |
306 | mov eax, ebx |
309 | mov eax, ebx |
307 | 310 | ||
308 | @@: |
311 | @@: |
309 | push eax |
312 | push eax |
310 | mov ebx, [ebp + EXTFS.ext2_temp_block] |
313 | mov ebx, [ebp + EXTFS.ext2_temp_block] |
311 | call ext2_block_read |
314 | call ext2_block_read |
312 | test eax, eax |
315 | test eax, eax |
313 | jnz .fail_alloc_4 |
316 | jnz .fail_alloc_4 |
314 | 317 | ||
315 | ; Get index in triply-indirect block. |
318 | ; Get index in triply-indirect block. |
316 | xor edx, edx |
319 | xor edx, edx |
317 | mov eax, ecx |
320 | mov eax, ecx |
318 | div [ebp + EXTFS.count_pointer_in_block_square] |
321 | div [ebp + EXTFS.count_pointer_in_block_square] |
319 | 322 | ||
320 | ; eax: index in triply-indirect block, edx: index in doubly-indirect block. |
323 | ; eax: index in triply-indirect block, edx: index in doubly-indirect block. |
321 | lea ecx, [ebx + eax*4] |
324 | lea ecx, [ebx + eax*4] |
322 | mov eax, [ebx + eax*4] |
325 | mov eax, [ebx + eax*4] |
323 | test eax, eax |
326 | test eax, eax |
324 | jnz @F |
327 | jnz @F |
325 | 328 | ||
326 | call ext2_inode_calloc_block |
329 | call ext2_inode_calloc_block |
327 | test eax, eax |
330 | test eax, eax |
328 | jnz .fail_alloc_4 |
331 | jnz .fail_alloc_4 |
329 | 332 | ||
330 | mov [ecx], ebx |
333 | mov [ecx], ebx |
331 | 334 | ||
332 | mov eax, [esp] |
335 | mov eax, [esp] |
333 | mov ebx, [ebp + EXTFS.ext2_temp_block] |
336 | mov ebx, [ebp + EXTFS.ext2_temp_block] |
334 | call ext2_block_write |
337 | call ext2_block_write |
335 | test eax, eax |
338 | test eax, eax |
336 | jnz .fail_alloc_4 |
339 | jnz .fail_alloc_4 |
337 | 340 | ||
338 | mov eax, [ecx] |
341 | mov eax, [ecx] |
339 | @@: |
342 | @@: |
340 | mov [esp], eax |
343 | mov [esp], eax |
341 | call ext2_block_read |
344 | call ext2_block_read |
342 | test eax, eax |
345 | test eax, eax |
343 | jnz .fail_alloc_4 |
346 | jnz .fail_alloc_4 |
344 | 347 | ||
345 | mov eax, edx |
348 | mov eax, edx |
346 | jmp @F |
349 | jmp @F |
347 | 350 | ||
348 | .double_indirect_block: |
351 | .double_indirect_block: |
349 | ; Get doubly-indirect block. |
352 | ; Get doubly-indirect block. |
350 | mov eax, [esi + EXT2_INODE_STRUC.i_block + 13*4] |
353 | mov eax, [esi + EXT2_INODE_STRUC.i_block + 13*4] |
351 | test eax, eax |
354 | test eax, eax |
352 | jnz .double_indirect_present |
355 | jnz .double_indirect_present |
353 | 356 | ||
354 | call ext2_inode_calloc_block |
357 | call ext2_inode_calloc_block |
355 | test eax, eax |
358 | test eax, eax |
356 | jnz .fail_alloc |
359 | jnz .fail_alloc |
357 | 360 | ||
358 | mov [esi + EXT2_INODE_STRUC.i_block + 13*4], ebx |
361 | mov [esi + EXT2_INODE_STRUC.i_block + 13*4], ebx |
359 | mov eax, ebx |
362 | mov eax, ebx |
360 | 363 | ||
361 | .double_indirect_present: |
364 | .double_indirect_present: |
362 | ; Save block we're at. |
365 | ; Save block we're at. |
363 | push eax |
366 | push eax |
364 | 367 | ||
365 | mov ebx, [ebp + EXTFS.ext2_temp_block] |
368 | mov ebx, [ebp + EXTFS.ext2_temp_block] |
366 | call ext2_block_read |
369 | call ext2_block_read |
367 | test eax, eax |
370 | test eax, eax |
368 | jnz .fail_alloc_4 |
371 | jnz .fail_alloc_4 |
369 | 372 | ||
370 | mov eax, ecx |
373 | mov eax, ecx |
371 | @@: |
374 | @@: |
372 | xor edx, edx |
375 | xor edx, edx |
373 | div [ebp + EXTFS.count_pointer_in_block] |
376 | div [ebp + EXTFS.count_pointer_in_block] |
374 | 377 | ||
375 | ; eax: index in doubly-indirect block, edx: index in indirect block. |
378 | ; eax: index in doubly-indirect block, edx: index in indirect block. |
376 | lea ecx, [ebx + edx*4] |
379 | lea ecx, [ebx + edx*4] |
377 | push ecx |
380 | push ecx |
378 | 381 | ||
379 | lea ecx, [ebx + eax*4] |
382 | lea ecx, [ebx + eax*4] |
380 | cmp dword[ecx], 0 |
383 | cmp dword[ecx], 0 |
381 | jne @F |
384 | jne @F |
382 | 385 | ||
383 | call ext2_inode_calloc_block |
386 | call ext2_inode_calloc_block |
384 | test eax, eax |
387 | test eax, eax |
385 | jnz .fail_alloc_8 |
388 | jnz .fail_alloc_8 |
386 | 389 | ||
387 | mov [ecx], ebx |
390 | mov [ecx], ebx |
388 | 391 | ||
389 | mov eax, [esp + 4] |
392 | mov eax, [esp + 4] |
390 | mov ebx, [ebp + EXTFS.ext2_temp_block] |
393 | mov ebx, [ebp + EXTFS.ext2_temp_block] |
391 | call ext2_block_write |
394 | call ext2_block_write |
392 | test eax, eax |
395 | test eax, eax |
393 | jnz .fail_alloc_8 |
396 | jnz .fail_alloc_8 |
394 | 397 | ||
395 | @@: |
398 | @@: |
396 | mov eax, [ecx] |
399 | mov eax, [ecx] |
397 | push eax |
400 | push eax |
398 | call ext2_block_read |
401 | call ext2_block_read |
399 | test eax, eax |
402 | test eax, eax |
400 | jnz .fail_alloc_12 |
403 | jnz .fail_alloc_12 |
401 | 404 | ||
402 | pop eax |
405 | pop eax |
403 | pop ecx |
406 | pop ecx |
404 | mov [ecx], edi |
407 | mov [ecx], edi |
405 | call ext2_block_write |
408 | call ext2_block_write |
406 | 409 | ||
407 | add esp, 4 |
410 | add esp, 4 |
408 | jmp .return |
411 | jmp .return |
409 | 412 | ||
410 | .indirect_block: |
413 | .indirect_block: |
411 | ; Get index of indirect block. |
414 | ; Get index of indirect block. |
412 | mov eax, [esi + EXT2_INODE_STRUC.i_block + 12*4] |
415 | mov eax, [esi + EXT2_INODE_STRUC.i_block + 12*4] |
413 | test eax, eax |
416 | test eax, eax |
414 | jnz @F |
417 | jnz @F |
415 | 418 | ||
416 | call ext2_inode_calloc_block |
419 | call ext2_inode_calloc_block |
417 | test eax, eax |
420 | test eax, eax |
418 | jnz .fail_alloc |
421 | jnz .fail_alloc |
419 | 422 | ||
420 | mov [esi + EXT2_INODE_STRUC.i_block + 12*4], ebx |
423 | mov [esi + EXT2_INODE_STRUC.i_block + 12*4], ebx |
421 | mov eax, ebx |
424 | mov eax, ebx |
422 | 425 | ||
423 | @@: |
426 | @@: |
424 | push eax |
427 | push eax |
425 | mov ebx, [ebp + EXTFS.ext2_temp_block] |
428 | mov ebx, [ebp + EXTFS.ext2_temp_block] |
426 | call ext2_block_read |
429 | call ext2_block_read |
427 | test eax, eax |
430 | test eax, eax |
428 | jnz .fail_alloc_4 |
431 | jnz .fail_alloc_4 |
429 | 432 | ||
430 | ; Get the block ID. |
433 | ; Get the block ID. |
431 | mov [ebx + ecx*4], edi |
434 | mov [ebx + ecx*4], edi |
432 | pop eax |
435 | pop eax |
433 | call ext2_block_write |
436 | call ext2_block_write |
434 | jmp .return |
437 | jmp .return |
435 | 438 | ||
436 | .direct_block: |
439 | .direct_block: |
437 | mov [esi + EXT2_INODE_STRUC.i_block + ecx*4], edi |
440 | mov [esi + EXT2_INODE_STRUC.i_block + ecx*4], edi |
438 | xor eax, eax |
441 | xor eax, eax |
439 | 442 | ||
440 | .return: |
443 | .return: |
441 | pop edx ecx ebx |
444 | pop edx ecx ebx |
442 | ret |
445 | ret |
443 | 446 | ||
444 | .fail_alloc: |
447 | .fail_alloc: |
445 | xor eax, eax |
448 | xor eax, eax |
446 | not eax |
449 | not eax |
447 | jmp .return |
450 | jmp .return |
448 | 451 | ||
449 | .fail_alloc_12: |
452 | .fail_alloc_12: |
450 | add esp, 4 |
453 | add esp, 4 |
451 | .fail_alloc_8: |
454 | .fail_alloc_8: |
452 | add esp, 4 |
455 | add esp, 4 |
453 | .fail_alloc_4: |
456 | .fail_alloc_4: |
454 | add esp, 4 |
457 | add esp, 4 |
455 | jmp .fail_alloc |
458 | jmp .fail_alloc |
456 | 459 | ||
457 | ;--------------------------------------------------------------------- |
460 | ;--------------------------------------------------------------------- |
458 | ; Receives block ID from indirect-addressing inode. |
461 | ; Receives block ID from indirect-addressing inode. |
459 | ; Input: ecx = index of block in inode |
462 | ; Input: ecx = index of block in inode |
460 | ; esi = address of inode |
463 | ; esi = address of inode |
461 | ; ebp = pointer to EXTFS |
464 | ; ebp = pointer to EXTFS |
462 | ; Output: ecx = block ID, if successful |
465 | ; Output: ecx = block ID, if successful |
463 | ; eax = error code (0 implies no error) |
466 | ; eax = error code (0 implies no error) |
464 | ;--------------------------------------------------------------------- |
467 | ;--------------------------------------------------------------------- |
465 | ext2_inode_get_block: |
468 | ext2_inode_get_block: |
466 | ; If inode is extent-based, use ext4_block_recursive_search. |
469 | ; If inode is extent-based, use ext4_block_recursive_search. |
467 | test [esi + EXT2_INODE_STRUC.i_flags], EXT2_EXTENTS_FL |
470 | test [esi + EXT2_INODE_STRUC.i_flags], EXT2_EXTENTS_FL |
468 | jz @F |
471 | jz @F |
469 | 472 | ||
470 | pushad |
473 | pushad |
471 | 474 | ||
472 | ; Get extent header in EBP. |
475 | ; Get extent header in EBP. |
473 | add esi, EXT2_INODE_STRUC.i_block |
476 | add esi, EXT2_INODE_STRUC.i_block |
474 | call ext4_block_recursive_search |
477 | call ext4_block_recursive_search |
475 | mov PUSHAD_ECX, ecx |
478 | mov PUSHAD_ECX, ecx |
476 | mov PUSHAD_EAX, eax |
479 | mov PUSHAD_EAX, eax |
477 | 480 | ||
478 | popad |
481 | popad |
479 | ret |
482 | ret |
480 | 483 | ||
481 | @@: |
484 | @@: |
482 | ; 0 to 11: direct blocks. |
485 | ; 0 to 11: direct blocks. |
483 | cmp ecx, 12 |
486 | cmp ecx, 12 |
484 | jb .get_direct_block |
487 | jb .get_direct_block |
485 | 488 | ||
486 | ; Indirect blocks |
489 | ; Indirect blocks |
487 | sub ecx, 12 |
490 | sub ecx, 12 |
488 | cmp ecx, [ebp + EXTFS.count_pointer_in_block] |
491 | cmp ecx, [ebp + EXTFS.count_pointer_in_block] |
489 | jb .get_indirect_block |
492 | jb .get_indirect_block |
490 | 493 | ||
491 | ; Double indirect blocks. |
494 | ; Double indirect blocks. |
492 | sub ecx, [ebp + EXTFS.count_pointer_in_block] |
495 | sub ecx, [ebp + EXTFS.count_pointer_in_block] |
493 | cmp ecx, [ebp + EXTFS.count_pointer_in_block_square] |
496 | cmp ecx, [ebp + EXTFS.count_pointer_in_block_square] |
494 | jb .get_double_indirect_block |
497 | jb .get_double_indirect_block |
495 | 498 | ||
496 | ; Triple indirect blocks. |
499 | ; Triple indirect blocks. |
497 | sub ecx, [ebp + EXTFS.count_pointer_in_block_square] |
500 | sub ecx, [ebp + EXTFS.count_pointer_in_block_square] |
498 | push edx ebx |
501 | push edx ebx |
499 | 502 | ||
500 | ; Get triply-indirect block in temp_block. |
503 | ; Get triply-indirect block in temp_block. |
501 | mov eax, [esi + EXT2_INODE_STRUC.i_block + 14*4] |
504 | mov eax, [esi + EXT2_INODE_STRUC.i_block + 14*4] |
502 | mov ebx, [ebp + EXTFS.ext2_temp_block] |
505 | mov ebx, [ebp + EXTFS.ext2_temp_block] |
503 | call ext2_block_read |
506 | call ext2_block_read |
504 | test eax, eax |
507 | test eax, eax |
505 | jnz .fail |
508 | jnz .fail |
506 | 509 | ||
507 | ; Get index in triply-indirect block. |
510 | ; Get index in triply-indirect block. |
508 | xor edx, edx |
511 | xor edx, edx |
509 | mov eax, ecx |
512 | mov eax, ecx |
510 | div [ebp + EXTFS.count_pointer_in_block_square] |
513 | div [ebp + EXTFS.count_pointer_in_block_square] |
511 | 514 | ||
512 | ; eax: index in triply-indirect block, edx: index in doubly-indirect block. |
515 | ; eax: index in triply-indirect block, edx: index in doubly-indirect block. |
513 | mov eax, [ebx + eax*4] |
516 | mov eax, [ebx + eax*4] |
514 | test eax, eax |
517 | test eax, eax |
515 | jz .fail_triple_indirect_block |
518 | jz .fail_triple_indirect_block |
516 | 519 | ||
517 | call ext2_block_read |
520 | call ext2_block_read |
518 | test eax, eax |
521 | test eax, eax |
519 | jnz .fail |
522 | jnz .fail |
520 | 523 | ||
521 | mov eax, edx |
524 | mov eax, edx |
522 | jmp @F |
525 | jmp @F |
523 | 526 | ||
524 | .get_double_indirect_block: |
527 | .get_double_indirect_block: |
525 | push edx ebx |
528 | push edx ebx |
526 | 529 | ||
527 | ; Get doubly-indirect block. |
530 | ; Get doubly-indirect block. |
528 | mov eax, [esi + EXT2_INODE_STRUC.i_block + 13*4] |
531 | mov eax, [esi + EXT2_INODE_STRUC.i_block + 13*4] |
529 | test eax, eax |
532 | test eax, eax |
530 | jz .fail_double_indirect_block |
533 | jz .fail_double_indirect_block |
531 | 534 | ||
532 | mov ebx, [ebp + EXTFS.ext2_temp_block] |
535 | mov ebx, [ebp + EXTFS.ext2_temp_block] |
533 | call ext2_block_read |
536 | call ext2_block_read |
534 | test eax, eax |
537 | test eax, eax |
535 | jnz .fail |
538 | jnz .fail |
536 | 539 | ||
537 | mov eax, ecx |
540 | mov eax, ecx |
538 | @@: |
541 | @@: |
539 | xor edx, edx |
542 | xor edx, edx |
540 | div [ebp + EXTFS.count_pointer_in_block] |
543 | div [ebp + EXTFS.count_pointer_in_block] |
541 | 544 | ||
542 | ; eax: index in doubly-indirect block, edx: index in indirect block. |
545 | ; eax: index in doubly-indirect block, edx: index in indirect block. |
543 | mov eax, [ebx + eax*4] |
546 | mov eax, [ebx + eax*4] |
544 | test eax, eax |
547 | test eax, eax |
545 | jz .fail_double_indirect_block |
548 | jz .fail_double_indirect_block |
546 | 549 | ||
547 | call ext2_block_read |
550 | call ext2_block_read |
548 | test eax, eax |
551 | test eax, eax |
549 | jnz .fail |
552 | jnz .fail |
550 | 553 | ||
551 | mov ecx, [ebx + edx*4] |
554 | mov ecx, [ebx + edx*4] |
552 | .fail: |
555 | .fail: |
553 | pop ebx edx |
556 | pop ebx edx |
554 | 557 | ||
555 | ret |
558 | ret |
556 | 559 | ||
557 | .get_indirect_block: |
560 | .get_indirect_block: |
558 | push ebx |
561 | push ebx |
559 | 562 | ||
560 | ; Get index of indirect block. |
563 | ; Get index of indirect block. |
561 | mov eax, [esi + EXT2_INODE_STRUC.i_block + 12*4] |
564 | mov eax, [esi + EXT2_INODE_STRUC.i_block + 12*4] |
562 | test eax, eax |
565 | test eax, eax |
563 | jz .fail_indirect_block |
566 | jz .fail_indirect_block |
564 | 567 | ||
565 | mov ebx, [ebp + EXTFS.ext2_temp_block] |
568 | mov ebx, [ebp + EXTFS.ext2_temp_block] |
566 | call ext2_block_read |
569 | call ext2_block_read |
567 | test eax, eax |
570 | test eax, eax |
568 | jnz @F |
571 | jnz @F |
569 | 572 | ||
570 | mov ecx, [ebx + ecx*4] |
573 | mov ecx, [ebx + ecx*4] |
571 | @@: |
574 | @@: |
572 | pop ebx |
575 | pop ebx |
573 | 576 | ||
574 | ret |
577 | ret |
575 | 578 | ||
576 | .get_direct_block: |
579 | .get_direct_block: |
577 | mov ecx, [esi + EXT2_INODE_STRUC.i_block + ecx*4] |
580 | mov ecx, [esi + EXT2_INODE_STRUC.i_block + ecx*4] |
578 | xor eax, eax |
581 | xor eax, eax |
579 | 582 | ||
580 | ret |
583 | ret |
581 | 584 | ||
582 | .fail_indirect_block: |
585 | .fail_indirect_block: |
583 | pop ebx |
586 | pop ebx |
584 | 587 | ||
585 | .fail_triple_indirect_block: |
588 | .fail_triple_indirect_block: |
586 | xor eax, eax |
589 | xor eax, eax |
587 | xor ecx, ecx |
590 | xor ecx, ecx |
588 | ret |
591 | ret |
589 | 592 | ||
590 | .fail_double_indirect_block: |
593 | .fail_double_indirect_block: |
591 | pop ebx edx |
594 | pop ebx edx |
592 | jmp .fail_triple_indirect_block |
595 | jmp .fail_triple_indirect_block |
593 | 596 | ||
594 | ;--------------------------------------------------------------------- |
597 | ;--------------------------------------------------------------------- |
595 | ; Get block containing inode. |
598 | ; Get block containing inode. |
596 | ; Input: eax = inode number. |
599 | ; Input: eax = inode number. |
597 | ; ebp = pointer to EXTFS. |
600 | ; ebp = pointer to EXTFS. |
598 | ; Output: ebx = block (hard disk) containing inode. |
601 | ; Output: ebx = block (hard disk) containing inode. |
599 | ; edx = index inside block. |
602 | ; edx = index inside block. |
600 | ; eax = error code (0 implies no error) |
603 | ; eax = error code (0 implies no error) |
601 | ;--------------------------------------------------------------------- |
604 | ;--------------------------------------------------------------------- |
602 | ext2_read_block_of_inode: |
605 | ext2_read_block_of_inode: |
603 | pushad |
606 | pushad |
604 | 607 | ||
605 | dec eax |
608 | dec eax |
606 | xor edx, edx |
609 | xor edx, edx |
607 | 610 | ||
608 | ; EAX = block group. |
611 | ; EAX = block group. |
609 | div [ebp + EXTFS.superblock + EXT2_SB_STRUC.inodes_per_group] |
612 | div [ebp + EXTFS.superblock + EXT2_SB_STRUC.inodes_per_group] |
610 | 613 | ||
611 | push edx ; Index in group. |
614 | push edx ; Index in group. |
612 | 615 | ||
613 | mov edx, 32 |
616 | mov edx, 32 |
614 | mul edx ; Get index of descriptor in global_desc_table. |
617 | mul edx ; Get index of descriptor in global_desc_table. |
615 | 618 | ||
616 | ; eax: inode group offset relative to global descriptor table start |
619 | ; eax: inode group offset relative to global descriptor table start |
617 | ; Find the block this block descriptor is in. |
620 | ; Find the block this block descriptor is in. |
618 | div [ebp + EXTFS.block_size] |
621 | div [ebp + EXTFS.block_size] |
619 | add eax, [ebp + EXTFS.superblock + EXT2_SB_STRUC.first_data_block] |
622 | add eax, [ebp + EXTFS.superblock + EXT2_SB_STRUC.first_data_block] |
620 | inc eax |
623 | inc eax |
621 | mov ebx, [ebp + EXTFS.ext2_temp_block] |
624 | mov ebx, [ebp + EXTFS.ext2_temp_block] |
622 | call ext2_block_read |
625 | call ext2_block_read |
623 | test eax, eax |
626 | test eax, eax |
624 | jnz .return |
627 | jnz .return |
625 | 628 | ||
626 | add ebx, edx ; edx: local index of descriptor inside block |
629 | add ebx, edx ; edx: local index of descriptor inside block |
627 | mov eax, [ebx + EXT2_BLOCK_GROUP_DESC.inode_table] ; Block number of inode table - in ext2 terms. |
630 | mov eax, [ebx + EXT2_BLOCK_GROUP_DESC.inode_table] ; Block number of inode table - in ext2 terms. |
628 | mov ecx, [ebp + EXTFS.log_block_size] |
631 | mov ecx, [ebp + EXTFS.log_block_size] |
629 | shl eax, cl |
632 | shl eax, cl |
630 | 633 | ||
631 | ; eax: points to inode table on HDD. |
634 | ; eax: points to inode table on HDD. |
632 | mov esi, eax |
635 | mov esi, eax |
633 | 636 | ||
634 | ; Add local address of inode. |
637 | ; Add local address of inode. |
635 | pop eax |
638 | pop eax |
636 | mov ecx, [ebp + EXTFS.inode_size] |
639 | mov ecx, [ebp + EXTFS.inode_size] |
637 | mul ecx ; (index * inode_size) |
640 | mul ecx ; (index * inode_size) |
638 | 641 | ||
639 | mov ebp, 512 |
642 | mov ebp, 512 |
640 | div ebp ; Divide by hard disk block size. |
643 | div ebp ; Divide by hard disk block size. |
641 | 644 | ||
642 | add eax, esi ; Found block to read. |
645 | add eax, esi ; Found block to read. |
643 | mov ebx, eax ; Get it inside ebx. |
646 | mov ebx, eax ; Get it inside ebx. |
644 | 647 | ||
645 | xor eax, eax |
648 | xor eax, eax |
646 | .return: |
649 | .return: |
647 | mov PUSHAD_EAX, eax |
650 | mov PUSHAD_EAX, eax |
648 | mov PUSHAD_EBX, ebx |
651 | mov PUSHAD_EBX, ebx |
649 | mov PUSHAD_EDX, edx |
652 | mov PUSHAD_EDX, edx |
650 | 653 | ||
651 | popad |
654 | popad |
652 | ret |
655 | ret |
653 | 656 | ||
654 | ;--------------------------------------------------------------------- |
657 | ;--------------------------------------------------------------------- |
655 | ; Sets content of inode by number. |
658 | ; Sets content of inode by number. |
656 | ; Input: eax = inode number. |
659 | ; Input: eax = inode number. |
657 | ; ebx = address from where to write inode content. |
660 | ; ebx = address from where to write inode content. |
658 | ; ebp = pointer to EXTFS. |
661 | ; ebp = pointer to EXTFS. |
659 | ; Output: eax = error code (0 implies no error) |
662 | ; Output: eax = error code (0 implies no error) |
660 | ;--------------------------------------------------------------------- |
663 | ;--------------------------------------------------------------------- |
661 | ext2_inode_write: |
664 | ext2_inode_write: |
662 | push edx edi esi ecx ebx |
665 | push edx edi esi ecx ebx |
663 | mov esi, ebx |
666 | mov esi, ebx |
664 | 667 | ||
665 | ; Ext2 actually stores time of modification of inode in ctime. |
668 | ; Ext2 actually stores time of modification of inode in ctime. |
666 | lea edi, [ebx + EXT2_INODE_STRUC.i_ctime] |
669 | lea edi, [ebx + EXT2_INODE_STRUC.i_ctime] |
667 | call current_unix_time |
670 | call current_unix_time |
668 | 671 | ||
669 | ; Get block where inode is situated. |
672 | ; Get block where inode is situated. |
670 | call ext2_read_block_of_inode |
673 | call ext2_read_block_of_inode |
671 | test eax, eax |
674 | test eax, eax |
672 | jnz .error |
675 | jnz .error |
673 | 676 | ||
674 | mov eax, ebx ; Get block into EAX. |
677 | mov eax, ebx ; Get block into EAX. |
675 | mov ebx, [ebp + EXTFS.ext2_temp_block] |
678 | mov ebx, [ebp + EXTFS.ext2_temp_block] |
676 | 679 | ||
677 | mov ecx, eax ; Save block. |
680 | mov ecx, eax ; Save block. |
678 | call fs_read32_sys |
681 | call fs_read32_sys |
679 | test eax, eax |
682 | test eax, eax |
680 | jz @F |
683 | jz @F |
681 | 684 | ||
682 | .error: |
685 | .error: |
683 | mov eax, ERROR_DEVICE |
686 | mov eax, ERROR_DEVICE |
684 | jmp .return |
687 | jmp .return |
685 | 688 | ||
686 | @@: |
689 | @@: |
687 | mov eax, ecx |
690 | mov eax, ecx |
688 | mov ecx, [ebp + EXTFS.inode_size] |
691 | mov ecx, [ebp + EXTFS.inode_size] |
689 | mov edi, edx ; The index into the block. |
692 | mov edi, edx ; The index into the block. |
690 | add edi, ebx |
693 | add edi, ebx |
691 | rep movsb |
694 | rep movsb |
692 | 695 | ||
693 | ; Write the block. |
696 | ; Write the block. |
694 | call fs_write32_sys |
697 | call fs_write32_sys |
695 | 698 | ||
696 | .return: |
699 | .return: |
697 | pop ebx ecx esi edi edx |
700 | pop ebx ecx esi edi edx |
698 | ret |
701 | ret |
699 | 702 | ||
700 | ;--------------------------------------------------------------------- |
703 | ;--------------------------------------------------------------------- |
701 | ; Get content of inode by number. |
704 | ; Get content of inode by number. |
702 | ; Input: eax = inode number. |
705 | ; Input: eax = inode number. |
703 | ; ebx = address where to store inode content. |
706 | ; ebx = address where to store inode content. |
704 | ; ebp = pointer to EXTFS. |
707 | ; ebp = pointer to EXTFS. |
705 | ; Output: eax = error code (0 implies no error) |
708 | ; Output: eax = error code (0 implies no error) |
706 | ;--------------------------------------------------------------------- |
709 | ;--------------------------------------------------------------------- |
707 | ext2_inode_read: |
710 | ext2_inode_read: |
708 | push edx edi esi ecx ebx |
711 | push edx edi esi ecx ebx |
709 | mov edi, ebx |
712 | mov edi, ebx |
710 | 713 | ||
711 | ; Get block where inode is situated. |
714 | ; Get block where inode is situated. |
712 | call ext2_read_block_of_inode |
715 | call ext2_read_block_of_inode |
713 | test eax, eax |
716 | test eax, eax |
714 | jnz .error |
717 | jnz .error |
715 | 718 | ||
716 | mov eax, ebx ; Get block into EAX. |
719 | mov eax, ebx ; Get block into EAX. |
717 | mov ebx, [ebp + EXTFS.ext2_temp_block] |
720 | mov ebx, [ebp + EXTFS.ext2_temp_block] |
718 | call fs_read32_sys |
721 | call fs_read32_sys |
719 | test eax, eax |
722 | test eax, eax |
720 | jz @F |
723 | jz @F |
721 | 724 | ||
722 | .error: |
725 | .error: |
723 | mov eax, ERROR_DEVICE |
726 | mov eax, ERROR_DEVICE |
724 | jmp .return |
727 | jmp .return |
725 | 728 | ||
726 | @@: |
729 | @@: |
727 | mov ecx, [ebp + EXTFS.inode_size] |
730 | mov ecx, [ebp + EXTFS.inode_size] |
728 | mov esi, edx ; The index into the inode. |
731 | mov esi, edx ; The index into the inode. |
729 | add esi, ebx |
732 | add esi, ebx |
730 | rep movsb |
733 | rep movsb |
731 | 734 | ||
732 | xor eax, eax |
735 | xor eax, eax |
733 | .return: |
736 | .return: |
734 | pop ebx ecx esi edi edx |
737 | pop ebx ecx esi edi edx |
735 | ret |
738 | ret |
736 | 739 | ||
737 | ;--------------------------------------------------------------------- |
740 | ;--------------------------------------------------------------------- |
738 | ; Seek inode from the path. |
741 | ; Seek inode from the path. |
739 | ; Input: esi + [esp + 4] = name. |
742 | ; Input: esi + [esp + 4] = name. |
740 | ; ebp = pointer to EXTFS. |
743 | ; ebp = pointer to EXTFS. |
741 | ; Output: eax = error code (0 implies no error) |
744 | ; Output: eax = error code (0 implies no error) |
742 | ; esi = inode number. |
745 | ; esi = inode number. |
743 | ; dl = first byte of file/folder name. |
746 | ; dl = first byte of file/folder name. |
744 | ; [ext2_data.ext2_save_inode] stores the inode. |
747 | ; [ext2_data.ext2_save_inode] stores the inode. |
745 | ;--------------------------------------------------------------------- |
748 | ;--------------------------------------------------------------------- |
746 | ext2_inode_find: |
749 | ext2_inode_find: |
747 | mov edx, [ebp + EXTFS.root_inode] |
750 | mov edx, [ebp + EXTFS.root_inode] |
748 | 751 | ||
749 | ; Check for empty root. |
752 | ; Check for empty root. |
750 | cmp [edx + EXT2_INODE_STRUC.i_blocks], 0 |
753 | cmp [edx + EXT2_INODE_STRUC.i_blocks], 0 |
751 | je .error_empty_root |
754 | je .error_empty_root |
752 | 755 | ||
753 | ; Check for root. |
756 | ; Check for root. |
754 | cmp byte[esi], 0 |
757 | cmp byte[esi], 0 |
755 | jne .next_path_part |
758 | jne .next_path_part |
756 | 759 | ||
757 | push edi ecx |
760 | push edi ecx |
758 | mov esi, [ebp + EXTFS.root_inode] |
761 | mov esi, [ebp + EXTFS.root_inode] |
759 | mov edi, [ebp + EXTFS.ext2_save_inode] |
762 | mov edi, [ebp + EXTFS.ext2_save_inode] |
760 | mov ecx, [ebp + EXTFS.inode_size] |
763 | mov ecx, [ebp + EXTFS.inode_size] |
761 | rep movsb |
764 | rep movsb |
762 | pop ecx edi |
765 | pop ecx edi |
763 | 766 | ||
764 | xor eax, eax |
767 | xor eax, eax |
765 | xor dl, dl |
768 | xor dl, dl |
766 | mov esi, EXT2_ROOT_INO |
769 | mov esi, EXT2_ROOT_INO |
767 | ret 4 |
770 | ret 4 |
768 | 771 | ||
769 | .next_path_part: |
772 | .next_path_part: |
770 | push [edx + EXT2_INODE_STRUC.i_blocks] |
773 | push [edx + EXT2_INODE_STRUC.i_blocks] |
771 | xor ecx, ecx |
774 | xor ecx, ecx |
772 | 775 | ||
773 | .folder_block_cycle: |
776 | .folder_block_cycle: |
774 | push ecx |
777 | push ecx |
775 | xchg esi, edx |
778 | xchg esi, edx |
776 | call ext2_inode_get_block |
779 | call ext2_inode_get_block |
777 | xchg esi, edx |
780 | xchg esi, edx |
778 | test eax, eax |
781 | test eax, eax |
779 | jnz .error_get_inode_block |
782 | jnz .error_get_inode_block |
780 | 783 | ||
781 | mov eax, ecx |
784 | mov eax, ecx |
782 | mov ebx, [ebp + EXTFS.ext2_save_block] ; Get directory records from directory. |
785 | mov ebx, [ebp + EXTFS.ext2_save_block] ; Get directory records from directory. |
783 | call ext2_block_read |
786 | call ext2_block_read |
784 | test eax, eax |
787 | test eax, eax |
785 | jnz .error_get_block |
788 | jnz .error_get_block |
786 | 789 | ||
787 | push esi |
790 | push esi |
788 | push edx |
791 | push edx |
789 | call ext2_block_find_parent |
792 | call ext2_block_find_parent |
790 | pop edx |
793 | pop edx |
791 | pop edi ecx |
794 | pop edi ecx |
792 | 795 | ||
793 | cmp edi, esi ; Did something match? |
796 | cmp edi, esi ; Did something match? |
794 | je .next_folder_block ; No, move to next block. |
797 | je .next_folder_block ; No, move to next block. |
795 | 798 | ||
796 | cmp byte [esi], 0 ; Reached the "end" of path successfully. |
799 | cmp byte [esi], 0 ; Reached the "end" of path successfully. |
797 | jnz @F |
800 | jnz @F |
798 | cmp dword[esp + 8], 0 |
801 | cmp dword[esp + 8], 0 |
799 | je .get_inode_ret |
802 | je .get_inode_ret |
800 | mov esi, [esp + 8] |
803 | mov esi, [esp + 8] |
801 | mov dword[esp + 8], 0 |
804 | mov dword[esp + 8], 0 |
802 | 805 | ||
803 | @@: |
806 | @@: |
804 | mov eax, [ebx + EXT2_DIR_STRUC.inode] |
807 | mov eax, [ebx + EXT2_DIR_STRUC.inode] |
805 | mov ebx, [ebp + EXTFS.ext2_save_inode] |
808 | mov ebx, [ebp + EXTFS.ext2_save_inode] |
806 | call ext2_inode_read |
809 | call ext2_inode_read |
807 | test eax, eax |
810 | test eax, eax |
808 | jnz .error_get_inode |
811 | jnz .error_get_inode |
809 | 812 | ||
810 | movzx eax, [ebx + EXT2_INODE_STRUC.i_mode] |
813 | movzx eax, [ebx + EXT2_INODE_STRUC.i_mode] |
811 | and eax, EXT2_S_IFMT ; Get the mask. |
814 | and eax, EXT2_S_IFMT ; Get the mask. |
812 | cmp eax, EXT2_S_IFDIR |
815 | cmp eax, EXT2_S_IFDIR |
813 | jne .not_found ; Matched till part, but directory entry we got doesn't point to folder. |
816 | jne .not_found ; Matched till part, but directory entry we got doesn't point to folder. |
814 | 817 | ||
815 | pop ecx ; Stack top contains number of blocks. |
818 | pop ecx ; Stack top contains number of blocks. |
816 | mov edx, ebx |
819 | mov edx, ebx |
817 | jmp .next_path_part |
820 | jmp .next_path_part |
818 | 821 | ||
819 | .next_folder_block: |
822 | .next_folder_block: |
820 | ; Next block in current folder. |
823 | ; Next block in current folder. |
821 | pop eax ; Get blocks counter. |
824 | pop eax ; Get blocks counter. |
822 | sub eax, [ebp + EXTFS.count_block_in_block] |
825 | sub eax, [ebp + EXTFS.count_block_in_block] |
823 | jle .not_found |
826 | jle .not_found |
824 | 827 | ||
825 | push eax |
828 | push eax |
826 | inc ecx |
829 | inc ecx |
827 | jmp .folder_block_cycle |
830 | jmp .folder_block_cycle |
828 | 831 | ||
829 | .not_found: |
832 | .not_found: |
830 | mov eax, ERROR_FILE_NOT_FOUND |
833 | mov eax, ERROR_FILE_NOT_FOUND |
831 | ret 4 |
834 | ret 4 |
832 | 835 | ||
833 | .get_inode_ret: |
836 | .get_inode_ret: |
834 | pop ecx ; Stack top contains number of blocks. |
837 | pop ecx ; Stack top contains number of blocks. |
835 | 838 | ||
836 | mov dl, [ebx + EXT2_DIR_STRUC.name] ; First character of file-name. |
839 | mov dl, [ebx + EXT2_DIR_STRUC.name] ; First character of file-name. |
837 | mov eax, [ebx + EXT2_DIR_STRUC.inode] |
840 | mov eax, [ebx + EXT2_DIR_STRUC.inode] |
838 | mov ebx, [ebp + EXTFS.ext2_save_inode] |
841 | mov ebx, [ebp + EXTFS.ext2_save_inode] |
839 | mov esi, eax |
842 | mov esi, eax |
840 | 843 | ||
841 | ; If we can't get the inode, eax contains the error. |
844 | ; If we can't get the inode, eax contains the error. |
842 | call ext2_inode_read |
845 | call ext2_inode_read |
843 | ret 4 |
846 | ret 4 |
844 | 847 | ||
845 | .error_get_inode_block: |
848 | .error_get_inode_block: |
846 | .error_get_block: |
849 | .error_get_block: |
847 | pop ecx |
850 | pop ecx |
848 | .error_get_inode: |
851 | .error_get_inode: |
849 | pop ebx |
852 | pop ebx |
850 | .error_empty_root: |
853 | .error_empty_root: |
851 | mov eax, ERROR_FS_FAIL |
854 | mov eax, ERROR_FS_FAIL |
852 | ret 4 |
855 | ret 4 |
853 | 856 | ||
854 | ;--------------------------------------------------------------------- |
857 | ;--------------------------------------------------------------------- |
855 | ; Seeks parent inode from path. |
858 | ; Seeks parent inode from path. |
856 | ; Input: esi = path. |
859 | ; Input: esi = path. |
857 | ; ebp = pointer to EXTFS. |
860 | ; ebp = pointer to EXTFS. |
858 | ; Output: eax = error code. |
861 | ; Output: eax = error code. |
859 | ; esi = inode. |
862 | ; esi = inode. |
860 | ; edi = pointer to file name. |
863 | ; edi = pointer to file name. |
861 | ;--------------------------------------------------------------------- |
864 | ;--------------------------------------------------------------------- |
862 | ext2_inode_find_parent: |
865 | ext2_inode_find_parent: |
863 | push esi |
866 | push esi |
864 | xor edi, edi |
867 | xor edi, edi |
865 | 868 | ||
866 | .loop: |
869 | .loop: |
867 | cmp byte[esi], '/' |
870 | cmp byte[esi], '/' |
868 | jne @F |
871 | jne @F |
869 | 872 | ||
870 | mov edi, esi |
873 | mov edi, esi |
871 | inc esi |
874 | inc esi |
872 | jmp .loop |
875 | jmp .loop |
873 | 876 | ||
874 | @@: |
877 | @@: |
875 | inc esi |
878 | inc esi |
876 | cmp byte[esi - 1], 0 |
879 | cmp byte[esi - 1], 0 |
877 | jne .loop |
880 | jne .loop |
878 | 881 | ||
879 | ; If it was just a filename (without any additional directories), |
882 | ; If it was just a filename (without any additional directories), |
880 | ; use the last byte as "parent path". |
883 | ; use the last byte as "parent path". |
881 | cmp edi, 0 |
884 | cmp edi, 0 |
882 | jne @F |
885 | jne @F |
883 | 886 | ||
884 | pop edi |
887 | pop edi |
885 | dec esi |
888 | dec esi |
886 | jmp .get_inode |
889 | jmp .get_inode |
887 | 890 | ||
888 | ; It had some additional directories, so handle it that way. |
891 | ; It had some additional directories, so handle it that way. |
889 | @@: |
892 | @@: |
890 | mov byte[edi], 0 |
893 | mov byte[edi], 0 |
891 | inc edi |
894 | inc edi |
892 | pop esi |
895 | pop esi |
893 | 896 | ||
894 | .get_inode: |
897 | .get_inode: |
895 | push ebx edx |
898 | push ebx edx |
896 | stdcall ext2_inode_find, 0 |
899 | stdcall ext2_inode_find, 0 |
897 | pop edx ebx |
900 | pop edx ebx |
898 | 901 | ||
899 | .return: |
902 | .return: |
900 | ret |
903 | ret |
901 | 904 | ||
902 | ;--------------------------------------------------------------------- |
905 | ;--------------------------------------------------------------------- |
903 | ; Link an inode. |
906 | ; Link an inode. |
904 | ; Input: eax = inode on which to link. |
907 | ; Input: eax = inode on which to link. |
905 | ; ebx = inode to link. |
908 | ; ebx = inode to link. |
906 | ; dl = file type. |
909 | ; dl = file type. |
907 | ; esi = name. |
910 | ; esi = name. |
908 | ; ebp = pointer to EXTFS. |
911 | ; ebp = pointer to EXTFS. |
909 | ; Output: eax = error code. |
912 | ; Output: eax = error code. |
910 | ;--------------------------------------------------------------------- |
913 | ;--------------------------------------------------------------------- |
911 | ext2_inode_link: |
914 | ext2_inode_link: |
912 | push eax |
915 | push eax |
913 | push esi edi ebx ecx edx |
916 | push esi edi ebx ecx edx |
914 | 917 | ||
915 | ; Get string length, and then directory entry structure size. |
918 | ; Get string length, and then directory entry structure size. |
916 | call strlen |
919 | call strlen |
917 | add ecx, 8 |
920 | add ecx, 8 |
918 | 921 | ||
919 | push esi ebx ecx |
922 | push esi ebx ecx |
920 | 923 | ||
921 | xor ecx, ecx |
924 | xor ecx, ecx |
922 | mov esi, [ebp + EXTFS.ext2_temp_inode] |
925 | mov esi, [ebp + EXTFS.ext2_temp_inode] |
923 | mov ebx, esi |
926 | mov ebx, esi |
924 | 927 | ||
925 | call ext2_inode_read |
928 | call ext2_inode_read |
926 | test eax, eax |
929 | test eax, eax |
927 | jnz .error_inode_read |
930 | jnz .error_inode_read |
928 | 931 | ||
929 | ; Get the maximum addressible i_block index by (i_blocks/(2 << s_log_block_size)). |
932 | ; Get the maximum addressible i_block index by (i_blocks/(2 << s_log_block_size)). |
930 | ; Note that i_blocks contains number of reserved 512B blocks, which is why we've to |
933 | ; Note that i_blocks contains number of reserved 512B blocks, which is why we've to |
931 | ; find out the ext2 blocks. |
934 | ; find out the ext2 blocks. |
932 | mov eax, 2 |
935 | mov eax, 2 |
933 | mov ecx, [ebp + EXTFS.superblock + EXT2_SB_STRUC.log_block_size] |
936 | mov ecx, [ebp + EXTFS.superblock + EXT2_SB_STRUC.log_block_size] |
934 | shl eax, cl |
937 | shl eax, cl |
935 | mov ecx, eax |
938 | mov ecx, eax |
936 | 939 | ||
937 | mov eax, [esi + EXT2_INODE_STRUC.i_blocks] |
940 | mov eax, [esi + EXT2_INODE_STRUC.i_blocks] |
938 | xor edx, edx |
941 | xor edx, edx |
939 | 942 | ||
940 | div ecx |
943 | div ecx |
941 | 944 | ||
942 | ; EAX is the maximum index inside i_block we can go. |
945 | ; EAX is the maximum index inside i_block we can go. |
943 | push eax |
946 | push eax |
944 | push dword 0 |
947 | push dword 0 |
945 | 948 | ||
946 | ; ECX contains the "block inside i_block" index. |
949 | ; ECX contains the "block inside i_block" index. |
947 | xor ecx, ecx |
950 | xor ecx, ecx |
948 | @@: |
951 | @@: |
949 | call ext2_inode_get_block |
952 | call ext2_inode_get_block |
950 | test eax, eax |
953 | test eax, eax |
951 | jnz .error_get_inode_block |
954 | jnz .error_get_inode_block |
952 | test ecx, ecx |
955 | test ecx, ecx |
953 | jz .alloc_block ; We've got no block here, so allocate one. |
956 | jz .alloc_block ; We've got no block here, so allocate one. |
954 | 957 | ||
955 | push ecx ; Save block number. |
958 | push ecx ; Save block number. |
956 | 959 | ||
957 | mov eax, ecx |
960 | mov eax, ecx |
958 | mov ebx, [ebp + EXTFS.ext2_temp_block] |
961 | mov ebx, [ebp + EXTFS.ext2_temp_block] |
959 | call ext2_block_read |
962 | call ext2_block_read |
960 | test eax, eax |
963 | test eax, eax |
961 | jnz .error_block_read |
964 | jnz .error_block_read |
962 | 965 | ||
963 | ; Try to find free space in current block. |
966 | ; Try to find free space in current block. |
964 | mov ecx, [esp + 8] |
967 | mov ecx, [esp + 8] |
965 | call ext2_block_find_fspace |
968 | call ext2_block_find_fspace |
966 | test eax, eax |
969 | test eax, eax |
967 | jz .found |
970 | jz .found |
968 | 971 | ||
969 | cmp eax, 0x00000001 |
972 | cmp eax, 0x00000001 |
970 | jne .next_iter |
973 | jne .next_iter |
971 | 974 | ||
972 | ; This block wasn't linking to the next block, so fix that, and use the next one. |
975 | ; This block wasn't linking to the next block, so fix that, and use the next one. |
973 | ; Write the block. |
976 | ; Write the block. |
974 | pop eax |
977 | pop eax |
975 | mov ebx, [ebp + EXTFS.ext2_temp_block] |
978 | mov ebx, [ebp + EXTFS.ext2_temp_block] |
976 | call ext2_block_write |
979 | call ext2_block_write |
977 | test eax, eax |
980 | test eax, eax |
978 | jnz .error_get_inode_block |
981 | jnz .error_get_inode_block |
979 | 982 | ||
980 | inc dword [esp] |
983 | inc dword [esp] |
981 | mov ecx, [esp] |
984 | mov ecx, [esp] |
982 | call ext2_inode_get_block |
985 | call ext2_inode_get_block |
983 | test eax, eax |
986 | test eax, eax |
984 | jnz .error_get_inode_block |
987 | jnz .error_get_inode_block |
985 | 988 | ||
986 | test ecx, ecx |
989 | test ecx, ecx |
987 | jz .alloc_block |
990 | jz .alloc_block |
988 | 991 | ||
989 | ; If there was a block there, prepare it for our use! |
992 | ; If there was a block there, prepare it for our use! |
990 | push ecx |
993 | push ecx |
991 | jmp .prepare_block |
994 | jmp .prepare_block |
992 | 995 | ||
993 | .next_iter: |
996 | .next_iter: |
994 | add esp, 4 |
997 | add esp, 4 |
995 | 998 | ||
996 | inc dword [esp] |
999 | inc dword [esp] |
997 | mov ecx, [esp] |
1000 | mov ecx, [esp] |
998 | cmp ecx, [esp + 4] |
1001 | cmp ecx, [esp + 4] |
999 | jbe @B |
1002 | jbe @B |
1000 | 1003 | ||
1001 | .alloc_block: |
1004 | .alloc_block: |
1002 | mov eax, [esp + 12] ; Get inode ID of what we're linking. |
1005 | mov eax, [esp + 12] ; Get inode ID of what we're linking. |
1003 | call ext2_block_calloc |
1006 | call ext2_block_calloc |
1004 | test eax, eax |
1007 | test eax, eax |
1005 | jnz .error_get_inode_block |
1008 | jnz .error_get_inode_block |
1006 | 1009 | ||
1007 | mov ecx, [esp] ; Get the index of it inside the inode. |
1010 | mov ecx, [esp] ; Get the index of it inside the inode. |
1008 | mov edi, ebx ; And what to set to. |
1011 | mov edi, ebx ; And what to set to. |
1009 | call ext2_inode_set_block |
1012 | call ext2_inode_set_block |
1010 | test eax, eax |
1013 | test eax, eax |
1011 | jnz .error_get_inode_block |
1014 | jnz .error_get_inode_block |
1012 | 1015 | ||
1013 | ; Update i_size. |
1016 | ; Update i_size. |
1014 | mov eax, [ebp + EXTFS.block_size] |
1017 | mov eax, [ebp + EXTFS.block_size] |
1015 | add [esi + EXT2_INODE_STRUC.i_size], eax |
1018 | add [esi + EXT2_INODE_STRUC.i_size], eax |
1016 | 1019 | ||
1017 | ; Update i_blocks. |
1020 | ; Update i_blocks. |
1018 | mov ecx, [ebp + EXTFS.superblock + EXT2_SB_STRUC.log_block_size] |
1021 | mov ecx, [ebp + EXTFS.superblock + EXT2_SB_STRUC.log_block_size] |
1019 | mov eax, 2 |
1022 | mov eax, 2 |
1020 | shl eax, cl |
1023 | shl eax, cl |
1021 | add [esi + EXT2_INODE_STRUC.i_blocks], eax |
1024 | add [esi + EXT2_INODE_STRUC.i_blocks], eax |
1022 | 1025 | ||
1023 | ; Write the inode. |
1026 | ; Write the inode. |
1024 | mov eax, [esp + 40] |
1027 | mov eax, [esp + 40] |
1025 | mov ebx, esi |
1028 | mov ebx, esi |
1026 | call ext2_inode_write |
1029 | call ext2_inode_write |
1027 | test eax, eax |
1030 | test eax, eax |
1028 | jnz .error_get_inode_block |
1031 | jnz .error_get_inode_block |
1029 | 1032 | ||
1030 | push edi ; Save the block we just allocated. |
1033 | push edi ; Save the block we just allocated. |
1031 | 1034 | ||
1032 | ; If we've allocated/using-old-block outside of loop, prepare it. |
1035 | ; If we've allocated/using-old-block outside of loop, prepare it. |
1033 | .prepare_block: |
1036 | .prepare_block: |
1034 | mov eax, [esp] |
1037 | mov eax, [esp] |
1035 | mov ebx, [ebp + EXTFS.ext2_temp_block] |
1038 | mov ebx, [ebp + EXTFS.ext2_temp_block] |
1036 | call ext2_block_read |
1039 | call ext2_block_read |
1037 | test eax, eax |
1040 | test eax, eax |
1038 | jnz .error_block_read |
1041 | jnz .error_block_read |
1039 | 1042 | ||
1040 | mov edi, ebx |
1043 | mov edi, ebx |
1041 | mov eax, [ebp + EXTFS.block_size] |
1044 | mov eax, [ebp + EXTFS.block_size] |
1042 | mov [edi + EXT2_DIR_STRUC.rec_len], ax |
1045 | mov [edi + EXT2_DIR_STRUC.rec_len], ax |
1043 | 1046 | ||
1044 | .found: |
1047 | .found: |
1045 | pop edx |
1048 | pop edx |
1046 | add esp, 8 |
1049 | add esp, 8 |
1047 | pop ecx ebx esi |
1050 | pop ecx ebx esi |
1048 | 1051 | ||
1049 | push ebx |
1052 | push ebx |
1050 | mov [edi], ebx ; Save inode. |
1053 | mov [edi], ebx ; Save inode. |
1051 | 1054 | ||
1052 | mov eax, [esp + 4] ; Get EDX off the stack -- contains the file_type. |
1055 | mov eax, [esp + 4] ; Get EDX off the stack -- contains the file_type. |
1053 | cmp [ebp + EXTFS.superblock + EXT2_SB_STRUC.rev_level], EXT2_GOOD_OLD_REV |
1056 | cmp [ebp + EXTFS.superblock + EXT2_SB_STRUC.rev_level], EXT2_GOOD_OLD_REV |
1054 | je .name |
1057 | je .name |
1055 | 1058 | ||
1056 | ; Set the file-type. |
1059 | ; Set the file-type. |
1057 | mov [edi + EXT2_DIR_STRUC.file_type], al |
1060 | mov [edi + EXT2_DIR_STRUC.file_type], al |
1058 | 1061 | ||
1059 | .name: |
1062 | .name: |
1060 | ; Save name. |
1063 | ; Save name. |
1061 | sub ecx, 8 |
1064 | sub ecx, 8 |
1062 | mov [edi + EXT2_DIR_STRUC.name_len], cl |
1065 | mov [edi + EXT2_DIR_STRUC.name_len], cl |
1063 | add edi, 8 |
1066 | add edi, 8 |
1064 | rep movsb |
1067 | rep movsb |
1065 | 1068 | ||
1066 | ; Write block. |
1069 | ; Write block. |
1067 | mov eax, edx |
1070 | mov eax, edx |
1068 | mov ebx, [ebp + EXTFS.ext2_temp_block] |
1071 | mov ebx, [ebp + EXTFS.ext2_temp_block] |
1069 | call ext2_block_write |
1072 | call ext2_block_write |
1070 | test eax, eax |
1073 | test eax, eax |
1071 | jnz .error_block_write |
1074 | jnz .error_block_write |
1072 | 1075 | ||
1073 | mov eax, [esp] |
1076 | mov eax, [esp] |
1074 | mov ebx, [ebp + EXTFS.ext2_temp_inode] |
1077 | mov ebx, [ebp + EXTFS.ext2_temp_inode] |
1075 | call ext2_inode_read |
1078 | call ext2_inode_read |
1076 | test eax, eax |
1079 | test eax, eax |
1077 | jnz .error_block_write |
1080 | jnz .error_block_write |
1078 | 1081 | ||
1079 | pop eax |
1082 | pop eax |
1080 | inc [ebx + EXT2_INODE_STRUC.i_links_count] |
1083 | inc [ebx + EXT2_INODE_STRUC.i_links_count] |
1081 | call ext2_inode_write |
1084 | call ext2_inode_write |
1082 | test eax, eax |
1085 | test eax, eax |
1083 | jnz .error |
1086 | jnz .error |
1084 | 1087 | ||
1085 | xor eax, eax |
1088 | xor eax, eax |
1086 | .ret: |
1089 | .ret: |
1087 | pop edx ecx ebx edi esi |
1090 | pop edx ecx ebx edi esi |
1088 | add esp, 4 |
1091 | add esp, 4 |
1089 | ret |
1092 | ret |
1090 | 1093 | ||
1091 | .error_block_read: |
1094 | .error_block_read: |
1092 | add esp, 4 |
1095 | add esp, 4 |
1093 | .error_get_inode_block: |
1096 | .error_get_inode_block: |
1094 | add esp, 8 |
1097 | add esp, 8 |
1095 | .error_inode_read: |
1098 | .error_inode_read: |
1096 | add esp, 8 |
1099 | add esp, 8 |
1097 | .error_block_write: |
1100 | .error_block_write: |
1098 | add esp, 4 |
1101 | add esp, 4 |
1099 | .error: |
1102 | .error: |
1100 | xor eax, eax |
1103 | xor eax, eax |
1101 | not eax |
1104 | not eax |
1102 | jmp .ret |
1105 | jmp .ret |
1103 | 1106 | ||
1104 | ;--------------------------------------------------------------------- |
1107 | ;--------------------------------------------------------------------- |
1105 | ; Unlink an inode. |
1108 | ; Unlink an inode. |
1106 | ; Input: eax = inode from which to unlink. |
1109 | ; Input: eax = inode from which to unlink. |
1107 | ; ebx = inode to unlink. |
1110 | ; ebx = inode to unlink. |
1108 | ; ebp = pointer to EXTFS. |
1111 | ; ebp = pointer to EXTFS. |
1109 | ; Output: eax = number of links to inode, after unlinking (0xFFFFFFFF implies error) |
1112 | ; Output: eax = number of links to inode, after unlinking (0xFFFFFFFF implies error) |
1110 | ;--------------------------------------------------------------------- |
1113 | ;--------------------------------------------------------------------- |
1111 | ext2_inode_unlink: |
1114 | ext2_inode_unlink: |
1112 | push ebx ecx edx esi edi |
1115 | push ebx ecx edx esi edi |
1113 | 1116 | ||
1114 | push ebx |
1117 | push ebx |
1115 | mov ebx, [ebp + EXTFS.ext2_temp_inode] |
1118 | mov ebx, [ebp + EXTFS.ext2_temp_inode] |
1116 | call ext2_inode_read |
1119 | call ext2_inode_read |
1117 | 1120 | ||
1118 | test eax, eax |
1121 | test eax, eax |
1119 | jnz .fail_get_inode |
1122 | jnz .fail_get_inode |
1120 | 1123 | ||
1121 | ; The index into the inode block data. |
1124 | ; The index into the inode block data. |
1122 | push dword 0 |
1125 | push dword 0 |
1123 | mov esi, [ebp + EXTFS.ext2_temp_inode] |
1126 | mov esi, [ebp + EXTFS.ext2_temp_inode] |
1124 | 1127 | ||
1125 | .loop: |
1128 | .loop: |
1126 | mov ecx, [esp] |
1129 | mov ecx, [esp] |
1127 | call ext2_inode_get_block |
1130 | call ext2_inode_get_block |
1128 | 1131 | ||
1129 | test eax, eax |
1132 | test eax, eax |
1130 | jnz .fail_loop |
1133 | jnz .fail_loop |
1131 | test ecx, ecx |
1134 | test ecx, ecx |
1132 | jz .fail_loop |
1135 | jz .fail_loop |
1133 | 1136 | ||
1134 | mov eax, ecx |
1137 | mov eax, ecx |
1135 | mov edi, eax |
1138 | mov edi, eax |
1136 | mov ebx, [ebp + EXTFS.ext2_temp_block] |
1139 | mov ebx, [ebp + EXTFS.ext2_temp_block] |
1137 | call ext2_block_read |
1140 | call ext2_block_read |
1138 | test eax, eax |
1141 | test eax, eax |
1139 | jnz .fail_loop |
1142 | jnz .fail_loop |
1140 | 1143 | ||
1141 | ; edi -> block. |
1144 | ; edi -> block. |
1142 | .first_dir_entry: |
1145 | .first_dir_entry: |
1143 | mov eax, [esp + 4] |
1146 | mov eax, [esp + 4] |
1144 | cmp [ebx], eax |
1147 | cmp [ebx], eax |
1145 | jne @F |
1148 | jne @F |
1146 | 1149 | ||
1147 | mov dword[ebx], 0 ; inode. |
1150 | mov dword[ebx], 0 ; inode. |
1148 | mov word[ebx + 6], 0 ; name_len + file_type. |
1151 | mov word[ebx + 6], 0 ; name_len + file_type. |
1149 | jmp .write_block |
1152 | jmp .write_block |
1150 | 1153 | ||
1151 | @@: |
1154 | @@: |
1152 | mov edx, ebx |
1155 | mov edx, ebx |
1153 | add edx, [ebp + EXTFS.block_size] |
1156 | add edx, [ebp + EXTFS.block_size] |
1154 | push edx |
1157 | push edx |
1155 | 1158 | ||
1156 | mov edx, ebx |
1159 | mov edx, ebx |
1157 | movzx ecx, [ebx + EXT2_DIR_STRUC.rec_len] |
1160 | movzx ecx, [ebx + EXT2_DIR_STRUC.rec_len] |
1158 | add ebx, ecx |
1161 | add ebx, ecx |
1159 | 1162 | ||
1160 | .dir_entry: |
1163 | .dir_entry: |
1161 | cmp [ebx], eax |
1164 | cmp [ebx], eax |
1162 | jne @F |
1165 | jne @F |
1163 | 1166 | ||
1164 | mov cx, [ebx + EXT2_DIR_STRUC.rec_len] |
1167 | mov cx, [ebx + EXT2_DIR_STRUC.rec_len] |
1165 | add [edx + EXT2_DIR_STRUC.rec_len], cx |
1168 | add [edx + EXT2_DIR_STRUC.rec_len], cx |
1166 | add esp, 4 |
1169 | add esp, 4 |
1167 | jmp .write_block |
1170 | jmp .write_block |
1168 | 1171 | ||
1169 | @@: |
1172 | @@: |
1170 | mov edx, ebx |
1173 | mov edx, ebx |
1171 | movzx ecx, [ebx + EXT2_DIR_STRUC.rec_len] |
1174 | movzx ecx, [ebx + EXT2_DIR_STRUC.rec_len] |
1172 | 1175 | ||
1173 | ; If it's a zero length entry, error. |
1176 | ; If it's a zero length entry, error. |
1174 | test ecx, ecx |
1177 | test ecx, ecx |
1175 | jz .fail_inode |
1178 | jz .fail_inode |
1176 | 1179 | ||
1177 | add ebx, ecx |
1180 | add ebx, ecx |
1178 | 1181 | ||
1179 | cmp ebx, [esp] |
1182 | cmp ebx, [esp] |
1180 | jb .dir_entry |
1183 | jb .dir_entry |
1181 | 1184 | ||
1182 | add esp, 4 |
1185 | add esp, 4 |
1183 | inc dword[esp] |
1186 | inc dword[esp] |
1184 | jmp .loop |
1187 | jmp .loop |
1185 | 1188 | ||
1186 | .write_block: |
1189 | .write_block: |
1187 | mov eax, edi |
1190 | mov eax, edi |
1188 | mov ebx, [ebp + EXTFS.ext2_temp_block] |
1191 | mov ebx, [ebp + EXTFS.ext2_temp_block] |
1189 | call ext2_block_write |
1192 | call ext2_block_write |
1190 | test eax, eax |
1193 | test eax, eax |
1191 | jnz .fail_loop |
1194 | jnz .fail_loop |
1192 | 1195 | ||
1193 | add esp, 4 |
1196 | add esp, 4 |
1194 | mov ebx, [ebp + EXTFS.ext2_temp_inode] |
1197 | mov ebx, [ebp + EXTFS.ext2_temp_inode] |
1195 | mov eax, [esp] |
1198 | mov eax, [esp] |
1196 | call ext2_inode_read |
1199 | call ext2_inode_read |
1197 | test eax, eax |
1200 | test eax, eax |
1198 | jnz .fail_get_inode |
1201 | jnz .fail_get_inode |
1199 | 1202 | ||
1200 | dec word[ebx + EXT2_INODE_STRUC.i_links_count] |
1203 | dec word[ebx + EXT2_INODE_STRUC.i_links_count] |
1201 | movzx eax, word[ebx + EXT2_INODE_STRUC.i_links_count] |
1204 | movzx eax, word[ebx + EXT2_INODE_STRUC.i_links_count] |
1202 | push eax |
1205 | push eax |
1203 | 1206 | ||
1204 | mov eax, [esp + 4] |
1207 | mov eax, [esp + 4] |
1205 | call ext2_inode_write |
1208 | call ext2_inode_write |
1206 | test eax, eax |
1209 | test eax, eax |
1207 | jnz .fail_loop |
1210 | jnz .fail_loop |
1208 | 1211 | ||
1209 | pop eax |
1212 | pop eax |
1210 | add esp, 4 |
1213 | add esp, 4 |
1211 | .return: |
1214 | .return: |
1212 | pop edi esi edx ecx ebx |
1215 | pop edi esi edx ecx ebx |
1213 | ret |
1216 | ret |
1214 | 1217 | ||
1215 | .fail_inode: |
1218 | .fail_inode: |
1216 | add esp, 4 |
1219 | add esp, 4 |
1217 | 1220 | ||
1218 | .fail_loop: |
1221 | .fail_loop: |
1219 | add esp, 4 |
1222 | add esp, 4 |
1220 | 1223 | ||
1221 | .fail_get_inode: |
1224 | .fail_get_inode: |
1222 | add esp, 4 |
1225 | add esp, 4 |
1223 | 1226 | ||
1224 | .fail: |
1227 | .fail: |
1225 | xor eax, eax |
1228 | xor eax, eax |
1226 | not eax |
1229 | not eax |
1227 | jmp .return |
1230 | jmp .return |
1228 | 1231 | ||
1229 | ;--------------------------------------------------------------------- |
1232 | ;--------------------------------------------------------------------- |
1230 | ; Checks if a directory is empty. |
1233 | ; Checks if a directory is empty. |
1231 | ; Input: ebx = inode to check. |
1234 | ; Input: ebx = inode to check. |
1232 | ; ebp = pointer to EXTFS. |
1235 | ; ebp = pointer to EXTFS. |
1233 | ; [EXTFS.ext2_save_inode] = points to saved inode. |
1236 | ; [EXTFS.ext2_save_inode] = points to saved inode. |
1234 | ; Output: eax = 0 signifies empty directory. |
1237 | ; Output: eax = 0 signifies empty directory. |
1235 | ;--------------------------------------------------------------------- |
1238 | ;--------------------------------------------------------------------- |
1236 | ext2_dir_empty: |
1239 | ext2_dir_empty: |
1237 | push ebx ecx edx |
1240 | push ebx ecx edx |
1238 | 1241 | ||
1239 | ; The index into the inode block data. |
1242 | ; The index into the inode block data. |
1240 | push dword 0 |
1243 | push dword 0 |
1241 | mov esi, [ebp + EXTFS.ext2_save_inode] |
1244 | mov esi, [ebp + EXTFS.ext2_save_inode] |
1242 | 1245 | ||
1243 | .loop: |
1246 | .loop: |
1244 | mov ecx, [esp] |
1247 | mov ecx, [esp] |
1245 | call ext2_inode_get_block |
1248 | call ext2_inode_get_block |
1246 | 1249 | ||
1247 | ; Treat a failure as not-empty. |
1250 | ; Treat a failure as not-empty. |
1248 | test eax, eax |
1251 | test eax, eax |
1249 | jnz .not_empty |
1252 | jnz .not_empty |
1250 | test ecx, ecx |
1253 | test ecx, ecx |
1251 | jz .empty |
1254 | jz .empty |
1252 | 1255 | ||
1253 | mov eax, ecx |
1256 | mov eax, ecx |
1254 | mov ebx, [ebp + EXTFS.ext2_temp_block] |
1257 | mov ebx, [ebp + EXTFS.ext2_temp_block] |
1255 | call ext2_block_read |
1258 | call ext2_block_read |
1256 | test eax, eax |
1259 | test eax, eax |
1257 | jnz .not_empty |
1260 | jnz .not_empty |
1258 | 1261 | ||
1259 | mov edx, ebx |
1262 | mov edx, ebx |
1260 | add edx, [ebp + EXTFS.block_size] |
1263 | add edx, [ebp + EXTFS.block_size] |
1261 | 1264 | ||
1262 | movzx ecx, [ebx + EXT2_DIR_STRUC.rec_len] |
1265 | movzx ecx, [ebx + EXT2_DIR_STRUC.rec_len] |
1263 | add ebx, ecx |
1266 | add ebx, ecx |
1264 | 1267 | ||
1265 | .dir_entry: |
1268 | .dir_entry: |
1266 | ; Process entry. |
1269 | ; Process entry. |
1267 | cmp byte[ebx + EXT2_DIR_STRUC.name_len], 1 |
1270 | cmp byte[ebx + EXT2_DIR_STRUC.name_len], 1 |
1268 | jne @F |
1271 | jne @F |
1269 | 1272 | ||
1270 | cmp byte[ebx + EXT2_DIR_STRUC.name], '.' |
1273 | cmp byte[ebx + EXT2_DIR_STRUC.name], '.' |
1271 | jne .not_empty |
1274 | jne .not_empty |
1272 | 1275 | ||
1273 | @@: |
1276 | @@: |
1274 | cmp byte[ebx + EXT2_DIR_STRUC.name_len], 2 |
1277 | cmp byte[ebx + EXT2_DIR_STRUC.name_len], 2 |
1275 | jne .not_empty |
1278 | jne .not_empty |
1276 | 1279 | ||
1277 | cmp word[ebx + EXT2_DIR_STRUC.name], '..' |
1280 | cmp word[ebx + EXT2_DIR_STRUC.name], '..' |
1278 | jne .not_empty |
1281 | jne .not_empty |
1279 | 1282 | ||
1280 | @@: |
1283 | @@: |
1281 | movzx ecx, [ebx + EXT2_DIR_STRUC.rec_len] |
1284 | movzx ecx, [ebx + EXT2_DIR_STRUC.rec_len] |
1282 | add ebx, ecx |
1285 | add ebx, ecx |
1283 | 1286 | ||
1284 | cmp ebx, edx |
1287 | cmp ebx, edx |
1285 | jb .dir_entry |
1288 | jb .dir_entry |
1286 | 1289 | ||
1287 | inc dword[esp] |
1290 | inc dword[esp] |
1288 | jmp .loop |
1291 | jmp .loop |
1289 | 1292 | ||
1290 | .empty: |
1293 | .empty: |
1291 | xor eax, eax |
1294 | xor eax, eax |
1292 | .return: |
1295 | .return: |
1293 | add esp, 4 |
1296 | add esp, 4 |
1294 | pop edx ecx ebx |
1297 | pop edx ecx ebx |
1295 | ret |
1298 | ret |
1296 | 1299 | ||
1297 | .not_empty: |
1300 | .not_empty: |
1298 | xor eax, eax |
1301 | xor eax, eax |
1299 | not eax |
1302 | not eax |
1300 | jmp .return |
1303 | jmp .return |
1301 | 1304 | ||
1302 | ;--------------------------------------------------------------------- |
1305 | ;--------------------------------------------------------------------- |
1303 | ; Gets the block group's inode bitmap. |
1306 | ; Gets the block group's inode bitmap. |
1304 | ; Input: eax = block group. |
1307 | ; Input: eax = block group. |
1305 | ; Output: eax = if zero, error; else, points to block group descriptor. |
1308 | ; Output: eax = if zero, error; else, points to block group descriptor. |
1306 | ; ebx = inode bitmap's block (hard disk). |
1309 | ; ebx = inode bitmap's block (hard disk). |
1307 | ;--------------------------------------------------------------------- |
1310 | ;--------------------------------------------------------------------- |
1308 | ext2_bg_read_inode_bitmap: |
1311 | ext2_bg_read_inode_bitmap: |
1309 | push ecx |
1312 | push ecx |
1310 | 1313 | ||
1311 | call ext2_bg_read_desc |
1314 | call ext2_bg_read_desc |
1312 | test eax, eax |
1315 | test eax, eax |
1313 | jz .fail |
1316 | jz .fail |
1314 | 1317 | ||
1315 | mov ebx, [eax + EXT2_BLOCK_GROUP_DESC.inode_bitmap] ; Block number of inode bitmap - in ext2 terms. |
1318 | mov ebx, [eax + EXT2_BLOCK_GROUP_DESC.inode_bitmap] ; Block number of inode bitmap - in ext2 terms. |
1316 | 1319 | ||
1317 | .return: |
1320 | .return: |
1318 | pop ecx |
1321 | pop ecx |
1319 | ret |
1322 | ret |
1320 | 1323 | ||
1321 | .fail: |
1324 | .fail: |
1322 | xor eax, eax |
1325 | xor eax, eax |
1323 | jmp .return |
1326 | jmp .return |
1324 | 1327 | ||
1325 | ;--------------------------------------------------------------------- |
1328 | ;--------------------------------------------------------------------- |
1326 | ; Allocates a inode. |
1329 | ; Allocates a inode. |
1327 | ; Input: eax = inode ID for "preference". |
1330 | ; Input: eax = inode ID for "preference". |
1328 | ; ebp = pointer to EXTFS. |
1331 | ; ebp = pointer to EXTFS. |
1329 | ; Output: Inode marked as set in inode group. |
1332 | ; Output: Inode marked as set in inode group. |
1330 | ; eax = error code. |
1333 | ; eax = error code. |
1331 | ; ebx = inode ID. |
1334 | ; ebx = inode ID. |
1332 | ;--------------------------------------------------------------------- |
1335 | ;--------------------------------------------------------------------- |
1333 | ext2_inode_alloc: |
1336 | ext2_inode_alloc: |
1334 | push [ebp + EXTFS.superblock + EXT2_SB_STRUC.inodes_count] |
1337 | push [ebp + EXTFS.superblock + EXT2_SB_STRUC.inodes_count] |
1335 | push EXT2_BLOCK_GROUP_DESC.free_inodes_count |
1338 | push EXT2_BLOCK_GROUP_DESC.free_inodes_count |
1336 | push [ebp + EXTFS.superblock + EXT2_SB_STRUC.inodes_per_group] |
1339 | push [ebp + EXTFS.superblock + EXT2_SB_STRUC.inodes_per_group] |
1337 | 1340 | ||
1338 | lea ebx, [ebp + EXTFS.superblock + EXT2_SB_STRUC.free_inodes_count] |
1341 | lea ebx, [ebp + EXTFS.superblock + EXT2_SB_STRUC.free_inodes_count] |
1339 | push ebx |
1342 | push ebx |
1340 | 1343 | ||
1341 | push ext2_bg_read_inode_bitmap |
1344 | push ext2_bg_read_inode_bitmap |
1342 | 1345 | ||
1343 | call ext2_resource_alloc |
1346 | call ext2_resource_alloc |
1344 | 1347 | ||
1345 | ; Inode table starts with 1. |
1348 | ; Inode table starts with 1. |
1346 | inc ebx |
1349 | inc ebx |
1347 | 1350 | ||
1348 | ret |
1351 | ret |
1349 | 1352 | ||
1350 | ;--------------------------------------------------------------------- |
1353 | ;--------------------------------------------------------------------- |
1351 | ; Frees a inode. |
1354 | ; Frees a inode. |
1352 | ; Input: eax = inode ID. |
1355 | ; Input: eax = inode ID. |
1353 | ; ebp = pointer to EXTFS. |
1356 | ; ebp = pointer to EXTFS. |
1354 | ; Output: inode marked as free in block group. |
1357 | ; Output: inode marked as free in block group. |
1355 | ; eax = error code. |
1358 | ; eax = error code. |
1356 | ;--------------------------------------------------------------------- |
1359 | ;--------------------------------------------------------------------- |
1357 | ext2_inode_free: |
1360 | ext2_inode_free: |
1358 | push edi ecx |
1361 | push edi ecx |
1359 | 1362 | ||
1360 | ; Inode table starts with 1. |
1363 | ; Inode table starts with 1. |
1361 | dec eax |
1364 | dec eax |
1362 | 1365 | ||
1363 | mov edi, ext2_bg_read_inode_bitmap |
1366 | mov edi, ext2_bg_read_inode_bitmap |
1364 | xor ecx, ecx |
1367 | xor ecx, ecx |
1365 | inc cl |
1368 | inc cl |
1366 | call ext2_resource_free |
1369 | call ext2_resource_free |
1367 | 1370 | ||
1368 | pop ecx edi |
1371 | pop ecx edi |
1369 | ret |
1372 | ret |
1370 | 1373 | ||
1371 | ;--------------------------------------------------------------------- |
1374 | ;--------------------------------------------------------------------- |
1372 | ; Blanks a particular entry in an inode. |
1375 | ; Blanks a particular entry in an inode. |
1373 | ; Input: eax = index into block. |
1376 | ; Input: eax = index into block. |
1374 | ; edx = inode. |
1377 | ; edx = inode. |
1375 | ; ebp = pointer to EXTFS. |
1378 | ; ebp = pointer to EXTFS. |
1376 | ; [ebp + EXTFS.ext2_temp_inode] = the inode. |
1379 | ; [ebp + EXTFS.ext2_temp_inode] = the inode. |
1377 | ; Output: eax = error code. |
1380 | ; Output: eax = error code. |
1378 | ;--------------------------------------------------------------------- |
1381 | ;--------------------------------------------------------------------- |
1379 | ext2_inode_blank_entry: |
1382 | ext2_inode_blank_entry: |
1380 | push ebx ecx edx edi esi |
1383 | push ebx ecx edx edi esi |
1381 | 1384 | ||
1382 | mov edi, eax |
1385 | mov edi, eax |
1383 | 1386 | ||
1384 | mov ecx, eax |
1387 | mov ecx, eax |
1385 | mov esi, [ebp + EXTFS.ext2_temp_inode] |
1388 | mov esi, [ebp + EXTFS.ext2_temp_inode] |
1386 | call ext2_inode_get_block |
1389 | call ext2_inode_get_block |
1387 | test eax, eax |
1390 | test eax, eax |
1388 | jnz .error |
1391 | jnz .error |
1389 | 1392 | ||
1390 | test ecx, ecx |
1393 | test ecx, ecx |
1391 | jz .allocate |
1394 | jz .allocate |
1392 | 1395 | ||
1393 | mov edx, ecx |
1396 | mov edx, ecx |
1394 | mov ecx, [ebp + EXTFS.block_size] |
1397 | mov ecx, [ebp + EXTFS.block_size] |
1395 | mov edi, [ebp + EXTFS.ext2_temp_block] |
1398 | mov edi, [ebp + EXTFS.ext2_temp_block] |
1396 | xor eax, eax |
1399 | xor eax, eax |
1397 | rep stosb |
1400 | rep stosb |
1398 | 1401 | ||
1399 | mov eax, edx |
1402 | mov eax, edx |
1400 | mov ebx, [ebp + EXTFS.ext2_temp_block] |
1403 | mov ebx, [ebp + EXTFS.ext2_temp_block] |
1401 | call ext2_block_write |
1404 | call ext2_block_write |
1402 | test eax, eax |
1405 | test eax, eax |
1403 | jnz .error |
1406 | jnz .error |
1404 | 1407 | ||
1405 | jmp .success |
1408 | jmp .success |
1406 | 1409 | ||
1407 | ; Need to allocate a block. |
1410 | ; Need to allocate a block. |
1408 | .allocate: |
1411 | .allocate: |
1409 | mov eax, edx |
1412 | mov eax, edx |
1410 | call ext2_block_calloc |
1413 | call ext2_block_calloc |
1411 | test eax, eax |
1414 | test eax, eax |
1412 | jnz .error |
1415 | jnz .error |
1413 | 1416 | ||
1414 | mov ecx, edi |
1417 | mov ecx, edi |
1415 | mov edi, ebx |
1418 | mov edi, ebx |
1416 | mov esi, [ebp + EXTFS.ext2_temp_inode] |
1419 | mov esi, [ebp + EXTFS.ext2_temp_inode] |
1417 | call ext2_inode_set_block |
1420 | call ext2_inode_set_block |
1418 | test eax, eax |
1421 | test eax, eax |
1419 | jnz .error |
1422 | jnz .error |
1420 | 1423 | ||
1421 | mov ecx, [ebp + EXTFS.superblock + EXT2_SB_STRUC.log_block_size] |
1424 | mov ecx, [ebp + EXTFS.superblock + EXT2_SB_STRUC.log_block_size] |
1422 | mov eax, 2 |
1425 | mov eax, 2 |
1423 | shl eax, cl |
1426 | shl eax, cl |
1424 | add [esi + EXT2_INODE_STRUC.i_blocks], eax |
1427 | add [esi + EXT2_INODE_STRUC.i_blocks], eax |
1425 | 1428 | ||
1426 | .success: |
1429 | .success: |
1427 | xor eax, eax |
1430 | xor eax, eax |
1428 | 1431 | ||
1429 | .ret: |
1432 | .ret: |
1430 | pop esi edi edx ecx ebx |
1433 | pop esi edi edx ecx ebx |
1431 | ret |
1434 | ret |
1432 | 1435 | ||
1433 | .error: |
1436 | .error: |
1434 | xor eax, eax |
1437 | xor eax, eax |
1435 | not eax |
1438 | not eax |
1436 | jmp .ret |
1439 | jmp .ret |
1437 | 1440 | ||
1438 | ;--------------------------------------------------------------------- |
1441 | ;--------------------------------------------------------------------- |
1439 | ; Frees a particular entry in an inode. |
1442 | ; Frees a particular entry in an inode. |
1440 | ; Input: eax = index into block. |
1443 | ; Input: eax = index into block. |
1441 | ; ebp = pointer to EXTFS. |
1444 | ; ebp = pointer to EXTFS. |
1442 | ; [ebp + EXTFS.ext2_temp_inode] = the inode. |
1445 | ; [ebp + EXTFS.ext2_temp_inode] = the inode. |
1443 | ; Output: eax = error code. |
1446 | ; Output: eax = error code. |
1444 | ;--------------------------------------------------------------------- |
1447 | ;--------------------------------------------------------------------- |
1445 | ext2_inode_free_entry: |
1448 | ext2_inode_free_entry: |
1446 | push ebx ecx edi esi |
1449 | push ebx ecx edi esi |
1447 | 1450 | ||
1448 | mov edi, eax |
1451 | mov edi, eax |
1449 | 1452 | ||
1450 | mov ecx, eax |
1453 | mov ecx, eax |
1451 | mov esi, [ebp + EXTFS.ext2_temp_inode] |
1454 | mov esi, [ebp + EXTFS.ext2_temp_inode] |
1452 | call ext2_inode_get_block |
1455 | call ext2_inode_get_block |
1453 | test eax, eax |
1456 | test eax, eax |
1454 | jnz .error |
1457 | jnz .error |
1455 | 1458 | ||
1456 | test ecx, ecx |
1459 | test ecx, ecx |
1457 | jz .success |
1460 | jz .success |
1458 | 1461 | ||
1459 | mov eax, ecx |
1462 | mov eax, ecx |
1460 | call ext2_block_free |
1463 | call ext2_block_free |
1461 | test eax, eax |
1464 | test eax, eax |
1462 | jnz .error |
1465 | jnz .error |
1463 | 1466 | ||
1464 | mov ecx, edi |
1467 | mov ecx, edi |
1465 | xor edi, edi |
1468 | xor edi, edi |
1466 | mov esi, [ebp + EXTFS.ext2_temp_inode] |
1469 | mov esi, [ebp + EXTFS.ext2_temp_inode] |
1467 | call ext2_inode_set_block |
1470 | call ext2_inode_set_block |
1468 | 1471 | ||
1469 | mov ecx, [ebp + EXTFS.superblock + EXT2_SB_STRUC.log_block_size] |
1472 | mov ecx, [ebp + EXTFS.superblock + EXT2_SB_STRUC.log_block_size] |
1470 | mov eax, 2 |
1473 | mov eax, 2 |
1471 | shl eax, cl |
1474 | shl eax, cl |
1472 | sub [esi + EXT2_INODE_STRUC.i_blocks], eax |
1475 | sub [esi + EXT2_INODE_STRUC.i_blocks], eax |
1473 | 1476 | ||
1474 | .success: |
1477 | .success: |
1475 | xor eax, eax |
1478 | xor eax, eax |
1476 | 1479 | ||
1477 | .ret: |
1480 | .ret: |
1478 | pop esi edi ecx ebx |
1481 | pop esi edi ecx ebx |
1479 | ret |
1482 | ret |
1480 | 1483 | ||
1481 | .error: |
1484 | .error: |
1482 | xor eax, eax |
1485 | xor eax, eax |
1483 | not eax |
1486 | not eax |
1484 | jmp .ret |
1487 | jmp .ret |
1485 | 1488 | ||
1486 | ;--------------------------------------------------------------------- |
1489 | ;--------------------------------------------------------------------- |
1487 | ; Reads a particular entry from an inode. |
1490 | ; Reads a particular entry from an inode. |
1488 | ; Input: eax = index into block. |
1491 | ; Input: eax = index into block. |
1489 | ; ebp = pointer to EXTFS. |
1492 | ; ebp = pointer to EXTFS. |
1490 | ; [ebp + EXTFS.ext2_temp_inode] = the inode. |
1493 | ; [ebp + EXTFS.ext2_temp_inode] = the inode. |
1491 | ; Output: eax = error code. |
1494 | ; Output: eax = error code. |
1492 | ; [ebp + EXTFS.ext2_save_block] = the read block. |
1495 | ; [ebp + EXTFS.ext2_save_block] = the read block. |
1493 | ;--------------------------------------------------------------------- |
1496 | ;--------------------------------------------------------------------- |
1494 | ext2_inode_read_entry: |
1497 | ext2_inode_read_entry: |
1495 | push ebx ecx edx esi |
1498 | push ebx ecx edx esi |
1496 | 1499 | ||
1497 | mov ecx, eax |
1500 | mov ecx, eax |
1498 | mov esi, [ebp + EXTFS.ext2_temp_inode] |
1501 | mov esi, [ebp + EXTFS.ext2_temp_inode] |
1499 | call ext2_inode_get_block |
1502 | call ext2_inode_get_block |
1500 | test eax, eax |
1503 | test eax, eax |
1501 | jnz .error |
1504 | jnz .error |
1502 | 1505 | ||
1503 | test ecx, ecx |
1506 | test ecx, ecx |
1504 | jz .error |
1507 | jz .error |
1505 | 1508 | ||
1506 | mov eax, ecx |
1509 | mov eax, ecx |
1507 | mov ebx, [ebp + EXTFS.ext2_save_block] |
1510 | mov ebx, [ebp + EXTFS.ext2_save_block] |
1508 | call ext2_block_read |
1511 | call ext2_block_read |
1509 | test eax, eax |
1512 | test eax, eax |
1510 | jnz .error |
1513 | jnz .error |
1511 | 1514 | ||
1512 | .ret: |
1515 | .ret: |
1513 | pop esi edx ecx ebx |
1516 | pop esi edx ecx ebx |
1514 | ret |
1517 | ret |
1515 | 1518 | ||
1516 | .error: |
1519 | .error: |
1517 | xor eax, eax |
1520 | xor eax, eax |
1518 | not eax |
1521 | not eax |
1519 | jmp .ret |
1522 | jmp .ret |
1520 | 1523 | ||
1521 | ;--------------------------------------------------------------------- |
1524 | ;--------------------------------------------------------------------- |
1522 | ; Writes a particular entry from an inode. |
1525 | ; Writes a particular entry from an inode. |
1523 | ; Input: eax = index into block. |
1526 | ; Input: eax = index into block. |
1524 | ; ebp = pointer to EXTFS. |
1527 | ; ebp = pointer to EXTFS. |
1525 | ; [ebp + EXTFS.ext2_temp_inode] = the inode. |
1528 | ; [ebp + EXTFS.ext2_temp_inode] = the inode. |
1526 | ; [ebp + EXTFS.ext2_save_block] = the block to write. |
1529 | ; [ebp + EXTFS.ext2_save_block] = the block to write. |
1527 | ; Output: eax = error code. |
1530 | ; Output: eax = error code. |
1528 | ;--------------------------------------------------------------------- |
1531 | ;--------------------------------------------------------------------- |
1529 | ext2_inode_write_entry: |
1532 | ext2_inode_write_entry: |
1530 | push ebx ecx edx esi |
1533 | push ebx ecx edx esi |
1531 | 1534 | ||
1532 | mov ecx, eax |
1535 | mov ecx, eax |
1533 | mov esi, [ebp + EXTFS.ext2_temp_inode] |
1536 | mov esi, [ebp + EXTFS.ext2_temp_inode] |
1534 | call ext2_inode_get_block |
1537 | call ext2_inode_get_block |
1535 | test eax, eax |
1538 | test eax, eax |
1536 | jnz .error |
1539 | jnz .error |
1537 | 1540 | ||
1538 | test ecx, ecx |
1541 | test ecx, ecx |
1539 | jz .error |
1542 | jz .error |
1540 | 1543 | ||
1541 | mov eax, ecx |
1544 | mov eax, ecx |
1542 | mov ebx, [ebp + EXTFS.ext2_save_block] |
1545 | mov ebx, [ebp + EXTFS.ext2_save_block] |
1543 | call ext2_block_write |
1546 | call ext2_block_write |
1544 | test eax, eax |
1547 | test eax, eax |
1545 | jnz .error |
1548 | jnz .error |
1546 | 1549 | ||
1547 | .ret: |
1550 | .ret: |
1548 | pop esi edx ecx ebx |
1551 | pop esi edx ecx ebx |
1549 | ret |
1552 | ret |
1550 | 1553 | ||
1551 | .error: |
1554 | .error: |
1552 | xor eax, eax |
1555 | xor eax, eax |
1553 | not eax |
1556 | not eax |
1554 | jmp .ret |
1557 | jmp .ret |
1555 | 1558 | ||
1556 | ;--------------------------------------------------------------------- |
1559 | ;--------------------------------------------------------------------- |
1557 | ; Extends inode to said size. |
1560 | ; Extends inode to said size. |
1558 | ; Input: eax = inode ID. |
1561 | ; Input: eax = inode ID. |
1559 | ; ecx = size to extend to. |
1562 | ; ecx = size to extend to. |
1560 | ; ebp = pointer to EXTFS. |
1563 | ; ebp = pointer to EXTFS. |
1561 | ; Output: eax = error code. |
1564 | ; Output: eax = error code. |
1562 | ;--------------------------------------------------------------------- |
1565 | ;--------------------------------------------------------------------- |
1563 | ext2_inode_extend: |
1566 | ext2_inode_extend: |
1564 | push ebx ecx edx esi edi |
1567 | push ebx ecx edx esi edi |
1565 | 1568 | ||
1566 | ; Save the inode. |
1569 | ; Save the inode. |
1567 | push eax |
1570 | push eax |
1568 | 1571 | ||
1569 | ; Read the inode. |
1572 | ; Read the inode. |
1570 | mov ebx, [ebp + EXTFS.ext2_temp_inode] |
1573 | mov ebx, [ebp + EXTFS.ext2_temp_inode] |
1571 | call ext2_inode_read |
1574 | call ext2_inode_read |
1572 | test eax, eax |
1575 | test eax, eax |
1573 | jnz .error |
1576 | jnz .error |
1574 | 1577 | ||
1575 | mov eax, [ebx + EXT2_INODE_STRUC.i_size] |
1578 | mov eax, [ebx + EXT2_INODE_STRUC.i_size] |
1576 | cmp eax, ecx |
1579 | cmp eax, ecx |
1577 | jge .success |
1580 | jge .success |
1578 | 1581 | ||
1579 | ; Save the size of the inode. |
1582 | ; Save the size of the inode. |
1580 | push eax |
1583 | push eax |
1581 | 1584 | ||
1582 | ; ECX contains the size we've to write. |
1585 | ; ECX contains the size we've to write. |
1583 | sub ecx, eax |
1586 | sub ecx, eax |
1584 | xor edx, edx |
1587 | xor edx, edx |
1585 | div [ebp + EXTFS.block_size] |
1588 | div [ebp + EXTFS.block_size] |
1586 | 1589 | ||
1587 | test edx, edx |
1590 | test edx, edx |
1588 | jz .start_aligned |
1591 | jz .start_aligned |
1589 | 1592 | ||
1590 | ; Start isn't aligned, so deal with the non-aligned bytes. |
1593 | ; Start isn't aligned, so deal with the non-aligned bytes. |
1591 | mov esi, [ebp + EXTFS.block_size] |
1594 | mov esi, [ebp + EXTFS.block_size] |
1592 | sub esi, edx |
1595 | sub esi, edx |
1593 | 1596 | ||
1594 | cmp esi, ecx |
1597 | cmp esi, ecx |
1595 | jbe @F |
1598 | jbe @F |
1596 | 1599 | ||
1597 | ; If the size to entend to fits in current block, limit to that. |
1600 | ; If the size to entend to fits in current block, limit to that. |
1598 | mov esi, ecx |
1601 | mov esi, ecx |
1599 | 1602 | ||
1600 | @@: |
1603 | @@: |
1601 | ; Clear ESI bytes, in EAX indexed block. |
1604 | ; Clear ESI bytes, in EAX indexed block. |
1602 | push eax |
1605 | push eax |
1603 | call ext2_inode_read_entry |
1606 | call ext2_inode_read_entry |
1604 | test eax, eax |
1607 | test eax, eax |
1605 | pop eax |
1608 | pop eax |
1606 | jnz .error_inode_size |
1609 | jnz .error_inode_size |
1607 | 1610 | ||
1608 | push eax ecx |
1611 | push eax ecx |
1609 | 1612 | ||
1610 | xor eax, eax |
1613 | xor eax, eax |
1611 | mov ecx, esi |
1614 | mov ecx, esi |
1612 | mov edi, ebx |
1615 | mov edi, ebx |
1613 | add edi, edx |
1616 | add edi, edx |
1614 | 1617 | ||
1615 | rep stosb |
1618 | rep stosb |
1616 | 1619 | ||
1617 | pop ecx eax |
1620 | pop ecx eax |
1618 | 1621 | ||
1619 | ; Write the block. |
1622 | ; Write the block. |
1620 | call ext2_inode_write_entry |
1623 | call ext2_inode_write_entry |
1621 | test eax, eax |
1624 | test eax, eax |
1622 | jnz .error_inode_size |
1625 | jnz .error_inode_size |
1623 | 1626 | ||
1624 | add [esp], esi |
1627 | add [esp], esi |
1625 | sub ecx, esi |
1628 | sub ecx, esi |
1626 | jz .write_inode |
1629 | jz .write_inode |
1627 | 1630 | ||
1628 | .start_aligned: |
1631 | .start_aligned: |
1629 | cmp ecx, [ebp + EXTFS.block_size] |
1632 | cmp ecx, [ebp + EXTFS.block_size] |
1630 | jb @F |
1633 | jb @F |
1631 | 1634 | ||
1632 | mov eax, [esp] |
1635 | mov eax, [esp] |
1633 | xor edx, edx |
1636 | xor edx, edx |
1634 | div [ebp + EXTFS.block_size] |
1637 | div [ebp + EXTFS.block_size] |
1635 | 1638 | ||
1636 | mov edx, [esp + 4] |
1639 | mov edx, [esp + 4] |
1637 | call ext2_inode_blank_entry |
1640 | call ext2_inode_blank_entry |
1638 | 1641 | ||
1639 | test eax, eax |
1642 | test eax, eax |
1640 | jnz .error_inode_size |
1643 | jnz .error_inode_size |
1641 | 1644 | ||
1642 | mov eax, [ebp + EXTFS.block_size] |
1645 | mov eax, [ebp + EXTFS.block_size] |
1643 | sub ecx, eax |
1646 | sub ecx, eax |
1644 | add [esp], eax |
1647 | add [esp], eax |
1645 | jmp .start_aligned |
1648 | jmp .start_aligned |
1646 | 1649 | ||
1647 | ; Handle the remaining bytes. |
1650 | ; Handle the remaining bytes. |
1648 | @@: |
1651 | @@: |
1649 | test ecx, ecx |
1652 | test ecx, ecx |
1650 | jz .write_inode |
1653 | jz .write_inode |
1651 | 1654 | ||
1652 | mov eax, [esp] |
1655 | mov eax, [esp] |
1653 | xor edx, edx |
1656 | xor edx, edx |
1654 | div [ebp + EXTFS.block_size] |
1657 | div [ebp + EXTFS.block_size] |
1655 | 1658 | ||
1656 | mov edx, [esp + 4] |
1659 | mov edx, [esp + 4] |
1657 | call ext2_inode_blank_entry |
1660 | call ext2_inode_blank_entry |
1658 | 1661 | ||
1659 | test eax, eax |
1662 | test eax, eax |
1660 | jnz .error_inode_size |
1663 | jnz .error_inode_size |
1661 | add [esp], ecx |
1664 | add [esp], ecx |
1662 | 1665 | ||
1663 | .write_inode: |
1666 | .write_inode: |
1664 | mov ebx, [ebp + EXTFS.ext2_temp_inode] |
1667 | mov ebx, [ebp + EXTFS.ext2_temp_inode] |
1665 | pop eax |
1668 | pop eax |
1666 | mov [ebx + EXT2_INODE_STRUC.i_size], eax |
1669 | mov [ebx + EXT2_INODE_STRUC.i_size], eax |
1667 | mov eax, [esp] |
1670 | mov eax, [esp] |
1668 | call ext2_inode_write |
1671 | call ext2_inode_write |
1669 | 1672 | ||
1670 | test eax, eax |
1673 | test eax, eax |
1671 | jnz .error |
1674 | jnz .error |
1672 | 1675 | ||
1673 | .success: |
1676 | .success: |
1674 | xor eax, eax |
1677 | xor eax, eax |
1675 | 1678 | ||
1676 | .ret: |
1679 | .ret: |
1677 | add esp, 4 |
1680 | add esp, 4 |
1678 | 1681 | ||
1679 | pop edi esi edx ecx ebx |
1682 | pop edi esi edx ecx ebx |
1680 | ret |
1683 | ret |
1681 | 1684 | ||
1682 | .error_inode_size: |
1685 | .error_inode_size: |
1683 | mov ebx, [ebp + EXTFS.ext2_temp_inode] |
1686 | mov ebx, [ebp + EXTFS.ext2_temp_inode] |
1684 | pop eax |
1687 | pop eax |
1685 | mov [ebx + EXT2_INODE_STRUC.i_size], eax |
1688 | mov [ebx + EXT2_INODE_STRUC.i_size], eax |
1686 | mov eax, [esp] |
1689 | mov eax, [esp] |
1687 | call ext2_inode_write |
1690 | call ext2_inode_write |
1688 | 1691 | ||
1689 | .error: |
1692 | .error: |
1690 | xor eax, eax |
1693 | xor eax, eax |
1691 | not eax |
1694 | not eax |
1692 | jmp .ret |
1695 | jmp .ret |
1693 | 1696 | ||
1694 | ;--------------------------------------------------------------------- |
1697 | ;--------------------------------------------------------------------- |
1695 | ; Truncates inode to said size. |
1698 | ; Truncates inode to said size. |
1696 | ; Input: eax = inode ID. |
1699 | ; Input: eax = inode ID. |
1697 | ; ecx = size to truncate to. |
1700 | ; ecx = size to truncate to. |
1698 | ; ebp = pointer to EXTFS. |
1701 | ; ebp = pointer to EXTFS. |
1699 | ; Output: eax = error code. |
1702 | ; Output: eax = error code. |
1700 | ;--------------------------------------------------------------------- |
1703 | ;--------------------------------------------------------------------- |
1701 | ext2_inode_truncate: |
1704 | ext2_inode_truncate: |
1702 | push ebx ecx edx esi edi |
1705 | push ebx ecx edx esi edi |
1703 | 1706 | ||
1704 | ; Save the inode. |
1707 | ; Save the inode. |
1705 | push eax |
1708 | push eax |
1706 | 1709 | ||
1707 | ; Read the inode. |
1710 | ; Read the inode. |
1708 | mov ebx, [ebp + EXTFS.ext2_temp_inode] |
1711 | mov ebx, [ebp + EXTFS.ext2_temp_inode] |
1709 | call ext2_inode_read |
1712 | call ext2_inode_read |
1710 | test eax, eax |
1713 | test eax, eax |
1711 | jnz .error |
1714 | jnz .error |
1712 | 1715 | ||
1713 | mov eax, [ebx + EXT2_INODE_STRUC.i_size] |
1716 | mov eax, [ebx + EXT2_INODE_STRUC.i_size] |
1714 | cmp ecx, eax |
1717 | cmp ecx, eax |
1715 | jge .success |
1718 | jge .success |
1716 | 1719 | ||
1717 | ; Save the size of the inode. |
1720 | ; Save the size of the inode. |
1718 | push eax |
1721 | push eax |
1719 | 1722 | ||
1720 | ; ECX contains the size we've to truncate. |
1723 | ; ECX contains the size we've to truncate. |
1721 | sub ecx, eax |
1724 | sub ecx, eax |
1722 | not ecx |
1725 | not ecx |
1723 | inc ecx |
1726 | inc ecx |
1724 | xor edx, edx |
1727 | xor edx, edx |
1725 | div [ebp + EXTFS.block_size] |
1728 | div [ebp + EXTFS.block_size] |
1726 | 1729 | ||
1727 | test edx, edx |
1730 | test edx, edx |
1728 | jz .start_aligned |
1731 | jz .start_aligned |
1729 | 1732 | ||
1730 | ; Start isn't aligned, so deal with the non-aligned bytes. |
1733 | ; Start isn't aligned, so deal with the non-aligned bytes. |
1731 | mov esi, edx |
1734 | mov esi, edx |
1732 | 1735 | ||
1733 | cmp esi, ecx |
1736 | cmp esi, ecx |
1734 | jbe @F |
1737 | jbe @F |
1735 | 1738 | ||
1736 | ; If the size to truncate is smaller than the un-aligned bytes |
1739 | ; If the size to truncate is smaller than the un-aligned bytes |
1737 | ; we're going to have to mark neccessary bytes from the EOF |
1740 | ; we're going to have to mark neccessary bytes from the EOF |
1738 | ; as 0. |
1741 | ; as 0. |
1739 | push eax |
1742 | push eax |
1740 | call ext2_inode_read_entry |
1743 | call ext2_inode_read_entry |
1741 | test eax, eax |
1744 | test eax, eax |
1742 | pop eax |
1745 | pop eax |
1743 | jnz .error_inode_size |
1746 | jnz .error_inode_size |
1744 | 1747 | ||
1745 | mov edi, [ebp + EXTFS.ext2_save_block] |
1748 | mov edi, [ebp + EXTFS.ext2_save_block] |
1746 | sub edx, ecx |
1749 | sub edx, ecx |
1747 | add edi, edx |
1750 | add edi, edx |
1748 | 1751 | ||
1749 | push ecx eax |
1752 | push ecx eax |
1750 | xor eax, eax |
1753 | xor eax, eax |
1751 | rep stosb |
1754 | rep stosb |
1752 | pop eax ecx |
1755 | pop eax ecx |
1753 | 1756 | ||
1754 | call ext2_inode_write_entry |
1757 | call ext2_inode_write_entry |
1755 | test eax, eax |
1758 | test eax, eax |
1756 | jnz .error_inode_size |
1759 | jnz .error_inode_size |
1757 | 1760 | ||
1758 | sub [esp], ecx |
1761 | sub [esp], ecx |
1759 | jmp .write_inode |
1762 | jmp .write_inode |
1760 | 1763 | ||
1761 | @@: |
1764 | @@: |
1762 | ; Since ECX is greater than or equal to the bytes here un-aligned |
1765 | ; Since ECX is greater than or equal to the bytes here un-aligned |
1763 | ; just free the block. |
1766 | ; just free the block. |
1764 | call ext2_inode_free_entry |
1767 | call ext2_inode_free_entry |
1765 | 1768 | ||
1766 | sub [esp], esi |
1769 | sub [esp], esi |
1767 | sub ecx, esi |
1770 | sub ecx, esi |
1768 | jz .write_inode |
1771 | jz .write_inode |
1769 | 1772 | ||
1770 | .start_aligned: |
1773 | .start_aligned: |
1771 | cmp ecx, [ebp + EXTFS.block_size] |
1774 | cmp ecx, [ebp + EXTFS.block_size] |
1772 | jb @F |
1775 | jb @F |
1773 | 1776 | ||
1774 | mov eax, [esp] |
1777 | mov eax, [esp] |
1775 | xor edx, edx |
1778 | xor edx, edx |
1776 | div [ebp + EXTFS.block_size] |
1779 | div [ebp + EXTFS.block_size] |
1777 | dec eax |
1780 | dec eax |
1778 | 1781 | ||
1779 | call ext2_inode_free_entry |
1782 | call ext2_inode_free_entry |
1780 | 1783 | ||
1781 | test eax, eax |
1784 | test eax, eax |
1782 | jnz .error_inode_size |
1785 | jnz .error_inode_size |
1783 | 1786 | ||
1784 | mov eax, [ebp + EXTFS.block_size] |
1787 | mov eax, [ebp + EXTFS.block_size] |
1785 | sub ecx, eax |
1788 | sub ecx, eax |
1786 | sub [esp], eax |
1789 | sub [esp], eax |
1787 | jmp .start_aligned |
1790 | jmp .start_aligned |
1788 | 1791 | ||
1789 | ; Handle the remaining bytes. |
1792 | ; Handle the remaining bytes. |
1790 | @@: |
1793 | @@: |
1791 | test ecx, ecx |
1794 | test ecx, ecx |
1792 | jz .write_inode |
1795 | jz .write_inode |
1793 | 1796 | ||
1794 | mov eax, [esp] |
1797 | mov eax, [esp] |
1795 | xor edx, edx |
1798 | xor edx, edx |
1796 | div [ebp + EXTFS.block_size] |
1799 | div [ebp + EXTFS.block_size] |
1797 | dec eax |
1800 | dec eax |
1798 | 1801 | ||
1799 | push eax |
1802 | push eax |
1800 | call ext2_inode_read_entry |
1803 | call ext2_inode_read_entry |
1801 | test eax, eax |
1804 | test eax, eax |
1802 | pop eax |
1805 | pop eax |
1803 | jnz .error_inode_size |
1806 | jnz .error_inode_size |
1804 | 1807 | ||
1805 | mov edi, [ebp + EXTFS.ext2_save_block] |
1808 | mov edi, [ebp + EXTFS.ext2_save_block] |
1806 | mov edx, [ebp + EXTFS.block_size] |
1809 | mov edx, [ebp + EXTFS.block_size] |
1807 | sub edx, ecx |
1810 | sub edx, ecx |
1808 | add edi, edx |
1811 | add edi, edx |
1809 | 1812 | ||
1810 | push ecx eax |
1813 | push ecx eax |
1811 | xor eax, eax |
1814 | xor eax, eax |
1812 | rep stosb |
1815 | rep stosb |
1813 | pop eax ecx |
1816 | pop eax ecx |
1814 | 1817 | ||
1815 | call ext2_inode_write_entry |
1818 | call ext2_inode_write_entry |
1816 | test eax, eax |
1819 | test eax, eax |
1817 | jnz .error_inode_size |
1820 | jnz .error_inode_size |
1818 | 1821 | ||
1819 | sub [esp], ecx |
1822 | sub [esp], ecx |
1820 | 1823 | ||
1821 | .write_inode: |
1824 | .write_inode: |
1822 | mov ebx, [ebp + EXTFS.ext2_temp_inode] |
1825 | mov ebx, [ebp + EXTFS.ext2_temp_inode] |
1823 | pop eax |
1826 | pop eax |
1824 | mov [ebx + EXT2_INODE_STRUC.i_size], eax |
1827 | mov [ebx + EXT2_INODE_STRUC.i_size], eax |
1825 | mov eax, [esp] |
1828 | mov eax, [esp] |
1826 | call ext2_inode_write |
1829 | call ext2_inode_write |
1827 | 1830 | ||
1828 | test eax, eax |
1831 | test eax, eax |
1829 | jnz .error |
1832 | jnz .error |
1830 | 1833 | ||
1831 | .success: |
1834 | .success: |
1832 | xor eax, eax |
1835 | xor eax, eax |
1833 | 1836 | ||
1834 | .ret: |
1837 | .ret: |
1835 | add esp, 4 |
1838 | add esp, 4 |
1836 | 1839 | ||
1837 | pop edi esi edx ecx ebx |
1840 | pop edi esi edx ecx ebx |
1838 | ret |
1841 | ret |
1839 | 1842 | ||
1840 | .error_inode_size: |
1843 | .error_inode_size: |
1841 | mov ebx, [ebp + EXTFS.ext2_temp_inode] |
1844 | mov ebx, [ebp + EXTFS.ext2_temp_inode] |
1842 | pop eax |
1845 | pop eax |
1843 | mov [ebx + EXT2_INODE_STRUC.i_size], eax |
1846 | mov [ebx + EXT2_INODE_STRUC.i_size], eax |
1844 | mov eax, [esp] |
1847 | mov eax, [esp] |
1845 | call ext2_inode_write |
1848 | call ext2_inode_write |
1846 | 1849 | ||
1847 | .error: |
1850 | .error: |
1848 | xor eax, eax |
1851 | xor eax, eax |
1849 | not eax |
1852 | not eax |
1850 | jmp .ret><> |
1853 | jmp .ret><> |