In the original AOS FFS implementation for floppies, the FFS handler was bound to the trackdisk.device(s).
When an eject was detected, a ACTION_INHIBIT/TRUE was sent to the FFS handler. That volume was then either dropped from the volume list by FFS if there were no open locks, or left in the volume list if there were.
When a new volume was inserted, a ACTION_INHIBIT/FALSE was sent to the FFS for that trackdisk.device. If, when FFS probed the disk, it didn't match the old volume, a new DOS volume was created on the DOS list. Who would send the ACTION_INHIBIT packets? I thought the handler instead responded to disk-change notifications from the device or Intuition. Currently, this is the case. But if multiple handlers are attached to the same device (ie a FFS handler for an ejected volume with an open lock, and a FAT handler which is currently running on the device), would argue that the notification of a disk change should come via a DOS packet from outside the handler.
Otherwise, both the FFS and FAT handlers would try to open the device on every disk change, correct?
[There's in interesting test to run on AOS. Make a pile of floppies with 800K a.txt, b.txt, c.txt, and do a 'MORE DF0:a.txt' etc on each, eject the floppy, put a new one in, do 'MORE DF0:b.txt' in a new CLI, etc, leaving all those MOREs open. I'd like to see what happens.] Don't think anything would happen until one of the More tasks needed to read more data. Then, a "Please insert volume 'Name-of-floppy' in device DF0:" requester would appear. The filehandles will be associated with particular volumes, even if they were initially opened with a device-based path.
But the trackdisk.device was always served by the same filesystem handler. If you mounted both FAT and FFS to the same trackdisk.device, Strange Things Could Happen. Which is why things like MultiFS (see mfs21.lha on AmiNet) were needed. MultiFS acted as a proxy in front of both FFS and FAT filesystems, and did a disk format check after a diskchange before passing the DOS packets to the appropriate filesystem's handlers. Partition.library can play the role that was played by MultiFS without the need for any proxies. As you mention, the case of trackdisk.device was complicated by it being usual for a single handler to be statically bound to each of its units. Partitioned media with dynamically assigned handlers are easier to handle (even so, suspect that dynamically assigning handlers to trackdisk.device might have been a feasible alternative to MultiFS's proxy-based approach)
What I'm proposing is a similar thing. There is a proxy (probably DOS Packets proxy, may be Device IO, I need to experiment) for each device, that determines what filesystem type to send to after a diskchange.
Once determined, all future packets/ios are send to the appropriate location.
I'm currently leaning towards a DOS Packets proxy instead of a device proxy, as that (currently) appears to be a much cleaner implementation when it comes to handling the missing volume case, and queuing IOs instead of just dropping them on the floor.
Except that I thought that multiple volumes with the same name could co-exist without faking new names for any of them. You are correct. While DOS devices must all be unique, DOS volumes have no such restriction (which is, of course, why FindDosEntry() take in a DosList parameter...). However, it still holds true that DLT_DEVICEs must unique, and be able to properly handle ACTION_DIE, and set their dol_Task to BNULL, to support ejection and replacement of an alternate filesystem. Then if the handler *cannot* process the ACTION_DIE (ie open locks), then it needs to have an ACTION_INHIBIT sent to it before the new filesystem task is attached to the device.
It all depends on how we want to deal with the following user cases: To support ejectable, partitioned, media in a general purpose manner, and to detect when the old media that had still-running handlers has returned, so that new, competing handlers are not loaded.
- User inserts a FAT32 device, copies a file off of it, and ejects the device
- User inserts a RDB(FFS) device, runs a program off of it, that keeps opens a database file on that device. While the file is still open, the device is physically ejected.
- User then inserts a MBR(FAT32,FFS) device, where the FAT32 had the same volume name as the preview RDB(FFS) device, but (obviously) different contents. The FFS partition is a new name.
1.a) No locks are held, so this should be the simple case. 1.a.1) Filesystem handler gets sent ACTION_DIE, since it has no locks in the dl_LockList for that handler. 1.a.2) Filesystem is dismounted 1.b) What happens if the handler refuses to ACTION_DIE? 1.c) What happens if the handler refuses to even ACTION_INHIBIT? 2.a) A lock is held. What happens? 2.a.1) Does a requester pop up on the next action to that device? 2.a.2) Do we return errors to the open applications on read/write/etc? 2.a.3) Do we prohibit any other device from being recognized until the original volume is reinserted? 2.b) Do we keep that handler task running? 2.b.1) For how long? Until all its locks are closed (due to error handling by the application)? 2.c) Do we need some sort of iconography in Wanderer/Workbook to let the user know what volumes are 'in use' and should not be ejected? 3.a) Should we assume the OS is smart enough to recognize this case? 3.a.1) Should the OS reject the volume(s)? 3.a.2) Fake a new name for the volume(s) in conflict? (ie 'FooBar.1'?) 3.b) What changes to handlers (if any) are needed to support 3.a? 3.c) Should there be Wanderer/Workbook iconography for missing volumes?