bitmap的清零是由bitmap_daemon_work()来实现的。Raid1守护进程定期执行时调用md_check_recovery,然后md_check_recovery会调用bitmap_daemon_work根据各种状态进行清零的操作。Bitmap_daemon_work的实现比较复杂,bitmap的清理需要两次调用bitmap_daemon_work来完成的。下面主要以图的形式逐步分析bitmap清除的全部过程。
刚进入这个函数的时候内存bitmap file的页bitmap_attr设置为BITMAP_PAGE_CLEAN。
每次进入bitmap_daemon_work首先判断该函数是否睡够,如果没有睡够,则直接返回。这个睡眠是为了将一定时间见内的写盘操作集中批量处理。为了达到异步刷磁盘的效果,bitmap_daemon_work函数进行两轮才完成bit的清除。
第一次bitmap_daemon_work()的作用:
- 将所有的内存bitmap file的页bitmap_attr的属性BITMAP_PAGE_CLEAN清除;
- 设置bit所在页属性为BITMAP_PAGE_CLEAN和BITMAP_PAGE_NEEDWRITE;
- 处理到的每个bit对应的*bmc值设置为1。
第二次bitmap_daemon_work()的作用:
- 将所有的内存bitmap file的页bitmap_attr属性BITMAP_PAGE_CLEAN清除;
- bit对应的*bmc设置为0;
- bit逐一清零;
- 将bitmap_attr属性BITMAP_PAGE_NEEDWRITE清除;
- bitmap对于一个page的bitmap file一次下刷到磁盘。
不论哪次进入bitmap_daemon_work(),处理流程都是以page为单位来对bitmap file缓存处理,从第一个page逐步处理到最后一个page,作为一个大循环遍历所有的page。在page内部,以每个bit和对应的chunk来处理,从第一个chunk逐步处理到最后一个chunk。
具体处理流程见下面几幅图所示,注意其中的lastpage的含义可能会有不同,已经在图中标出,需要注意的是每一步的先后顺序,bitmap_attr属性设置、bitmap刷磁盘的时机,每次处理bitmap file的page的不同之处已经用红框标出。
这种异步清零的机制好处在于,在还未清零或者内存位图清0但没有刷到磁盘的时候,又有对该页的写请求到来,就只用增加bmc计数器或者只是把内存位图置位,而不用再写到外存的位图文件中,从而减少了一次写外存位图的io。另外,bit清零不用急着去做,异步则可以使系统资源转向处理更要紧的进程。
……
……
……
……
……
……
转载请注明出处:http://www.cnblogs.com/fangpei/