Subversion Repositories Kolibri OS

Rev

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

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