0,0 → 1,223 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Contains common resource allocation + freeing code. ;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;; |
;; Distributed under the terms of the new BSD license. ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
|
;--------------------------------------------------------------------- |
; Frees a resource (block/inode). |
; Input: eax = resource ID. |
; edi = function pointer of ext2_bg_*_bitmap form, to |
; get bitmap of resource. |
; ecx = 0, block; 1, inode. |
; ebp = pointer to EXTFS. |
; Output: Block marked as free in block group. |
; eax = error code. |
;--------------------------------------------------------------------- |
ext2_resource_free: |
push ebx edx esi |
|
; Get block group. |
sub eax, [ebp + EXTFS.superblock + EXT2_SB_STRUC.first_data_block] |
xor edx, edx |
div [ebp + EXTFS.superblock + EXT2_SB_STRUC.blocks_per_group] |
push eax edx |
|
call edi |
test eax, eax |
jz .fail |
mov esi, eax |
|
; Read the bitmap. |
mov eax, ebx |
mov edx, eax |
mov ebx, [ebp + EXTFS.ext2_save_block] |
call ext2_block_read |
test eax, eax |
jnz .fail |
|
pop eax |
; Mark bit free. |
call bitmap_clear_bit |
test eax, eax |
jz @F |
|
; No need to save anything. |
xor eax, eax |
|
add esp, 4 |
jmp .return |
|
@@: |
mov eax, edx |
mov ebx, [ebp + EXTFS.ext2_save_block] |
call ext2_block_write |
test eax, eax |
jnz .fail |
|
; Read the descriptor. |
mov eax, [esp] |
call ext2_bg_read_desc |
test eax, eax |
jz .fail_bg_desc_read |
|
lea eax, [eax + EXT2_BLOCK_GROUP_DESC.free_blocks_count] |
shl ecx, 1 |
add eax, ecx |
inc word[eax] |
|
lea eax, [ebp + EXTFS.superblock + EXT2_SB_STRUC.free_block_count] |
shl ecx, 1 |
add eax, ecx |
inc dword[eax] |
|
pop eax |
call ext2_bg_write_desc |
|
.return: |
pop esi edx ebx |
ret |
|
.fail: |
add esp, 4 |
.fail_bg_desc_read: |
add esp, 4 |
xor eax, eax |
not eax |
jmp .return |
|
;--------------------------------------------------------------------- |
; Allocates a resource. |
; Input: eax = inode ID for "preference". |
; ebp = pointer to EXTFS. |
; [esp + 4], func pointer to ext2_bg_*_bitmap |
; [esp + 8], pointer to free_*_count in SB. |
; [esp + 12], *_per_group |
; [esp + 16], offset to free_*_count in bg descriptor. |
; [esp + 20], *_count |
; Output: Resource marked as set in block group. |
; eax = error code. |
; ebx = resource ID. |
;--------------------------------------------------------------------- |
ext2_resource_alloc: |
; Block allocation is a pretty serious area, since bad allocation |
; can lead to defragmentation. Thus, the best way to allocate that |
; comes to mind is to allocate around an inode as much as possible. |
; On the other hand, this isn't about a single inode/file/directory, |
; and focusing just around the preferred inode would lead to |
; congestion. Thus, after much though, the chosen allocation algorithm |
; is to search forward, then backward. |
push ecx edx esi edi |
|
cmp dword[esp + 16 + 8], 0 |
jnz @F |
|
; No free blocks. |
xor eax, eax |
not eax |
pop edi esi edx ecx |
ret 20 |
|
@@: |
; Calculate which block group the preferred inode belongs to. |
dec eax |
xor edx, edx |
|
; EAX = block group. |
div [ebp + EXTFS.superblock + EXT2_SB_STRUC.inodes_per_group] |
push eax |
push eax |
|
mov edi, .forward |
|
.test_block_group: |
call dword[esp + 16 + 8 + 4] |
test eax, eax |
jz .fail |
mov esi, eax |
|
mov eax, ebx |
mov edx, eax |
mov ebx, [ebp + EXTFS.ext2_save_block] |
call ext2_block_read |
test eax, eax |
jnz .fail |
|
mov ecx, [esp + 16 + 8 + 12] |
call ext2_find_free_bit |
cmp eax, 0xFFFFFFFF |
jne @F |
|
mov eax, edi |
jmp eax |
|
@@: |
mov ecx, eax |
|
mov eax, edx |
mov ebx, [ebp + EXTFS.ext2_save_block] |
call ext2_block_write |
test eax, eax |
jnz .fail |
|
; ecx: the index of the matched entry. |
; [esp]: block group where we found. |
; [esp + 4]: starting block group. |
; esi: block group descriptor. |
mov eax, [esp] ; Index of block group in which we found. |
mul dword[esp + 16 + 8 + 12] |
add eax, ecx |
mov ebx, eax |
|
mov eax, [esp + 16 + 8 + 8] |
dec dword[eax] |
|
mov eax, esi |
add eax, [esp + 16 + 8 + 16] |
dec word[eax] |
|
pop eax |
call ext2_bg_write_desc |
|
add esp, 4 |
jmp .return |
|
; Continue forward. |
.forward: |
inc dword[esp] |
mov eax, [esp] |
mul dword[esp + 16 + 8 + 12] |
cmp eax, [esp + 16 + 8 + 20] |
jbe @F |
|
; We need to go backward. |
mov eax, [esp + 4] |
mov [esp], eax |
mov edi, .backward |
jmp .backward |
|
@@: |
mov eax, [esp] |
jmp .test_block_group |
|
; Continue backward. |
.backward: |
cmp dword[esp], 0 |
je .fail |
|
dec dword[esp] |
mov eax, [esp] |
jmp .test_block_group |
|
.return: |
pop edi esi edx ecx |
ret 20 |
|
.fail: |
add esp, 8 |
xor eax, eax |
not eax |
jmp .return |
Property changes: |
Added: svn:eol-style |
+native |
\ No newline at end of property |