今天,我了解到FreeBSD完全取消了对块设备的支持。当我阅读他们对这个决定的理性时,我发现了这一点:
块设备是内核为其提供缓存的磁盘设备。这种缓存使得块设备几乎不可用,或者至少是危险的不可靠。缓存将重新排序写入操作的顺序,从而使应用程序无法在任何时刻知道确切的磁盘内容。这使得磁盘上数据结构(文件系统、数据库等)的可预测和可靠的崩溃恢复。不可能。由于写入可能会延迟,内核无法向特定写入操作遇到写入错误的应用程序报告,这进一步加剧了一致性问题。
(来自https://www.freebsd.org/doc/en_US.ISO8859-1/books/arch-handbook/driverbasics-block.html)
然而,我知道Linux几乎只使用块设备(尽管可以请求原始设备)。
那么Linux如何绕过这段引用中提到的问题呢?还是大多数驱动程序只是请求一个原始设备呢?
发布于 2015-09-20 23:43:52
BSD是真正的核心,并且经常做一些令人惊讶的事情:-)在我看来,删除块设备层并不是一个问题(例如,nfs甚至没有底层的块设备),但是这种推理并不是针对块设备,而是反对写缓存。在我看来,删除写缓存是一件非常糟糕的事情。如果您的进程向磁盘写入了某些内容,那么直到它没有成功时,您才返回控件?
但我不认为他们不知道自己在做什么。希望有人能在另一个答案中解释他们的理由。
为了清楚地解释这一点,我需要解释一下文件系统是如何工作的。文件系统驱动程序本质上是文件系统操作(目录打开、文件创建、读-写、删除等)和块操作之间的转换层(例如:“将页0xfce2e31写入磁盘块0xc0深度”)。
但是,块操作不能当场到达硬盘。首先,它们将进入块缓存。这意味着,如果文件系统想要将内存页写入磁盘,则首先将其写入保留内存区域。内核的内存管理会将这些数据写入硬盘,如果它认为这是最优的。这就实现了各种速度的改进:例如,许多写操作发生在磁盘的开始和结束,内核可以以这样的方式组合它们,以便磁盘头必须尽可能少地重新定位自己。
还有另一个改进:如果您的程序写入文件,它将经历如此快速的操作,就好像它将是一个ramdisk。当然,这是可能的,直到系统的RAM将不满,之后,他们必须等待清空写缓存。但是,只有在同时执行大量的写操作(例如,您正在复制大型文件)时,才会发生这种情况。
在文件系统方面,在磁盘上运行的文件系统(即块设备)和不运行的文件系统之间有很大的区别(f.e。( nfs)。在第二种情况下,不可能进行块缓存,因为没有块。在他们的例子中,有一个所谓的“缓冲区缓存”,它本质上意味着仍然缓存(读和写),但是它不是围绕内存块组织的,而是任何大小的I/O片段。
是的,在Linux中,有一些“原始”块设备可以在没有块缓存机制的情况下使用磁盘设备。但是这个问题并没有被他们解决。
取而代之的是所谓的“日志记录文件系统”。在日志记录文件系统的情况下,文件系统有机会指示内核,必须先写出哪个页面。如果文件系统中没有日志记录机制,那么它只将块写入磁盘(更准确地说:写到块缓存),如果内核认为它是最佳的,那么内核实际上将执行真正的写操作。
您可以将日志记录文件系统想象为每一次写入操作都会发生两次:首先,进入“日志”,它是磁盘上的一个保留区域,然后才进入它的实际位置。在系统崩溃或磁盘错误的情况下,磁盘的最后一个未损坏状态的内容可以非常快速地在日志上重建。
但是这大大降低了写性能,因为每次写必须执行两次。这就是为什么在现实中,日志记录文件系统的工作方式要复杂得多,他们正在使用各种复杂的数据结构操作,以将这种开销降低到几乎不可见的水平。但这很难做到:例如,ext3相对于ext2的主要改进是包含日志记录,这会使其代码大小成倍增加。
在Linux中,块层API有一个“屏障”机制。文件系统可以在它们的写操作之间设置“屏障”。屏障的意思是,屏障之后的数据只有在屏障被写出来之前,才会被写入磁盘。日志记录文件系统正在使用屏障机制来指示块层实际写入操作的所需顺序。据我所知,他们不使用原始设备映射。
我不知道,FreeBSD对这个案子做了什么。也许它们对块设备的消除只意味着所有的东西都将与缓冲区缓存,而不是与块缓存。或者他们有什么东西不是在这里写的。在文件系统内部,*BSD和Linux世界之间有很大的区别。
https://unix.stackexchange.com/questions/230943
复制相似问题