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