了解 Mac OS 块设备和 IOFilterScheme KEXT 的缓冲

Understanding buffering for Mac OS block devices and IOFilterScheme KEXTs

我正在尝试了解 IOFilterScheme KEXT 的工作原理,以便最终自己开发一个。我已经尝试了一些示例程序并获得了基本的加密功能,例如使用 this sample.

但是,当我添加 printf() 语句并查看控制台日志时,我看到了一些令人困惑的行为。具体来说,我几乎从来没有看到 read() 调用进来,除了我配置东西时的几个进程(比如 mount_hfs 和 fsck_hfs)。

例如,如果我从某个应用程序(例如:vim)向卷(从已安装的磁盘映像)写入一个新文件,当我在控制台日志中看到相应的 write() 时,正确的 PID 为 'vim'。我在使用其他应用程序时也看到了这一点。

但是,如果我尝试从另一个应用程序(比如 Sublime Text 编辑器)读取同一个文件,该文件可以正常打开,但我从未在控制台日志中看到任何相应的 read() 条目。

虽然我可以通过查看 DMG 文件判断样本加密工作正常,但我看到的行为有两个问题:

1) 我很难理解读写方面的情况。

2) 最终我想编写一个 KEXT,其中的行为因进行读取或写入的应用程序而异。为此,我需要每个尝试访问该文件的应用程序的实际 read()(至少在该应用程序第一次访问该文件时)。

经过一些研究,Mac OS 上的块设备似乎有某种缓冲,但我找不到太多细节。实验上,我尝试在 read() 和 write() 调用中执行这一行,但它没有效果

super::IOStorage::synchronize(client, 0, 0);

如果有人能告诉我如何获得对缓冲的更多控制,以便我可以看到实际的 read() 调用,那就太好了。如果那不可能,那么我可能不得不在不同的级别编写我的加密驱动程序。然而,IOFilterScheme KEXT 似乎(除了这一点)它确实适合我的用例,所以我希望我能让它工作。

缓存主要发生在文件级别,在统一缓冲区缓存 (UBC) 中。文件系统本身可以进行任何类型的缓存,尤其是元数据(内部树结构等)。这是 IOKit 之上的许多层,因此您无法从 IOStorage 驱动程序中影响任何这些。

2) Eventually I would like to write a KEXT where the behavior differs depending on the application that is going the reading or writing. To do this, I would need an actual read() from each application that tries to access the file (at least the first time that app does).

尝试在块中执行此操作 I/O kext 可能是傻瓜的差事。现代文件系统是复杂的野兽,因此您不能指望文件 I/O 和块 I/O 之间存在任何类型的 1:1 对应关系。如果你想要 application/file 级别的粒度,你需要在 VFS 层工作,要么通过你自己的文件系统,要么取决于你到底想做什么,使用 kauth。如果你不害怕使用 Apple 明确表示不要使用的 API(例如内部 use/learning),你也可以使用 MAC 框架 kext API,它比 kauth 给你更多的控制。