我的问题根本出版IOMedia:没有简而言之IOBlockStorageDevice
是它KEXT可接受/常见的做法是发布不具有IOBlockStorageDevice在其供应商栈的IOMedia对象?
背景:
我写一个内核扩展,将提供某种形式的虚拟设备到用户空间。 目前我有一个与IOResources相匹配的驱动程序,然后创建一个派生自IOMedia的类的对象并将其附加到'this'。这个媒体对象发布后,标准IOMediaBSDClient附加到它并在/ dev /中创建一个节点。
第一次测试通过,我可以成功地打开创建的设备并从中读取数据,但是当我尝试使用本地FS驱动程序安装它时,我偶然发现了一个问题。设备安装成功,挂载点可浏览,但在此之后的一段时间内,由于vfs代码内部存在段错误,导致内核崩溃。
长时间的调试后,我发现了问题的根源:
- IOMediaBSDClient通过这些设备提供和组合,所有的媒体对象通过媒体父母IOBlockStorageDevice对象迭代,然后迭代实现DKIOCGETTHROTTLEMASK IOCTL其BSD单元编号为位掩码。由于我的介质没有任何IOBlockStorageDevice父项,因此生成的掩码为0.
- 由此ioctl返回的值由vfs_init_io_attributes()用于填充对应于我的装载的mp struct的mnt_throttle_mask字段。
- 在此之后,mnt_throttle_mask被转换为mnt_devbsdunit,通过计算它后面的零。由于在我的情况mnt_throttle_mask是0,mnt_devbsdunit变得64.
- mnt_devbsdunit用于通过spec_strategy(和与节流处理一些其他功能)为_throttle_io_info的元件数目,这是LOWPRI_MAX_NUM_DEV元件和LOWPRI_MAX_NUM_DEV的阵列是等于64。 显然,访问_throttle_io_info的64元素会抛出刚好在它后面的数据,在我的情况下是speclisth数组。
此刻,我看到2种方式在我的代码来解决这个问题: 1.实现从IOMediaBSDClient派生的类将corrrectly处理DKIOCGETTHROTTLEMASK IOCTL。 2.重写代码以发布IOBlockStorageDevice对象,并让标准IOBlockStorageDriver发布Media对象。
就我个人而言,我更喜欢第一个解决方案,但我遇到的问题似乎相当顽固,我无法摆脱我正在做一些根本性错误的想法。
我想避免将来出现这样的问题,因此我在问这个问题。
编辑:至少对于OS X 10.8.3和10.8.5是这样。我还没有在其他版本上测试过。
谢谢您的回答。我将代码转换为IOBlockStorageDevice子类,现在它工作正常。 无论如何,它似乎是这种情况下唯一的选择,因为经过一番调查后,我发现不能简单地在IOMediaBSDClient中重新实现DKIOCGETTHROTTLEMASK ioctl,因为它直接在dkioctl函数中处理。 – 2015-04-04 12:13:07
很高兴你把它全部整理出来!我以前没有意识到DKIOCGETTHROTTLEMASK的问题,你每天都会学到新的东西。 :-) – pmdj 2015-04-04 21:56:29