块设备是一种具有一定结构的随机存取设备,对这种设备的读写是按块进行的,它使用缓冲区来存放暂时的数据,待条件成熟后,从缓存一次性写入设备或者从设备一次性读到缓冲区,块设备与字符设备并列,这两类设备在Linux中驱动的结构有较大差异,块设备驱动比字符设备驱动要复杂得多,在I/O操作上表现出极大的不同,如缓冲、I/O调度、请求队列等都是与块设备驱动相关的概念。
块设备读写流程
1、打开块设备:用户态程序通过open()系统调用打开指定的块设备,陷入内核后执行blkdev_open()函数,该函数注册到文件系统方法(file_operations)中的open上,在blkdev_open函数中调用bd_acquire()函数完成文件系统inode到块设备bdev的转换,得到具体块设备的bdev之后,调用do_open()函数完成设备打开的操作。
2、读写操作:用户程序通过read、write函数对设备进行读写,文件系统会调用相应的方法,如generic_file_read和blkdev_file_write,在读写过程中采用了多种策略,如直接IO方式和buffered write操作过程。
3、数据流操作:对于读操作,如果数据没有命中Cache,则通过address_space->a_ops->readpage函数发起一个真实的读请求,对于写操作,数据被写入Cache后,write函数就可以返回,后续异步写入的任务由pdflush daemon完成。
4、I/O调度:内核中的I/O调度程序子系统负责管理块设备的请求队列,决定队列中的请求的排列顺序以及什么时候派发请求到设备,内核提供了几种电梯算法来实现I/O调度,如No-op I/O scheduler、Anticipatory I/O scheduler、Deadline I/O scheduler和CFQ I/O scheduler。
5、通用块层(Generic Block Layer):由通用块层负责维持一个I/O请求在上层文件系统与底层物理磁盘之间的关系,在通用块层中,通常用一个bio结构体来对应一个I/O请求。
块设备相关结构体
扇区(Sectors):任何块设备硬件对数据处理的基本单位,1个扇区的大小为512字节。
块(Blocks):由Linux制定对内核或文件系统等数据处理的基本单位,1个块由1个或多个扇区组成。
段(Segments):由若干个相邻的块组成,是Linux内存管理机制中一个内存页或者内存页的一部分。
块设备驱动框架
块设备的应用在Linux中是一个完整的子系统,驱动对块设备的输入或输出(I/O)操作都会向块设备发出一个请求,在驱动中用request结构体描述,内核提供一种队列的机制把这些I/O请求添加到队列中(即:请求队列),在驱动中用request_queue结构体描述,在向块设备提交这些请求前内核会先执行请求的合并和排序预操作,以提高访问的效率。
Linux块设备的读写涉及多个步骤和组件,包括打开块设备、读写操作、数据流操作、I/O调度和通用块层等,这些组件协同工作,确保了块设备在Linux系统中的高效运行。
小伙伴们,上文介绍linux 块设备读写的内容,你了解清楚吗?希望对你有所帮助,任何问题可以给我留言,让我们下期再见吧。
本文来源于互联网,如若侵权,请联系管理员删除,本文链接:https://www.9969.net/67411.html