Aros/开发者/文档/处理程序/FFS
在原始 AOS FFS 实现中,为软盘的 FFS 处理程序绑定到 trackdisk.device(s)。
当检测到弹出时,ACTION_INHIBIT/TRUE 被发送到 FFS 处理程序。如果没有任何打开的锁,则 FFS 会从卷列表中删除该卷;如果存在打开的锁,则保留在卷列表中。
当插入新的卷时,ACTION_INHIBIT/FALSE 被发送到该 trackdisk.device 的 FFS。如果 FFS 探测磁盘时,不匹配旧卷,则会在 DOS 列表中创建一个新的 DOS 卷。谁会发送 ACTION_INHIBIT 包?我认为处理程序会响应来自设备或 Intuition 的磁盘更改通知。目前情况就是这样。但是,如果多个处理程序连接到同一个设备(例如,一个针对弹出卷(带有打开的锁)的 FFS 处理程序,以及一个当前在设备上运行的 FAT 处理程序),则我认为磁盘更改通知应该通过来自处理程序外部的 DOS 包发出。
否则,FFS 和 FAT 处理程序都会尝试在每次磁盘更改时打开设备,对吗?
[在 AOS 上有一个有趣的测试。准备一堆软盘,分别存储 800K a.txt、b.txt、c.txt 等文件,并在每个软盘上执行 `MORE DF0:a.txt` 等操作,然后弹出软盘,插入新的软盘,并在新的 CLI 中执行 `MORE DF0:b.txt` 等操作,并保持所有这些 MORE 处于打开状态。我想看看会发生什么。] 我认为,直到其中一个 More 任务需要读取更多数据时,才会发生任何事情。然后,会出现一个“请在 DF0 设备中插入“软盘名称”卷”的请求。文件句柄将与特定的卷相关联,即使它们最初是通过设备路径打开的。
但是 trackdisk.device 始终由同一个文件系统处理程序提供服务。如果你将 FAT 和 FFS 都安装到同一个 trackdisk.device,可能会发生奇怪的事情。这就是为什么需要 MultiFS 之类的东西(参见 AmiNet 上的 mfs21.lha)。MultiFS 充当 FFS 和 FAT 文件系统的代理,在磁盘更改后执行磁盘格式检查,然后再将 DOS 包传递给相应文件系统的处理程序。Partition.library 可以发挥 MultiFS 的作用,而无需任何代理。正如你所提到的,trackdisk.device 的情况之所以复杂,是因为通常单个处理程序会静态绑定到其每个单元。分区介质以及动态分配的处理程序更容易处理(即便如此,我还是怀疑将处理程序动态分配给 trackdisk.device 可能是 MultiFS 基于代理的方法的另一种可行方案)。
我建议使用类似的方法。对于每个设备,存在一个 代理(可能是 DOS 包代理,也可能是设备 I/O,我需要进行试验),它在磁盘更改后确定要发送给哪个文件系统类型。
一旦确定,所有未来的数据包/I/O 都将发送到相应的位置。
我目前倾向于使用 DOS 包代理而不是设备代理,因为在处理丢失卷情况以及排队 I/O 而不是简单地将其丢弃时,这(目前)似乎是一个更清晰的实现。
除了我认为,具有相同名称的多个卷可以共存,而无需为它们中的任何一个伪造新名称。你说得对。虽然 DOS 设备必须是唯一的,但 DOS 卷没有这样的限制(当然,这就是 FindDosEntry() 接受 DosList 参数的原因...)。但是,DLT_DEVICEs 必须唯一,并且能够正确处理 ACTION_DIE,并将它们的 dol_Task 设置为 BNULL,以支持弹出和替换备用文件系统。然后,如果处理程序 *不能* 处理 ACTION_DIE(例如,存在打开的锁),则需要在将新的文件系统任务连接到设备之前,向其发送 ACTION_INHIBIT。
这一切都取决于我们如何处理以下用户案例:为了以通用方式支持可弹出、已分区的介质,并检测到旧介质(仍有运行的处理程序)何时返回,以便不会加载新的、相互竞争的处理程序。
- 用户插入一个 FAT32 设备,从该设备复制一个文件,然后弹出设备。
- 用户插入一个 RDB(FFS) 设备,运行一个程序,该程序打开该设备上的一个数据库文件。在文件仍处于打开状态时,设备被物理弹出。
- 然后用户插入一个 MBR(FAT32,FFS) 设备,其中 FAT32 的卷名与之前的 RDB(FFS) 设备相同,但(显然)内容不同。FFS 分区是一个新的名称。
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?