当前位置: 首页 > 科技观察

了解Linux操作系统中的块设备

时间:2023-03-15 11:05:37 科技观察

块设备是以“块”为单位存储数据的设备,例如磁盘设备、CD或U盘。本文首先重点分析磁盘设备的相关内容。其他设备类型大同小异,暂不介绍。磁盘设备在Windows操作系统下就好像是一个真实的设备,我们可以通过图形界面来管理磁盘设备。图1是Windows下的磁盘管理界面。通过这个界面,可以清楚的看到磁盘设备,并可以进行格式化等操作。图1Windows磁盘设备Linux操作系统的磁盘设备并不直观。在LInux系统“一切皆文件”的理念下,磁盘设备其实就是一个文件,只不过是一个比较特殊的文件。如图2,部分磁盘和分区的文件路径,黄色字体部分为磁盘的路径(类似文件路径),前面红框中的b表示该文件为磁盘设备文件,不是普通文件。图2Linux系统下的磁盘设备磁盘设备文件也位于VFS(VirtualFileSystem)下,类似于Ext4等文件系统(参见图3)。用户平面可以使用访问普通文件的接口(API)来访问磁盘。下面的代码是用Python实现的一个将字符串写入磁盘的程序。代码很简单,就是打开磁盘所在路径(path),然后调用write函数写入数据。Linux系统中磁盘的本质通过上面的描述,我们知道对于Linux操作系统来说,磁盘就是一个文件。磁盘本身就是一个线性的存储空间(可以理解为一个大数组),这和文件很相似。鉴于上述相似性,Linux将磁盘设备抽象为文件并没有错。本质上,Linux操作系统中的磁盘设备是基于一个名为bdev的伪文件系统进行管理的。bdev文件系统是内存中的伪文件系统(filesysteminmemory,nopersistentdata),其位置与Ext4等文件系统相同。如图3所示,bdev文件系统所在位置为图中红色区域。图3bdev文件系统所在位置了解了块设备的管理方式后,结合我们之前对文件系统的介绍,后面的内容就很容易理解了。在文件系统相关文章的介绍中,我们知道不同文件系统处理数据的关键是其提供的函数集,而这个函数集是在文件打开时确定的。磁盘设备也是如此。当我们打开一个磁盘设备时,操作系统会根据该磁盘设备的特性来初始化inode中设置的函数。后续对磁盘设备的读写操作都可以通过这个函数集来完成。如下代码所示,将块设备、字符设备和管道作为特殊文件处理,并初始化相应的函数集。函数集初始化完成后,当用户调用VFS层的接口时,VFS层可以找到具体的处理函数,进而完成用户的操作。这里设置的功能与本地文件系统的功能设置相同。不同的是普通文件系统需要对目录和文件进行管理,而bdev伪文件系统将磁盘当做一个大文件来处理,更加简单。磁盘缓存由于磁盘伪文件系统bdev本身也是一个文件系统,自然要有缓存。此缓存是用于提高磁盘性能的缓存系统。磁盘的缓存系统类似于文件系统的缓存系统,也是通过页缓存来实现的。当然也可以关闭Linux磁盘的缓存,此时又会调用另外一组函数。这听起来可能很抽象。下面通过一个具体的例子来看一下磁盘缓存的具体实现。下面是磁盘伪文件系统的功能集,我们以写入数据为例进行介绍。图4磁盘函数集写入数据的函数是blkdev_write_iter,调用了generic_perform_write函数。如果你看过本期关于文件系统的文件,就知道后者是VFS中向pagecache写入数据的功能。也就是说,块设备伪文件系统的逻辑与本地文件系统完全一样。缓存部分到此结束,具体代码请自行阅读。好了,今天我们主要介绍了Linux磁盘设备及其缓存的原理。稍后我们将逐步详细介绍各种功能。