From f2b939c5ba779ade12e7e8711ab44092079bf936 Mon Sep 17 00:00:00 2001 From: "E. C. Masloch" Date: Wed, 22 Apr 2026 22:40:43 +0200 Subject: [PATCH 1/2] fatfs.c: fix earlier fix, update dir_size in map_cluster loop Earlier fix was https://github.com/FDOS/kernel/pull/242 (this got the cluster value to use wrong). Original problem recorded in https://github.com/FDOS/kernel/issues/241 Reset disk scriptlet: nasm -I ~/proj/lmacros/ ~/proj/bootimg/bootimg.asm \ -D_PAYLOADFILE=::empty -o diskempt.img cp -a ~/proj/kernel/bin/kernel.sys fdkernel.sys Run dosemu2 with -I "floppy { device diskempt.img }" After a test, run /sbin/dosfsck -n diskempt.img The following Script for lDebug files are test cases: === testshrt.sld e 200 "A:\test.dat" 0 f 300 l 100 26 a mov ah, 3C mov cx, 0 mov dx, 200 int 21 xchg bx, ax mov ax, 4200 mov cx, 1000 mov dx, cx int 21 mov dx, 300 mov cx, 10 mov ah, 3F int 21 . r v0 := aao a mov ah, 40 int 21 int3 int3 jmp (v0) . === testfull.sld e 200 "A:\test.dat" 0 f 400 l 400 38 a mov ah, 3C mov cx, 0 mov dx, 200 int 21 xchg bx, ax mov ax, 4200 mov cx, ((#1424 * #1024 - 1) >> 10) mov dx, ((#1424 * #1024 - 1) & FFFF) int 21 mov ah, 40 mov dx, 400 mov cx, 1 int 21 mov ah, 68 int 21 mov ax, 4202 mov cx, -1 mov dx, -10 int 21 mov ah, 40 mov dx, 400 mov cx, 10 int 21 int3 mov ah, 68 int 21 nop int3 nop jmp 100 . === testful2.sld e 200 "A:\test.dat" 0 f 400 l 400 38 a mov ah, 3C mov cx, 0 mov dx, 200 int 21 xchg bx, ax mov ax, 4200 mov cx, ((#1424 * #1024 - #512 - 1) >> 10) mov dx, ((#1424 * #1024 - #512 - 1) & FFFF) int 21 mov ah, 40 mov dx, 400 mov cx, 1 int 21 mov ah, 68 int 21 mov ax, 4202 mov cx, -1 mov dx, -10 int 21 mov ah, 40 mov dx, 400 mov cx, 10 int 21 int3 mov ah, 68 int 21 nop int3 nop jmp 100 . === testful3.sld e 200 "A:\test.dat" 0 f 400 l 400 38 a mov ah, 3C mov cx, 0 mov dx, 200 int 21 xchg bx, ax mov ax, 4200 mov cx, ((#1424 * #1024 - #512) >> 10) mov dx, ((#1424 * #1024 - #512) & FFFF) int 21 mov ah, 40 mov dx, 400 mov cx, 0 int 21 mov ah, 68 int 21 mov ax, 4202 mov cx, -1 mov dx, -10 int 21 mov ah, 40 mov dx, 400 mov cx, 10 int 21 int3 mov ah, 68 int 21 nop int3 nop jmp 100 . === --- kernel/fatfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/fatfs.c b/kernel/fatfs.c index ec89418f..b10b5694 100644 --- a/kernel/fatfs.c +++ b/kernel/fatfs.c @@ -1029,7 +1029,7 @@ COUNT map_cluster(REG f_node_ptr fnp, COUNT mode) fnp->f_cluster = cluster; fnp->f_cluster_offset++; fnp->f_dir.dir_size = - ((ULONG)fnp->f_cluster + (((ULONG)fnp->f_cluster_offset + 1) * (ULONG)fnp->f_dpb->dpb_secsize) << fnp->f_dpb->dpb_shftcnt; From c63f9f4caf2eb97b47fb8b9865ea26d58b711530 Mon Sep 17 00:00:00 2001 From: "E. C. Masloch" Date: Wed, 22 Apr 2026 23:14:14 +0200 Subject: [PATCH 2/2] fatfs.c: comment unexpected alloc of cluster past needed if CX=0 Reset disk scriptlet: nasm -I ~/proj/lmacros/ ~/proj/bootimg/bootimg.asm \ -D_PAYLOADFILE=::empty -o diskempt.img cp -a ~/proj/kernel/bin/kernel.sys fdkernel.sys Run dosemu2 with -I "floppy { device diskempt.img }" After a test, run /sbin/dosfsck -n diskempt.img The following Script for lDebug is a test case: === testsect.sld e 200 "A:\test.dat" 0 f 400 l 400 38 a mov ah, 3C mov cx, 0 mov dx, 200 int 21 xchg bx, ax mov ax, 4200 mov cx, (#1024 >> 10) mov dx, (#1024 & FFFF) int 21 mov ah, 40 mov dx, 400 mov cx, 0 int 21 int3 mov ah, 68 int 21 nop int3 nop jmp 100 . === --- kernel/fatfs.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/kernel/fatfs.c b/kernel/fatfs.c index b10b5694..249ced95 100644 --- a/kernel/fatfs.c +++ b/kernel/fatfs.c @@ -1218,9 +1218,21 @@ long rwblock(COUNT fd, VOID FAR * buffer, UCOUNT count, int mode) if (dos_extend(fnp) != SUCCESS) { + /* ecm: control flow may end up here if CX = 0000h and + the extending failed to allocate a cluster + behind the last needed. in this case, our + return here of 0 happens to be correct and + indicates the extension succeeded. */ fnode_to_sft(fnp); return 0; } + /* ecm: if CX = 0000h and seek was on a cluster boundary > size, + the dos_extend call will have allocated one cluster + too many. this is truncated later without problems. + but does this aid fragmentation maybe ? + if CX > 0000h then we want to write to the cluster + anyway, so extending to the cluster that starts at + the boundary is desired. */ } /* Test that we are really about to do a data transfer. If the */