164,13 → 164,14 |
dwordsPerBranch dd ? ; dwordsPerBlock ^ 2 |
mainBlockBuffer dd ? |
tempBlockBuffer dd ? |
align0 rb 200h-EXTFS.align0 |
align 512 |
superblock SUPERBLOCK |
align1 rb 400h-EXTFS.align1 |
align 1024 |
rootInodeBuffer INODE |
align2 rb 600h-EXTFS.align2 |
inodeBuffer INODE |
align3 rb 800h-EXTFS.align3 |
align 1024 |
mainInodeBuffer INODE |
align 1024 |
tempInodeBuffer INODE |
ends |
|
; mount if it's a valid EXT partition |
203,8 → 204,7 |
je .fail |
cmp [ebx+SUPERBLOCK.inodesPerGroup], 0 |
je .fail |
movi eax, sizeof.EXTFS |
call malloc |
stdcall kernel_alloc, 1000h |
test eax, eax |
jz .fail |
mov ecx, dword [ebp+PARTITION.FirstSector] |
267,8 → 267,7 |
@@: |
stdcall kernel_free, [ebp+EXTFS.mainBlockBuffer] |
.error: |
mov eax, ebp |
call free |
stdcall kernel_free, ebp |
pop edi esi ebp |
.fail: |
pop ebx |
280,8 → 279,8 |
; in: eax -> EXTFS structure |
push eax |
stdcall kernel_free, [eax+EXTFS.mainBlockBuffer] |
pop eax |
jmp free |
call kernel_free |
ret |
|
extfsWriteBlock: |
push fs_write64_sys |
419,8 → 418,10 |
ret |
|
inodeBlockAlloc: |
; in: esi -> inode, eax = inode number |
; in: esi -> inode |
; out: ebx = block number |
; TODO: fix to have correct preference. |
mov eax, ROOT_INODE |
call extfsBlockAlloc |
jc @f |
mov eax, [ebp+EXTFS.sectorsPerBlock] |
602,13 → 603,15 |
ret |
|
.get_indirect_block: |
push edx ebx |
mov eax, [esi+INODE.addressBlock] |
test eax, eax |
jz .noBlock |
jz .fail3 |
mov ebx, [ebp+EXTFS.tempBlockBuffer] |
call extfsReadBlock |
jc .fail2 |
jc @f |
mov ecx, [ebx+ecx*4] |
@@: |
pop ebx edx |
ret |
|
620,7 → 623,6 |
.listTreeSearch: |
cmp ecx, 12 |
jb .get_direct_block |
push edx ebx |
sub ecx, 12 |
cmp ecx, [ebp+EXTFS.dwordsPerBlock] |
jb .get_indirect_block |
629,9 → 631,8 |
jb .get_double_indirect_block |
; triply-indirect blocks |
sub ecx, [ebp+EXTFS.dwordsPerBranch] |
push edx ebx |
mov eax, [esi+INODE.tripleAddress] |
test eax, eax |
jz .noBlock |
mov ebx, [ebp+EXTFS.tempBlockBuffer] |
call extfsReadBlock |
jc .fail2 |
641,22 → 642,23 |
; eax = number in triply-indirect block, edx = number in branch |
mov eax, [ebx+eax*4] |
test eax, eax |
jz .noBlock |
jz .fail3 |
call extfsReadBlock |
jc .fail2 |
mov eax, edx |
jmp @f |
|
.noBlock: |
xor ecx, ecx |
.fail2: |
.fail3: |
pop ebx edx |
movi eax, ERROR_FS_FAIL |
stc |
ret |
|
.get_double_indirect_block: |
push edx ebx |
mov eax, [esi+INODE.doubleAddress] |
test eax, eax |
jz .noBlock |
jz .fail3 |
mov ebx, [ebp+EXTFS.tempBlockBuffer] |
call extfsReadBlock |
jc .fail2 |
667,10 → 669,11 |
; eax = number in doubly-indirect block, edx = number in indirect block |
mov eax, [ebx+eax*4] |
test eax, eax |
jz .noBlock |
jz .fail3 |
call extfsReadBlock |
jc .fail2 |
mov ecx, [ebx+edx*4] |
.fail2: |
pop ebx edx |
ret |
|
678,7 → 681,6 |
; in: |
; ecx = file block number |
; edi = block number |
; edx = inode number |
; esi -> inode |
push ebx ecx edx |
cmp ecx, 12 |
694,7 → 696,6 |
mov eax, [esi+INODE.tripleAddress] |
test eax, eax |
jnz @f |
mov eax, edx |
call inodeBlockAlloc |
jc .ret |
mov [esi+INODE.tripleAddress], ebx |
712,7 → 713,6 |
mov eax, [ebx+eax*4] |
test eax, eax |
jnz @f |
mov eax, [esp+4] |
call inodeBlockAlloc |
jc .fail_alloc_4 |
mov [ecx], ebx |
732,7 → 732,6 |
mov eax, [esi+INODE.doubleAddress] |
test eax, eax |
jnz .double_indirect_present |
mov eax, edx |
call inodeBlockAlloc |
jc .ret |
mov [esi+INODE.doubleAddress], ebx |
752,7 → 751,6 |
lea ecx, [ebx+eax*4] |
cmp dword[ecx], 0 |
jne @f |
mov eax, [esp+8] |
call inodeBlockAlloc |
jc .fail_alloc_8 |
mov [ecx], ebx |
774,7 → 772,6 |
mov eax, [esi+INODE.addressBlock] |
test eax, eax |
jnz @f |
mov eax, edx |
call inodeBlockAlloc |
jc .ret |
mov [esi+INODE.addressBlock], ebx |
808,11 → 805,11 |
; in: |
; edx = inode number |
; eax = file block number |
; [ebp+EXTFS.inodeBuffer] = inode |
; [ebp+EXTFS.tempInodeBuffer] = inode |
push ebx ecx edx edi esi |
mov edi, eax |
mov ecx, eax |
lea esi, [ebp+EXTFS.inodeBuffer] |
lea esi, [ebp+EXTFS.tempInodeBuffer] |
call extfsGetFileBlock |
jc @f |
test ecx, ecx |
833,7 → 830,7 |
jc @f |
mov ecx, edi |
mov edi, ebx |
lea esi, [ebp+EXTFS.inodeBuffer] |
lea esi, [ebp+EXTFS.tempInodeBuffer] |
call extfsSetFileBlock |
jc @f |
mov eax, [ebp+EXTFS.sectorsPerBlock] |
846,11 → 843,11 |
extfsFreeFileBlock: |
; in: |
; eax = file block number |
; [ebp+EXTFS.inodeBuffer] = inode |
push ebx ecx edx edi esi |
; [ebp+EXTFS.tempInodeBuffer] = inode |
push ebx ecx edi esi |
mov edi, eax |
mov ecx, eax |
lea esi, [ebp+EXTFS.inodeBuffer] |
lea esi, [ebp+EXTFS.tempInodeBuffer] |
call extfsGetFileBlock |
jc @f |
test ecx, ecx |
860,25 → 857,24 |
call extfsResourceFree |
mov ecx, edi |
xor edi, edi |
movi edx, ROOT_INODE |
lea esi, [ebp+EXTFS.inodeBuffer] |
lea esi, [ebp+EXTFS.tempInodeBuffer] |
call extfsSetFileBlock |
mov eax, [ebp+EXTFS.sectorsPerBlock] |
sub [esi+INODE.sectorsUsed], eax |
xor eax, eax |
@@: |
pop esi edi edx ecx ebx |
pop esi edi ecx ebx |
ret |
|
extfsReadFileBlock: |
; in: |
; eax = file block number |
; [ebp+EXTFS.inodeBuffer] = inode |
; [ebp+EXTFS.tempInodeBuffer] = inode |
; out: |
; [ebp+EXTFS.mainBlockBuffer] -> block |
push ebx ecx edx esi |
mov ecx, eax |
lea esi, [ebp+EXTFS.inodeBuffer] |
lea esi, [ebp+EXTFS.tempInodeBuffer] |
call extfsGetFileBlock |
jc .ret |
test ecx, ecx |
898,11 → 894,11 |
extfsWriteFileBlock: |
; in: |
; eax = file block number |
; [ebp+EXTFS.inodeBuffer] = inode |
; [ebp+EXTFS.tempInodeBuffer] = inode |
; [ebp+EXTFS.mainBlockBuffer] -> block to write |
push ebx ecx edx esi |
mov ecx, eax |
lea esi, [ebp+EXTFS.inodeBuffer] |
lea esi, [ebp+EXTFS.tempInodeBuffer] |
call extfsGetFileBlock |
jc @f |
test ecx, ecx |
1003,11 → 999,12 |
|
extfsExtendFile: |
; in: |
; [ebp+EXTFS.inodeBuffer] = inode |
; eax = inode number |
; ecx = new size |
push ebx ecx edx esi edi eax |
lea ebx, [ebp+EXTFS.inodeBuffer] |
lea ebx, [ebp+EXTFS.tempInodeBuffer] |
call readInode |
jc .ret |
cmp [ebx+INODE.fileSize], ecx |
jnc .ret |
mov eax, [ebx+INODE.fileSize] |
1038,7 → 1035,7 |
jc .error_inode_size |
add [esp], esi |
sub ecx, esi |
jz .done |
jz .write_inode |
.start_aligned: |
cmp ecx, [ebp+EXTFS.bytesPerBlock] |
jb @f |
1055,7 → 1052,7 |
|
@@: ; handle the remaining bytes |
test ecx, ecx |
jz .done |
jz .write_inode |
mov eax, [esp] |
xor edx, edx |
div [ebp+EXTFS.bytesPerBlock] |
1063,11 → 1060,18 |
call extfsEraseFileBlock |
jc .error_inode_size |
add [esp], ecx |
.done: |
.write_inode: |
xor eax, eax |
.error_inode_size: |
lea ebx, [ebp+EXTFS.inodeBuffer] |
lea ebx, [ebp+EXTFS.tempInodeBuffer] |
pop [ebx+INODE.fileSize] |
push eax |
mov eax, [esp+4] |
call writeInode |
pop ebx |
jc .ret |
xchg eax, ebx |
cmp ebx, eax ; set CF |
.ret: |
pop edi edi esi edx ecx ebx |
ret |
1074,10 → 1078,12 |
|
extfsTruncateFile: |
; in: |
; [ebp+EXTFS.inodeBuffer] = inode |
; eax = inode number |
; ecx = new size |
push ebx ecx edx esi edi |
lea ebx, [ebp+EXTFS.inodeBuffer] |
push ebx ecx edx esi edi eax |
lea ebx, [ebp+EXTFS.tempInodeBuffer] |
call readInode |
jc .ret |
cmp ecx, [ebx+INODE.fileSize] |
jnc .ret |
mov eax, [ebx+INODE.fileSize] |
1108,13 → 1114,13 |
call extfsWriteFileBlock |
jc .error_inode_size |
sub [esp], ecx |
jmp .done |
jmp .write_inode |
|
@@: |
call extfsFreeFileBlock |
sub [esp], esi |
sub ecx, esi |
jz .done |
jz .write_inode |
.start_aligned: |
cmp ecx, [ebp+EXTFS.bytesPerBlock] |
jb @f |
1130,7 → 1136,7 |
|
@@: ; handle the remaining bytes |
test ecx, ecx |
jz .done |
jz .write_inode |
mov eax, [esp] |
xor edx, edx |
div [ebp+EXTFS.bytesPerBlock] |
1150,13 → 1156,20 |
call extfsWriteFileBlock |
jc .error_inode_size |
sub [esp], ecx |
.done: |
.write_inode: |
xor eax, eax |
.error_inode_size: |
lea ebx, [ebp+EXTFS.inodeBuffer] |
lea ebx, [ebp+EXTFS.tempInodeBuffer] |
pop [ebx+INODE.fileSize] |
push eax |
mov eax, [esp+4] |
call writeInode |
pop ebx |
jc .ret |
xchg eax, ebx |
cmp ebx, eax ; set CF |
.ret: |
pop edi esi edx ecx ebx |
pop edi edi esi edx ecx ebx |
ret |
|
linkInode: |
1170,7 → 1183,7 |
add ecx, 8 ; directory entry size |
push esi ebx ecx |
xor ecx, ecx |
lea esi, [ebp+EXTFS.inodeBuffer] |
lea esi, [ebp+EXTFS.tempInodeBuffer] |
mov ebx, esi |
call readInode |
jc .error_inode_read |
1178,11 → 1191,9 |
mov eax, [esi+INODE.sectorsUsed] |
shr eax, cl |
xor ecx, ecx |
push eax ; maximum file block number |
push ecx ; current file block number |
.searchBlock: |
push eax ; blocks total |
push ecx ; current file block number |
cmp eax, ecx |
jz .alloc_block |
call extfsGetFileBlock |
jc .error_get_inode_block |
test ecx, ecx |
1192,7 → 1203,7 |
mov ebx, [ebp+EXTFS.tempBlockBuffer] |
call extfsReadBlock |
jc .error_block_read |
mov ecx, [esp+12] |
mov ecx, [esp+8] |
mov edi, [ebp+EXTFS.tempBlockBuffer] |
mov edx, edi |
add edx, [ebp+EXTFS.bytesPerBlock] |
1222,9 → 1233,7 |
add edi, eax |
cmp edi, edx |
jb .searchSpace |
pop ecx ecx eax |
inc ecx |
jmp .searchBlock |
jmp .nextBlock |
|
.zeroLength: |
mov [edi+DIRENTRY.entryLength], cx |
1248,9 → 1257,14 |
push ecx |
jmp .prepare_block |
|
.nextBlock: |
add esp, 4 |
inc dword[esp] |
mov ecx, [esp] |
cmp ecx, [esp+4] |
jbe .searchBlock |
.alloc_block: |
mov eax, [esp+24] |
mov edx, eax |
mov eax, [esp+12] |
call extfsBlockAlloc |
jc .error_get_inode_block |
mov ecx, [esp] |
1292,7 → 1306,7 |
call extfsWriteBlock |
jc .error_block_write |
mov eax, [esp] |
lea ebx, [ebp+EXTFS.inodeBuffer] |
lea ebx, [ebp+EXTFS.tempInodeBuffer] |
call readInode |
jc .error_block_write |
pop eax |
1321,11 → 1335,11 |
; out: |
; eax = current number of links to inode, -1 = error |
push edx ebx |
lea ebx, [ebp+EXTFS.inodeBuffer] |
lea ebx, [ebp+EXTFS.tempInodeBuffer] |
call readInode |
jc .fail |
push eax |
lea esi, [ebp+EXTFS.inodeBuffer] |
lea esi, [ebp+EXTFS.tempInodeBuffer] |
.loop: |
mov ecx, [esp] |
call extfsGetFileBlock |
1387,7 → 1401,7 |
call extfsWriteBlock |
jc .fail |
mov eax, [esp] |
lea ebx, [ebp+EXTFS.inodeBuffer] |
lea ebx, [ebp+EXTFS.tempInodeBuffer] |
call readInode |
jc .fail |
dec word [ebx+INODE.linksCount] |
1404,23 → 1418,23 |
; out: |
; edi -> file name in UTF-8 |
; esi = last inode number |
; [ebp+EXTFS.inodeBuffer] = last inode |
; [ebp+EXTFS.mainInodeBuffer] = last inode |
; ecx = parent inode number |
; CF=1 -> file not found, edi=0 -> error |
push esi |
lea esi, [ebp+EXTFS.rootInodeBuffer] |
lea edi, [ebp+EXTFS.inodeBuffer] |
lea edi, [ebp+EXTFS.mainInodeBuffer] |
movzx ecx, [ebp+EXTFS.superblock.inodeSize] |
mov edx, esi |
rep movsb |
pop esi |
pushd 0 ROOT_INODE |
mov edi, esi |
cmp [edx+INODE.sectorsUsed], 0 |
jz .not_found |
cmp byte [esi], 0 |
jnz .next_path_part |
xor eax, eax |
mov edi, esi |
pop esi ecx |
ret |
|
1487,7 → 1501,7 |
pop eax |
mov [esp], eax |
mov eax, [ebx+DIRENTRY.inodeNumber] |
lea ebx, [ebp+EXTFS.inodeBuffer] |
lea ebx, [ebp+EXTFS.mainInodeBuffer] |
push eax |
call readInode |
jc .error |
1499,17 → 1513,7 |
cmp eax, DIRECTORY |
jz .next_path_part |
xor edi, edi ; path folder is a file |
jmp @f |
|
.not_found: |
mov esi, edi |
call strlen |
mov al, '/' |
repnz scasb |
mov edi, esi |
jnz @f |
xor edi, edi ; path folder not found |
@@: |
movi eax, ERROR_FILE_NOT_FOUND |
stc |
.ret: |
1553,7 → 1557,7 |
call findInode |
pop ebx |
jc .error_ret |
lea esi, [ebp+EXTFS.inodeBuffer] |
lea esi, [ebp+EXTFS.mainInodeBuffer] |
test [esi+INODE.accessMode], FLAG_FILE |
jnz .error_not_found |
jmp @f |
1560,7 → 1564,7 |
|
.root_folder: |
lea esi, [ebp+EXTFS.rootInodeBuffer] |
lea edi, [ebp+EXTFS.inodeBuffer] |
lea edi, [ebp+EXTFS.mainInodeBuffer] |
movzx ecx, [ebp+EXTFS.superblock.inodeSize] |
shr ecx, 2 |
push edi |
1637,15 → 1641,15 |
jz .empty_rec |
inc dword [edi+8] |
inc dword [edi+4] |
push ebx edi ecx esi edx edi |
push ebx edi ecx esi edx |
pushd [edi+12] |
mov edi, edx |
xor eax, eax |
mov ecx, 40 / 4 |
rep stosd |
popd [edx+4] edi |
popd [edx+4] |
mov eax, [ebx+DIRENTRY.inodeNumber] |
mov ebx, [ebp+EXTFS.tempBlockBuffer] |
lea ebx, [ebp+EXTFS.tempInodeBuffer] |
call readInode |
jc .error_read_subinode |
mov esi, ebx |
1761,7 → 1765,7 |
pop ebx |
jc .error_eax |
push ERROR_ACCESS_DENIED |
lea esi, [ebp+EXTFS.inodeBuffer] |
lea esi, [ebp+EXTFS.mainInodeBuffer] |
mov ax, [esi+INODE.accessMode] |
and ax, TYPE_MASK |
cmp ax, FLAG_FILE |
1889,7 → 1893,7 |
push edx |
call findInode |
pop edx |
lea esi, [ebp+EXTFS.inodeBuffer] |
lea esi, [ebp+EXTFS.mainInodeBuffer] |
jnc @f |
push eax |
call ext_unlock |
1943,7 → 1947,7 |
jc @f |
push esi ; inode number |
lea esi, [edx+16] |
lea edi, [ebp+EXTFS.inodeBuffer] |
lea edi, [ebp+EXTFS.mainInodeBuffer] |
call fsCalculateTime |
add eax, 978307200 ; 01.01.1970-01.01.2001 = (365*31+8)*24*60*60 |
mov [edi+INODE.accessedTime], eax |
1974,13 → 1978,13 |
push eax |
jc .ret |
pop eax |
lea edx, [ebp+EXTFS.inodeBuffer] |
lea edx, [ebp+EXTFS.mainInodeBuffer] |
movzx edx, [edx+INODE.accessMode] |
and edx, TYPE_MASK |
cmp edx, DIRECTORY |
jne .file |
push ebx ecx edx 0 |
lea esi, [ebp+EXTFS.inodeBuffer] |
lea esi, [ebp+EXTFS.mainInodeBuffer] |
.checkDirectory: |
mov ecx, [esp] |
call extfsGetFileBlock |
2030,11 → 2034,11 |
call unlinkInode |
@@: |
mov eax, [esp] |
lea ebx, [ebp+EXTFS.inodeBuffer] |
lea ebx, [ebp+EXTFS.mainInodeBuffer] |
call readInode |
jc .error_stack4_eax |
; free file's data |
lea esi, [ebp+EXTFS.inodeBuffer] |
lea esi, [ebp+EXTFS.mainInodeBuffer] |
xor ecx, ecx |
@@: |
push ecx |
2052,7 → 2056,7 |
@@: ; free indirect blocks |
pop ecx |
push edx |
lea edi, [ebp+EXTFS.inodeBuffer] |
lea edi, [ebp+EXTFS.mainInodeBuffer] |
mov eax, [edi+INODE.addressBlock] |
test eax, eax |
jz .success |
2091,7 → 2095,7 |
xor eax, eax |
movzx ecx, [ebp+EXTFS.superblock.inodeSize] |
rep stosb |
lea edi, [ebp+EXTFS.inodeBuffer] |
lea edi, [ebp+EXTFS.mainInodeBuffer] |
call fsGetTime |
pop edx |
add eax, 978307200 |
2161,10 → 2165,10 |
inc ebx |
push ebx esi edi |
xor al, al |
lea edi, [ebp+EXTFS.inodeBuffer] |
lea edi, [ebp+EXTFS.tempInodeBuffer] |
movzx ecx, [ebp+EXTFS.superblock.inodeSize] |
rep stosb |
lea edi, [ebp+EXTFS.inodeBuffer] |
lea edi, [ebp+EXTFS.tempInodeBuffer] |
call fsGetTime |
add eax, 978307200 |
mov [edi+INODE.accessedTime], eax |
2244,10 → 2248,10 |
inc ebx |
push ebx ebx esi edi |
xor al, al |
lea edi, [ebp+EXTFS.inodeBuffer] |
lea edi, [ebp+EXTFS.tempInodeBuffer] |
movzx ecx, [ebp+EXTFS.superblock.inodeSize] |
rep stosb |
lea edi, [ebp+EXTFS.inodeBuffer] |
lea edi, [ebp+EXTFS.tempInodeBuffer] |
call fsGetTime |
add eax, 978307200 |
mov [edi+INODE.accessedTime], eax |
2272,12 → 2276,13 |
jmp ext_WriteFile.start |
|
.exist: |
lea edx, [ebp+EXTFS.inodeBuffer] |
lea edx, [ebp+EXTFS.mainInodeBuffer] |
movi eax, ERROR_ACCESS_DENIED |
test [edx+INODE.accessMode], FLAG_FILE |
jz .error ; not a file |
pop ebx |
push ebx esi |
mov eax, esi |
mov ecx, [ebx+12] |
call extfsTruncateFile |
jnc ext_WriteFile.start |
2298,7 → 2303,7 |
pop ebx |
push ebx esi |
jc .error |
lea edx, [ebp+EXTFS.inodeBuffer] |
lea edx, [ebp+EXTFS.mainInodeBuffer] |
movi eax, ERROR_ACCESS_DENIED |
test [edx+INODE.accessMode], FLAG_FILE |
jz .error ; not a file |
2389,7 → 2394,7 |
.error_inode_size: |
mov [esp+12], eax |
.write_inode: |
lea ebx, [ebp+EXTFS.inodeBuffer] |
lea ebx, [ebp+EXTFS.tempInodeBuffer] |
pop eax eax |
call writeInode |
pop ebx |
2419,7 → 2424,7 |
call findInode |
pop ecx |
jc @f |
lea edx, [ebp+EXTFS.inodeBuffer] |
lea edx, [ebp+EXTFS.mainInodeBuffer] |
movi eax, ERROR_ACCESS_DENIED |
cmp [edx+INODE.accessMode], FLAG_FILE |
jnz @f ; not a file |
2426,10 → 2431,11 |
mov eax, esi |
call extfsExtendFile |
jc @f |
mov eax, esi |
call extfsTruncateFile |
jc @f |
mov eax, esi |
lea ebx, [ebp+EXTFS.inodeBuffer] |
lea ebx, [ebp+EXTFS.tempInodeBuffer] |
call writeInode |
@@: |
push eax |