Skip to main content


reshared this

in reply to Simon Tatham

The slightly more specific root cause:

The key difference between OFS and FFS is that in OFS, each disk sector that contains file _data_ (as opposed to file headers, directories, etc) has a 24-byte header, and only 488 bytes of data. In FFS, they threw out the header, and just use all 512 bytes of the sector for data.

It was possible to make that design change because none of the data in the header is _necessary_. It's all redundant copies of things you could have worked out another way. So Linux implementations of the filesystem ignore it completely when reading, which makes their OFS and FFS reading code conveniently more similar.

Therefore they can get it very wrong indeed, without noticing any problem themselves!

(2/5)

This entry was edited (21 hours ago)
in reply to Simon Tatham

The reason the Linux kernel created disk files that the Amiga just wouldn't read at all:

One of the fields in the OFS data block header is a sequence number: each data block identifies itself as "I am the Nth block in this file". The sequence numbers are supposed to start at 1. But the Linux kernel wrote them starting from 0. It did it consistently, so I guess that was just a misunderstanding.

When I found this problem I hoped that it might be specific to _creating_ files, so I worked around it by making a valid file using the Amiga, and overwriting its data. I guessed right (although wrong about the cause, I was expecting a bogus field in the _file_ header). Writing an existing file, the kernel finds the sequence numbers already set up and doesn't mess with them.

I made sure my starting file was at least the same size as the one I wanted, on general principles of caution. That was a good call too – otherwise the kernel would have had to add data blocks at the end, and got the sequence numbers wrong again!

(3/5)

This entry was edited (22 hours ago)
in reply to Simon Tatham

in reply to Simon Tatham

As well as the Linux kernel, I also tried an independent implementation of the Amiga filesystem: 'fuseadf', a FUSE wrapper around 'ADFlib'. That too had the problem that it seemed to have been mostly tested on FFS and neglected OFS.

But ADFlib went the other way. It wrote data blocks with a too _short_ size field, by forgetting to update the field at all when you appended to a block.

My file copy wrote 4096 bytes to the file in its first write(). That left a short data block at the end, because 4096 isn't a multiple of 488. Then it appended another 4096 bytes, so that that short data block was filled up and more blocks appeared after it – but the data block that had _temporarily_ been short still had its old data-size header value, claiming less than 488 bytes.

So when the Amiga read _that_ file back, it _deleted_ ranges of bytes from the file!

ADFlib has merged my fix now. The Linux kernel might take longer…

(5/5)

This entry was edited (21 hours ago)
in reply to Simon Tatham

Nice story!

Do you have links to the fixes? Could be fun to see...

in reply to Adam Sjøgren

@asjo two kernel patches: lore.kernel.org/linux-fsdevel/…

ADFlib PR: github.com/lclevy/ADFlib/pull/…

in reply to Simon Tatham

Wow, what a flashback. I had almost forgotten about the Amiga's OFS and FFS. 💚
in reply to Metin Seven 🎨

@metin I hadn't known there were two in the first place! But then, that's not surprising, because when I was an Amiga user, there weren't. 😀
in reply to Simon Tatham

🙂 When did you use your Amiga? I started with an A1000 in 1986, and ended with an A4000 in the mid-1990s. Such great times. 💚
in reply to Metin Seven 🎨

@metin mine was an A500, acquired around 1988 (though I can't remember the exact date). I kept using it until I went off to university in 1994, when I replaced it with a boring old PC.

I never upgraded it to a more up-to-date actual computer, but I did end up giving it a hard disk, via a strange third-party upgrade Dad found somewhere which fitted into the slot on the bottom where the 512Kb RAM upgrade went, and was indeed a perfectly functional 512Kb RAM upgrade but _also_ an ST-506 interface. Dad's employer had a ton of disused ST-506 hard drives waiting to be landfill, and didn't mind employees helping themselves, so he brought an armful of them back from work one day and we tried them all until we found one that still worked.

in reply to Simon Tatham

I know the jokes have all been done, but sounds like it'd be fair to call the FS that linux'd accidentally implemented "OFFS"?
in reply to Philippa Cowderoy

@flippac ah, yes, in the same way that if you UTF-8-encode something twice, or encode the Unicode typographical quotes by UTF-8-ifying their Windows-1252 code points, you're writing WTF-8.
in reply to Simon Tatham

So far as I can remember, OFS remained the default for floppy disks even up to AmigaOS 3.1, while FFS was used on most hard disks. I think the reasoning was that the extra data validation and copying of data in OFS was worthwhile for slow and unreliable floppy disks but unnecessary and a performance bottleneck for hard disks.