<@UUC4EN004>: i was hoping for some agent to popup...
# aros
o
@Kalamatee: i was hoping for some agent to popup and repair that f* virtual disk πŸ™‚
πŸ˜‚ 1
j
Claude is saying: The error is a length rejection in nvme.device, not a bad block on your drive The requester is the FAT handler's, from rom/filesys/fat/disk.c (the title string "FAT filesystem" is at rom/filesys/fat/support.c:98). It prints
num
and
num + nblocks - 1
, so "3024 - 3039" tells me the failing request was 16 sectors, 8192 bytes, starting at device sector 3024. 3024 is your partition's first sector. The handler computes
first_device_sector = de_BlocksPerTrack * de_Surfaces * de_LowCyl
at volume.c:97, and 63 Γ— 16 Γ— 3 = 3024, so the partition begins at cylinder 3. The FAT cache works in fixed 32-sector ranges (
RANGE_SHIFT 5
in cache.c:62). The range holding the volume's first FAT sector (3025) has base 3008, which starts before the partition, so
AccessDisk
clamps it to num=3024, nblocks=16. That is why you get a 16-sector window at an address that is 16-aligned but not 32-aligned, and why it is the very first multi-sector transfer this volume ever attempts. Now the driver side. nvme_io.c:73 refuses the request on length:
Copy code
} else if ((len == 0) || (len > (1 << unit->au_Bus->ab_Dev->dev_mdts) * unit->au_Bus->ab_Dev->pagesize)) {
dev_mdts
is taken straight from Identify Controller at nvme_controllerclass.c:420 with no interpretation, and
pagesize
is 4096 (
PAGESHIFT 12
, MPSMIN 0). In the NVMe spec, MDTS = 0 means there is no maximum transfer size. AROS reads it as a power of two unconditionally, so 0 becomes
(1 << 0) * 4096
= one page. Every transfer over 4096 bytes gets
IOERR_BADLENGTH
. The arithmetic pins this down rather than leaving it a guess: for an 8192-byte request to be refused, the cap has to be below 8192, and
(1 << mdts) * 4096 < 8192
only when
mdts == 0
. So your controller reports MDTS 0 and AROS is treating "no limit" as "one page, 8 sectors". Why only FAT breaks nvme_busclass.c:616 sets
DE_MAXTRANSFER
from the same expression, so every partition on that drive advertises MaxTransfer 4096. SFS and FFS honour MaxTransfer and split their transfers, so your system partition keeps working. The FAT handler ignores MaxTransfer completely,
AccessDisk
never looks at it, so FAT walks straight into the cap. That asymmetry is the giveaway. Why it lands in the same place after a reboot Nothing random is involved. Mounting reads the FAT through the same cache, and
first_fat_sector
is 1 for FAT12/16, so the first cache fill is sector 3025 again, same clamp, same 8192 bytes (fat.c:51). On FAT32 the FSInfo read at
first_device_sector + 1
(volume.c:381) does exactly the same thing. Since the error hit during format at 3024 rather than at 3040, your partition is under 512 MiB and got FAT16 (volume.c:495 picks FAT16 below 1024Γ—1024 sectors). Format also aborts at the first FAT block, so the boot sector is on disk but the FAT is never written. You are left with something that looks like a FAT16 volume and fails the moment anything reads its FAT. Why Wanderer goes away Two things stack up.
ErrorMessage
calls
EasyRequestArgs
and blocks the handler process until you answer, so every DOS packet to that volume stalls while the requester is up. And once any block is dirty,
Cache_Flush
puts the failed block back at the head of the dirty list, while
HandleTimer
calls
UpdateDisk
once a second (timer.c:95). So the requester returns every second, indefinitely. Retry can never succeed, because the size is refused deterministically before the command ever reaches the controller. Confirming it in one line The BADLENGTH
bug()
is not wrapped in
D()
, so it prints on a normal build. On a serial log or under sashimi you should see:
Copy code
[NVME00] nvme_sector_rw: BADLENGTH (read 8192 bytes at block bd0, cmd 24, task 'FAT filesystem')
0xbd0 is 3024, cmd 24 is TD_READ64. If that line is there, it is MDTS and the fix is to treat
mdts == 0
as unlimited, capped by the 16-bit NLB field. If you instead see BADADDRESS, or no line at all (meaning the controller itself completed with an error status), then I am wrong about the cause and I would look at the PRP list construction in nvme_prp.c next. Worth knowing: no partition alignment will dodge this. The cap is 8 sectors and the cache always asks for 32, so aligning the partition just moves the failure from an 8192-byte request to a 16384-byte one. Three nearby problems I noticed while reading, none of them your symptom: the bounds check at nvme_io.c:70 tests only the starting LBA against
au_High
, so a transfer starting inside the namespace but ending past it still gets submitted;
cmdio.rw.length = (len >> au_SecShift) - 1
silently truncates a length that is not a whole number of LBAs; and
pagesize
is a
UWORD
in nvme_intern.h:159, so a controller reporting MPSMIN 4 would truncate 65536 to 0 and then fail every single transfer.
o
impressive
but how would i have typed that as long a text in so short time?
even
very handy, T
j
You don't type that, I just asked: "in aros", and then your message, and I had to stop it from correcting anything. I'd be curious to hear if that described the problem accurately. And if it's wrong, to be fair, I stopped it from making changes which is probably how it refines the prognostic along the way.
o
read the last commits from kalamatee?
i'm out re-compiling again) lol
this is very near. or correct anyway. too much verbuous
j
I did not read them, no. I can't program while I'm in holidays πŸ˜› And it is verbuous, but you generally don't read it, it gives you a sense of it and usually does the work in parallel. sorry if you know all that already πŸ˜‰
o
don't be sorry, i dont know
☺️ 1