Subversion Repositories Kolibri OS

Rev

Rev 5565 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
4265 Serge 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
3
;; Contains common resource allocation + freeing code.          ;;
4
;;                                                              ;;
5565 serge 5
;; Copyright (C) KolibriOS team 2013-2015. All rights reserved. ;;
5201 serge 6
;; Distributed under terms of the GNU General Public License    ;;
4265 Serge 7
;;                                                              ;;
8
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
9
 
5596 serge 10
$Revision: 5363 $
5201 serge 11
 
12
 
4265 Serge 13
;---------------------------------------------------------------------
14
; Frees a resource (block/inode).
15
; Input:        eax = resource ID.
16
;               edi = function pointer of ext2_bg_*_bitmap form, to
17
;                     get bitmap of resource.
18
;               ecx = 0, block; 1, inode.
19
;               ebp = pointer to EXTFS.
20
; Output:       Block marked as free in block group.
21
;               eax = error code.
22
;---------------------------------------------------------------------
23
ext2_resource_free:
24
        push    ebx edx esi
25
 
26
        ; Get block group.
27
        sub     eax, [ebp + EXTFS.superblock + EXT2_SB_STRUC.first_data_block]
28
        xor     edx, edx
29
        div     [ebp + EXTFS.superblock + EXT2_SB_STRUC.blocks_per_group]
30
        push    eax edx
31
 
32
        call    edi
33
        test    eax, eax
34
        jz      .fail
35
        mov     esi, eax
36
 
37
        ; Read the bitmap.
38
        mov     eax, ebx
39
        mov     edx, eax
40
        mov     ebx, [ebp + EXTFS.ext2_save_block]
41
        call    ext2_block_read
42
        test    eax, eax
43
        jnz     .fail
44
 
45
        pop     eax
46
        ; Mark bit free.
47
        call    bitmap_clear_bit
48
        test    eax, eax
49
        jz      @F
50
 
51
        ; No need to save anything.
52
        xor     eax, eax
53
 
54
        add     esp, 4
55
        jmp     .return
56
 
57
    @@:
58
        mov     eax, edx
59
        mov     ebx, [ebp + EXTFS.ext2_save_block]
60
        call    ext2_block_write
61
        test    eax, eax
62
        jnz     .fail
63
 
64
        ; Read the descriptor.
65
        mov     eax, [esp]
66
        call    ext2_bg_read_desc
67
        test    eax, eax
68
        jz      .fail_bg_desc_read
69
 
70
        lea     eax, [eax + EXT2_BLOCK_GROUP_DESC.free_blocks_count]
71
        shl     ecx, 1
72
        add     eax, ecx
73
        inc     word[eax]
74
 
75
        lea     eax, [ebp + EXTFS.superblock + EXT2_SB_STRUC.free_block_count]
76
        shl     ecx, 1
77
        add     eax, ecx
78
        inc     dword[eax]
79
 
80
        pop     eax
81
        call    ext2_bg_write_desc
82
 
83
    .return:
84
        pop     esi edx ebx
85
        ret
86
 
87
    .fail:
88
        add     esp, 4
89
    .fail_bg_desc_read:
90
        add     esp, 4
91
        xor     eax, eax
92
        not     eax
93
        jmp     .return
94
 
95
;---------------------------------------------------------------------
96
; Allocates a resource.
97
; Input:        eax = inode ID for "preference".
98
;               ebp = pointer to EXTFS.
99
;               [esp + 4], func pointer to ext2_bg_*_bitmap
100
;               [esp + 8], pointer to free_*_count in SB.
101
;               [esp + 12], *_per_group
102
;               [esp + 16], offset to free_*_count in bg descriptor.
103
;               [esp + 20], *_count
104
; Output:       Resource marked as set in block group.
105
;               eax = error code.
106
;               ebx = resource ID.
107
;---------------------------------------------------------------------
108
ext2_resource_alloc:
109
        ; Block allocation is a pretty serious area, since bad allocation
110
        ; can lead to fragmentation. Thus, the best way to allocate that
111
        ; comes to mind is to allocate around an inode as much as possible.
112
        ; On the other hand, this isn't about a single inode/file/directory,
113
        ; and focusing just around the preferred inode would lead to
114
        ; congestion. Thus, after much thought, the chosen allocation algorithm
115
        ; is to search forward, then backward.
116
        push    ecx edx esi edi
117
 
118
        cmp     dword[esp + 16 + 8], 0
119
        jnz     @F
120
 
121
        ; No free blocks.
122
        xor     eax, eax
123
        not     eax
124
        pop     edi esi edx ecx
125
        ret     20
126
 
127
    @@:
128
        ; Calculate which block group the preferred inode belongs to.
129
        dec     eax
130
        xor     edx, edx
131
 
132
        ; EAX = block group.
133
        div     [ebp + EXTFS.superblock + EXT2_SB_STRUC.inodes_per_group]
134
        push    eax
135
        push    eax
136
 
137
        mov     edi, .forward
138
 
139
    .test_block_group:
140
        call    dword[esp + 16 + 8 + 4]
141
        test    eax, eax
142
        jz      .fail
143
        mov     esi, eax
144
 
145
        mov     eax, ebx
146
        mov     edx, eax
147
        mov     ebx, [ebp + EXTFS.ext2_save_block]
148
        call    ext2_block_read
149
        test    eax, eax
150
        jnz     .fail
151
 
152
        mov     ecx, [esp + 16 + 8 + 12]
153
        call    ext2_find_free_bit
154
        cmp     eax, 0xFFFFFFFF
155
        jne     @F
156
 
157
        mov     eax, edi
158
        jmp     eax
159
 
160
    @@:
161
        mov     ecx, eax
162
 
163
        mov     eax, edx
164
        mov     ebx, [ebp + EXTFS.ext2_save_block]
165
        call    ext2_block_write
166
        test    eax, eax
167
        jnz     .fail
168
 
169
        ; ecx: the index of the matched entry.
170
        ; [esp]: block group where we found.
171
        ; [esp + 4]: starting block group.
172
        ; esi: block group descriptor.
173
        mov     eax, [esp]                             ; Index of block group in which we found.
174
        mul     dword[esp + 16 + 8 + 12]
175
        add     eax, ecx
176
        mov     ebx, eax
177
 
178
        mov     eax, [esp + 16 + 8 + 8]
179
        dec     dword[eax]
180
 
181
        mov     eax, esi
182
        add     eax, [esp + 16 + 8 + 16]
183
        dec     word[eax]
184
 
185
        pop     eax
186
        call    ext2_bg_write_desc
187
 
188
        add     esp, 4
189
        jmp     .return
190
 
191
    ; Continue forward.
192
    .forward:
193
        inc     dword[esp]
194
        mov     eax, [esp]
195
        mul     dword[esp + 16 + 8 + 12]
196
        cmp     eax, [esp + 16 + 8 + 20]
197
        jbe     @F
198
 
199
        ; We need to go backward.
200
        mov     eax, [esp + 4]
201
        mov     [esp], eax
202
        mov     edi, .backward
203
        jmp     .backward
204
 
205
    @@:
206
        mov     eax, [esp]
207
        jmp     .test_block_group
208
 
209
    ; Continue backward.
210
    .backward:
211
        cmp     dword[esp], 0
212
        je      .fail
213
 
214
        dec     dword[esp]
215
        mov     eax, [esp]
216
        jmp     .test_block_group
217
 
218
    .return:
219
        pop     edi esi edx ecx
220
        ret     20
221
 
222
    .fail:
223
        add     esp, 8
224
        xor     eax, eax
225
        not     eax
226
        jmp     .return