扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
怎样进行Linux内核文件系统的分析,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。
成都创新互联公司主要业务有网站营销策划、网站制作、成都网站建设、微信公众号开发、微信小程序开发、H5页面制作、程序开发等业务。一次合作终身朋友,是我们奉行的宗旨;我们不仅仅把客户当客户,还把客户视为我们的合作伙伴,在开展业务的过程中,公司还积累了丰富的行业经验、全网整合营销推广资源和合作伙伴关系资源,并逐渐建立起规范的客户服务和保障体系。
内核存储栈从上到下主要分为三层:1. VFS 2.Block layer 3.驱动
这张图来自https://blog.vmsplice.net/2020/04/how-linux-vfs-block-layer-and-device.html。主要介绍了内核中存储栈几个重要的数据结构之间的连接关系。VFS层数据结构struct block_device连接着快层数据结构struct gendisk。块层接收到VFS的请求发送到request_queue,驱动最后会响应该请求,操作最后的物理设备。
2.1 VFS层
VFS为不同的底层文件系统(ext4,XFS,NFS等)提供了一个接口层。
open,read等系统调用由VFS处理,然后分发给相应struct file_operations的处理函数。
块设备使用struct block_device表示,VFS层数据结构。struct block_device使用块层数据结构struct gendisk和struct request_queue连接VFS inode和struct file_operations接口。
block device nodes如/dev/sda在fs/block_dev.c中实现,提供了桥的作用,连接VFS和Linux block layer。块层处理实际的IO请求,并且知道磁盘的特定信息,如磁盘容量,块大小等。
2.2 Block layer层
每一个磁盘使用数据结构struct gendisk表示,struct hd_struct表示磁盘分区。
总是存在part0分区,表示整个磁盘
IO请求队列使用struct request_queue表示
2.3 驱动层
磁盘设备驱动程序向块层注册struct genhd,并设置struct request_queue以接收需要提交给物理设备的请求。
即使用户空间可能为磁盘上的多个分区打开struct block_device实例,整个设备也只有一个struct genhd。
驱动层看不到磁盘分区,因为IO请求已经根据分区的起始位置偏移做了逻辑地址的调整处理
VFS连接着块层struct gendisk。设备驱动连接着块层和VFS层struct block_device。块层和其他两层没有直接联系,只是有驱动层注册的回调函数。
内核中的I/O流所经过的组件如下图所示:
这里列出一张内核中存储栈中主要数据结构之间的关联关系图。
这里追踪一个从用户空间出发的read函数调用的数据流,来分析从内核到驱动最终到物理设备硬件的过程。
3.1 内核执行系统调用sys_read响应用户空间的read操作。
3.2 在VFS层调用vfs_read通用的文件系统read接口。这里会根据具体的文件系统类型调用相应的read函数。
3.3 这里以ext4文件系统为例。会执行ext4_file_read_iter。
3.4 VFS层最主要的数据结构式bio,它定义的一系列对文件操作的具体行为。在构造了相应的bio数据结构后,会调用ext4_file_read_iter将请求提交到块层。
3.5 块层收到请求后会根据文件系统是否有定义自己的submit_bio函数来调用自定义函数还是通用submit_bio。ext4文件系统调用的是通用submit_bio。
3.6 块层对于VFS的请求不会直接提交到设备驱动去执行。而是会做合并的延迟处理,因为在物理磁盘上的寻到处理是十分耗时的操作。对于可以与请求队列中的请求进行合并的操作,会首先进行合并。否则会插入请求队列中。内核对于I/O调度有多种不同的算法:1.电梯调度 2. 最后期限算法 3. CFQ完全公平队列算法 4.预期算法 5.No Operations算法。
3.7 最后会调用驱动的queue_rq方法,将请求发送给驱动程序。不同的驱动会注册不同的queue_rq方法。这里以iscsi驱动程序为例。调用执行scsi_queue_rq方法。
3.8 scsi_queue_rq会构造请求cmd,然后调用scsi_dispatch_cmd,分发cmd到底层驱动。
3.9 之后根据不同的底层设备类型,调用相应的queuecommand函数执行cmd命令。
内核的存储栈中,块层起着承上启下的作用。北向承接VFS的发送过来的IO请求,南向对接设备驱动程序,提交请求到设备驱动。这当中比较重要的几个点是:1. 块层对于I/O请求的合并优化处理。这块对于I/O的性能的影响巨大。2. 对于页高速缓存的处理。设计到如何将磁盘数据导入到内存,以及inode等数据结构如何操作访问页数据。对于很多细节好有待分析。
看完上述内容,你们掌握怎样进行Linux内核文件系统的分析的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注创新互联行业资讯频道,感谢各位的阅读!
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流