ext fs optimizing

git-svn-id: svn://kolibrios.org@6726 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
pathoswithin 2016-11-18 14:43:26 +00:00
parent e9b1c1bac6
commit ba50660e2b

View File

@ -625,89 +625,70 @@ extfsExtentAlloc:
xor ecx, ecx xor ecx, ecx
jmp .ret jmp .ret
extfsGetFileBlock: extfsGetExtent:
; in: esi -> inode, ecx = file block number ; in: ecx = starting file block
; out: ecx = block number ; out: eax = first block number, ecx = extent size
push ebx edx esi
lea esi, [ebp+EXTFS.inodeBuffer]
test [esi+INODE.featureFlags], EXTENTS_USED test [esi+INODE.featureFlags], EXTENTS_USED
jz .listTreeSearch jz .listTreeSearch
pushad
add esi, INODE.blockNumbers add esi, INODE.blockNumbers
.extentTreeSearch: .extentTreeSearch:
cmp word [esi+NODEHEADER.magic], 0xF30A cmp word [esi+NODEHEADER.magic], 0xF30A
jne .fail jne .fail
movzx ebx, [esi+NODEHEADER.entriesFolow] movzx ebx, [esi+NODEHEADER.entriesFolow]
add esi, sizeof.NODEHEADER add esi, sizeof.NODEHEADER
test ebx, ebx
jz .noBlock
cmp word [esi-sizeof.NODEHEADER+NODEHEADER.currentDepth], 0 cmp word [esi-sizeof.NODEHEADER+NODEHEADER.currentDepth], 0
je .leaf_block je .leaf_block
test ebx, ebx dec ebx
jz .fail ; empty jz .end_search_index
@@: @@:
cmp ebx, 1
je .end_search_index
cmp ecx, [esi+INDEX.fileBlock]
jb .fail
cmp ecx, [esi+sizeof.INDEX+INDEX.fileBlock] cmp ecx, [esi+sizeof.INDEX+INDEX.fileBlock]
jb .end_search_index jb .end_search_index
add esi, sizeof.INDEX add esi, sizeof.INDEX
dec ebx dec ebx
jmp @b jnz @b
.end_search_index: .end_search_index:
mov ebx, [ebp+EXTFS.tempBlockBuffer] mov ebx, [ebp+EXTFS.tempBlockBuffer]
mov eax, [esi+INDEX.nodeBlock] mov eax, [esi+INDEX.nodeBlock]
call extfsReadBlock call extfsReadBlock
jc .fail jc .fail2
mov esi, ebx mov esi, ebx
jmp .extentTreeSearch jmp .extentTreeSearch
.fail:
movi eax, ERROR_FS_FAIL
jmp .fail2
.leaf_block: .leaf_block:
test ebx, ebx movzx edx, [esi+EXTENT.blocksCount]
jz .fail add edx, [esi+EXTENT.fileBlock]
mov edx, [esi+EXTENT.fileBlock] sub edx, ecx
cmp ecx, edx ja .end_search_extent
jb .fail
movzx edi, [esi+EXTENT.blocksCount]
add edx, edi
cmp ecx, edx
jb .end_search_extent
add esi, sizeof.EXTENT add esi, sizeof.EXTENT
dec ebx dec ebx
jmp .leaf_block jnz .leaf_block
.noBlock:
.end_search_extent: movi eax, ERROR_END_OF_FILE
sub ecx, [esi+EXTENT.fileBlock] .fail2:
add ecx, [esi+EXTENT.fsBlock] pop esi edx ebx
mov PUSHAD_ECX, ecx
popad
xor eax, eax
ret
.fail:
popad
movi eax, ERROR_FS_FAIL
stc stc
ret ret
.get_indirect_block: .end_search_extent:
mov eax, [esi+INODE.addressBlock] sub ecx, [esi+EXTENT.fileBlock]
test eax, eax jc .fail
jz .noBlock add ecx, [esi+EXTENT.fsBlock]
mov ebx, [ebp+EXTFS.tempBlockBuffer] mov eax, ecx
call extfsReadBlock mov ecx, edx
jc .fail2 pop esi edx ebx
mov ecx, [ebx+ecx*4]
pop ebx edx
ret
.get_direct_block:
mov ecx, [esi+INODE.blockNumbers+ecx*4]
xor eax, eax
ret ret
.listTreeSearch: .listTreeSearch:
cmp ecx, 12 cmp ecx, 12
jb .get_direct_block jb .get_direct_block
push edx ebx
sub ecx, 12 sub ecx, 12
cmp ecx, [ebp+EXTFS.dwordsPerBlock] cmp ecx, [ebp+EXTFS.dwordsPerBlock]
jb .get_indirect_block jb .get_indirect_block
@ -734,11 +715,22 @@ extfsGetFileBlock:
mov eax, edx mov eax, edx
jmp @f jmp @f
.noBlock: .get_direct_block:
xor ecx, ecx mov edx, ecx
.fail2: mov cl, 12
pop ebx edx lea ebx, [esi+INODE.blockNumbers]
ret jmp .calculateExtent
.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: .get_double_indirect_block:
mov eax, [esi+INODE.doubleAddress] mov eax, [esi+INODE.doubleAddress]
@ -750,58 +742,33 @@ extfsGetFileBlock:
mov eax, ecx mov eax, ecx
@@: @@:
xor edx, edx xor edx, edx
div [ebp+EXTFS.dwordsPerBlock] mov ecx, [ebp+EXTFS.dwordsPerBlock]
div ecx
; eax = number in doubly-indirect block, edx = number in indirect block ; eax = number in doubly-indirect block, edx = number in indirect block
mov eax, [ebx+eax*4] mov eax, [ebx+eax*4]
test eax, eax test eax, eax
jz .noBlock jz .noBlock
call extfsReadBlock call extfsReadBlock
jc .fail2 jc .fail2
mov ecx, [ebx+edx*4] .calculateExtent:
pop ebx edx lea esi, [ebx+edx*4]
ret lodsd
mov ebx, eax
extfsReadFileBlock: sub ecx, edx
; in: xor edx, edx
; eax = file block number @@:
; [ebp+EXTFS.inodeBuffer] = inode inc edx
; out: dec ecx
; [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 jz @f
mov eax, ecx lodsd
mov ebx, [ebp+EXTFS.mainBlockBuffer] sub eax, ebx
call extfsReadBlock sub eax, edx
.ret:
pop esi edx ecx ebx
ret
@@:
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 jz @b
mov eax, ecx
call extfsWriteBlock
@@: @@:
pop esi edx ecx mov eax, ebx
mov ecx, edx
pop esi edx ebx
clc
ret ret
getInodeLocation: getInodeLocation:
@ -1443,12 +1410,9 @@ linkInode:
push ecx ; current file block number push ecx ; current file block number
cmp eax, ecx cmp eax, ecx
jz .alloc_block jz .alloc_block
call extfsGetFileBlock call extfsGetExtent
jc .error_get_inode_block jc .error_get_inode_block
test ecx, ecx push eax
jz .alloc_block
push ecx
mov eax, ecx
mov ebx, [ebp+EXTFS.tempBlockBuffer] mov ebx, [ebp+EXTFS.tempBlockBuffer]
call extfsReadBlock call extfsReadBlock
jc .error_block_read jc .error_block_read
@ -1486,18 +1450,6 @@ linkInode:
inc ecx inc ecx
jmp .searchBlock 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: .zeroLength:
mov [edi+DIRENTRY.entryLength], cx mov [edi+DIRENTRY.entryLength], cx
mov eax, edx mov eax, edx
@ -1511,14 +1463,26 @@ linkInode:
mov ebx, [ebp+EXTFS.tempBlockBuffer] mov ebx, [ebp+EXTFS.tempBlockBuffer]
call extfsWriteBlock call extfsWriteBlock
jc .error_get_inode_block jc .error_get_inode_block
inc dword[esp] pop ecx
@@: inc ecx
mov ecx, [esp] cmp ecx, [esp]
call extfsGetFileBlock
jc .error_get_inode_block
test ecx, ecx
jz .alloc_block
push ecx 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
mov ecx, [esp]
@@:
call extfsGetExtent
jc .error_get_inode_block
push eax
mov edi, [ebp+EXTFS.tempBlockBuffer] mov edi, [ebp+EXTFS.tempBlockBuffer]
mov eax, [ebp+EXTFS.bytesPerBlock] mov eax, [ebp+EXTFS.bytesPerBlock]
mov [edi+DIRENTRY.entryLength], ax mov [edi+DIRENTRY.entryLength], ax
@ -1573,15 +1537,11 @@ unlinkInode:
call readInode call readInode
jc .fail jc .fail
push eax push eax
lea esi, [ebp+EXTFS.inodeBuffer]
.loop: .loop:
mov ecx, [esp] mov ecx, [esp]
call extfsGetFileBlock call extfsGetExtent
jc .fail_loop jc .fail_loop
test ecx, ecx mov edi, eax
jz .fail_loop
mov eax, ecx
mov edi, ecx
mov ebx, [ebp+EXTFS.tempBlockBuffer] mov ebx, [ebp+EXTFS.tempBlockBuffer]
call extfsReadBlock call extfsReadBlock
jc .fail_loop jc .fail_loop
@ -1685,11 +1645,8 @@ findInode:
xor ecx, ecx xor ecx, ecx
.folder_block_cycle: .folder_block_cycle:
push ecx push ecx
xchg esi, edx call extfsGetExtent
call extfsGetFileBlock
jc @b jc @b
xchg esi, edx
mov eax, ecx
mov ebx, [ebp+EXTFS.mainBlockBuffer] mov ebx, [ebp+EXTFS.mainBlockBuffer]
call extfsReadBlock call extfsReadBlock
jc @b jc @b
@ -1829,9 +1786,8 @@ ext_ReadFolder:
mov edi, esp ; edi -> local variables mov edi, esp ; edi -> local variables
add edx, 32 add edx, 32
xor ecx, ecx xor ecx, ecx
call extfsGetFileBlock call extfsGetExtent
jc .error_get_block jc .error_get_block
mov eax, ecx
mov ebx, [ebp+EXTFS.mainBlockBuffer] mov ebx, [ebp+EXTFS.mainBlockBuffer]
call extfsReadBlock call extfsReadBlock
jc .error_get_block jc .error_get_block
@ -1863,9 +1819,8 @@ ext_ReadFolder:
inc dword [edi] inc dword [edi]
push ecx push ecx
mov ecx, [edi] mov ecx, [edi]
call extfsGetFileBlock call extfsGetExtent
jc .error_get_block jc .error_get_block
mov eax, ecx
mov ebx, [ebp+EXTFS.mainBlockBuffer] mov ebx, [ebp+EXTFS.mainBlockBuffer]
call extfsReadBlock call extfsReadBlock
jc .error_get_block jc .error_get_block
@ -2001,131 +1956,111 @@ ext_ReadFolder:
;---------------------------------------------------------------- ;----------------------------------------------------------------
ext_ReadFile: ext_ReadFile:
call ext_lock call ext_lock
push ERROR_ACCESS_DENIED pushd 0 ERROR_ACCESS_DENIED
cmp byte [esi], 0 cmp byte [esi], 0
jz .error ; root jz .ret ; root
mov [esp], ebx mov [esp], ebx
call findInode call findInode
pop ebx pop ebx
jc .error_eax push eax
push ERROR_ACCESS_DENIED jc .ret
lea esi, [ebp+EXTFS.inodeBuffer] lea esi, [ebp+EXTFS.inodeBuffer]
mov ax, [esi+INODE.accessMode] mov byte [esp], ERROR_ACCESS_DENIED
and ax, TYPE_MASK test [esi+INODE.accessMode], FLAG_FILE
cmp ax, FLAG_FILE jz .ret ; not a file
jnz .error ; not a file mov byte [esp], ERROR_END_OF_FILE
pop eax mov eax, [esi+INODE.fileSize]
mov edi, [ebx+16] mov edx, [esi+INODE.fileSizeHigh]
sub eax, [ebx+4]
sbb edx, [ebx+8]
jc .ret
mov ecx, [ebx+12] mov ecx, [ebx+12]
sub eax, ecx
sbb edx, 0
jc @f
xor eax, eax
mov [esp], eax
@@:
add ecx, eax
mov eax, [ebx+4] mov eax, [ebx+4]
mov edx, [ebx+8] mov edx, [ebx+8]
push ERROR_END_OF_FILE mov edi, [ebx+16]
cmp [esi+INODE.fileSizeHigh], edx
ja @f
jb .error
cmp [esi+INODE.fileSize], eax
jna .error
@@:
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]
div [ebp+EXTFS.bytesPerBlock] div [ebp+EXTFS.bytesPerBlock]
push eax
push ecx
mov ecx, eax
call extfsGetFileBlock
jc .error_at_first_block
mov ebx, [ebp+EXTFS.mainBlockBuffer]
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
pop esi
mov ebx, edi
xor edx, edx
div [ebp+EXTFS.bytesPerBlock]
mov edi, eax
@@:
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
.finish_block: ; edx = number of bytes in the last block
test edx, edx test edx, edx
jz .end_read jz .aligned
pop ecx ; block counter .piece:
inc ecx push eax ecx
call extfsGetFileBlock mov esi, edx
jc .error_at_finish_block mov ecx, eax
mov edi, ebx call extfsGetExtent
mov eax, ecx jc .errorGet
mov ecx, [ebp+EXTFS.sectorsPerBlock]
mul ecx
mov ebx, [ebp+EXTFS.mainBlockBuffer] mov ebx, [ebp+EXTFS.mainBlockBuffer]
call extfsReadBlock call fs_read64_sys
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 test eax, eax
jz @f jnz .errorRead
movi eax, ERROR_END_OF_FILE
@@:
ret
.error_at_first_block:
pop ebx
.error_at_read_cycle:
pop ebx
.error_at_finish_block:
pop ebx ebx
.error_eax:
push eax
.error:
call ext_unlock
xor ebx, ebx
pop eax 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
rep movsb
mov ecx, eax
pop eax
inc eax
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
@@:
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
.end:
mov eax, ecx
pop ecx
jecxz .ret
jmp .piece
.errorRead:
movi eax, ERROR_DEVICE
.errorGet:
pop ebx ebx
mov [esp], eax
.ret:
call ext_unlock
pop eax ebx
ret ret
;---------------------------------------------------------------- ;----------------------------------------------------------------
@ -2227,15 +2162,12 @@ ext_Delete:
and edx, TYPE_MASK and edx, TYPE_MASK
cmp edx, DIRECTORY cmp edx, DIRECTORY
jne .file jne .file
push ebx ecx edx 0 push ebx ecx edx
lea esi, [ebp+EXTFS.inodeBuffer] xor ecx, ecx
.checkDirectory: .checkDirectory:
mov ecx, [esp] push ecx
call extfsGetFileBlock call extfsGetExtent
jc .not_empty_eax jc .empty
test ecx, ecx
jz .empty
mov eax, ecx
mov ebx, [ebp+EXTFS.tempBlockBuffer] mov ebx, [ebp+EXTFS.tempBlockBuffer]
call extfsReadBlock call extfsReadBlock
jc .not_empty_eax jc .not_empty_eax
@ -2257,10 +2189,13 @@ ext_Delete:
add ebx, ecx add ebx, ecx
cmp ebx, edx cmp ebx, edx
jb .dir_entry jb .dir_entry
inc dword[esp] pop ecx
inc ecx
jmp .checkDirectory jmp .checkDirectory
.empty: .empty:
cmp eax, ERROR_END_OF_FILE
jnz .not_empty_eax
pop edx edx ecx ebx pop edx edx ecx ebx
.file: .file:
mov eax, ecx mov eax, ecx
@ -2422,7 +2357,7 @@ parent_link db "..", 0
;---------------------------------------------------------------- ;----------------------------------------------------------------
ext_CreateFile: ext_CreateFile:
call extfsWritingInit call extfsWritingInit
push 0 ebx pushd 0 0 ebx
call findInode call findInode
jnc .exist jnc .exist
test edi, edi test edi, edi
@ -2456,17 +2391,14 @@ ext_CreateFile:
call linkInode call linkInode
jc .error2 jc .error2
pop esi ebx pop esi ebx
push ebx esi
mov ecx, [ebx+12] mov ecx, [ebx+12]
jmp ext_WriteFile.start jmp ext_WriteFile.start
.exist: .exist:
lea edx, [ebp+EXTFS.inodeBuffer]
movi eax, ERROR_ACCESS_DENIED movi eax, ERROR_ACCESS_DENIED
test [edx+INODE.accessMode], FLAG_FILE test [ebp+EXTFS.inodeBuffer.accessMode], FLAG_FILE
jz .error ; not a file jz .error ; not a file
pop ebx pop ebx
push ebx esi
mov ecx, [ebx+12] mov ecx, [ebx+12]
call extfsTruncateFile call extfsTruncateFile
jmp ext_WriteFile.start jmp ext_WriteFile.start
@ -2476,204 +2408,187 @@ ext_CreateFile:
.error: .error:
push eax push eax
call ext_unlock call ext_unlock
pop eax ebx ebx pop eax ebx ebx ebx
xor ebx, ebx
ret ret
;---------------------------------------------------------------- ;----------------------------------------------------------------
ext_WriteFile: ext_WriteFile:
call extfsWritingInit call extfsWritingInit
push 0 ebx push ebx
call findInode call findInode
pop ebx pop ebx
push ebx esi pushd 0 eax
jc .error jc .ret
lea edx, [ebp+EXTFS.inodeBuffer] mov byte [esp], ERROR_ACCESS_DENIED
movi eax, ERROR_ACCESS_DENIED test [ebp+EXTFS.inodeBuffer.accessMode], FLAG_FILE
test [edx+INODE.accessMode], FLAG_FILE jz .ret ; not a file
jz .error ; not a file
mov ecx, [ebx+4] mov ecx, [ebx+4]
add ecx, [ebx+12] add ecx, [ebx+12]
.start: .start:
push esi
mov eax, esi mov eax, esi
call extfsExtendFile call extfsExtendFile
mov ecx, [ebx+12] jc .errorExtend
push eax
jc .error_inode_size
pop eax
mov eax, [ebx+4] mov eax, [ebx+4]
mov ebx, [ebx+16] mov ecx, [ebx+12]
push eax mov esi, [ebx+16]
.write:
xor edx, edx xor edx, edx
div [ebp+EXTFS.bytesPerBlock] div [ebp+EXTFS.bytesPerBlock]
test edx, edx test edx, edx
jz .start_aligned jz .aligned
mov esi, [ebp+EXTFS.bytesPerBlock] .piece:
sub esi, edx mov ebx, ecx
cmp esi, ecx mov edi, edx
jbe @f mov ecx, eax
mov esi, ecx push eax
@@: call extfsGetExtent
mov edi, eax jc .errorGet
call extfsReadFileBlock mov ecx, [ebp+EXTFS.sectorsPerBlock]
jc .error_inode_size mul ecx
mov eax, edi push ecx eax ebx
push ebx ecx mov ebx, [ebp+EXTFS.mainBlockBuffer]
mov ecx, esi call fs_read64_sys
mov edi, [ebp+EXTFS.mainBlockBuffer]
mov esi, ebx
mov ebx, edi
add edi, edx
mov edx, ecx
rep movsb
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
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
div [ebp+EXTFS.bytesPerBlock]
push ecx
mov esi, ebx
mov edi, [ebp+EXTFS.mainBlockBuffer]
mov ebx, edi
rep movsb
pop ecx
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
call writeInode
pop ebx
mov ebx, [ebx+12]
sub ebx, ecx
test eax, eax test eax, eax
jz @f jnz .errorDevice
mov [esp], eax pop eax
mov ecx, [ebp+EXTFS.bytesPerBlock]
sub ecx, edi
sub eax, ecx
jnc @f
add ecx, eax
xor eax, eax
@@: @@:
add edi, ebx
add [esp+20], ecx
rep movsb
mov edi, eax
pop eax ecx
xor edx, edx
call fs_write64_sys
mov ecx, edi
pop eax
inc eax
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
pop ecx
jecxz .done
jmp .piece
.errorDevice:
pop eax eax
movi eax, ERROR_DEVICE
.errorGet2:
pop ebx
.errorGet:
pop ebx
.errorExtend:
mov [esp+4], eax
.done:
lea ebx, [ebp+EXTFS.inodeBuffer]
pop eax
call writeInode
add [esp], eax
call writeSuperblock call writeSuperblock
mov esi, [ebp+PARTITION.Disk] mov esi, [ebp+PARTITION.Disk]
call disk_sync call disk_sync
@@: .ret:
call ext_unlock call ext_unlock
pop eax pop eax ebx
ret ret
.error: .erase:
pop ebx ebx ebx push eax eax edx
push eax mov eax, ebx
jmp @b jmp .write
;---------------------------------------------------------------- ;----------------------------------------------------------------
ext_SetFileEnd: ext_SetFileEnd:
call extfsWritingInit call extfsWritingInit
pushd [ebx+4] pushd [ebx+4]
call findInode call findInode
pop ecx
jc .error2 jc .error2
lea edi, [ebp+EXTFS.inodeBuffer] lea edi, [ebp+EXTFS.inodeBuffer]
movi eax, ERROR_ACCESS_DENIED movi eax, ERROR_ACCESS_DENIED
cmp [edi+INODE.accessMode], FLAG_FILE test [edi+INODE.accessMode], FLAG_FILE
jnz .error2 ; not a file jz .error2 ; not a file
pop ecx
push esi push esi
mov ebx, [edi+INODE.fileSize] mov ebx, [edi+INODE.fileSize]
mov eax, esi mov eax, esi
cmp ebx, ecx cmp ebx, ecx
jc @f jnc @f
call extfsTruncateFile
jmp .done
@@:
call extfsExtendFile call extfsExtendFile
jc .error jc .error
sub ecx, ebx sub ecx, ebx
mov eax, ebx cmp ecx, 1000001h
xor edx, edx jnc .done
div [ebp+EXTFS.bytesPerBlock] 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 edi, eax 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 xor eax, eax
mov edx, ecx rep stosd
rep stosb pop ecx edx
pop ecx edi push esi
mov eax, edi call ext_WriteFile.erase
call extfsWriteFileBlock call kernel_free
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 xor eax, eax
rep stosb ret
pop edi ecx
@@: @@:
mov eax, edi call extfsTruncateFile
call extfsWriteFileBlock
jc .error
inc edi
loop @b
.done: .done:
xor eax, eax xor eax, eax
.error: .error:
xchg eax, [esp] xchg eax, [esp]
lea ebx, [ebp+EXTFS.inodeBuffer] lea ebx, [ebp+EXTFS.inodeBuffer]
call writeInode call writeInode
jnc @f add [esp], eax
mov [esp], eax
@@:
call writeSuperblock call writeSuperblock
mov esi, [ebp+PARTITION.Disk] mov esi, [ebp+PARTITION.Disk]
call disk_sync call disk_sync
mov eax, [esp] pop eax
.error2: .error2:
mov [esp], eax push eax
call ext_unlock call ext_unlock
pop eax pop eax
ret ret