forked from KolibriOS/kolibrios
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
|
EXT2_S_IXGRP = 0x0008
|
||||||
;other inode right's
|
;other inode right's
|
||||||
EXT2_S_IROTH = 0x0004
|
EXT2_S_IROTH = 0x0004
|
||||||
EXT2_S_IROTH = 0x0002
|
EXT2_S_IWOTH = 0x0002
|
||||||
EXT2_S_IROTH = 0x0001
|
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_REG_FILE = 1 ;это файл, запись в родительском каталоге
|
||||||
EXT2_FT_DIR = 2 ;это папка
|
EXT2_FT_DIR = 2 ;это папка
|
||||||
@ -49,6 +52,8 @@ uglobal
|
|||||||
EXT2_end_block dd ? ;конец очередного блока папки
|
EXT2_end_block dd ? ;конец очередного блока папки
|
||||||
EXT2_counter_blocks dd ?
|
EXT2_counter_blocks dd ?
|
||||||
EXT2_filename db 256 dup ?
|
EXT2_filename db 256 dup ?
|
||||||
|
EXT2_parent_name db 256 dup ?
|
||||||
|
EXT2_name_len dd ?
|
||||||
endg
|
endg
|
||||||
|
|
||||||
struct EXT2_INODE_STRUC
|
struct EXT2_INODE_STRUC
|
||||||
@ -80,6 +85,64 @@ struct EXT2_DIR_STRUC
|
|||||||
.name db ? ; 0..255
|
.name db ? ; 0..255
|
||||||
ends
|
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:
|
ext2_test_superblock:
|
||||||
cmp [fs_type], 0x83
|
cmp [fs_type], 0x83
|
||||||
@ -111,6 +174,24 @@ ext2_test_superblock:
|
|||||||
|
|
||||||
ext2_setup:
|
ext2_setup:
|
||||||
mov [fs_type], 2
|
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]
|
mov ecx, [ebx+24]
|
||||||
inc ecx
|
inc ecx
|
||||||
mov [ext2_data.log_block_size], ecx ; 1, 2, 3, 4 equ 1kb, 2kb, 4kb, 8kb
|
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
|
shl eax, 2
|
||||||
mov [ext2_data.block_size], eax
|
mov [ext2_data.block_size], eax
|
||||||
|
|
||||||
push eax eax eax ; 3 kernel_alloc
|
push eax eax ; 2 kernel_alloc
|
||||||
|
|
||||||
mov eax, edx
|
mov eax, edx
|
||||||
mul edx
|
mul edx
|
||||||
mov [ext2_data.count_pointer_in_block_square], eax
|
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
|
call kernel_alloc
|
||||||
mov [ext2_data.ext2_save_block], eax ; and for temp block
|
mov [ext2_data.ext2_save_block], eax ; and for temp block
|
||||||
call kernel_alloc
|
call kernel_alloc
|
||||||
@ -142,16 +221,11 @@ ext2_setup:
|
|||||||
movzx ebp, word [ebx+88]
|
movzx ebp, word [ebx+88]
|
||||||
mov ecx, [ebx+32]
|
mov ecx, [ebx+32]
|
||||||
mov edx, [ebx+40]
|
mov edx, [ebx+40]
|
||||||
mov eax, [ebx+20] ; first_data_block
|
|
||||||
|
|
||||||
mov [ext2_data.inode_size], ebp
|
mov [ext2_data.inode_size], ebp
|
||||||
mov [ext2_data.blocks_per_group], ecx
|
mov [ext2_data.blocks_per_group], ecx
|
||||||
mov [ext2_data.inodes_per_group], edx
|
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
|
push ebp ebp ebp ;3 kernel_alloc
|
||||||
call kernel_alloc
|
call kernel_alloc
|
||||||
mov [ext2_data.ext2_save_inode], eax
|
mov [ext2_data.ext2_save_inode], eax
|
||||||
@ -163,6 +237,7 @@ ext2_setup:
|
|||||||
mov ebx, eax
|
mov ebx, eax
|
||||||
mov eax, EXT2_ROOT_INO
|
mov eax, EXT2_ROOT_INO
|
||||||
call ext2_get_inode ; read root inode
|
call ext2_get_inode ; read root inode
|
||||||
|
|
||||||
jmp return_from_part_set
|
jmp return_from_part_set
|
||||||
|
|
||||||
;==================================================================
|
;==================================================================
|
||||||
@ -249,7 +324,6 @@ ext2_get_inode_block:
|
|||||||
mov ecx, dword [ebp + EXT2_INODE_STRUC.i_block + ecx*4]
|
mov ecx, dword [ebp + EXT2_INODE_STRUC.i_block + ecx*4]
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
;===================================================================
|
;===================================================================
|
||||||
;get content inode by num
|
;get content inode by num
|
||||||
;in: eax = inode_num
|
;in: eax = inode_num
|
||||||
@ -257,18 +331,28 @@ ext2_get_inode_block:
|
|||||||
ext2_get_inode:
|
ext2_get_inode:
|
||||||
|
|
||||||
pushad
|
pushad
|
||||||
mov edi, ebx ;сохраним адрес inode
|
mov edi, ebx ;сохраним адрес inode
|
||||||
dec eax
|
dec eax
|
||||||
xor edx, edx
|
xor edx, edx
|
||||||
div [ext2_data.inodes_per_group]
|
div [ext2_data.inodes_per_group]
|
||||||
|
|
||||||
push edx ;locale num
|
push edx ;locale num in group
|
||||||
|
|
||||||
mov edx, 32
|
mov edx, 32
|
||||||
mul edx ; address block_group in global_desc_table
|
mul edx ; address block_group in global_desc_table
|
||||||
|
|
||||||
add eax, [ext2_data.global_desc_table]
|
; в eax - смещение группы с inode-ом относительно начала глобальной дескрипторной таблицы
|
||||||
mov eax, [eax+8] ; номер блока - в терминах ext2
|
; найдем блок в котором он находится
|
||||||
|
|
||||||
|
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]
|
mov ecx, [ext2_data.log_block_size]
|
||||||
shl eax, cl
|
shl eax, cl
|
||||||
@ -434,11 +518,17 @@ ext2_HdReadFolder:
|
|||||||
dec ecx
|
dec ecx
|
||||||
@@:
|
@@:
|
||||||
movzx ebx, [eax+EXT2_DIR_STRUC.rec_len]
|
movzx ebx, [eax+EXT2_DIR_STRUC.rec_len]
|
||||||
|
|
||||||
|
cmp ebx, 12 ; минимальная длина записи
|
||||||
|
jb .end_error
|
||||||
|
test ebx, 0x3 ; длина записи должна делиться на 4
|
||||||
|
jnz .end_error
|
||||||
|
|
||||||
add eax, ebx ; к следующей записи
|
add eax, ebx ; к следующей записи
|
||||||
cmp eax, [EXT2_end_block] ; проверяем "конец"
|
cmp eax, [EXT2_end_block] ; проверяем "конец"
|
||||||
jb .find_wanted_start
|
jb .find_wanted_start
|
||||||
|
|
||||||
push .find_wanted_start
|
push .find_wanted_start
|
||||||
.end_block: ;вылетили из цикла
|
.end_block: ;вылетили из цикла
|
||||||
mov ebx, [ext2_data.count_block_in_block]
|
mov ebx, [ext2_data.count_block_in_block]
|
||||||
sub [EXT2_counter_blocks], ebx
|
sub [EXT2_counter_blocks], ebx
|
||||||
@ -534,6 +624,11 @@ ext2_HdReadFolder:
|
|||||||
dec ecx ; если запись пустая ecx не надо уменьшать
|
dec ecx ; если запись пустая ecx не надо уменьшать
|
||||||
.empty_rec:
|
.empty_rec:
|
||||||
movzx ebx, [eax + EXT2_DIR_STRUC.rec_len]
|
movzx ebx, [eax + EXT2_DIR_STRUC.rec_len]
|
||||||
|
cmp ebx, 12 ; минимальная длина записи
|
||||||
|
jb .end_error
|
||||||
|
test ebx, 0x3 ; длина записи должна делиться на 4
|
||||||
|
jnz .end_error
|
||||||
|
|
||||||
add eax, ebx
|
add eax, ebx
|
||||||
cmp eax, [EXT2_end_block]
|
cmp eax, [EXT2_end_block]
|
||||||
jb .wanted_start
|
jb .wanted_start
|
||||||
@ -543,6 +638,7 @@ ext2_HdReadFolder:
|
|||||||
|
|
||||||
.end_dir:
|
.end_dir:
|
||||||
pop eax ; мусор (адрес возврата в цикл)
|
pop eax ; мусор (адрес возврата в цикл)
|
||||||
|
.end_error:
|
||||||
pop edx
|
pop edx
|
||||||
mov ebx, [EXT2_read_in_folder]
|
mov ebx, [EXT2_read_in_folder]
|
||||||
mov ecx, [EXT2_files_in_folder]
|
mov ecx, [EXT2_files_in_folder]
|
||||||
@ -658,7 +754,7 @@ ext2_HdRead:
|
|||||||
|
|
||||||
.size_less:
|
.size_less:
|
||||||
xor ebx, ebx
|
xor ebx, ebx
|
||||||
mov eax, 6 ;EOF
|
mov eax, ERROR_END_OF_FILE
|
||||||
ret
|
ret
|
||||||
.size_great:
|
.size_great:
|
||||||
add eax, ecx ;add to first_wanted кол-во байт для чтения
|
add eax, ecx ;add to first_wanted кол-во байт для чтения
|
||||||
@ -758,7 +854,7 @@ ext2_HdRead:
|
|||||||
cmp [EXT2_files_in_folder], 0
|
cmp [EXT2_files_in_folder], 0
|
||||||
jz @F
|
jz @F
|
||||||
|
|
||||||
mov eax, 6 ;EOF
|
mov eax, ERROR_END_OF_FILE
|
||||||
ret
|
ret
|
||||||
@@:
|
@@:
|
||||||
xor eax, eax
|
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:
|
ext2_HdGetFileInfo:
|
||||||
cmp byte [esi], 0
|
cmp byte [esi], 0
|
||||||
@ -893,14 +973,346 @@ ext2_HdGetFileInfo:
|
|||||||
xor eax, eax
|
xor eax, eax
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
ext2_HdRewrite:
|
||||||
|
ext2_HdWrite:
|
||||||
|
ext2_HdSetFileEnd:
|
||||||
ext2_HdSetFileInfo:
|
ext2_HdSetFileInfo:
|
||||||
; xchg bx, bx
|
ext2_HdDelete:
|
||||||
|
ext2_HdCreateFolder:
|
||||||
xor ebx, ebx
|
xor ebx, ebx
|
||||||
mov eax, ERROR_UNSUPPORTED_FS
|
mov eax, ERROR_UNSUPPORTED_FS
|
||||||
ret
|
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
|
xor ebx, ebx
|
||||||
mov eax, ERROR_UNSUPPORTED_FS
|
mov eax, ERROR_UNSUPPORTED_FS
|
||||||
ret
|
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_save_block dd ? ; ¡«®ª £«®¡ «ìãî 1 ¯à®æ¥¤ãàã
|
||||||
.ext2_temp_block dd ? ; ¡«®ª ¤«ï ¬¥«ª¨å ¯à®æ¥¤ãà
|
.ext2_temp_block dd ? ; ¡«®ª ¤«ï ¬¥«ª¨å ¯à®æ¥¤ãà
|
||||||
.ext2_save_inode dd ? ; inode £«®¡ «ìãî ¯à®æ¥¤ãàã
|
.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
|
if $ > fs_dependent_data_end
|
||||||
ERROR: increase sizeof(fs_dependent_data)!
|
ERROR: increase sizeof(fs_dependent_data)!
|
||||||
end if
|
end if
|
||||||
|
Loading…
Reference in New Issue
Block a user