Subversion Repositories Kolibri OS

Rev

Rev 4066 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

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