我们知道常规的一个块组是128M,有1个block(假设1个block是4K)的bitmap,也就是4K=4096*8=32768个位,其中每个位代表一个block的使用情况,1代表使用,0代表空闲。这个大家都知道,现在分析一下buddy bitmap的构建:磁盘上的bitmap在内存里使用一个page来表示,而buddy bitmap只在内存里也是一个page,因此一个块组在磁盘的位图占用了两个page,第一个和磁盘对应,第二个是伙伴系统的位图如下图所示:
(注释,此处再次强调bitmap是磁盘上bitmap在内存里的表现,而buddy bitmap只在内存里,是扫描磁盘构建出来的,umount的时候会清理掉)
其中磁盘的bitmap一个位代表一个block的使用情况,而buddy bitmap也是一个page也就是4096 *8 = 32768位,使用前0-16383位表示每2个blocks的使用与否,用16834-24575位表示每4个blocks使用与否,以此类推,情况如下图所示:
以上就是buddy bitmap的存储格式。但是如何利用空闲的block来填充buddy bitmap中的位呢?
这个函数就是在初始化buddy bitmap,首先函数用mb_find_next_zero_bit在bitmap里找到第一个空闲的block的位置,之后再while里,继续在bitmap里找第一个1的位置,从开始的0到下一个1,其实就是在找这之间空闲的块到底有多少个,也就是代码的i-first=len,如果len=1则直接添加到bb_counter[0]里,这里解释一下这个bb_counter是什么意思,源码的注释截图如下:
也就是表示2的index(数组的索引)个blocks的个数,假如bb_counter[3]=5也就是磁盘上连续8个block有5个,所以我们找到的len=1自然也就在bb_counter[0]加1.接着看len>1的情况,这是会调用
代码上面的例子很简单,也就是说假如从5开始有7个block空闲,则要拆分为4+2+1,修改对应的bb_counter,同时根据block要清楚他在buddy bitmap里对应的位,以表示空闲。这样就函数执行完毕,我们就构建出了buddybitmap。最后放一张google到的PPT里的图
从这图就可以看出假设磁盘0-14个block是空闲的,拆分为8+4+2,第一个8个block到对应的buddy bitmap里表示连续8个block的位图区域把第一个位清零。第二个4个block到对应的表示连续4个block的位图区域把第三个清零,最后的两个块,到最开始表示连续2个块的block位图区域把第7个位清零,这样就验证了前面分析的正确性。