read()/write()的生命旅程之五——第五章:从bio到media

第四章中writeback thread已经将要写的page或inode(meta data)变成了bio,bio就是已经对应到了block device的哪一块了。本章我们就要搞清楚最后一步,即bio是怎样写到实际的存储media上的。下面这张图从submit_bio开始,揭示了bio最后被写到media上的过程。

从上图可以看到,写到media的过程以submit_bio()触发,通过BLOCK_SOFTIRQ完成接力。bio被合并成request,放在request queue里。

1. request queue的init
前面讲writeback的时候已经讲过request queue是在add block disk的时候创建的。下图以scsi disk为例,说明了request queue的建立过程。request queue有6个重要的函数钩子,下图橙色方块中。这些钩子函数是由block device的(这里是scsi disk)的 driver注册的,但q->make_request_fn()是用的通用的blk_queue_bio()。


2. submit_bio()的作用:
(1)将bio被合并到request queue里的某一个request中,如不能合并则创建一个行的request。通过q->make_request_fn()完成。
(2)从request queue里取得一个request,将该request写到media。通过q-> request_fn()函数完成。

下图是submit_bio()的内部流程:
submit_bio()的核心函数是generic_make_request(bio)

在q->make_request_fn()中将bio merge到某个request中,同时因为增加了一个bio,原本不相邻的两个request可能变得相邻,从而可以merge成一个request。
在q->request_fn(q)中执行真正的HW读写media。

3. q->request_fn()做了什么
q->request_fn()是由具体的block disk driver实现的,这里以scsi disk为例简单看一下一个具体的block device driver里是怎样处理request的。

这里最重要的一点是最后在完成一个request后,将其link到per_cpu_list blk_cpu_done上并将BLOCK_SOFTIRQ raise起来。这样在下一次softirq或ksoftirqd的时候将接力处理下一个request。下面我们来看看block softirq里是怎样接力的。

4. BLOCK_SOFTIRQ的接力

我们可以看到注册好的q->softirq_done_fn()函数会在softirq时调用,这个例子里 q->softirq_done_fn()是scsi_softirq_done()。在这个函数里最终会再次调用q->request_fn(q),从queue里读出下一个request,开始下一轮接力,知道queue里不再有request为止。

至此,从bio写到media的过程就讲完了。全部5章的read()/write()的生命旅程也讲完了。其中许多细节还需要在阅读代码和调试过程中慢慢体会~~~
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值