From 9d022746fdb2a84669d2b016372d37df850e8909 Mon Sep 17 00:00:00 2001 From: CleverMouse <theclevermouse@yandex.ru> Date: Wed, 3 Sep 2014 12:11:19 +0000 Subject: [PATCH] disk cache: support for sector sizes other than 512 bytes git-svn-id: svn://kolibrios.org@5089 a494cfbc-eb01-0410-851d-a64ba20cac60 --- kernel/trunk/blkdev/disk.inc | 32 ++-- kernel/trunk/blkdev/disk_cache.inc | 260 +++++++++++++++++------------ kernel/trunk/fs/ext2/ext2.asm | 2 + kernel/trunk/fs/fat.inc | 3 + kernel/trunk/fs/ntfs.inc | 2 + kernel/trunk/fs/xfs.asm | 2 + 6 files changed, 176 insertions(+), 125 deletions(-) diff --git a/kernel/trunk/blkdev/disk.inc b/kernel/trunk/blkdev/disk.inc index b4b97497dc..605753d6a0 100644 --- a/kernel/trunk/blkdev/disk.inc +++ b/kernel/trunk/blkdev/disk.inc @@ -108,6 +108,7 @@ struct DISKCACHE data dd ? sad_size dd ? search_start dd ? + sector_size_log dd ? ends ; This structure represents a disk device and its media for the kernel. @@ -271,13 +272,13 @@ disk_list_mutex MUTEX endg iglobal -; The function 'disk_scan_partitions' needs three 512-byte buffers for +; The function 'disk_scan_partitions' needs three sector-sized buffers for ; MBR, bootsector and fs-temporary sector data. It can not use the static ; buffers always, since it can be called for two or more disks in parallel. ; However, this case is not typical. We reserve three static 512-byte buffers ; and a flag that these buffers are currently used. If 'disk_scan_partitions' ; detects that the buffers are currently used, it allocates buffers from the -; heap. +; heap. Also, the heap is used when sector size is other than 512. ; The flag is implemented as a global dword variable. When the static buffers ; are not used, the value is -1. When the static buffers are used, the value ; is normally 0 and temporarily can become greater. The function increments @@ -638,28 +639,25 @@ disk_scan_partitions: ; 1. Initialize .NumPartitions and .Partitions fields as zeros: empty list. and [esi+DISK.NumPartitions], 0 and [esi+DISK.Partitions], 0 -; 2. Currently we can work only with 512-bytes sectors. Check this restriction. -; The only exception is 2048-bytes CD/DVD, but they are not supported yet by -; this code. - cmp [esi+DISK.MediaInfo.SectorSize], 512 - jz .doscan - DEBUGF 1,'K : sector size is %d, only 512 is supported\n',[esi+DISK.MediaInfo.SectorSize] - ret -.doscan: -; 3. Acquire the buffer for MBR and bootsector tests. See the comment before +; 2. Acquire the buffer for MBR and bootsector tests. See the comment before ; the 'partition_buffer_users' variable. + mov eax, [esi+DISK.MediaInfo.SectorSize] + cmp eax, 512 + jnz @f mov ebx, mbr_buffer ; assume the global buffer is free lock inc [partition_buffer_users] jz .buffer_acquired ; yes, it is free lock dec [partition_buffer_users] ; no, we must allocate - stdcall kernel_alloc, 512*3 +@@: + lea eax, [eax*3] + stdcall kernel_alloc, eax test eax, eax jz .nothing xchg eax, ebx .buffer_acquired: ; MBR/EBRs are organized in the chain. We use a loop over MBR/EBRs, but no ; more than MAX_NUM_PARTITION times. -; 4. Prepare things for the loop. +; 3. Prepare things for the loop. ; ebp will hold the sector number for current MBR/EBR. ; [esp] will hold the sector number for current extended partition, if there ; is one. @@ -668,6 +666,10 @@ disk_scan_partitions: push MAX_NUM_PARTITIONS ; the counter of max MBRs to process xor ebp, ebp ; start from sector zero push ebp ; no extended partition yet +; 4. MBR is 512 bytes long. If sector size is less than 512 bytes, +; assume no MBR, no partitions and go to 10. + cmp [esi+DISK.MediaInfo.SectorSize], 512 + jb .notmbr .new_mbr: ; 5. Read the current sector. ; Note that 'read' callback operates with 64-bit sector numbers, so we must @@ -986,7 +988,7 @@ end virtual ; a three-sectors-sized buffer. This function saves ebx in the stack ; immediately before ebp. mov ebx, [ebp-4] ; get buffer - add ebx, 512 ; advance over MBR data to bootsector data + add ebx, [esi+DISK.MediaInfo.SectorSize] ; advance over MBR data to bootsector data add ebp, 8 ; ebp points to part of PARTITION structure xor eax, eax ; first sector of the partition call fs_read32_sys @@ -997,7 +999,7 @@ end virtual ; ebp -> first three fields of PARTITION structure, .start, .length, .disk; ; [esp] = error code after bootsector read: 0 = ok, otherwise = failed, ; ebx points to the buffer for bootsector, -; ebx+512 points to 512-bytes buffer that can be used for anything. +; ebx+[esi+DISK.MediaInfo.SectorSize] points to sector-sized buffer that can be used for anything. call fat_create_partition test eax, eax jnz .success diff --git a/kernel/trunk/blkdev/disk_cache.inc b/kernel/trunk/blkdev/disk_cache.inc index 6454666179..6f9fcfc926 100644 --- a/kernel/trunk/blkdev/disk_cache.inc +++ b/kernel/trunk/blkdev/disk_cache.inc @@ -118,7 +118,6 @@ end virtual add [.sector_lo], eax adc [.sector_hi], edx ; 5. If the cache is disabled, pass the request directly to the driver. - mov edi, [.buffer] cmp [ebx+DISKCACHE.pointer], 0 jz .nocache ; 6. Look for sectors in the cache, sequentially from the beginning. @@ -137,13 +136,15 @@ end virtual ; release the lock and go to 7. jc .not_found_in_cache ; The sector is found in cache. -; 6d. Copy data for the caller. -; Note that buffer in edi is advanced automatically. - mov esi, ecx - shl esi, 9 - add esi, [ebx+DISKCACHE.data] - mov ecx, 512/4 +; 6d. Copy data for the caller, advance [.buffer]. + mov esi, edi + mov edi, [.buffer] + mov eax, 1 + shl eax, cl + mov ecx, eax + shr ecx, 2 rep movsd + mov [.buffer], edi ; 6e. Advance the sector. add [.sector_lo], 1 adc [.sector_hi], 0 @@ -177,6 +178,7 @@ end virtual ; However, for extra-large requests make an upper limit: ; do not use more than half of the free memory ; or more than CACHE_MAX_ALLOC_SIZE bytes. + mov ecx, [ebx+DISKCACHE.sector_size_log] mov ebx, [pg_data.pages_free] shr ebx, 1 jz .nomemory @@ -184,13 +186,15 @@ end virtual jbe @f mov ebx, CACHE_MAX_ALLOC_SIZE shr 12 @@: - shl ebx, 12 - 9 + shl ebx, 12 + shr ebx, cl + jz .nomemory cmp ebx, [.num_sectors] jbe @f mov ebx, [.num_sectors] @@: mov eax, ebx - shl eax, 9 + shl eax, cl stdcall kernel_alloc, eax ; If failed, return the appropriate error code. test eax, eax @@ -233,28 +237,31 @@ end virtual jz @f mov [.error_code+.local_vars2_size], eax @@: -; 11. Copy data for the caller. -; Note that buffer in edi is advanced automatically. +; 11. Copy data for the caller, advance .buffer. cmp [.current_num_sectors], 0 jz .copy_done - mov ecx, [.current_num_sectors] - shl ecx, 9-2 + mov ebx, [.cache+.local_vars2_size] + mov eax, [.current_num_sectors] + mov ecx, [ebx+DISKCACHE.sector_size_log] + shl eax, cl mov esi, [.allocated_buffer] + mov edi, [.buffer+.local_vars2_size] + mov ecx, eax + shr ecx, 2 rep movsd + mov [.buffer+.local_vars2_size], edi ; 12. Copy data to the cache. ; 12a. Acquire the lock. - mov ebx, [.cache+.local_vars2_size] mov ecx, [ebp+PARTITION.Disk] add ecx, DISK.CacheLock call mutex_lock -; 12b. Prepare for the loop: save edi and create a local variable that +; 12b. Prepare for the loop: create a local variable that ; stores number of sectors to be copied. - push edi - push [.current_num_sectors+4] + push [.current_num_sectors] .store_to_cache: ; 12c. For each sector, call the lookup function with adding to the cache, if not yet. - mov eax, [.sector_lo+.local_vars2_size+8] - mov edx, [.sector_hi+.local_vars2_size+8] + mov eax, [.sector_lo+.local_vars2_size+4] + mov edx, [.sector_hi+.local_vars2_size+4] call cache_lookup_write test eax, eax jnz .cache_error @@ -263,39 +270,39 @@ end virtual ; so rewrite data for the caller from the cache. cmp [esi+CACHE_ITEM.Status], CACHE_ITEM_MODIFIED jnz .not_modified - mov esi, ecx - shl esi, 9 - add esi, [ebx+DISKCACHE.data] - mov edi, [esp+4] - mov ecx, [esp] - shl ecx, 9-2 - sub edi, ecx - mov ecx, 512/4 + mov esi, edi + mov edi, [.buffer+.local_vars2_size+4] + mov eax, [esp] + shl eax, cl + sub edi, eax + mov eax, 1 + shl eax, cl + mov ecx, eax + shr ecx, 2 rep movsd - add [.current_buffer+8], 512 + add [.current_buffer+4], eax jmp .sector_done .not_modified: ; 12e. For each not-modified sector, ; copy data, mark the item as not-modified copy of the disk, ; advance .current_buffer and .sector_hi:.sector_lo to the next sector. mov [esi+CACHE_ITEM.Status], CACHE_ITEM_COPY - mov esi, [.current_buffer+8] - mov edi, ecx - shl edi, 9 - add edi, [ebx+DISKCACHE.data] - mov ecx, 512/4 + mov eax, 1 + shl eax, cl + mov esi, [.current_buffer+4] + mov ecx, eax + shr ecx, 2 rep movsd - mov [.current_buffer+8], esi + mov [.current_buffer+4], esi .sector_done: - add [.sector_lo+.local_vars2_size+8], 1 - adc [.sector_hi+.local_vars2_size+8], 0 + add [.sector_lo+.local_vars2_size+4], 1 + adc [.sector_hi+.local_vars2_size+4], 0 ; 12f. Continue the loop 12c-12e until all sectors are read. dec dword [esp] jnz .store_to_cache .cache_error: -; 12g. Restore after the loop: pop the local variable and restore edi. +; 12g. Restore after the loop: pop the local variable. pop ecx - pop edi ; 12h. Release the lock. mov ecx, [ebp+PARTITION.Disk] add ecx, DISK.CacheLock @@ -328,7 +335,7 @@ end virtual push eax ; numsectors push [.sector_hi+4] ; startsector push [.sector_lo+8] ; startsector - push edi ; buffer + push [.buffer+12] ; buffer mov esi, [ebp+PARTITION.Disk] mov al, DISKFUNC.read call disk_call_driver @@ -440,11 +447,11 @@ end virtual ; 6c. For each sector, copy data, mark the item as modified and not saved, ; advance .current_buffer to the next sector. mov [esi+CACHE_ITEM.Status], CACHE_ITEM_MODIFIED + mov eax, 1 + shl eax, cl mov esi, [.cur_buffer] - mov edi, ecx - shl edi, 9 - add edi, [ebx+DISKCACHE.data] - mov ecx, 512/4 + mov ecx, eax + shr ecx, 2 rep movsd mov [.cur_buffer], esi ; 6d. Remove the sector from the other cache. @@ -592,11 +599,12 @@ end virtual jc .not_found_in_cache .found_in_cache: ; 4c. Copy the data. + mov esi, edi mov edi, [.buffer] - mov esi, ecx - shl esi, 9 - add esi, [ebx+DISKCACHE.data] - mov ecx, 512/4 + mov eax, 1 + shl eax, cl + mov ecx, eax + shr ecx, 2 rep movsd ; 4d. Release the lock and return success. mov ecx, [ebp+PARTITION.Disk] @@ -627,7 +635,10 @@ end virtual add ecx, DISK.CacheLock call mutex_unlock ; 7. Allocate buffer for CACHE_LEGACY_READ_SIZE sectors. - stdcall kernel_alloc, CACHE_LEGACY_READ_SIZE shl 9 + mov eax, CACHE_LEGACY_READ_SIZE + mov ecx, [ebx+DISKCACHE.sector_size_log] + shl eax, cl + stdcall kernel_alloc, eax ; If failed, return the corresponding error code. test eax, eax jz .nomemory @@ -656,7 +667,11 @@ end virtual ; 10. Copy data for the caller. mov esi, [.allocated_buffer] mov edi, [.buffer+.local_vars2_size] - mov ecx, 512/4 + mov ecx, [ebx+DISKCACHE.sector_size_log] + mov eax, 1 + shl eax, cl + mov ecx, eax + shr ecx, 2 rep movsd ; 11. Store all sectors that were successfully read to the cache. ; 11a. Acquire the lock. @@ -671,19 +686,19 @@ end virtual test eax, eax jnz .cache_error ; 11c. Ignore sectors marked as modified: for them the cache is more recent that disk data. + mov eax, 1 + shl eax, cl cmp [esi+CACHE_ITEM.Status], CACHE_ITEM_MODIFIED jnz .not_modified - add [.current_buffer], 512 + add [.current_buffer], eax jmp .sector_done .not_modified: ; 11d. For each sector, copy data, mark the item as not-modified copy of the disk, ; advance .current_buffer and .sector_hi:.sector_lo to the next sector. mov [esi+CACHE_ITEM.Status], CACHE_ITEM_COPY mov esi, [.current_buffer] - mov edi, ecx - shl edi, 9 - add edi, [ebx+DISKCACHE.data] - mov ecx, 512/4 + mov ecx, eax + shr ecx, 2 rep movsd mov [.current_buffer], esi .sector_done: @@ -721,16 +736,14 @@ end virtual call cache_lookup_write test eax, eax jnz .floppy_cache_error - push ecx + push esi ; 14. Call the driver to read one sector. push 1 push esp push edx push [.sector_lo+16] - shl ecx, 9 - add ecx, [ebx+DISKCACHE.data] - push ecx + push edi mov esi, [ebp+PARTITION.Disk] mov al, DISKFUNC.read call disk_call_driver @@ -740,10 +753,7 @@ end virtual ; 15. Get the slot and pointer to the cache item, ; change the status to not-modified copy of the disk ; and go to 4c. - pop ecx - lea esi, [ecx*sizeof.CACHE_ITEM/4] - shl esi, 2 - add esi, [ebx+DISKCACHE.pointer] + pop esi mov [esi+CACHE_ITEM.Status], CACHE_ITEM_COPY jmp .found_in_cache @@ -795,13 +805,14 @@ fs_write32_app: ; in: edx:eax = sector ; in: ebx -> DISKCACHE structure ; out: CF set if sector is not in cache -; out: ecx = index in cache +; out: ecx = sector_size_log ; out: esi -> sector:status +; out: edi -> sector data proc cache_lookup_read mov esi, [ebx+DISKCACHE.pointer] add esi, sizeof.CACHE_ITEM - mov ecx, 1 + mov edi, 1 .hdreadcache: @@ -812,14 +823,17 @@ proc cache_lookup_read jne .nohdcache cmp [esi+CACHE_ITEM.SectorHi], edx jne .nohdcache + mov ecx, [ebx+DISKCACHE.sector_size_log] + shl edi, cl + add edi, [ebx+DISKCACHE.data] clc ret .nohdcache: add esi, sizeof.CACHE_ITEM - inc ecx - cmp ecx, [ebx+DISKCACHE.sad_size] + inc edi + cmp edi, [ebx+DISKCACHE.sad_size] jbe .hdreadcache stc ret @@ -832,8 +846,8 @@ endp ; in: ebx -> DISKCACHE structure ; in: ebp -> PARTITION structure ; out: eax = error code -; out: ecx = index in cache ; out: esi -> sector:status +; out: edi -> sector data proc cache_lookup_write call cache_lookup_read jnc .return0 @@ -874,6 +888,10 @@ proc cache_lookup_write popd [esi+CACHE_ITEM.SectorLo] popd [esi+CACHE_ITEM.SectorHi] mov [esi+CACHE_ITEM.Status], CACHE_ITEM_EMPTY + mov edi, ecx + mov ecx, [ebx+DISKCACHE.sector_size_log] + shl edi, cl + add edi, [ebx+DISKCACHE.data] .return0: xor eax, eax ; success ret @@ -902,7 +920,7 @@ virtual at esp .sequential dd ? ; boolean variable, 1 if the current chain is sequential in the cache, ; 0 if additional buffer is needed to perform the operation -.chain_start_pos dd ? ; slot of chain start item +.chain_start_pos dd ? ; data of chain start item .chain_start_ptr dd ? ; pointer to chain start item .chain_size dd ? ; chain size (thanks, C.O.) .iteration_size dd ? @@ -951,6 +969,9 @@ end virtual mov eax, [ebx+DISKCACHE.sad_size] sub eax, [.size_left] inc eax + mov ecx, [ebx+DISKCACHE.sector_size_log] + shl eax, cl + add eax, [ebx+DISKCACHE.data] mov [.chain_start_pos], eax mov [.chain_size], 0 mov [.sequential], 1 @@ -978,7 +999,7 @@ end virtual ; before returning to 6b; if there is a sequential block indeed, this saves some ; time instead of many full-fledged lookups. mov [.sequential], 0 - mov [.chain_start_pos], ecx + mov [.chain_start_pos], edi .look_backward: ; 6e. For each sector, update chain start pos/ptr, decrement sector number, ; look at the previous item. @@ -1001,7 +1022,9 @@ end virtual ; ...expand the chain one sector backwards and continue the loop at 6e. ; Otherwise, advance to step 7 if the previous item describes the correct sector ; but is not modified, and return to step 6b otherwise. - dec [.chain_start_pos] + mov edi, 1 + shl edi, cl + sub [.chain_start_pos], edi jmp .look_backward .found_chain_start: ; 7. Expand the chain forward. @@ -1046,14 +1069,11 @@ end virtual ; 9. Write a sequential chain to disk. ; 9a. Pass the entire chain to the driver. mov eax, [.chain_start_ptr] - mov edx, [.chain_start_pos] - shl edx, 9 - add edx, [ebx+DISKCACHE.data] lea ecx, [.chain_size] push ecx ; numsectors pushd [eax+CACHE_ITEM.SectorHi] ; startsector pushd [eax+CACHE_ITEM.SectorLo] ; startsector - push edx ; buffer + push [.chain_start_pos+12] ; buffer mov esi, [ebp+PARTITION.Disk] mov al, DISKFUNC.write call disk_call_driver @@ -1088,13 +1108,15 @@ end virtual jbe @f mov eax, CACHE_MAX_ALLOC_SIZE shr 12 @@: - shl eax, 12 - 9 + shl eax, 12 + shr eax, cl + jz .nomemory cmp eax, [.chain_size] jbe @f mov eax, [.chain_size] @@: mov [.iteration_size], eax - shl eax, 9 + shl eax, cl stdcall kernel_alloc, eax test eax, eax jz .nomemory @@ -1123,10 +1145,13 @@ end virtual ; 13b. For each sector, copy the data. ; Note that edi is advanced automatically. mov esi, [.chain_start_pos+24] - shl esi, 9 - add esi, [ebx+DISKCACHE.data] - mov ecx, 512/4 + mov ecx, [ebx+DISKCACHE.sector_size_log] + mov eax, 1 + shl eax, cl + mov ecx, eax + shr ecx, 2 rep movsd + mov ecx, eax ; keep for 13e ; 13c. Mark the item as not-modified. mov esi, [.chain_start_ptr+24] mov [esi+CACHE_ITEM.Status], CACHE_ITEM_COPY @@ -1145,7 +1170,7 @@ end virtual jnz .no_forward ; 13e. Increment position/pointer to the chain and ; continue the loop. - inc [.chain_start_pos+24] + add [.chain_start_pos+24], ecx mov [.chain_start_ptr+24], esi dec dword [esp] jnz .copy_loop @@ -1153,11 +1178,13 @@ end virtual .no_forward: ; 13f. Call the lookup function without adding to the cache. ; Update position/pointer with returned value. -; Note: for the last sector in the chain, ecx/esi may contain +; Note: for the last sector in the chain, edi/esi may contain ; garbage; we are not going to use them in this case. + push edi call cache_lookup_read - mov [.chain_start_pos+24], ecx - mov [.chain_start_ptr+24], esi + mov [.chain_start_pos+28], edi + mov [.chain_start_ptr+28], esi + pop edi dec dword [esp] jnz .copy_loop .copy_done: @@ -1203,13 +1230,32 @@ endp ; is most useful example of a non-trivial adjustment. ; esi = pointer to DISK structure disk_init_cache: -; 1. Calculate the suggested cache size. -; 1a. Get the size of free physical memory in pages. +; 1. Verify sector size. The code requires it to be a power of 2 not less than 4. +; In the name of sanity check that sector size is not too small or too large. + bsf ecx, [esi+DISK.MediaInfo.SectorSize] + jz .invalid_sector_size + mov eax, 1 + shl eax, cl + cmp eax, [esi+DISK.MediaInfo.SectorSize] + jnz .invalid_sector_size + cmp ecx, 6 + jb .invalid_sector_size + cmp ecx, 14 + jbe .normal_sector_size +.invalid_sector_size: + DEBUGF 1,'K : sector size %x is invalid\n',[esi+DISK.MediaInfo.SectorSize] + xor eax, eax + ret +.normal_sector_size: + mov [esi+DISK.SysCache.sector_size_log], ecx + mov [esi+DISK.AppCache.sector_size_log], ecx +; 2. Calculate the suggested cache size. +; 2a. Get the size of free physical memory in pages. mov eax, [pg_data.pages_free] -; 1b. Use the value to calculate the size. +; 2b. Use the value to calculate the size. shl eax, 12 - 5 ; 1/32 of it in bytes and eax, -8*4096 ; round down to the multiple of 8 pages -; 1c. Force lower and upper limits. +; 2c. Force lower and upper limits. cmp eax, 1024*1024 jb @f mov eax, 1024*1024 @@ -1218,7 +1264,7 @@ disk_init_cache: ja @f mov eax, 128*1024 @@: -; 1d. Give a chance to the driver to adjust the size. +; 2d. Give a chance to the driver to adjust the size. push eax mov al, DISKFUNC.adjust_cache_size call disk_call_driver @@ -1226,16 +1272,16 @@ disk_init_cache: mov [esi+DISK.cache_size], eax test eax, eax jz .nocache -; 2. Allocate memory for the cache. -; 2a. Call the allocator. +; 3. Allocate memory for the cache. +; 3a. Call the allocator. stdcall kernel_alloc, eax test eax, eax jnz @f -; 2b. If it failed, say a message and return with eax = 0. +; 3b. If it failed, say a message and return with eax = 0. dbgstr 'no memory for disk cache' jmp .nothing @@: -; 3. Fill two DISKCACHE structures. +; 4. Fill two DISKCACHE structures. mov [esi+DISK.SysCache.pointer], eax lea ecx, [esi+DISK.CacheLock] call mutex_init @@ -1252,9 +1298,7 @@ disk_init_cache: mov [esi+DISK.AppCache.pointer], edx mov eax, [esi+DISK.SysCache.data_size] - push ebx - call calculate_for_hd64 - pop ebx + call calculate_cache_slots add eax, [esi+DISK.SysCache.pointer] mov [esi+DISK.SysCache.data], eax mov [esi+DISK.SysCache.sad_size], ecx @@ -1267,9 +1311,7 @@ disk_init_cache: pop edi mov eax, [esi+DISK.AppCache.data_size] - push ebx - call calculate_for_hd64 - pop ebx + call calculate_cache_slots add eax, [esi+DISK.AppCache.pointer] mov [esi+DISK.AppCache.data], eax mov [esi+DISK.AppCache.sad_size], ecx @@ -1281,9 +1323,9 @@ disk_init_cache: rep stosd pop edi -; 4. Return with nonzero al. +; 5. Return with nonzero al. mov al, 1 -; 5. Return. +; 6. Return. .nothing: ret ; No caching is required for this driver. Zero cache pointers and return with @@ -1294,18 +1336,16 @@ disk_init_cache: mov al, 1 ret -calculate_for_hd64: +calculate_cache_slots: push eax - mov ebx, eax - shr eax, 9 - lea eax, [eax*3] - shl eax, 2 - sub ebx, eax - shr ebx, 9 - mov ecx, ebx - shl ebx, 9 + mov ecx, [esi+DISK.MediaInfo.SectorSize] + add ecx, sizeof.CACHE_ITEM + xor edx, edx + div ecx + mov ecx, eax + imul eax, [esi+DISK.MediaInfo.SectorSize] + sub [esp], eax pop eax - sub eax, ebx dec ecx ret diff --git a/kernel/trunk/fs/ext2/ext2.asm b/kernel/trunk/fs/ext2/ext2.asm index fe10fe435b..49df131ccf 100644 --- a/kernel/trunk/fs/ext2/ext2.asm +++ b/kernel/trunk/fs/ext2/ext2.asm @@ -59,6 +59,8 @@ endp ;--------------------------------------------------------------------- proc ext2_create_partition push ebx + cmp dword [esi+DISK.MediaInfo.SectorSize], 512 + jnz .fail mov eax, 2 ; Superblock starts at 1024-bytes. add ebx, 512 ; Get pointer to fs-specific buffer. diff --git a/kernel/trunk/fs/fat.inc b/kernel/trunk/fs/fat.inc index 83e01474d3..53dd13a5a0 100644 --- a/kernel/trunk/fs/fat.inc +++ b/kernel/trunk/fs/fat.inc @@ -154,6 +154,9 @@ fat_create_partition.return0: xor eax, eax ret fat_create_partition: +; sector size must be 512 + cmp dword [esi+DISK.MediaInfo.SectorSize], 512 + jnz .return0 ; bootsector must have been successfully read cmp dword [esp+4], 0 jnz .return0 diff --git a/kernel/trunk/fs/ntfs.inc b/kernel/trunk/fs/ntfs.inc index 346bf6cf63..8e81c458c9 100644 --- a/kernel/trunk/fs/ntfs.inc +++ b/kernel/trunk/fs/ntfs.inc @@ -152,6 +152,8 @@ ntfs_test_bootsec: ret proc ntfs_create_partition + cmp dword [esi+DISK.MediaInfo.SectorSize], 512 + jnz .nope mov edx, dword [ebp+PARTITION.Length] cmp dword [esp+4], 0 jz .boot_read_ok diff --git a/kernel/trunk/fs/xfs.asm b/kernel/trunk/fs/xfs.asm index 4a7c707db2..6ba866d685 100644 --- a/kernel/trunk/fs/xfs.asm +++ b/kernel/trunk/fs/xfs.asm @@ -25,6 +25,8 @@ include 'xfs.inc' ; returns 0 (not XFS or invalid) / pointer to partition structure xfs_create_partition: push ebx ecx edx esi edi + cmp dword [esi+DISK.MediaInfo.SectorSize], 512 + jnz .error cmp dword[ebx + xfs_sb.sb_magicnum], XFS_SB_MAGIC ; signature jne .error