From d205bffbfaf47cb855c3f11c4e853737552bec48 Mon Sep 17 00:00:00 2001 From: turbanoff Date: Wed, 25 Jul 2012 16:26:11 +0000 Subject: [PATCH] ext4 support git-svn-id: svn://kolibrios.org@2889 a494cfbc-eb01-0410-851d-a64ba20cac60 --- kernel/trunk/fs/ext2.inc | 1209 ++++++++++++++++------------------ kernel/trunk/fs/fat32.inc | 13 - kernel/trunk/fs/fs_lfn.inc | 13 + kernel/trunk/fs/part_set.inc | 1 - 4 files changed, 574 insertions(+), 662 deletions(-) diff --git a/kernel/trunk/fs/ext2.inc b/kernel/trunk/fs/ext2.inc index 838c24e75f..77f7a265a7 100644 --- a/kernel/trunk/fs/ext2.inc +++ b/kernel/trunk/fs/ext2.inc @@ -10,51 +10,38 @@ $Revision$ -EXT2_BAD_INO = 1 +EXT2_BAD_INO = 1 EXT2_ROOT_INO = 2 -EXT2_ACL_IDX_INO = 3 +EXT2_ACL_IDX_INO = 3 EXT2_ACL_DATA_INO = 4 -EXT2_BOOT_LOADER_INO= 5 -EXT2_UNDEL_DIR_INO = 6 +EXT2_BOOT_LOADER_INO = 5 +EXT2_UNDEL_DIR_INO = 6 -;type inode -EXT2_S_IFREG = 0x8000 -EXT2_S_IFDIR = 0x4000 -;user inode right's -EXT2_S_IRUSR = 0x0100 -EXT2_S_IWUSR = 0x0080 -EXT2_S_IXUSR = 0x0040 -;group inode right's -EXT2_S_IRGRP = 0x0020 -EXT2_S_IWGRP = 0x0010 -EXT2_S_IXGRP = 0x0008 -;other inode right's -EXT2_S_IROTH = 0x0004 -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 +;флаги, указываемый в inode файла +EXT2_S_IFREG = 0x8000 +EXT2_S_IFDIR = 0x4000 -EXT2_FT_REG_FILE = 1 ;это файл, запись в родительском каталоге -EXT2_FT_DIR = 2 ;это папка +;флаги, указываемые в linked list родительской папки +EXT2_FT_REG_FILE = 1 ;это файл, запись в родительском каталоге +EXT2_FT_DIR = 2 ;это папка -FS_FT_HIDDEN = 2 -FS_FT_DIR = 0x10 ;это папка -FS_FT_ASCII = 0 ;имя в ascii -FS_FT_UNICODE = 1 ;имя в unicode +;флаги используемые KolibriOS +FS_FT_HIDDEN = 2 +FS_FT_DIR = 0x10 ;это папка +FS_FT_ASCII = 0 ;имя в ascii +FS_FT_UNICODE = 1 ;имя в unicode -EXT2_FEATURE_INCOMPAT_FILETYPE = 0x0002 +EXT2_FEATURE_INCOMPAT_FILETYPE = 0x0002 ;тип файла должен указываться в директории +EXT4_FEATURE_INCOMPAT_EXTENTS = 0x0040 ;экстенты +EXT4_FEATURE_INCOMPAT_FLEX_BG = 0x0200 ;гибкие группы блоков +;реализованные ext[234] features +EXT4_FEATURE_INCOMPAT_SUPP = EXT2_FEATURE_INCOMPAT_FILETYPE \ + or EXT4_FEATURE_INCOMPAT_EXTENTS \ + or EXT4_FEATURE_INCOMPAT_FLEX_BG -uglobal - EXT2_files_in_folder dd ? ;всего файлов в папке - EXT2_read_in_folder dd ? ;сколько файлов "считали" - EXT2_end_block dd ? ;конец очередного блока папки - EXT2_counter_blocks dd ? - EXT2_filename rb 256 - EXT2_parent_name rb 256 - EXT2_name_len dd ? -endg + +;флаги, указываемые для inode в i_flags +EXT2_EXTENTS_FL = 0x00080000 struct EXT2_INODE_STRUC i_mode dw ? @@ -86,12 +73,14 @@ struct EXT2_DIR_STRUC 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 ? + block_bitmap dd ? ;+0 + inode_bitmap dd ? ;+4 + inode_table dd ? ;+8 + free_blocks_count dw ? ;+12 + free_inodes_count dw ? ;+14 + used_dirs_count dw ? ;+16 + pad dw ? ;+18 + reserved rb 12;+20 ends struct EXT2_SB_STRUC @@ -132,7 +121,7 @@ struct EXT2_SB_STRUC algo_bitmap dd ? ;+200 prealloc_blocks db ? ;+204 preallock_dir_blocks db ? ;+205 - dw ? ;+206 alignment + reserved_gdt_blocks dw ? ;+206 journal_uuid rb 16 ;+208 journal_inum dd ? ;+224 journal_dev dd ? ;+228 @@ -142,6 +131,41 @@ struct EXT2_SB_STRUC rb 3 ;+253 reserved default_mount_options dd ? ;+256 first_meta_bg dd ? ;+260 + mkfs_time dd ? ;+264 + jnl_blocks rd 17 ;+268 + blocks_count_hi dd ? ;+336 + r_blocks_count_hi dd ? ;+340 + free_blocks_count_hi dd ? ;+344 + min_extra_isize dw ? ;+348 + want_extra_isize dw ? ;+350 + flags dd ? ;+352 + raid_stride dw ? ;+356 + mmp_interval dw ? ;+358 + mmp_block dq ? ;+360 + raid_stripe_width dd ? ;+368 + log_groups_per_flex db ? ;+372 +ends + +struct EXT4_EXTENT_HEADER ;заголовок блока экстентов/индексов + eh_magic dw ? ;в текущей реализации ext4 должно быть 0xF30A + eh_entries dw ? ;количество экстентов/индексов в блоке + eh_max dw ? ;max количество (используется при записи) + eh_depth dw ? ;глубина дерева (0, если это блок экстентов) + eh_generation dd ? ;??? +ends + +struct EXT4_EXTENT ;экстент + ee_block dd ? ;номер ext4 блока + ee_len dw ? ;длина экстента + ee_start_hi dw ? ;старшие 16 бит 48-битного адреса (пока не используются в KOS) + ee_start_lo dd ? ;младшие 32 бита 48-битного адреса +ends + +struct EXT4_EXTENT_IDX ;индес - указатель на блок с экстентами/индексами + ei_block dd ? ;номер ext4 блока + ei_leaf_lo dd ? ;младшие 32 бит 48-битного адреса + ei_leaf_hi dw ? ;старшие 16 бит 48-битного адреса (пока не используются в KOS) + ei_unused dw ? ;зарезервировано ends ext2_test_superblock: @@ -152,16 +176,19 @@ ext2_test_superblock: add eax, 2 ;superblock start at 1024b call hd_read - cmp dword [ebx+24], 3 ;s_block_size 0,1,2,3 + cmp [ebx + EXT2_SB_STRUC.log_block_size], 3 ;0,1,2,3 ja .no - cmp word [ebx+56], 0xEF53 ;s_magic + cmp [ebx + EXT2_SB_STRUC.magic], 0xEF53 jne .no - cmp word [ebx+58], 1 ;s_state (EXT_VALID_FS=1) + cmp [ebx + EXT2_SB_STRUC.state], 1 ;EXT_VALID_FS=1 jne .no - mov eax, [ebx+96] + cmp [ebx + EXT2_SB_STRUC.inodes_per_group], 0 + je .no + + mov eax, [ebx + EXT2_SB_STRUC.feature_incompat] test eax, EXT2_FEATURE_INCOMPAT_FILETYPE jz .no - test eax, not EXT2_FEATURE_INCOMPAT_FILETYPE + test eax, not EXT4_FEATURE_INCOMPAT_SUPP jnz .no ; OK, this is correct EXT2 superblock @@ -192,7 +219,7 @@ ext2_setup: inc eax mov [ext2_data.groups_count], eax - mov ecx, [ebx+24] + mov ecx, [ebx + EXT2_SB_STRUC.log_block_size] inc ecx mov [ext2_data.log_block_size], ecx ; 1, 2, 3, 4 equ 1kb, 2kb, 4kb, 8kb @@ -218,13 +245,11 @@ ext2_setup: call kernel_alloc mov [ext2_data.ext2_temp_block], eax ; and for get_inode proc - movzx ebp, word [ebx+88] - mov ecx, [ebx+32] - mov edx, [ebx+40] + movzx ebp, word [ebx + EXT2_SB_STRUC.inode_size] + mov ecx, [ebx + EXT2_SB_STRUC.blocks_per_group] mov [ext2_data.inode_size], ebp mov [ext2_data.blocks_per_group], ecx - mov [ext2_data.inodes_per_group], edx push ebp ebp ebp ;3 kernel_alloc call kernel_alloc @@ -241,31 +266,130 @@ ext2_setup: jmp return_from_part_set ;================================================================== -;in: eax = i_block -; ebx = pointer to return memory +;read ext2 block form FS to memory +;in: eax = i_block (address of block in ext2 terms) +; ebx = pointer to return memory +;out: eax - error code (0 = no_error) ext2_get_block: - push eax ebx ecx + push 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_read + cmp [hd_error], 0 + jnz .fail inc eax add ebx, 512 loop @B - pop ecx ebx eax + xor eax, eax + @@: + pop ecx ebx ret + .fail: + mov eax, ERROR_DEVICE + jmp @B + + ;=================================================================== -; in: ecx = номер блока в inode (0..) -; ebp = адрес inode -; out: ecx = адрес очередного блока +;получает номер блока из extent inode +;in: ecx = номер блока по порядку +; ebp = адрес extent header`а +;out: ecx - адрес очередного блока в случае успеха +; eax - номер ошибки (если равно 0, то ошибки нет) +ext4_block_recursive_search: + cmp word [ebp + EXT4_EXTENT_HEADER.eh_magic], 0xF30A ;EXT4_EXT_MAGIC + jne .fail + + movzx ebx, [ebp + EXT4_EXTENT_HEADER.eh_entries] + add ebp, sizeof.EXT4_EXTENT_HEADER + cmp word [ebp - sizeof.EXT4_EXTENT_HEADER + EXT4_EXTENT_HEADER.eh_depth], 0 + je .leaf_block ;листовой ли это блок? + + ;не листовой блок, а индексный ; eax - ext4_extent_idx + test ebx, ebx + jz .fail ;пустой индексный блок -> ошибка + + ;цикл по индексам экстентов + @@: + cmp ebx, 1 ;у индексов не хранится длина, + je .end_search_index ;поэтому, если остался последний - то это нужный + + cmp ecx, [ebp + EXT4_EXTENT_IDX.ei_block] + jb .fail + + cmp ecx, [ebp + sizeof.EXT4_EXTENT_IDX + EXT4_EXTENT_IDX.ei_block] ;блок слeдующего индекса + jb .end_search_index ;следующий дальше - значит текущий, то что нам нужен + + add ebp, sizeof.EXT4_EXTENT_IDX + dec ebx + jmp @B + + .end_search_index: + ;ebp указывает на нужный extent_idx, считываем следующий блок + mov ebx, [ext2_data.ext2_temp_block] + mov eax, [ebp + EXT4_EXTENT_IDX.ei_leaf_lo] + call ext2_get_block + test eax, eax + jnz .fail + mov ebp, ebx + jmp ext4_block_recursive_search ;рекурсивно прыгаем в начало + + .leaf_block: ;листовой блок ebp - ext4_extent + ;цикл по экстентам + @@: + test ebx, ebx + jz .fail ;ни один узел не подошел - ошибка + + mov edx, [ebp + EXT4_EXTENT.ee_block] + cmp ecx, edx + jb .fail ;если меньше, значит он был в предыдущих блоках -> ошибка + + movzx edi, [ebp + EXT4_EXTENT.ee_len] + add edx, edi + cmp ecx, edx + jb .end_search_extent ;нашли нужный блок + + add ebp, sizeof.EXT4_EXTENT + dec ebx + jmp @B + + .end_search_extent: + mov edx, [ebp + EXT4_EXTENT.ee_start_lo] + sub ecx, [ebp + EXT4_EXTENT.ee_block] ;разница в ext4 блоках + add ecx, edx + xor eax, eax + ret + + .fail: + mov eax, ERROR_FS_FAIL + ret + +;=================================================================== +;получает адрес ext2 блока из inode с определнным номером +;in: ecx = номер блока в inode (0..) +; ebp = адрес inode +;out: ecx = адрес очередного блока +; eax - error code ext2_get_inode_block: + test [ebp + EXT2_INODE_STRUC.i_flags], EXT2_EXTENTS_FL + jz @F + + pushad + add ebp, EXT2_INODE_STRUC.i_block ;ebp - extent_header + call ext4_block_recursive_search + mov PUSHAD_ECX, ecx + mov PUSHAD_EAX, eax + popad + ret + + @@: cmp ecx, 12 ; 0..11 - direct block address jb .get_direct_block sub ecx, 12 - cmp ecx, [ext2_data.count_pointer_in_block] ; 12.. - indirect block + cmp ecx, [ext2_data.count_pointer_in_block] ; 12.. - indirect blocks jb .get_indirect_block sub ecx, [ext2_data.count_pointer_in_block] @@ -273,12 +397,14 @@ ext2_get_inode_block: jb .get_double_indirect_block sub ecx, [ext2_data.count_pointer_in_block_square] - ;.get_triple_indirect_block: - push eax edx ebx + ;triple indirect block + push edx ebx mov eax, [ebx + EXT2_INODE_STRUC.i_block + 14*4] mov ebx, [ext2_data.ext2_temp_block] call ext2_get_block + test eax, eax + jnz .fail xor edx, edx mov eax, ecx @@ -287,54 +413,67 @@ ext2_get_inode_block: ;eax - номер в полученном блоке edx - номер дальше mov eax, [ebx + eax*4] call ext2_get_block + test eax, eax + jnz .fail mov eax, edx jmp @F .get_double_indirect_block: - push eax edx ebx + push edx ebx mov eax, [ebp + EXT2_INODE_STRUC.i_block + 13*4] mov ebx, [ext2_data.ext2_temp_block] call ext2_get_block + test eax, eax + jnz .fail mov eax, ecx - @@: + @@: xor edx, edx div [ext2_data.count_pointer_in_block] mov eax, [ebx + eax*4] call ext2_get_block - mov ecx, [ebx + edx*4] + test eax, eax + jnz .fail - pop ebx edx eax + mov ecx, [ebx + edx*4] + .fail: + pop ebx edx ret .get_indirect_block: - push eax ebx + push ebx mov eax, [ebp + EXT2_INODE_STRUC.i_block + 12*4] mov ebx, [ext2_data.ext2_temp_block] call ext2_get_block + test eax, eax + jz @F ;если не было ошибки - mov ecx, [ebx + ecx*4] - pop ebx eax + mov ecx, [ebx + ecx*4] ;заносим результат + @@: + pop ebx ret .get_direct_block: - mov ecx, dword [ebp + EXT2_INODE_STRUC.i_block + ecx*4] + mov ecx, [ebp + EXT2_INODE_STRUC.i_block + ecx*4] + xor eax, eax ret ;=================================================================== ;get content inode by num -;in: eax = inode_num -; ebx = address of inode content +;in: eax = inode_num +; ebx = address of inode content +;out: eax - error code ext2_get_inode: - pushad mov edi, ebx ;сохраним адрес inode dec eax xor edx, edx - div [ext2_data.inodes_per_group] + + mov ecx, [ext2_data.sb] + div [ecx + EXT2_SB_STRUC.inodes_per_group] push edx ;locale num in group @@ -343,20 +482,20 @@ ext2_get_inode: ; в 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 + test eax, eax + jnz .fail add ebx, edx ; локальный номер в блоке - mov eax, [ebx+8] ; номер блока - в терминах ext2 + mov eax, [ebx + EXT2_BLOCK_GROUP_DESC.inode_table]; номер блока - в терминах ext2 mov ecx, [ext2_data.log_block_size] shl eax, cl - add eax, [PARTITION_START] ; а старт раздела - в терминах hdd (512) + add eax, [PARTITION_START] ; а старт раздела - в терминах hdd (512) ;eax - указывает на таблицу inode-ов на hdd mov esi, eax ;сохраним его пока в esi @@ -371,74 +510,18 @@ ext2_get_inode: add eax, esi ;нашли адрес блока для чтения mov ebx, [ext2_data.ext2_temp_block] call hd_read + cmp [hd_error], 0 + jnz .fail mov esi, edx ;добавим "остаток" add esi, ebx ;к адресу - ; mov ecx, [ext2_data.inode_size] rep movsb ;копируем inode + xor eax, eax + .fail: + mov PUSHAD_EAX, eax popad ret -;---------------------------------------------------------------- -; in: esi -> children -; ebx -> pointer to dir block -; out: esi -> name without parent or not_changed -; ebx -> dir_rec of inode children or trash -ext2_test_block_by_name: - push eax ecx edx edi - - mov edx, ebx - add edx, [ext2_data.block_size] ;запомним конец блока - - .start_rec: - cmp [ebx + EXT2_DIR_STRUC.inode], 0 - jz .next_rec - - push esi - movzx ecx, [ebx + EXT2_DIR_STRUC.name_len] - mov edi, EXT2_filename - lea esi, [ebx + EXT2_DIR_STRUC.name] - - call utf8toansi_str - mov ecx, edi - sub ecx, EXT2_filename ;кол-во байт в получившейся строке - - mov edi, EXT2_filename - mov esi, [esp] - @@: - jecxz .test_find - dec ecx - - lodsb - call char_toupper - - mov ah, [edi] - inc edi - xchg al, ah - call char_toupper - cmp al, ah - je @B - @@: ;не подошло - pop esi - .next_rec: - movzx eax, [ebx + EXT2_DIR_STRUC.rec_len] - add ebx, eax ;к след. записи - cmp ebx, edx ;проверим конец ли - jb .start_rec - jmp .ret - - .test_find: - cmp byte [esi], 0 - je .find ;нашли конец - cmp byte [esi], '/' - jne @B - inc esi - .find: - pop eax ;удаляем из стека сохраненое значение - .ret: - pop edi edx ecx eax - ret - ;---------------------------------------------------------------- ; ; ext2_HdReadFolder - read disk folder @@ -456,124 +539,141 @@ ext2_test_block_by_name: ;-------------------------------------------------------------- ext2_HdReadFolder: cmp byte [esi], 0 - jz .doit + jz .root_folder - push ecx ebx - call ext2_find_lfn - jnc .doit2 - pop ebx - .not_found: - pop ecx - or ebx, -1 - mov eax, ERROR_FILE_NOT_FOUND - ret - - .doit: - mov ebp, [ext2_data.root_inode] - push ecx - jmp @F - .doit2: - pop ebx + push ebx ecx edx + call ext2_find_lfn ;вернет в ebp адрес inode + pop edx ecx ebx + test eax, eax + jnz .error_ret test [ebp + EXT2_INODE_STRUC.i_mode], EXT2_S_IFDIR - jz .not_found + jz .error_not_found + jmp @F + + .root_folder: + mov ebp, [ext2_data.root_inode] + test [ebp + EXT2_INODE_STRUC.i_mode], EXT2_S_IFDIR + jz .error_root + ;придется копировать inode + push ecx + mov esi, ebp + mov edi, [ext2_data.ext2_save_inode] + mov ecx, [ext2_data.inode_size] + shr ecx, 2 + mov ebp, edi + rep movsd + pop ecx @@: - xor eax, eax + cmp [ebp + EXT2_INODE_STRUC.i_blocks], 0 ;папка пуста + je .error_empty_dir + + push edx ;адрес результата [edi + 28] + push 0 ;конец очередного блока папки [edi + 24] + push ecx ;сколько файлов нужно прочитать [edi + 20] + push dword [ebx] ;первый "нужный" файл [edi + 16] + push dword [ebx + 4];флаги [edi + 12] + push 0 ;[EXT2_read_in_folder] [edi + 8] + push 0 ;[EXT2_files_in_folder] [edi + 4] + push 0 ;номер блока по порядку [edi] + mov edi, edx mov ecx, 32/4 rep stosd ; fill header zero - pop edi ; edi = число блоков для чтения - push edx ebx + + mov edi, esp ; edi - указатель на локальные переменные + add edx, 32 ; edx = current mem for return - ;--------------------------------------------- final step - and [EXT2_read_in_folder], 0 - and [EXT2_files_in_folder], 0 - - mov eax, [ebp + EXT2_INODE_STRUC.i_blocks] - mov [EXT2_counter_blocks], eax - - add edx, 32 ; (header pointer in stack) edx = current mem for return - xor esi, esi ; esi = номер блока по порядку - - .new_block_folder: ;reserved label - mov ecx, esi ; получим номер блока + xor ecx, ecx ; получим номер первого блока call ext2_get_inode_block + test eax, eax + jnz .error_get_block mov eax, ecx mov ebx, [ext2_data.ext2_save_block] call ext2_get_block ; и считываем блок с hdd + test eax, eax + jnz .error_get_block - mov eax, ebx ; eax = current dir record + mov esi, ebx ; esi = current dir record add ebx, [ext2_data.block_size] - mov [EXT2_end_block], ebx ; запомним конец очередного блока + mov [edi + 24], ebx ; запомним конец очередного блока - pop ecx - mov ecx, [ecx] ; ecx = first wanted (flags ommited) + mov ecx, [edi + 16] ; ecx = first wanted (flags ommited) .find_wanted_start: jecxz .find_wanted_end .find_wanted_cycle: - cmp [eax + EXT2_DIR_STRUC.inode], 0 ; if (inode = 0) => not used + cmp [esi + EXT2_DIR_STRUC.inode], 0 ; if (inode = 0) => not used jz @F - inc [EXT2_files_in_folder] + inc dword [edi + 4] ; EXT2_files_in_folder dec ecx - @@: - movzx ebx, [eax+EXT2_DIR_STRUC.rec_len] + @@: + movzx ebx, [esi + EXT2_DIR_STRUC.rec_len] cmp ebx, 12 ; минимальная длина записи - jb .end_error + jb .error_bad_len test ebx, 0x3 ; длина записи должна делиться на 4 - jnz .end_error + jnz .error_bad_len - add eax, ebx ; к следующей записи - cmp eax, [EXT2_end_block] ; проверяем "конец" + add esi, ebx ; к следующей записи + cmp esi, [edi + 24] ; сравниваем с концом блока jb .find_wanted_start push .find_wanted_start - .end_block: ;вылетили из цикла + .end_block: ;вылетели из цикла mov ebx, [ext2_data.count_block_in_block] - sub [EXT2_counter_blocks], ebx - jbe .end_dir + sub [ebp + EXT2_INODE_STRUC.i_blocks], ebx ;вычитаем напрямую из структуры inode + jle .end_dir - inc esi ;получаем новый блок + inc dword [edi] ;получаем новый блок push ecx - mov ecx, esi + mov ecx, [edi] call ext2_get_inode_block + test eax, eax + jnz .error_get_block + mov eax, ecx mov ebx, [ext2_data.ext2_save_block] call ext2_get_block + test eax, eax + jnz .error_get_block + pop ecx - mov eax, ebx + mov esi, ebx add ebx, [ext2_data.block_size] - mov [EXT2_end_block], ebx - ret ; опять в цикл + mov [edi + 24], ebx ;запомним конец блока + ret ; опять в цикл .wanted_end: - loop .find_wanted_cycle ; ecx = -1 + loop .find_wanted_cycle ; ecx 0 => -1 нужно посчитать сколько файлов + ;дошли до первого "нужного" файла .find_wanted_end: - mov ecx, edi - .wanted_start: ; ищем first_wanted+count + mov ecx, [edi + 20] + .wanted_start: ; ищем first_wanted+count jecxz .wanted_end - cmp [eax + EXT2_DIR_STRUC.inode], 0 ; if (inode = 0) => not used + cmp [esi + EXT2_DIR_STRUC.inode], 0 ; if (inode = 0) => not used jz .empty_rec - inc [EXT2_files_in_folder] - inc [EXT2_read_in_folder] + inc dword [edi + 8] + inc dword [edi + 4] - mov edi, edx - push eax ecx + push edi ecx + mov edi, edx ;обнуляем место под очереное имя файла/папки xor eax, eax mov ecx, 40 / 4 rep stosd - pop ecx eax + pop ecx edi - push eax esi edx ;получим inode - mov eax, [eax + EXT2_DIR_STRUC.inode] + push esi edi edx + mov eax, [esi + EXT2_DIR_STRUC.inode] ;получим дочерний inode mov ebx, [ext2_data.ext2_temp_inode] call ext2_get_inode + test eax, eax + jnz .error_read_subinode lea edi, [edx + 8] - mov eax, [ebx + EXT2_INODE_STRUC.i_ctime] ; переведем время в ntfs формат + mov eax, [ebx + EXT2_INODE_STRUC.i_ctime] ; переведем время в ntfs формат xor edx, edx add eax, 3054539008 ;(369 * 365 + 89) * 24 * 3600 adc edx, 2 @@ -592,69 +692,88 @@ ext2_HdReadFolder: call ntfs_datetime_to_bdfe.sec pop edx ; пока достаем только буфер - test [ebx + EXT2_INODE_STRUC.i_mode], EXT2_S_IFDIR ; для папки размер + test [ebx + EXT2_INODE_STRUC.i_mode], EXT2_S_IFDIR ; для папки размер jnz @F ; не возвращаем - mov eax, [ebx + EXT2_INODE_STRUC.i_size] ;low size + mov eax, [ebx + EXT2_INODE_STRUC.i_size] ;low size stosd - mov eax, [ebx + EXT2_INODE_STRUC.i_dir_acl] ;high size + mov eax, [ebx + EXT2_INODE_STRUC.i_dir_acl] ;high size stosd - xor dword [edx], FS_FT_DIR - @@: - xor dword [edx], FS_FT_DIR - pop esi eax + xor dword [edx], FS_FT_DIR ;помечаем, что это файл(2 раза xor) + @@: + xor dword [edx], FS_FT_DIR ;помечаем, что это файл - or dword [edx+4], FS_FT_ASCII ; symbol type in name - - ;теперь скопируем имя, сконвертировав из UTF-8 в CP866 - push eax ecx esi - movzx ecx, [eax + EXT2_DIR_STRUC.name_len] + ;теперь скопируем имя, сконвертировав из UTF-8 в CP866 + push ecx ;edi и esi уже сохранены в стеке + movzx ecx, [esi + EXT2_DIR_STRUC.name_len] lea edi, [edx + 40] - lea esi, [eax + EXT2_DIR_STRUC.name] - call utf8toansi_str - pop esi ecx eax + lea esi, [esi + EXT2_DIR_STRUC.name] + call utf8_to_cp866 and byte [edi], 0 + pop ecx edi esi - cmp byte [edx + 40], '.' + cmp byte [edx + 40], '.' ; в linux файл, начинающийся с точки - скрытый jne @F or dword [edx], FS_FT_HIDDEN - @@: + @@: add edx, 40 + 264 ; go to next record dec ecx ; если запись пустая ecx не надо уменьшать - .empty_rec: - movzx ebx, [eax + EXT2_DIR_STRUC.rec_len] + .empty_rec: + movzx ebx, [esi + EXT2_DIR_STRUC.rec_len] cmp ebx, 12 ; минимальная длина записи - jb .end_error + jb .error_bad_len test ebx, 0x3 ; длина записи должна делиться на 4 - jnz .end_error + jnz .error_bad_len - add eax, ebx - cmp eax, [EXT2_end_block] + add esi, ebx + cmp esi, [edi + 24] ;дошли ли до конца блока? jb .wanted_start - push .wanted_start ; дошли до конца очередного блока + push .wanted_start ; дошли jmp .end_block - .end_dir: - pop eax ; мусор (адрес возврата в цикл) - .end_error: - pop edx - mov ebx, [EXT2_read_in_folder] - mov ecx, [EXT2_files_in_folder] + .end_dir: ;конец папки, когда еще не дошли до нужного файла + mov edx, [edi + 28] ;адрес структуры результата + mov ebx, [edi + 8] ;EXT2_read_in_folder + mov ecx, [edi + 4] ;EXT2_files_in_folder mov dword [edx], 1 ;version - xor eax, eax - mov [edx+4], ebx - mov [edx+8], ecx + mov [edx + 4], ebx + mov [edx + 8], ecx + + lea esp, [edi + 32] + + xor eax, eax ;зарезервировано: нули в текущей реализации lea edi, [edx + 12] mov ecx, 20 / 4 rep stosd ret -;====================== end ext2_HdReadFolder -utf8toansi_str: -; convert UTF-8 string to ASCII-string (codepage 866) -; in: ecx=length source, esi->source, edi->buffer + + .error_bad_len: + mov eax, ERROR_FS_FAIL + .error_read_subinode: + .error_get_block: + lea esp, [edi + 32] + .error_ret: + or ebx, -1 + ret + + .error_empty_dir: ;inode папки без блоков + .error_root: ;root - не папка + mov eax, ERROR_FS_FAIL + jmp .error_ret + + .error_not_found: ;файл не найден + mov eax, ERROR_FILE_NOT_FOUND + jmp .error_ret + +;============================================ +;convert UTF-8 string to ASCII-string (codepage 866) +;in: ecx = length source +; esi = source +; edi = buffer ; destroys: eax,esi,edi +utf8_to_cp866: jecxz .ret .start: lodsw @@ -712,7 +831,7 @@ utf8toansi_str: ; ; ret ebx = bytes read or 0xffffffff file not found ; eax = 0 ok read or other = errormsg -; + ;-------------------------------------------------------------- ext2_HdRead: cmp byte [esi], 0 @@ -724,27 +843,29 @@ ext2_HdRead: ret @@: - push ecx ebx + push ecx ebx edx call ext2_find_lfn - pop ebx ecx - jnc .doit - ;.not_found: + pop edx ebx ecx + test eax, eax + jz @F + or ebx, -1 mov eax, ERROR_FILE_NOT_FOUND ret - .doit: + @@: test [ebp + EXT2_INODE_STRUC.i_mode], EXT2_S_IFREG jz .this_is_nofile - ;-----------------------------------------------------------------------------final step mov edi, edx ; edi = pointer to return mem - mov esi, ebx ; esi = pointer to first_wanted - ;///// сравним хватит ли нам файла или нет + test ebx, ebx + jz @F + mov esi, ebx ; esi = pointer to first_wanted mov ebx, [esi+4] mov eax, [esi] ; ebx : eax - стартовый номер байта + ;///// сравним хватит ли нам файла или нет cmp [ebp + EXT2_INODE_STRUC.i_dir_acl], ebx ja .size_great jb .size_less @@ -756,6 +877,10 @@ ext2_HdRead: xor ebx, ebx mov eax, ERROR_END_OF_FILE ret + + @@: + xor ebx, ebx + xor eax, eax .size_great: add eax, ecx ;add to first_wanted кол-во байт для чтения adc ebx, 0 @@ -764,35 +889,45 @@ ext2_HdRead: ja .size_great_great jb .size_great_less cmp [ebp + EXT2_INODE_STRUC.i_size], eax - jae .size_great_great ; а если равно, то не важно куда + jae .size_great_great .size_great_less: - or [EXT2_files_in_folder], 1 ;читаем по границе размера + push 1 +; or [EXT2_files_in_folder], 1 ;читаем по границе размера mov ecx, [ebp + EXT2_INODE_STRUC.i_size] - sub ecx, [esi] ;(размер - старт) + sub ecx, [esi] ;(размер - старт) = сколько читать jmp @F .size_great_great: - and [EXT2_files_in_folder], 0 ;читаем столько сколько запросили + push 0 +; and [EXT2_files_in_folder], 0 ;читаем столько сколько запросили @@: - push ecx ;save for return + ;здесь мы точно знаем сколько байт читать - ecx + ;edi - return memory + ;esi -> first wanted + + push ecx ;количество считанных байт test esi, esi jz .zero_start - ;пока делаем п..ц криво =) + ;получим кусок из первого блока mov edx, [esi+4] mov eax, [esi] div [ext2_data.block_size] - mov [EXT2_counter_blocks], eax ;номер блока запоминаем - + push eax ;номер блока запоминаем + push ecx mov ecx, eax call ext2_get_inode_block + test eax, eax + jnz .error_at_first_block mov ebx, [ext2_data.ext2_save_block] mov eax, ecx call ext2_get_block + test eax, eax + jnz .error_at_first_block pop ecx add ebx, edx @@ -807,25 +942,30 @@ ext2_HdRead: mov esi, ebx rep movsb ;кусок 1-го блока - jmp @F + jmp .calc_blocks_count .zero_start: mov eax, ecx + push 0 ;счетчик блоков ;теперь в eax кол-во оставшихся байт для чтения - @@: + .calc_blocks_count: mov ebx, edi ;чтение блока прям в ->ebx xor edx, edx - div [ext2_data.block_size] ;кол-во байт в последнем блоке (остаток) в edx + div [ext2_data.block_size] ;кол-во байт в последнем блоке (остаток) в edx mov edi, eax ;кол-во целых блоков в edi @@: test edi, edi jz .finish_block - inc [EXT2_counter_blocks] - mov ecx, [EXT2_counter_blocks] + inc dword [esp] + mov ecx, [esp] call ext2_get_inode_block + test eax, eax + jnz .error_at_read_cycle mov eax, ecx ;а ebx уже забит нужным значением call ext2_get_block + test eax, eax + jnz .error_at_read_cycle add ebx, [ext2_data.block_size] dec edi @@ -835,23 +975,26 @@ ext2_HdRead: test edx, edx jz .end_read - mov ecx, [EXT2_counter_blocks] + pop ecx ;счетчик блоков -> ecx inc ecx call ext2_get_inode_block + test eax, eax + jz .error_at_finish_block mov edi, ebx mov eax, ecx mov ebx, [ext2_data.ext2_save_block] call ext2_get_block + test eax, eax + jnz .error_at_finish_block - mov ecx, edx - - .only_one_block: + mov ecx, edx mov esi, ebx rep movsb ;кусок last блока .end_read: pop ebx - cmp [EXT2_files_in_folder], 0 + pop eax + test eax, eax jz @F mov eax, ERROR_END_OF_FILE @@ -859,85 +1002,189 @@ ext2_HdRead: @@: xor eax, eax ret + + .only_one_block: + mov esi, ebx + rep movsb ;кусок last блока + pop eax + jmp .end_read + + .error_at_first_block: + pop edx + .error_at_read_cycle: + pop ebx + .error_at_finish_block: + pop ecx edx + or ebx, -1 + ret + +;---------------------------------------------------------------- +; in: esi = file path +; ebx = pointer to dir block +; out: esi - name without parent or not_changed +; ebx - dir_rec of inode children +ext2_test_block_by_name: + sub esp, 256 ;EXT2_filename + mov edx, ebx + add edx, [ext2_data.block_size] ;запомним конец блока + + .start_rec: + cmp [ebx + EXT2_DIR_STRUC.inode], 0 + jz .next_rec + + mov edi, esp + push esi + movzx ecx, [ebx + EXT2_DIR_STRUC.name_len] + lea esi, [ebx + EXT2_DIR_STRUC.name] + call utf8_to_cp866 + + mov ecx, edi + lea edi, [esp + 4] + sub ecx, edi ;кол-во байт в получившейся строке + + mov esi, [esp] + @@: + jecxz .test_find + dec ecx + + lodsb + call char_toupper + + mov ah, [edi] + inc edi + xchg al, ah + call char_toupper + cmp al, ah + je @B + @@: ;не подошло + pop esi + .next_rec: + movzx eax, [ebx + EXT2_DIR_STRUC.rec_len] + add ebx, eax ;к след. записи + cmp ebx, edx ;проверим конец ли + jb .start_rec + add esp, 256 + ret + + .test_find: + cmp byte [esi], 0 + je .ret ;нашли конец + cmp byte [esi], '/' + jne @B + inc esi + .ret: + add esp, 256 + 4 + ret + ;======================== -;in : esi -> name not save: eax ebx ecx -;out: ebp -> inode cf=0 -; ebp -> trash cf=1 +;Ищет inode по строке пути +;in: esi = name +;out: eax - error code +; ebp = inode +; dl - первый байт из имени файла/папки ext2_find_lfn: mov ebp, [ext2_data.root_inode] - .next_folder: - or [EXT2_counter_blocks], -1 ;счетчик блоков папки cur block of inode - mov eax, [ebp + EXT2_INODE_STRUC.i_blocks] ;убывающий счетчик блоков - add eax, [ext2_data.count_block_in_block] - mov [EXT2_end_block], eax - .next_block_folder: - mov eax, [ext2_data.count_block_in_block] - sub [EXT2_end_block], eax - jz .not_found - inc [EXT2_counter_blocks] - mov ecx, [EXT2_counter_blocks] + cmp [ebp + EXT2_INODE_STRUC.i_blocks], 0 + je .error_empty_root + + .next_path_part: + push [ebp + EXT2_INODE_STRUC.i_blocks] + xor ecx, ecx + .folder_block_cycle: call ext2_get_inode_block - + test eax, eax + jnz .error_get_inode_block + mov eax, ecx mov ebx, [ext2_data.ext2_save_block] ;ebx = cur dir record call ext2_get_block - - mov eax, esi + test eax, eax + jnz .error_get_block + + push esi call ext2_test_block_by_name - cmp eax, esi ;нашли имя? - jz .next_block_folder + pop edi - cmp byte [esi], 0 + cmp edi, esi ;нашли имя? + je .next_folder_block ;не нашли -> к след. блоку + + cmp byte [esi], 0 ;дошли до "конца" пути -> возваращаемся jz .get_inode_ret - cmp [ebx + EXT2_DIR_STRUC.file_type], EXT2_FT_DIR - jne .not_found ;нашли, но это не папка + cmp [ebx + EXT2_DIR_STRUC.file_type], EXT2_FT_DIR ;нашли, но это не папка + jne .not_found + mov eax, [ebx + EXT2_DIR_STRUC.inode] mov ebx, [ext2_data.ext2_save_inode] ;все же папка. call ext2_get_inode + test eax, eax + jnz .error_get_inode + pop ecx ;в стеке лежит кол-во блоков mov ebp, ebx - jmp .next_folder + jmp .next_path_part + + .next_folder_block: + ;к следующему блоку в текущей папке + pop eax ;счетчик блоков + sub eax, [ext2_data.count_block_in_block] + jle .not_found + + inc ecx + jmp .folder_block_cycle .not_found: - stc + pop ebx + mov eax, ERROR_FILE_NOT_FOUND ret + .get_inode_ret: - mov [EXT2_end_block], ebx ; сохраняем указатеть на dir_rec + pop ecx ;в стеке лежит кол-во блоков + mov dl, [ebx + EXT2_DIR_STRUC.name] ;в dl - первый символ () mov eax, [ebx + EXT2_DIR_STRUC.inode] mov ebx, [ext2_data.ext2_save_inode] call ext2_get_inode mov ebp, ebx - clc + xor eax, eax ret + .error_get_inode_block: + .error_get_block: + .error_get_inode: + pop ebx + .error_empty_root: + mov eax, ERROR_FS_FAIL + ret -;======================== - +;---------------------------------------------------------------- +;ext2_HdGetFileInfo - read file info from block device +; +;in: esi points to filename +; edx mem location to return data +;-------------------------------------------------------------- ext2_HdGetFileInfo: + xchg bx, bx cmp byte [esi], 0 - jz .doit + jz .is_root + push edx call ext2_find_lfn - jnc .doit2 - ;.not_found: - mov eax, ERROR_FILE_NOT_FOUND + mov ebx, edx + pop edx + test eax, eax + jz @F ret - .doit: + .is_root: + xor ebx, ebx ;root не может быть скрытым mov ebp, [ext2_data.root_inode] - mov ebx, .doit ;неважно что лишь бы этому адресу не '.' - jmp @F - .doit2: - mov ebx, [EXT2_end_block] - add ebx, EXT2_DIR_STRUC.name @@: xor eax, eax mov edi, edx mov ecx, 40/4 rep stosd ; fill zero - cmp byte [ebx], '.' - jnz @F + cmp bl, '.' + jne @F or dword [edx], FS_FT_HIDDEN @@: @@ -952,19 +1199,19 @@ ext2_HdGetFileInfo: xor dword [edx], FS_FT_DIR lea edi, [edx + 8] - mov eax, [ebx + EXT2_INODE_STRUC.i_ctime] + mov eax, [ebp + EXT2_INODE_STRUC.i_ctime] xor edx, edx add eax, 3054539008 adc edx, 2 call ntfs_datetime_to_bdfe.sec - mov eax, [ebx + EXT2_INODE_STRUC.i_atime] + mov eax, [ebp + EXT2_INODE_STRUC.i_atime] xor edx, edx add eax, 3054539008 adc edx, 2 call ntfs_datetime_to_bdfe.sec - mov eax, [ebx + EXT2_INODE_STRUC.i_mtime] + mov eax, [ebp + EXT2_INODE_STRUC.i_mtime] xor edx, edx add eax, 3054539008 adc edx, 2 @@ -982,337 +1229,3 @@ ext2_HdCreateFolder: xor ebx, ebx mov eax, ERROR_UNSUPPORTED_FS ret -;---------------------------------------------------------------- -; -; 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 - diff --git a/kernel/trunk/fs/fat32.inc b/kernel/trunk/fs/fat32.inc index 6ad28b2a21..ec75ea0777 100644 --- a/kernel/trunk/fs/fat32.inc +++ b/kernel/trunk/fs/fat32.inc @@ -49,19 +49,6 @@ $Revision$ cache_max equ 1919 ; max. is 1919*512+0x610000=0x6ffe00 -ERROR_SUCCESS = 0 -ERROR_DISK_BASE = 1 -ERROR_UNSUPPORTED_FS = 2 -ERROR_UNKNOWN_FS = 3 -ERROR_PARTITION = 4 -ERROR_FILE_NOT_FOUND = 5 -ERROR_END_OF_FILE = 6 -ERROR_MEMORY_POINTER = 7 -ERROR_DISK_FULL = 8 -ERROR_FAT_TABLE = 9 -ERROR_ACCESS_DENIED = 10 -ERROR_DEVICE = 11 - PUSHAD_EAX equ [esp+28] PUSHAD_ECX equ [esp+24] PUSHAD_EDX equ [esp+20] diff --git a/kernel/trunk/fs/fs_lfn.inc b/kernel/trunk/fs/fs_lfn.inc index 608cf14977..e806af3e06 100644 --- a/kernel/trunk/fs/fs_lfn.inc +++ b/kernel/trunk/fs/fs_lfn.inc @@ -7,6 +7,19 @@ $Revision$ +ERROR_SUCCESS = 0 +ERROR_DISK_BASE = 1 +ERROR_UNSUPPORTED_FS = 2 +ERROR_UNKNOWN_FS = 3 +ERROR_PARTITION = 4 +ERROR_FILE_NOT_FOUND = 5 +ERROR_END_OF_FILE = 6 +ERROR_MEMORY_POINTER = 7 +ERROR_DISK_FULL = 8 +ERROR_FAT_TABLE = 9 ;deprecated +ERROR_FS_FAIL = 9 +ERROR_ACCESS_DENIED = 10 +ERROR_DEVICE = 11 image_of_eax EQU esp+32 image_of_ebx EQU esp+20 diff --git a/kernel/trunk/fs/part_set.inc b/kernel/trunk/fs/part_set.inc index d41626d1ba..3c1aa8b686 100644 --- a/kernel/trunk/fs/part_set.inc +++ b/kernel/trunk/fs/part_set.inc @@ -72,7 +72,6 @@ ext2_data: .block_size dd ? .count_block_in_block dd ? .blocks_per_group dd ? - .inodes_per_group dd ? .global_desc_table dd ? .root_inode dd ? ; pointer to root inode in memory .inode_size dd ?