Skip to content

ecm fix fix partial extend#245

Merged
PerditionC merged 2 commits intoFDOS:masterfrom
ecm-pushbx:ecm-fix-fix-partial-extend
Apr 22, 2026
Merged

ecm fix fix partial extend#245
PerditionC merged 2 commits intoFDOS:masterfrom
ecm-pushbx:ecm-fix-fix-partial-extend

Conversation

@ecm-pushbx
Copy link
Copy Markdown
Contributor

Fixes #243 and properly fixes #241

This updates the commit from #242 with a correction.

I also added two comments on unexpected corner cases around writes of length 0 trying to extend more than actually needed. There is possibly a fragmentation source if a file is extended to fall exactly on a cluster boundary with 0-length write.

Earlier fix was FDOS#242 (this got the
cluster value to use wrong).

Original problem recorded in FDOS#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
 .

===
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
 .

===
@ecm-pushbx ecm-pushbx force-pushed the ecm-fix-fix-partial-extend branch from 9ff74d7 to c63f9f4 Compare April 22, 2026 21:26
@PerditionC PerditionC merged commit 2b7c317 into FDOS:master Apr 22, 2026
1 check passed
@ecm-pushbx
Copy link
Copy Markdown
Contributor Author

I'm not too happy about the calculation in

kernel/kernel/fatfs.c

Lines 1031 to 1035 in dd2293f

fnp->f_dir.dir_size =
(((ULONG)fnp->f_cluster_offset + 1)
* (ULONG)fnp->f_dpb->dpb_secsize)
<<
fnp->f_dpb->dpb_shftcnt;

The problem is that f_cluster_offset (which directly maps to relative current cluster in the SFT) is incremented to 1 when the second cluster has been allocated, so f_cluster_offset + 1 gives the currently allocated amount of clusters during the extend loop.

OH. I think my current and prior patches are both super wrong in one aspect. They will modify the file size when scanning a file (read or write) before EOF. Proper fix upcoming.

@ecm-pushbx
Copy link
Copy Markdown
Contributor Author

Test case to reproduce error: https://pushbx.org/ecm/test/20260422/testtrun.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, (#10240 >> 10)
 mov dx, (#10240 & FFFF)
 int 21
 mov ah, 40
 mov dx, 400
 mov cx, 0
 int 21
 mov ah, 68
 int 21
 nop
 mov ax, 4200
 xor cx, cx
 xor dx, dx
 int 21
 mov dx, 800
 mov ah, 3F
 mov cx, 380
 int 21
 int3
 mov ah, 68
 int 21
 nop
 int3
 nop
 jmp 100
 .

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants