其实在内核里面,raid的一些代码是很绕的,但如果真正的深入到里面了你就会发现原来它的实现是这么精妙和完美......
在内核里面raid这一块最主要的一些思想有:并发、异步......
以raid5为例,它执行的基本单元是stripe(条带),内核通过设置多个条带(默认256)建立并发所需的物理条件。
而在raid中真正实现并发的核心是:守护线程(md->thread)和同步/恢复线程(sync_request->thread);内核通过这两个线程来控制并实现并发的。以单磁盘坏了需要恢复为例,它由同步/恢复线程(sync_request->thread)来开启,在这个过程中会有向底层磁盘设备进行读写的操作;而这些读写的操作很耗时,如果同步等待的话,那么机器的效率会很低下,那么必然需要采用异步操作,而内核也确实是这样做的:它把读写命令发下去之后继续先把这一轮的事情做完,然后结束。
那既然是异步的话,在磁盘返回数据之后,必然需要一种机制来通知上层。这时候内核就采用回调函数来唤醒守护线程(md->thread),而守护线程(md->thread)被唤醒后就会去执行开始未执行完的操作。
这样每一个stripe(条带)的处理都是有同步/恢复线程(sync_request->thread)来开启,它先把第一轮执行完并把要读写的数据发给下层设备;前面说了下层设备处理数据的操作是异步,那么这时候系统就可以去处理另一个stripe(条带),直到守护线程(md->thread)被唤醒,系统就会去把开始未完成的工作去做完,然后再把stripe(条带)给释放掉。
这样系统怎么实现并发的就很明显了,然而这又有一个问题,当所有的256个stripe(条带)都被使用了,而这时又有新的数据需要处理,那怎么办?
很明显,那只能等待,等到守护线程(md->thread)把任意一个stripe(条带)处理完并把它释放掉才行。
代码:
md_do_sync }同步/恢复线程
sync_request }
往下发读写请求 }
............ }总共256个
............ }
sync_request }
往下发读写请求 }
sync_request
无法获取stripe
unplug_device
end_read_request/end_write_request }
.......... }个数与磁盘读写速率相关
.......... }
end_read_request/end_write_request }
raid5d }守护线程
handle_stripe }把之前未完成的工作做完
releaste_stripe }释放条带
sync_request }获取刚被释放的条带
往下发读写请求 }
..........}之后的处理差不多,可能是交错、循环......
..........}
阅读(1064) | 评论(0) | 转发(0) |