前两篇我们编写了在内存中的最简单的块设备驱动程序,并为其更换了我们心仪的’noop‘IO调度器。本篇我们试着搞清楚内核的块设备层在这里为我们做的事情,以及我们如何做点自己想做的事情。
其实,我们前面两篇都是围绕着请求队列(request_queue)这东西做事情。初始化请求队列时我们注册上驱动处理请求(request)的策略函数(simp_blkdev_do_request),然后在gendisk结构初始化时又填充上前面初始化好的queue。后面我们又用‘noop’IO调度器更换掉默认的'cfq'调度器。
下面试着搞清楚通用块层在这里的框架机制。先看一张图:

当通用块层以上的层要对块设备进行访问时,通常是准备好一个bio,调用generic_make_request(struct bio *bio),OK。
但是我们是编写底层驱动的可怜IT男,要是不知道generic_make_request是怎么把我们前面实现的simp_blkdev_do_request和request_queue联系起来,那就相当没有安全感。于是,我们开始RTFSC。
既然是围着request_queue做文章,那么我们先看下这个数据结构:
struct request_queue{
......

本文详细探讨了块设备驱动中bio如何通过通用块层和IO调度器进行处理。从generic_make_request函数开始,分析了request_queue的数据结构,揭示了bio请求如何通过make_request_fn传递给__make_request,进而触发 simp_blkdev_do_request执行实际的数据操作。在这一过程中,了解了块设备的阻塞与非阻塞状态以及IO调度器的作用。
最低0.47元/天 解锁文章
238

被折叠的 条评论
为什么被折叠?



