Lessons from Ancient File Systems
madcompiler.blogspot.com
madcompiler.blogspot.com
Interesting to hear this terminology used in the context of 8-bit Atari computers. The terms NOTE and POINT come from IBM mainframes, where there are OS/360 macros by those names. NOTE essentially does an fgetpos and POINT an fsetpos
IIRC, it also would occasionally write a backup copy of the file allocation table on another normally unused track as well as parking the disk head away from the track where the directory was after some default period of inactivity. Floppy drives were notorious for occasionally crashing the heads into whatever track they happen to be over if there was a power glitch or software crash - and of course, statistically, they spent most of their time over the directory track, thus greatly increasing to odds of blasting part of the file allocation table.
When I moved to PCs I remember being surprised that NTFS didn't seem to do any of this (at least early on) despite being more recent and supposedly advanced.
Which disk blocks were still available for allocation was tracked by the bitmap (never documented in the original AmigaDOS Manuals), a series of blocks in which each bit stood for an individual block which was either allocated or not. There is just one bitmap for the entire volume and the Amiga default file system did not care for redundancy. The bitmap does not even use block checksums because you could reconstruct it at any time by following the directory structures (unless the bitmap was corrupted and spread its troubles, which you would never suspect or know). This is what, as a by-product, the Disk-Validator accomplished in the Kickstart 1.x days.
The floppy disk version of the Amiga default file system made use of checksums for each of its data structures, with the exception of the bitmap. This made it slow going, but then you quickly learned of defects which the file system reported.
Fun fact: the Amiga default file system in the Kickstart 1.x days was particularly and likely needlessly slow during directory scanning. The metadata produced by the scanning API would include the number of data blocks which a file would consist of. The file system could have easily calculated that figure from the file size, but it did something else instead: It visited every single data block, counting their number one at a time. If you ever wondered why it took Workbench so incredibly long to read the contents of a volume or drawer until at last one single icon appeared, this is why. On the other hand, scanning a directory automatically verified that all of the file data in this directory was sound.
To the best of my knowledge, the Amiga default file system never paid any attention to the disk head position. The file system was designed for larger mass storage devices (up to 54 MBytes in the Kickstart 1.x version, with 512 bytes per block), not so much for floppy disks. The Amiga disk drive, however, could end up recalibrating the disk head position as needed, which could be mistaken for a return to a parking position, if you will.
The Amiga default file system would use write caching, with the lit floppy disk LED indicating that the cache had not yet been pushed to disk. The disk would keep on spinning for some three more seconds after the last write command had been executed. But if you used a third party floppy disk drive which had the LED indicator tied to the read head actuator instead of the spindle motor, you were likely to remove the disk when the buffer had not been flushed yet.
It's been a few decades since I used Amiga OS as a daily driver, so I must have been misremembering, or more likely, conflating my recollections with aspects of other disk operating systems which struck me as new or interesting around the same time.
I like the OS/8 file allocation scheme: files are always contiguous. Only one growing file can be open for writing and it allocates space out of the contiguous free space (actually it owns all of the free space until the file is closed, where the unused space is then given back). If you run out of disk space, you have to compact the disk, eliminating space taken up by deleted files.
I like it because it's illustrates the surprising fact that you can get away with only one file open for writing for most things.
https://en.wikipedia.org/wiki/CP/M#CP/M_Plus:
“The last 8-bit version of CP/M was version 3, often called CP/M Plus, released in 1983. Its BDOS was designed by Brown. It incorporated the bank switching memory management of MP/M in a single-user single-task operating system compatible with CP/M 2.2 applications”
Note the “single task” part. That excludes a lot from what we nowadays would be included in “most things”. That, I think, is the reason you could get away with that. I also would guess it was more that programmers would either not know what they missed or accepted it as a limitation that kept the OS small.
Compacting/squeezing was only necessary because magnetic disks were contiguous in their nature and had to be erased and rewritten, which was a time consuming (sometimes very time consuming) and potentially dangerous operation leading to a complete data loss if power flickered.
To a certain extent, the compacting is still there and is done in the SSD's (now called «garbage collection»), although it is also transparent to the user and to the operating system.
The future you can plan for, is specifically 10x more. If you have 160KB floppies, then design as though there might be 1.6MB floppies. You'll have to revisit your design anyway for the emergent complexities of the next order of magnitude, but this will at least give you some breathing room.
Designing for 100x more than your system has is overengineering. You have no idea what the needs of the future are, and the design for a 100x system will be detrimental for your current 1x system, and likely sink it. So ironically planning for 100x means you probably won't get there.
Yet that's only going from 2^32 to 2^40.
Windows NT 4 already contained the code necessary to allow for up to 16 exabyte partitions (https://web.archive.org/web/20010208131204/http://support.mi...), but the hardware it was running on probably didn't support anything bigger than a few terabytes. Sure, every text file takes up at least 2MB, but with an exabyte disk, you probably don't care about wasting sectors like that.
Ideally XP required 10GB-20GB for a casual usage.
If I only need to store 20 of them on that floppy, why wouldn't I use UUIDs? Anything else would be more work and likely less flexibility.
Deciding what are 'acceptable' limitations given current constraints vs 'planning for future expansion' is an art form. Unfortunately, too little thought is actually put into that decision in too many cases.
I remember working on a system (NetWare) when the server error code was a single byte. It didn't take long to run out and they started assigning the same error code to multiple conditions. The last one (0xFF) was so widely used, internal docs referred to it as 'something bad happened'.
Eventually, a major release fixed the problem with a different header with expanded fields; but that was not a simple fix. Like I said, backwards compatibility CAN be the bane of innovation.
Well put.