Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 6726 → Rev 6725

/kernel/trunk/fs/ext.inc
625,13 → 625,12
xor ecx, ecx
jmp .ret
 
extfsGetExtent:
; in: ecx = starting file block
; out: eax = first block number, ecx = extent size
push ebx edx esi
lea esi, [ebp+EXTFS.inodeBuffer]
extfsGetFileBlock:
; in: esi -> inode, ecx = file block number
; out: ecx = block number
test [esi+INODE.featureFlags], EXTENTS_USED
jz .listTreeSearch
pushad
add esi, INODE.blockNumbers
.extentTreeSearch:
cmp word [esi+NODEHEADER.magic], 0xF30A
638,57 → 637,77
jne .fail
movzx ebx, [esi+NODEHEADER.entriesFolow]
add esi, sizeof.NODEHEADER
test ebx, ebx
jz .noBlock
cmp word [esi-sizeof.NODEHEADER+NODEHEADER.currentDepth], 0
je .leaf_block
dec ebx
jz .end_search_index
test ebx, ebx
jz .fail ; empty
@@:
cmp ebx, 1
je .end_search_index
cmp ecx, [esi+INDEX.fileBlock]
jb .fail
cmp ecx, [esi+sizeof.INDEX+INDEX.fileBlock]
jb .end_search_index
add esi, sizeof.INDEX
dec ebx
jnz @b
jmp @b
 
.end_search_index:
mov ebx, [ebp+EXTFS.tempBlockBuffer]
mov eax, [esi+INDEX.nodeBlock]
call extfsReadBlock
jc .fail2
jc .fail
mov esi, ebx
jmp .extentTreeSearch
 
.fail:
movi eax, ERROR_FS_FAIL
jmp .fail2
 
.leaf_block:
movzx edx, [esi+EXTENT.blocksCount]
add edx, [esi+EXTENT.fileBlock]
sub edx, ecx
ja .end_search_extent
test ebx, ebx
jz .fail
mov edx, [esi+EXTENT.fileBlock]
cmp ecx, edx
jb .fail
movzx edi, [esi+EXTENT.blocksCount]
add edx, edi
cmp ecx, edx
jb .end_search_extent
add esi, sizeof.EXTENT
dec ebx
jnz .leaf_block
.noBlock:
movi eax, ERROR_END_OF_FILE
.fail2:
pop esi edx ebx
stc
ret
jmp .leaf_block
 
.end_search_extent:
sub ecx, [esi+EXTENT.fileBlock]
jc .fail
add ecx, [esi+EXTENT.fsBlock]
mov eax, ecx
mov ecx, edx
pop esi edx ebx
mov PUSHAD_ECX, ecx
popad
xor eax, eax
ret
 
.fail:
popad
movi eax, ERROR_FS_FAIL
stc
ret
 
.get_indirect_block:
mov eax, [esi+INODE.addressBlock]
test eax, eax
jz .noBlock
mov ebx, [ebp+EXTFS.tempBlockBuffer]
call extfsReadBlock
jc .fail2
mov ecx, [ebx+ecx*4]
pop ebx edx
ret
 
.get_direct_block:
mov ecx, [esi+INODE.blockNumbers+ecx*4]
xor eax, eax
ret
 
.listTreeSearch:
cmp ecx, 12
jb .get_direct_block
push edx ebx
sub ecx, 12
cmp ecx, [ebp+EXTFS.dwordsPerBlock]
jb .get_indirect_block
715,23 → 734,12
mov eax, edx
jmp @f
 
.get_direct_block:
mov edx, ecx
mov cl, 12
lea ebx, [esi+INODE.blockNumbers]
jmp .calculateExtent
.noBlock:
xor ecx, ecx
.fail2:
pop ebx edx
ret
 
.get_indirect_block:
mov eax, [esi+INODE.addressBlock]
test eax, eax
jz .noBlock
mov ebx, [ebp+EXTFS.tempBlockBuffer]
call extfsReadBlock
jc .fail2
mov edx, ecx
mov ecx, [ebp+EXTFS.dwordsPerBlock]
jmp .calculateExtent
 
.get_double_indirect_block:
mov eax, [esi+INODE.doubleAddress]
test eax, eax
742,8 → 750,7
mov eax, ecx
@@:
xor edx, edx
mov ecx, [ebp+EXTFS.dwordsPerBlock]
div ecx
div [ebp+EXTFS.dwordsPerBlock]
; eax = number in doubly-indirect block, edx = number in indirect block
mov eax, [ebx+eax*4]
test eax, eax
750,25 → 757,51
jz .noBlock
call extfsReadBlock
jc .fail2
.calculateExtent:
lea esi, [ebx+edx*4]
lodsd
mov ebx, eax
sub ecx, edx
xor edx, edx
mov ecx, [ebx+edx*4]
pop ebx edx
ret
 
extfsReadFileBlock:
; in:
; eax = file block number
; [ebp+EXTFS.inodeBuffer] = inode
; out:
; [ebp+EXTFS.mainBlockBuffer] -> block
push ebx ecx edx esi
mov ecx, eax
lea esi, [ebp+EXTFS.inodeBuffer]
call extfsGetFileBlock
jc .ret
test ecx, ecx
jz @f
mov eax, ecx
mov ebx, [ebp+EXTFS.mainBlockBuffer]
call extfsReadBlock
.ret:
pop esi edx ecx ebx
ret
 
@@:
inc edx
dec ecx
jz @f
lodsd
sub eax, ebx
sub eax, edx
movi eax, ERROR_FS_FAIL
stc
jmp .ret
 
extfsWriteFileBlock:
; in:
; eax = file block number
; ebx -> data
; [ebp+EXTFS.inodeBuffer] = inode
push ecx edx esi
mov ecx, eax
lea esi, [ebp+EXTFS.inodeBuffer]
call extfsGetFileBlock
jc @f
test ecx, ecx
jz @b
mov eax, ecx
call extfsWriteBlock
@@:
mov eax, ebx
mov ecx, edx
pop esi edx ebx
clc
pop esi edx ecx
ret
 
getInodeLocation:
1410,9 → 1443,12
push ecx ; current file block number
cmp eax, ecx
jz .alloc_block
call extfsGetExtent
call extfsGetFileBlock
jc .error_get_inode_block
push eax
test ecx, ecx
jz .alloc_block
push ecx
mov eax, ecx
mov ebx, [ebp+EXTFS.tempBlockBuffer]
call extfsReadBlock
jc .error_block_read
1450,6 → 1486,18
inc ecx
jmp .searchBlock
 
.alloc_block:
mov ecx, [esi+INODE.fileSize]
add ecx, [ebp+EXTFS.bytesPerBlock]
mov eax, [esp+24]
call extfsExtendFile
jc .error_get_inode_block
mov eax, [esp+24]
mov ebx, esi
call writeInode
jc .error_get_inode_block
jmp @f
 
.zeroLength:
mov [edi+DIRENTRY.entryLength], cx
mov eax, edx
1463,26 → 1511,14
mov ebx, [ebp+EXTFS.tempBlockBuffer]
call extfsWriteBlock
jc .error_get_inode_block
pop ecx
inc ecx
cmp ecx, [esp]
push ecx
jnz @f
.alloc_block:
mov ecx, [esi+INODE.fileSize]
add ecx, [ebp+EXTFS.bytesPerBlock]
mov eax, [esp+24]
call extfsExtendFile
jc .error_get_inode_block
mov eax, [esp+24]
mov ebx, esi
call writeInode
jc .error_get_inode_block
inc dword[esp]
@@:
mov ecx, [esp]
@@:
call extfsGetExtent
call extfsGetFileBlock
jc .error_get_inode_block
push eax
test ecx, ecx
jz .alloc_block
push ecx
mov edi, [ebp+EXTFS.tempBlockBuffer]
mov eax, [ebp+EXTFS.bytesPerBlock]
mov [edi+DIRENTRY.entryLength], ax
1537,11 → 1573,15
call readInode
jc .fail
push eax
lea esi, [ebp+EXTFS.inodeBuffer]
.loop:
mov ecx, [esp]
call extfsGetExtent
call extfsGetFileBlock
jc .fail_loop
mov edi, eax
test ecx, ecx
jz .fail_loop
mov eax, ecx
mov edi, ecx
mov ebx, [ebp+EXTFS.tempBlockBuffer]
call extfsReadBlock
jc .fail_loop
1645,8 → 1685,11
xor ecx, ecx
.folder_block_cycle:
push ecx
call extfsGetExtent
xchg esi, edx
call extfsGetFileBlock
jc @b
xchg esi, edx
mov eax, ecx
mov ebx, [ebp+EXTFS.mainBlockBuffer]
call extfsReadBlock
jc @b
1786,8 → 1829,9
mov edi, esp ; edi -> local variables
add edx, 32
xor ecx, ecx
call extfsGetExtent
call extfsGetFileBlock
jc .error_get_block
mov eax, ecx
mov ebx, [ebp+EXTFS.mainBlockBuffer]
call extfsReadBlock
jc .error_get_block
1819,8 → 1863,9
inc dword [edi]
push ecx
mov ecx, [edi]
call extfsGetExtent
call extfsGetFileBlock
jc .error_get_block
mov eax, ecx
mov ebx, [ebp+EXTFS.mainBlockBuffer]
call extfsReadBlock
jc .error_get_block
1956,111 → 2001,131
;----------------------------------------------------------------
ext_ReadFile:
call ext_lock
pushd 0 ERROR_ACCESS_DENIED
push ERROR_ACCESS_DENIED
cmp byte [esi], 0
jz .ret ; root
jz .error ; root
mov [esp], ebx
call findInode
pop ebx
push eax
jc .ret
jc .error_eax
push ERROR_ACCESS_DENIED
lea esi, [ebp+EXTFS.inodeBuffer]
mov byte [esp], ERROR_ACCESS_DENIED
test [esi+INODE.accessMode], FLAG_FILE
jz .ret ; not a file
mov byte [esp], ERROR_END_OF_FILE
mov eax, [esi+INODE.fileSize]
mov edx, [esi+INODE.fileSizeHigh]
sub eax, [ebx+4]
sbb edx, [ebx+8]
jc .ret
mov ax, [esi+INODE.accessMode]
and ax, TYPE_MASK
cmp ax, FLAG_FILE
jnz .error ; not a file
pop eax
mov edi, [ebx+16]
mov ecx, [ebx+12]
sub eax, ecx
sbb edx, 0
jc @f
xor eax, eax
mov [esp], eax
mov eax, [ebx+4]
mov edx, [ebx+8]
push ERROR_END_OF_FILE
cmp [esi+INODE.fileSizeHigh], edx
ja @f
jb .error
cmp [esi+INODE.fileSize], eax
jna .error
@@:
add ecx, eax
add esp, 4
add eax, ecx
adc edx, 0
cmp [esi+INODE.fileSizeHigh], edx
ja .read_till_requested
jb .read_whole_file
cmp [esi+INODE.fileSize], eax
jae .read_till_requested
.read_whole_file:
push 1 ; read till the end of file
mov ecx, [esi+INODE.fileSize]
sub ecx, [ebx+4]
jmp @f
 
.read_till_requested:
push 0 ; read as much as requested
@@: ; ecx = bytes to read, edi -> buffer
push ecx
; read part of the first block
mov edx, [ebx+8]
mov eax, [ebx+4]
mov edx, [ebx+8]
mov edi, [ebx+16]
div [ebp+EXTFS.bytesPerBlock]
test edx, edx
jz .aligned
.piece:
push eax ecx
mov esi, edx
push eax
push ecx
mov ecx, eax
call extfsGetExtent
jc .errorGet
mov ecx, [ebp+EXTFS.sectorsPerBlock]
mul ecx
call extfsGetFileBlock
jc .error_at_first_block
mov ebx, [ebp+EXTFS.mainBlockBuffer]
call fs_read64_sys
test eax, eax
jnz .errorRead
pop eax
mov ecx, [ebp+EXTFS.bytesPerBlock]
sub ecx, esi
sub eax, ecx
jnc @f
add ecx, eax
xor eax, eax
@@:
add esi, ebx
add [esp+8], ecx
mov eax, ecx
call extfsReadBlock
jc .error_at_first_block
pop ecx
add ebx, edx
neg edx
add edx, [ebp+EXTFS.bytesPerBlock]
cmp ecx, edx
jbe .only_one_block
mov eax, ecx
sub eax, edx ; bytes to read
mov ecx, edx
push esi
mov esi, ebx
rep movsb
mov ecx, eax
pop eax
inc eax
pop esi
mov ebx, edi
xor edx, edx
jecxz .ret
.aligned:
xchg eax, ecx
div [ebp+EXTFS.bytesPerBlock]
push edx
mov edx, eax
.writeExtent:
test edx, edx
jz .end
push ecx
call extfsGetExtent
jc .errorGet
sub edx, ecx
jnc @f
add ecx, edx
xor edx, edx
mov edi, eax
@@:
add [esp], ecx
imul ecx, [ebp+EXTFS.sectorsPerBlock]
mov ebx, edi
push edx ecx
mul [ebp+EXTFS.sectorsPerBlock]
call fs_read64_sys
pop ecx edx
test eax, eax
jnz .errorRead
shl ecx, 9
add edi, ecx
add [esp+12], ecx
pop ecx
jmp .writeExtent
test edi, edi
jz .finish_block
inc dword [esp]
mov ecx, [esp]
call extfsGetFileBlock
jc .error_at_read_cycle
mov eax, ecx
call extfsReadBlock
jc .error_at_read_cycle
add ebx, [ebp+EXTFS.bytesPerBlock]
dec edi
jmp @b
 
.end:
.finish_block: ; edx = number of bytes in the last block
test edx, edx
jz .end_read
pop ecx ; block counter
inc ecx
call extfsGetFileBlock
jc .error_at_finish_block
mov edi, ebx
mov eax, ecx
pop ecx
jecxz .ret
jmp .piece
mov ebx, [ebp+EXTFS.mainBlockBuffer]
call extfsReadBlock
jc .error_at_finish_block
push eax
mov ecx, edx
.only_one_block:
mov esi, ebx
rep movsb
.end_read:
call ext_unlock
pop eax ebx eax
test eax, eax
jz @f
movi eax, ERROR_END_OF_FILE
@@:
ret
 
.errorRead:
movi eax, ERROR_DEVICE
.errorGet:
.error_at_first_block:
pop ebx
.error_at_read_cycle:
pop ebx
.error_at_finish_block:
pop ebx ebx
mov [esp], eax
.ret:
.error_eax:
push eax
.error:
call ext_unlock
pop eax ebx
xor ebx, ebx
pop eax
ret
 
;----------------------------------------------------------------
2162,12 → 2227,15
and edx, TYPE_MASK
cmp edx, DIRECTORY
jne .file
push ebx ecx edx
xor ecx, ecx
push ebx ecx edx 0
lea esi, [ebp+EXTFS.inodeBuffer]
.checkDirectory:
push ecx
call extfsGetExtent
jc .empty
mov ecx, [esp]
call extfsGetFileBlock
jc .not_empty_eax
test ecx, ecx
jz .empty
mov eax, ecx
mov ebx, [ebp+EXTFS.tempBlockBuffer]
call extfsReadBlock
jc .not_empty_eax
2189,13 → 2257,10
add ebx, ecx
cmp ebx, edx
jb .dir_entry
pop ecx
inc ecx
inc dword[esp]
jmp .checkDirectory
 
.empty:
cmp eax, ERROR_END_OF_FILE
jnz .not_empty_eax
pop edx edx ecx ebx
.file:
mov eax, ecx
2357,7 → 2422,7
;----------------------------------------------------------------
ext_CreateFile:
call extfsWritingInit
pushd 0 0 ebx
push 0 ebx
call findInode
jnc .exist
test edi, edi
2391,14 → 2456,17
call linkInode
jc .error2
pop esi ebx
push ebx esi
mov ecx, [ebx+12]
jmp ext_WriteFile.start
 
.exist:
lea edx, [ebp+EXTFS.inodeBuffer]
movi eax, ERROR_ACCESS_DENIED
test [ebp+EXTFS.inodeBuffer.accessMode], FLAG_FILE
test [edx+INODE.accessMode], FLAG_FILE
jz .error ; not a file
pop ebx
push ebx esi
mov ecx, [ebx+12]
call extfsTruncateFile
jmp ext_WriteFile.start
2408,131 → 2476,117
.error:
push eax
call ext_unlock
pop eax ebx ebx ebx
pop eax ebx ebx
xor ebx, ebx
ret
 
;----------------------------------------------------------------
ext_WriteFile:
call extfsWritingInit
push ebx
push 0 ebx
call findInode
pop ebx
pushd 0 eax
jc .ret
mov byte [esp], ERROR_ACCESS_DENIED
test [ebp+EXTFS.inodeBuffer.accessMode], FLAG_FILE
jz .ret ; not a file
push ebx esi
jc .error
lea edx, [ebp+EXTFS.inodeBuffer]
movi eax, ERROR_ACCESS_DENIED
test [edx+INODE.accessMode], FLAG_FILE
jz .error ; not a file
mov ecx, [ebx+4]
add ecx, [ebx+12]
.start:
push esi
mov eax, esi
call extfsExtendFile
jc .errorExtend
mov ecx, [ebx+12]
push eax
jc .error_inode_size
pop eax
mov eax, [ebx+4]
mov ecx, [ebx+12]
mov esi, [ebx+16]
.write:
mov ebx, [ebx+16]
push eax
xor edx, edx
div [ebp+EXTFS.bytesPerBlock]
test edx, edx
jz .aligned
.piece:
mov ebx, ecx
mov edi, edx
mov ecx, eax
push eax
call extfsGetExtent
jc .errorGet
mov ecx, [ebp+EXTFS.sectorsPerBlock]
mul ecx
push ecx eax ebx
mov ebx, [ebp+EXTFS.mainBlockBuffer]
call fs_read64_sys
test eax, eax
jnz .errorDevice
pop eax
mov ecx, [ebp+EXTFS.bytesPerBlock]
sub ecx, edi
sub eax, ecx
jnc @f
add ecx, eax
xor eax, eax
jz .start_aligned
mov esi, [ebp+EXTFS.bytesPerBlock]
sub esi, edx
cmp esi, ecx
jbe @f
mov esi, ecx
@@:
add edi, ebx
add [esp+20], ecx
mov edi, eax
call extfsReadFileBlock
jc .error_inode_size
mov eax, edi
push ebx ecx
mov ecx, esi
mov edi, [ebp+EXTFS.mainBlockBuffer]
mov esi, ebx
mov ebx, edi
add edi, edx
mov edx, ecx
rep movsb
mov edi, eax
pop eax ecx
call extfsWriteFileBlock
pop ecx ebx
jc .error_inode_size
add [esp], edx
add ebx, edx
sub ecx, edx
jz .write_inode
.start_aligned:
cmp ecx, [ebp+EXTFS.bytesPerBlock]
jb @f
mov eax, [esp]
xor edx, edx
call fs_write64_sys
mov ecx, edi
pop eax
inc eax
div [ebp+EXTFS.bytesPerBlock]
call extfsWriteFileBlock
jc .error_inode_size
mov eax, [ebp+EXTFS.bytesPerBlock]
sub ecx, eax
add ebx, eax
add [esp], eax
jmp .start_aligned
 
@@: ; handle the remaining bytes
test ecx, ecx
jz .write_inode
mov eax, [esp]
xor edx, edx
jecxz .done
.aligned:
xchg eax, ecx
div [ebp+EXTFS.bytesPerBlock]
push edx
mov edx, eax
.writeExtent:
test edx, edx
jz .end
push ecx
call extfsGetExtent
jc .errorGet2
sub edx, ecx
jnc @f
add ecx, edx
xor edx, edx
@@:
add [esp], ecx
imul ecx, [ebp+EXTFS.sectorsPerBlock]
mov ebx, esi
push edx ecx
mul [ebp+EXTFS.sectorsPerBlock]
call fs_write64_sys
test eax, eax
jnz .errorDevice
pop ebx edx ecx
shl ebx, 9
add esi, ebx
add [esp+12], ebx
jmp .writeExtent
 
.end:
mov eax, ecx
mov esi, ebx
mov edi, [ebp+EXTFS.mainBlockBuffer]
mov ebx, edi
rep movsb
pop ecx
jecxz .done
jmp .piece
 
.errorDevice:
call extfsWriteFileBlock
jc .error_inode_size
xor ecx, ecx
.error_inode_size:
mov [esp+12], eax
.write_inode:
lea ebx, [ebp+EXTFS.inodeBuffer]
pop eax eax
movi eax, ERROR_DEVICE
.errorGet2:
call writeInode
pop ebx
.errorGet:
pop ebx
.errorExtend:
mov [esp+4], eax
.done:
lea ebx, [ebp+EXTFS.inodeBuffer]
pop eax
call writeInode
add [esp], eax
mov ebx, [ebx+12]
sub ebx, ecx
test eax, eax
jz @f
mov [esp], eax
@@:
call writeSuperblock
mov esi, [ebp+PARTITION.Disk]
call disk_sync
.ret:
@@:
call ext_unlock
pop eax ebx
pop eax
ret
 
.erase:
push eax eax edx
mov eax, ebx
jmp .write
.error:
pop ebx ebx ebx
push eax
jmp @b
 
;----------------------------------------------------------------
ext_SetFileEnd:
2539,43 → 2593,72
call extfsWritingInit
pushd [ebx+4]
call findInode
pop ecx
jc .error2
lea edi, [ebp+EXTFS.inodeBuffer]
movi eax, ERROR_ACCESS_DENIED
test [edi+INODE.accessMode], FLAG_FILE
jz .error2 ; not a file
cmp [edi+INODE.accessMode], FLAG_FILE
jnz .error2 ; not a file
pop ecx
push esi
mov ebx, [edi+INODE.fileSize]
mov eax, esi
cmp ebx, ecx
jnc @f
jc @f
call extfsTruncateFile
jmp .done
 
@@:
call extfsExtendFile
jc .error
sub ecx, ebx
cmp ecx, 1000001h
jnc .done
push ecx
stdcall kernel_alloc, ecx
pop ecx
test eax, eax
jz .error
push ecx
add ecx, 3
shr ecx, 2
mov esi, eax
mov eax, ebx
xor edx, edx
div [ebp+EXTFS.bytesPerBlock]
mov edi, eax
test edx, edx
jz .start_aligned
call extfsReadFileBlock
jc .error
mov eax, [ebp+EXTFS.bytesPerBlock]
sub eax, edx
cmp eax, ecx
jbe @f
mov eax, ecx
@@:
mov ebx, [ebp+EXTFS.mainBlockBuffer]
push edi ecx
mov ecx, eax
mov edi, ebx
add edi, edx
xor eax, eax
rep stosd
pop ecx edx
push esi
call ext_WriteFile.erase
call kernel_free
mov edx, ecx
rep stosb
pop ecx edi
mov eax, edi
call extfsWriteFileBlock
jc .error
sub ecx, edx
jz .done
inc edi
.start_aligned:
mov eax, ecx
mov ecx, [ebp+EXTFS.bytesPerBlock]
dec eax
xor edx, edx
div ecx
inc eax
mov ebx, [ebp+EXTFS.mainBlockBuffer]
push eax edi
mov edi, ebx
xor eax, eax
ret
 
rep stosb
pop edi ecx
@@:
call extfsTruncateFile
mov eax, edi
call extfsWriteFileBlock
jc .error
inc edi
loop @b
.done:
xor eax, eax
.error:
2582,13 → 2665,15
xchg eax, [esp]
lea ebx, [ebp+EXTFS.inodeBuffer]
call writeInode
add [esp], eax
jnc @f
mov [esp], eax
@@:
call writeSuperblock
mov esi, [ebp+PARTITION.Disk]
call disk_sync
pop eax
mov eax, [esp]
.error2:
push eax
mov [esp], eax
call ext_unlock
pop eax
ret