Subversion Repositories Kolibri OS

Rev

Rev 5201 | Go to most recent revision | Details | Last modification | View Log | RSS feed

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