mirror of
https://github.com/KolibriOS/kolibrios.git
synced 2024-12-25 08:06:49 +03:00
Fixed bug when working with a large number of groups of blocks
git-svn-id: svn://kolibrios.org@1419 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
8f306c2c3d
commit
5a063e44a7
@ -30,8 +30,11 @@ EXT2_S_IWGRP = 0x0010
|
||||
EXT2_S_IXGRP = 0x0008
|
||||
;other inode right's
|
||||
EXT2_S_IROTH = 0x0004
|
||||
EXT2_S_IROTH = 0x0002
|
||||
EXT2_S_IROTH = 0x0001
|
||||
EXT2_S_IWOTH = 0x0002
|
||||
EXT2_S_IXOTH = 0x0001
|
||||
EXT2_777_MODE = EXT2_S_IROTH or EXT2_S_IWOTH or EXT2_S_IXOTH or \
|
||||
EXT2_S_IRGRP or EXT2_S_IWGRP or EXT2_S_IXGRP or \
|
||||
EXT2_S_IRUSR or EXT2_S_IWUSR or EXT2_S_IXUSR
|
||||
|
||||
EXT2_FT_REG_FILE = 1 ;это файл, запись в родительском каталоге
|
||||
EXT2_FT_DIR = 2 ;это папка
|
||||
@ -49,6 +52,8 @@ uglobal
|
||||
EXT2_end_block dd ? ;конец очередного блока папки
|
||||
EXT2_counter_blocks dd ?
|
||||
EXT2_filename db 256 dup ?
|
||||
EXT2_parent_name db 256 dup ?
|
||||
EXT2_name_len dd ?
|
||||
endg
|
||||
|
||||
struct EXT2_INODE_STRUC
|
||||
@ -80,6 +85,64 @@ struct EXT2_DIR_STRUC
|
||||
.name db ? ; 0..255
|
||||
ends
|
||||
|
||||
struct EXT2_BLOCK_GROUP_DESC
|
||||
.block_bitmap dd ?
|
||||
.inode_bitmap dd ?
|
||||
.inode_table dd ?
|
||||
.free_blocks_count dw ?
|
||||
.free_inodes_count dw ?
|
||||
.used_dirs_count dw ?
|
||||
ends
|
||||
|
||||
struct EXT2_SB_STRUC
|
||||
.inodes_count dd ? ;+0
|
||||
.blocks_count dd ? ;+4
|
||||
.r_block_count dd ? ;+8
|
||||
.free_block_count dd ? ;+12
|
||||
.free_inodes_count dd ? ;+16
|
||||
.first_data_block dd ? ;+20
|
||||
.log_block_size dd ? ;+24
|
||||
.log_frag_size dd ? ;+28
|
||||
.blocks_per_group dd ? ;+32
|
||||
.frags_per_group dd ? ;+36
|
||||
.inodes_per_group dd ? ;+40
|
||||
.mtime dd ? ;+44
|
||||
.wtime dd ? ;+48
|
||||
.mnt_count dw ? ;+52
|
||||
.max_mnt_count dw ? ;+54
|
||||
.magic dw ? ;+56
|
||||
.state dw ? ;+58
|
||||
.errors dw ? ;+60
|
||||
.minor_rev_level dw ? ;+62
|
||||
.lastcheck dd ? ;+64
|
||||
.check_intervals dd ? ;+68
|
||||
.creator_os dd ? ;+72
|
||||
.rev_level dd ? ;+76
|
||||
.def_resuid dw ? ;+80
|
||||
.def_resgid dw ? ;+82
|
||||
.first_ino dd ? ;+84
|
||||
.inode_size dw ? ;+88
|
||||
.block_group_nr dw ? ;+90
|
||||
.feature_compat dd ? ;+92
|
||||
.feature_incompat dd ? ;+96
|
||||
.feature_ro_compat dd ? ;+100
|
||||
.uuid db 16 dup ? ;+104
|
||||
.volume_name db 16 dup ? ;+120
|
||||
.last_mounted db 64 dup ? ;+136
|
||||
.algo_bitmap dd ? ;+200
|
||||
.prealloc_blocks db ? ;+204
|
||||
.preallock_dir_blocks db ? ;+205
|
||||
dw ? ;+206 alignment
|
||||
.journal_uuid db 16 dup ? ;+208
|
||||
.journal_inum dd ? ;+224
|
||||
.journal_dev dd ? ;+228
|
||||
.last_orphan dd ? ;+232
|
||||
.hash_seed dd 4 dup ? ;+236
|
||||
.def_hash_version db ? ;+252
|
||||
db 3 dup ? ;+253 reserved
|
||||
.default_mount_options dd ? ;+256
|
||||
.first_meta_bg dd ? ;+260
|
||||
ends
|
||||
|
||||
ext2_test_superblock:
|
||||
cmp [fs_type], 0x83
|
||||
@ -111,6 +174,24 @@ ext2_test_superblock:
|
||||
|
||||
ext2_setup:
|
||||
mov [fs_type], 2
|
||||
|
||||
push 512
|
||||
call kernel_alloc ; mem for superblock
|
||||
mov esi, ebx
|
||||
mov edi, eax
|
||||
mov ecx, 512/4
|
||||
rep movsd ; copy sb to reserved mem
|
||||
mov ebx, eax
|
||||
mov [ext2_data.sb],eax
|
||||
|
||||
mov eax, [ebx + EXT2_SB_STRUC.blocks_count]
|
||||
sub eax, [ebx + EXT2_SB_STRUC.first_data_block]
|
||||
dec eax
|
||||
xor edx, edx
|
||||
div [ebx + EXT2_SB_STRUC.blocks_per_group]
|
||||
inc eax
|
||||
mov [ext2_data.groups_count], eax
|
||||
|
||||
mov ecx, [ebx+24]
|
||||
inc ecx
|
||||
mov [ext2_data.log_block_size], ecx ; 1, 2, 3, 4 equ 1kb, 2kb, 4kb, 8kb
|
||||
@ -126,14 +207,12 @@ ext2_setup:
|
||||
shl eax, 2
|
||||
mov [ext2_data.block_size], eax
|
||||
|
||||
push eax eax eax ; 3 kernel_alloc
|
||||
push eax eax ; 2 kernel_alloc
|
||||
|
||||
mov eax, edx
|
||||
mul edx
|
||||
mov [ext2_data.count_pointer_in_block_square], eax
|
||||
|
||||
call kernel_alloc
|
||||
mov [ext2_data.global_desc_table],eax ; reserve mem for gdt
|
||||
call kernel_alloc
|
||||
mov [ext2_data.ext2_save_block], eax ; and for temp block
|
||||
call kernel_alloc
|
||||
@ -142,16 +221,11 @@ ext2_setup:
|
||||
movzx ebp, word [ebx+88]
|
||||
mov ecx, [ebx+32]
|
||||
mov edx, [ebx+40]
|
||||
mov eax, [ebx+20] ; first_data_block
|
||||
|
||||
mov [ext2_data.inode_size], ebp
|
||||
mov [ext2_data.blocks_per_group], ecx
|
||||
mov [ext2_data.inodes_per_group], edx
|
||||
|
||||
mov ebx, [ext2_data.global_desc_table]
|
||||
inc eax ; first_data_block + 1 = gdt
|
||||
call ext2_get_block ; read gtd
|
||||
|
||||
push ebp ebp ebp ;3 kernel_alloc
|
||||
call kernel_alloc
|
||||
mov [ext2_data.ext2_save_inode], eax
|
||||
@ -163,6 +237,7 @@ ext2_setup:
|
||||
mov ebx, eax
|
||||
mov eax, EXT2_ROOT_INO
|
||||
call ext2_get_inode ; read root inode
|
||||
|
||||
jmp return_from_part_set
|
||||
|
||||
;==================================================================
|
||||
@ -249,7 +324,6 @@ ext2_get_inode_block:
|
||||
mov ecx, dword [ebp + EXT2_INODE_STRUC.i_block + ecx*4]
|
||||
ret
|
||||
|
||||
|
||||
;===================================================================
|
||||
;get content inode by num
|
||||
;in: eax = inode_num
|
||||
@ -257,18 +331,28 @@ ext2_get_inode_block:
|
||||
ext2_get_inode:
|
||||
|
||||
pushad
|
||||
mov edi, ebx ;сохраним адрес inode
|
||||
mov edi, ebx ;сохраним адрес inode
|
||||
dec eax
|
||||
xor edx, edx
|
||||
div [ext2_data.inodes_per_group]
|
||||
|
||||
push edx ;locale num
|
||||
push edx ;locale num in group
|
||||
|
||||
mov edx, 32
|
||||
mul edx ; address block_group in global_desc_table
|
||||
|
||||
add eax, [ext2_data.global_desc_table]
|
||||
mov eax, [eax+8] ; номер блока - в терминах ext2
|
||||
; в eax - смещение группы с inode-ом относительно начала глобальной дескрипторной таблицы
|
||||
; найдем блок в котором он находится
|
||||
|
||||
div [ext2_data.block_size]
|
||||
mov ecx, [ext2_data.sb]
|
||||
add eax, [ecx + EXT2_SB_STRUC.first_data_block]
|
||||
inc eax
|
||||
mov ebx, [ext2_data.ext2_temp_block]
|
||||
call ext2_get_block
|
||||
|
||||
add ebx, edx ; локальный номер в блоке
|
||||
mov eax, [ebx+8] ; номер блока - в терминах ext2
|
||||
|
||||
mov ecx, [ext2_data.log_block_size]
|
||||
shl eax, cl
|
||||
@ -434,11 +518,17 @@ ext2_HdReadFolder:
|
||||
dec ecx
|
||||
@@:
|
||||
movzx ebx, [eax+EXT2_DIR_STRUC.rec_len]
|
||||
|
||||
cmp ebx, 12 ; минимальная длина записи
|
||||
jb .end_error
|
||||
test ebx, 0x3 ; длина записи должна делиться на 4
|
||||
jnz .end_error
|
||||
|
||||
add eax, ebx ; к следующей записи
|
||||
cmp eax, [EXT2_end_block] ; проверяем "конец"
|
||||
jb .find_wanted_start
|
||||
|
||||
push .find_wanted_start
|
||||
push .find_wanted_start
|
||||
.end_block: ;вылетили из цикла
|
||||
mov ebx, [ext2_data.count_block_in_block]
|
||||
sub [EXT2_counter_blocks], ebx
|
||||
@ -534,6 +624,11 @@ ext2_HdReadFolder:
|
||||
dec ecx ; если запись пустая ecx не надо уменьшать
|
||||
.empty_rec:
|
||||
movzx ebx, [eax + EXT2_DIR_STRUC.rec_len]
|
||||
cmp ebx, 12 ; минимальная длина записи
|
||||
jb .end_error
|
||||
test ebx, 0x3 ; длина записи должна делиться на 4
|
||||
jnz .end_error
|
||||
|
||||
add eax, ebx
|
||||
cmp eax, [EXT2_end_block]
|
||||
jb .wanted_start
|
||||
@ -543,6 +638,7 @@ ext2_HdReadFolder:
|
||||
|
||||
.end_dir:
|
||||
pop eax ; мусор (адрес возврата в цикл)
|
||||
.end_error:
|
||||
pop edx
|
||||
mov ebx, [EXT2_read_in_folder]
|
||||
mov ecx, [EXT2_files_in_folder]
|
||||
@ -658,7 +754,7 @@ ext2_HdRead:
|
||||
|
||||
.size_less:
|
||||
xor ebx, ebx
|
||||
mov eax, 6 ;EOF
|
||||
mov eax, ERROR_END_OF_FILE
|
||||
ret
|
||||
.size_great:
|
||||
add eax, ecx ;add to first_wanted кол-во байт для чтения
|
||||
@ -758,7 +854,7 @@ ext2_HdRead:
|
||||
cmp [EXT2_files_in_folder], 0
|
||||
jz @F
|
||||
|
||||
mov eax, 6 ;EOF
|
||||
mov eax, ERROR_END_OF_FILE
|
||||
ret
|
||||
@@:
|
||||
xor eax, eax
|
||||
@ -816,22 +912,6 @@ ext2_find_lfn:
|
||||
|
||||
|
||||
;========================
|
||||
ext2_HdRewrite:
|
||||
; xchg bx, bx
|
||||
xor ebx, ebx
|
||||
mov eax, ERROR_UNSUPPORTED_FS
|
||||
ret
|
||||
|
||||
ext2_HdWrite:
|
||||
; xchg bx, bx
|
||||
xor ebx, ebx
|
||||
mov eax, ERROR_UNSUPPORTED_FS
|
||||
ret
|
||||
ext2_HdSetFileEnd:
|
||||
; xchg bx, bx
|
||||
xor ebx, ebx
|
||||
mov eax, ERROR_UNSUPPORTED_FS
|
||||
ret
|
||||
|
||||
ext2_HdGetFileInfo:
|
||||
cmp byte [esi], 0
|
||||
@ -893,14 +973,346 @@ ext2_HdGetFileInfo:
|
||||
xor eax, eax
|
||||
ret
|
||||
|
||||
ext2_HdRewrite:
|
||||
ext2_HdWrite:
|
||||
ext2_HdSetFileEnd:
|
||||
ext2_HdSetFileInfo:
|
||||
; xchg bx, bx
|
||||
ext2_HdDelete:
|
||||
ext2_HdCreateFolder:
|
||||
xor ebx, ebx
|
||||
mov eax, ERROR_UNSUPPORTED_FS
|
||||
ret
|
||||
ext2_HdDelete:
|
||||
; xchg bx, bx
|
||||
;----------------------------------------------------------------
|
||||
;
|
||||
; ext2_HdCreateFolder - create new folder
|
||||
;
|
||||
; esi points to filename
|
||||
;
|
||||
; ret eax = 0 ok read or other = errormsg
|
||||
;
|
||||
;--------------------------------------------------------------
|
||||
cmp byte [esi], 0
|
||||
jz .not_found
|
||||
cmp byte [esi], '/'
|
||||
jz .not_found
|
||||
|
||||
mov ebx, esi ; save source pointer
|
||||
xor edi, edi ; slah pointer
|
||||
@@:
|
||||
lodsb
|
||||
cmp al, 0
|
||||
jz .zero
|
||||
cmp al, '/'
|
||||
jz .slash
|
||||
jmp @B
|
||||
|
||||
.slash:
|
||||
lodsb
|
||||
cmp al, 0
|
||||
jz .zero ; уберем слеш из имени
|
||||
cmp al, '/'
|
||||
jz .not_found
|
||||
mov edi, esi ; edi -> next symbol after '/'
|
||||
dec edi
|
||||
jmp @B
|
||||
|
||||
.zero:
|
||||
dec esi
|
||||
test edi, edi
|
||||
jz .doit
|
||||
|
||||
;слеш был
|
||||
mov eax, esi
|
||||
sub eax, edi
|
||||
mov [EXT2_name_len], eax
|
||||
|
||||
mov ecx, edi
|
||||
sub ecx, ebx
|
||||
dec ecx ;выкинули '/' из имени ролителя
|
||||
mov esi, ebx
|
||||
mov edi, EXT2_parent_name
|
||||
rep movsb
|
||||
; esi - pointer to last slash
|
||||
|
||||
mov edx, esi
|
||||
mov esi, EXT2_parent_name
|
||||
call ext2_find_lfn
|
||||
jnc .doit2
|
||||
.not_found:
|
||||
or ebx, -1
|
||||
mov eax, ERROR_FILE_NOT_FOUND
|
||||
ret
|
||||
|
||||
.doit:
|
||||
mov ebp, [ext2_data.root_inode]
|
||||
mov edx, ebx ; имя создаваемой папки
|
||||
sub esi, ebx
|
||||
mov [EXT2_name_len], esi
|
||||
.doit2:
|
||||
;ebp -> parent_inode ebx->name_new_folder [EXT2_name_len]=length of name
|
||||
; стратегия выбора группы для нового inode: (так делает линукс)
|
||||
; 1) Ищем группу в которой меньше всего папок и в есть свободное место
|
||||
; 2) Если такая группа не нашлась, то берем группу в которой больше свободного места
|
||||
|
||||
|
||||
|
||||
|
||||
call ext2_balloc
|
||||
jmp ext2_HdDelete
|
||||
|
||||
push ebx
|
||||
push ebp
|
||||
|
||||
mov ecx, [ext2_data.sb]
|
||||
cmp [ecx + EXT2_SB_STRUC.free_inodes_count],0 ; есть ли место для inode
|
||||
jz .no_space
|
||||
mov eax, [ecx + EXT2_SB_STRUC.free_block_count]
|
||||
sub eax, [ecx + EXT2_SB_STRUC.r_block_count]
|
||||
cmp eax, 2 ; и как минимум на 2 блока
|
||||
jb .no_space
|
||||
|
||||
mov ecx, [ext2_data.groups_count]
|
||||
mov esi, [ext2_data.global_desc_table]
|
||||
mov edi, -1 ;указатель на лучшую группу
|
||||
mov edx, 0
|
||||
.find_group_dir:
|
||||
jecxz .end_find_group_dir
|
||||
movzx eax, [esi + EXT2_BLOCK_GROUP_DESC.free_inodes_count]
|
||||
cmp eax, edx
|
||||
jbe @F
|
||||
cmp [esi + EXT2_BLOCK_GROUP_DESC.free_blocks_count], 0
|
||||
jz @F
|
||||
mov edi, esi
|
||||
movzx edx, [esi + EXT2_BLOCK_GROUP_DESC.free_inodes_count]
|
||||
@@:
|
||||
dec ecx
|
||||
add esi, 32 ;размер структуры
|
||||
jmp .find_group_dir
|
||||
.end_find_group_dir:
|
||||
cmp edx, 0
|
||||
jz .no_space
|
||||
|
||||
;нашли группу, получим битовую карту inode-ов (найдем locale number)
|
||||
mov eax, [edi + EXT2_BLOCK_GROUP_DESC.inode_bitmap]
|
||||
mov ebx, [ext2_data.ext2_save_block]
|
||||
call ext2_get_block
|
||||
|
||||
;теперь цикл по всем битам
|
||||
mov esi, ebx
|
||||
mov ecx, [ext2_data.inodes_per_group]
|
||||
shr ecx, 5 ;делим на 32
|
||||
mov ebp, ecx ; всего сохраним в ebp
|
||||
or eax, -1 ; ищем первый свободный inode (!= -1)
|
||||
repne scasd
|
||||
jnz .test_last_dword ;нашли или нет
|
||||
mov eax, [esi-4]
|
||||
|
||||
sub ebp, ecx
|
||||
dec ebp
|
||||
shl ebp, 5 ; глобальный номер локального номера
|
||||
|
||||
mov ecx, 32
|
||||
@@:
|
||||
test eax, 1
|
||||
jz @F
|
||||
shr eax, 1
|
||||
loop @B
|
||||
@@:
|
||||
mov eax, 32
|
||||
sub eax, ecx
|
||||
|
||||
add ebp, eax ; locale num of inode
|
||||
|
||||
mov eax, [esi-4]
|
||||
;устанавливаем в eax крайний справа нулевой бит в 1
|
||||
mov ecx, eax
|
||||
inc ecx
|
||||
or eax, ecx ; x | (x+1)
|
||||
mov [esi-4], eax
|
||||
mov ebx, [ext2_data.ext2_save_block]
|
||||
mov eax, [edi + EXT2_BLOCK_GROUP_DESC.inode_bitmap]
|
||||
call ext2_set_block
|
||||
;считаем таблицу inode
|
||||
sub edi, [ext2_data.global_desc_table]
|
||||
shr edi, 5
|
||||
|
||||
mov eax, edi
|
||||
mul [ext2_data.inodes_per_group]
|
||||
add eax, ebp
|
||||
inc eax ; теперь в eax (ebp) номер inode-а
|
||||
mov ebp, eax
|
||||
;call ext2_get_inode_address
|
||||
|
||||
mov ebx, [ext2_data.ext2_save_block]
|
||||
call hd_read
|
||||
add edx, ebx ; в edx адрес нужного inode
|
||||
|
||||
;забьем 0 для начала
|
||||
mov edi, edx
|
||||
mov ecx, [ext2_data.inode_size]
|
||||
shr ecx, 2
|
||||
xor eax, eax
|
||||
rep stosd
|
||||
|
||||
mov edi, edx
|
||||
mov eax, EXT2_S_IFDIR or EXT2_777_MODE
|
||||
stosd ; i_mode
|
||||
xor eax, eax
|
||||
stosd ; i_uid
|
||||
mov eax, [ext2_data.block_size]
|
||||
stosd ; i_size
|
||||
xor eax, eax
|
||||
stosd ; i_atime
|
||||
stosd ; i_ctime
|
||||
stosd ; i_mtime
|
||||
stosd ; i_dtime
|
||||
stosd ; i_gid
|
||||
inc eax
|
||||
stosd ; i_links_count
|
||||
mov eax, [ext2_data.count_block_in_block]
|
||||
stosd ; i_blocks
|
||||
|
||||
|
||||
|
||||
|
||||
.test_last_dword:
|
||||
|
||||
xor ebx, ebx
|
||||
mov eax, ERROR_UNSUPPORTED_FS
|
||||
ret
|
||||
|
||||
|
||||
|
||||
.no_space:
|
||||
or ebx, -1
|
||||
mov eax, ERROR_DISK_FULL
|
||||
ret
|
||||
|
||||
;выделяет новый блок, если это можно
|
||||
;иначе возвращает eax=0
|
||||
ext2_balloc:
|
||||
mov ecx, [ext2_data.sb]
|
||||
mov eax, [ecx + EXT2_SB_STRUC.free_block_count]
|
||||
sub eax, [ecx + EXT2_SB_STRUC.r_block_count]
|
||||
jbe .no_space
|
||||
|
||||
mov ecx, [ext2_data.groups_count]
|
||||
mov edi, [ext2_data.global_desc_table]
|
||||
;mov esi, -1 ;указатель на лучшую группу
|
||||
mov edx, 0
|
||||
.find_group:
|
||||
jecxz .end_find_group
|
||||
movzx eax, [edi + EXT2_BLOCK_GROUP_DESC.free_blocks_count]
|
||||
cmp eax, edx
|
||||
jbe @F
|
||||
mov esi, edi
|
||||
mov edx, eax
|
||||
@@:
|
||||
dec ecx
|
||||
add edi, 32 ;размер структуры
|
||||
jmp .find_group
|
||||
.end_find_group:
|
||||
cmp edx, 0
|
||||
jz .no_space
|
||||
|
||||
;нашли группу, получим битовую карту block-ов
|
||||
mov eax, [esi + EXT2_BLOCK_GROUP_DESC.block_bitmap]
|
||||
mov ebx, [ext2_data.ext2_save_block]
|
||||
call ext2_get_block
|
||||
|
||||
;теперь цикл по всем битам
|
||||
mov edi, ebx
|
||||
mov ecx, [ext2_data.blocks_per_group]
|
||||
shr ecx, 5 ;делим на 32
|
||||
mov ebp, ecx ;всего сохраним в ebp
|
||||
or eax, -1 ;ищем первый свободный inode (!= -1)
|
||||
repe scasd
|
||||
jz .test_last_dword ;нашли или нет
|
||||
|
||||
mov eax, [edi-4]
|
||||
sub ebp, ecx
|
||||
dec ebp
|
||||
shl ebp, 5 ; ebp = 32*(номер div 32). Теперь найдем (номер mod 32)
|
||||
|
||||
mov ecx, 32
|
||||
@@:
|
||||
test eax, 1
|
||||
jz @F
|
||||
shr eax, 1
|
||||
loop @B
|
||||
@@:
|
||||
mov eax, 32
|
||||
sub eax, ecx
|
||||
|
||||
add ebp, eax ; ebp = номер блока в группе
|
||||
|
||||
mov eax, [edi-4]
|
||||
mov ecx, eax
|
||||
inc ecx
|
||||
or eax, ecx ; x | (x+1) - устанавливает в 1 крайний справа нулевой бит (block used)
|
||||
mov [edi-4], eax
|
||||
|
||||
mov ebx, [ext2_data.ext2_save_block]
|
||||
mov eax, [esi + EXT2_BLOCK_GROUP_DESC.inode_bitmap]
|
||||
; call ext2_set_block ; и пишем на hdd новую битовую маску
|
||||
|
||||
;============== тут получаем номер блока
|
||||
mov eax, [ext2_data.blocks_per_group]
|
||||
sub esi, [ext2_data.global_desc_table]
|
||||
shr esi, 5 ;esi - номер группы
|
||||
mul esi
|
||||
add ebp, eax ;(номер_группы) * (blocks_per_group) + локальный номер в группе
|
||||
mov eax, [ext2_data.sb]
|
||||
add ebp, [eax + EXT2_SB_STRUC.first_data_block]
|
||||
|
||||
;теперь поправим глобальную дескрипторную таблицу и суперблок
|
||||
mov ebx, [ext2_data.sb]
|
||||
dec [ebx + EXT2_SB_STRUC.free_block_count]
|
||||
mov eax, 2
|
||||
add eax, [PARTITION_START]
|
||||
call hd_write
|
||||
mov eax, [ebx + EXT2_SB_STRUC.first_data_block]
|
||||
inc eax
|
||||
dec [esi + EXT2_BLOCK_GROUP_DESC.free_blocks_count];edi все еще указывает на группу в которой мы выделил блок
|
||||
call ext2_set_block
|
||||
|
||||
mov eax, ebx
|
||||
ret
|
||||
|
||||
.test_last_dword:
|
||||
lodsd
|
||||
mov ecx, [ext2_data.blocks_per_group]
|
||||
and ecx, not (32-1) ;обнуляем все кроме последних 5 бит
|
||||
mov edx, ecx
|
||||
mov ebx, 1
|
||||
@@:
|
||||
jecxz .no_space
|
||||
mov edx, ebx
|
||||
or edx, eax ; тестируем очередной бит
|
||||
shl ebx, 1
|
||||
jmp @B
|
||||
@@:
|
||||
sub edx, ecx
|
||||
dec edx ;номер в последнем блоке
|
||||
|
||||
|
||||
.no_space:
|
||||
xor eax, eax
|
||||
ret
|
||||
|
||||
;in: eax = i_block
|
||||
; ebx = pointer to memory
|
||||
ext2_set_block:
|
||||
push eax ebx ecx
|
||||
mov ecx, [ext2_data.log_block_size]
|
||||
shl eax, cl
|
||||
add eax, [PARTITION_START]
|
||||
mov ecx, [ext2_data.count_block_in_block]
|
||||
@@:
|
||||
call hd_write
|
||||
inc eax
|
||||
add ebx, 512
|
||||
loop @B
|
||||
pop ecx ebx eax
|
||||
ret
|
||||
|
||||
|
@ -95,7 +95,9 @@ ext2_data:
|
||||
.ext2_save_block dd ? ; ¡«®ª £«®¡ «ìãî 1 ¯à®æ¥¤ãàã
|
||||
.ext2_temp_block dd ? ; ¡«®ª ¤«ï ¬¥«ª¨å ¯à®æ¥¤ãà
|
||||
.ext2_save_inode dd ? ; inode £«®¡ «ìãî ¯à®æ¥¤ãàã
|
||||
.ext2_temp_inode dd ? ; inode ¤«ï ¬¥«ª¨å ¯à®æ¥¤ãà
|
||||
.ext2_temp_inode dd ? ; inode ¤«ï ¬¥«ª¨å ¯à®æ¥¤ãà
|
||||
.sb dd ? ; superblock
|
||||
.groups_count dd ?
|
||||
if $ > fs_dependent_data_end
|
||||
ERROR: increase sizeof(fs_dependent_data)!
|
||||
end if
|
||||
|
Loading…
Reference in New Issue
Block a user