如何在Linux中实现文件系统驱动程序驱动程序?[关闭]


14

假设我已经发明了一个新的文件系统,现在我想为其创建文件系统驱动程序。

如何使用内核模块完成此文件系统驱动程序?

文件系统驱动程序如何访问硬盘,文件系统驱动程序应包含访问硬盘的代码,还是Linux包含设备访问所有文件系统驱动程序使用的硬盘的驱动程序?

Answers:


24

是的,Linux中的文件系统可以实现为内核模块。但是,还有FUSE(USErspace中的文件系统)接口,该接口可以允许常规的用户空间进程充当文件系统驱动程序。如果要对新文件系统进行原型制作,则首先使用FUSE接口对其进行实施可以使测试和开发更加容易。一旦以FUSE形式解决了文件系统的内部问题,然后就可以开始实现其性能优化的内核模块版本。

这是有关在内核空间中实现文件系统的一些基本信息。它已经很老了(从1996年开始!),但这至少应该使您对需要做的事情有一个基本的了解。

如果您选择进入保险丝路线, 这里为libfuse,它是FUSE接口的用户空间端的参考实现。

文件系统驱动程序作为内核模块

基本上,文件系统驱动程序模块的初始化函数只需要调用一个register_filesystem()函数,并将其作为参数提供一个结构,该结构包含一个函数指针,该指针标识文件系统驱动程序中的函数,这将用作标识文件系统的第一步。键入并安装。在此阶段没有任何事情发生。

挂载文件系统时,或者指定文件系统类型以匹配您的驱动程序,或者正在执行文件系统类型自动检测时,内核的虚拟文件系统(简称VFS)层将调用该函数。它基本上说:“这里是一个指向标准Linux块设备的内核级表示的指针。请看一下它,看看它是否可以处理,然后告诉我可以使用它做什么。”

到那时,您的驱动程序应该读取所​​需的内容以验证它是文件系统的正确驱动程序,然后返回一个结构,该结构包含指向该驱动程序可以对该特定文件系统执行的其他功能的指针。或者,如果文件系统驱动程序无法识别磁盘上的数据,则应该返回适​​当的错误结果,然后VFS将向用户空间报告故障,或者-如果正在执行文件系统类型自动检测-将会询问另一个文件系统司机试试。

内核中的其他驱动程序将提供标准的块设备接口,因此文件系统驱动程序将不必实现硬件支持。基本上,文件系统驱动程序可以使用标准的内核级功能以及为其指定的设备指针来读写磁盘块。

VFS层希望文件系统驱动程序为VFS层提供许多标准功能。为了使VFS层对文件系统做任何有意义的事情,其中​​一些是必需的,其他则是可选的,您可以仅返回NULL来代替指向此类可选功能的指针。


1
尽管要完全回答所陈述的问题,这还是一个很好的答案,您还需要对块设备层为文件系统层提供的功能进行一些说明。
卡巴斯德,

我用“这是一个指向标准块设备的指针”的位暗示了这一点,但这是有好处的。我对此进行了扩展。
telcoM

这个答案,特别是对以什么顺序发生的事情的描述是神圣的。我可以阅读某种类型的书/网站,其中对所有“ linux的工作原理”都有类似的描述吗?
亚当·巴恩斯

您可能对Linux Kernel InternalsLinux Device Drivers,3rd Edition感兴趣。当然,还有读取实际源代码的选项。
telcoM


0

是的,通常使用内核驱动程序来完成,该驱动程序既可以作为内核模块加载,也可以编译为内核。

您可以在此处查看类似的文件系统驱动程序以及它们的工作方式。

这些驱动程序可能使用内部内核功能以字节块的形式访问存储设备,但是您也可以使用由块设备字符设备文件夹中的驱动程序公开的块设备


0

您可以使用保险丝来制作用户级文件系统或编写内核模块。由于可以选择多种语言,因此使用保险丝比较容易,并且不会使内核(因此也不会导致整个系统)崩溃。

内核模块可以更快,但是优化的第一条规则是:在测试了工作代码之前不要这样做。第二个是这样的:不要做它,直到有证据证明它太慢为止。第三:除非有证据表明它会使速度更快/更小,否则不要保留它。

是的,内核已经具有用于硬件的驱动程序,您无需重新实现它们。


除了性能以外,FUSE还存在其他主要缺点:很难将其用于根文件系统。(也许有一个initrd可能,但是FUSE二进制文件在引导后无法释放,因为它仍然可以从ramdisk中执行。)
Peter Cordes

1
@PeterCordes无法释放,但这并不意味着不能取消链接。如果仍然有对它的引用,则无论您是否离开initramfs并删除基础二进制文件,它都将保留在内存中。
森林

@forest:对,因此您不能在之后卸载initrd pivot_root,因为initramfs中仍然有繁忙的inode。
彼得·科德斯

/init从initramfs开始的法线(在我看来)将/init在ivot_root之后执行,以将控制权转移到真正的根FS /init。但是,如果对根FS的访问取决于响应内核的FUSE进程,则FUSE二进制文件无法用execve代替自身。好吧,也许可以先启动页面缓存,但这听起来并不可靠。
彼得·科德斯
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.