BLOCK层代码分析(1)数据的组织BIO

        对于BLOCK层,表示一个IO的数据结构为BIO和request。对于request在后续的章节中做介绍,这里只介绍与BIO相关的结构体。

1. bio/bio_vec结构体

        bio结构体用于表示数据在内存中的组织以及IO完成情况。结构体bio包含两个重要的结构体: bio_vec和bi_iter。

        结构体bio_vec描述了IO数据在内存中的组织,通过此结构体可以找到数据在内存中的位置。每个bio可能包含多块连续的内存,每块连续的内存用结构体bio_vec表示,其中结构体bio_vec中bv_page指向本块连续内存的物理页的起始位置,bv_len指连续内存的长度,bv_offset表示连续物理内存的起始offset。

        结构体bi_iter描述了数据在硬盘中位置以及当前IO数据的完成情况。其中bi_sector表示数据在硬盘中的扇区号,即表示了数据在硬盘中的位置。bi_size表示BIO剩余未完成的大小。bi_idx表示当前处理到的bio_vec的索引号,即前面的都已经处理完。bi_bvec_done表示当前bio_vec已经完成的大小。

        下图简单描述了bio/bio_vec/bvec_iter之间关系的例子。其中bio包含两块连续内存,分别指向bio_vec 0和bio_vec 1。其中bio_vec 0数据起始位置并不是页首,因此会有offset偏移。而IO已完成bio_vec0,当前在处理bio_vec 1。

        结构体bio其他成员bi_next指向下一个bio;bi_pool指向bio的mempool池;bi_inline_vecs[]表示内置bio_vec,若定义BIOSET_NEED_BVECS,此时在分配bio时也会同时分配一定数目内置bio_vec(这对性能有优化,一般系统中一个IO包含的连续数据段不多时,不需要额外分配其他的bio_vec)。

2. bio_set结构体 

        bio_set主要用于分配bio,其中bio_slab是bio缓冲池(SLAB),大小为front_pad + sizeof(struct bio) + back_pad(若定义BIOSET_NEED_BVECS,此时是内置的bio_vec)。

        bio_slab是bio的SLAB缓存池,用于分配bio结构体。

        bio_pool和bvec_pool分别为分配bio和bio_vec的mempool池,在分配bio和bio_vec时默认是从SLAB分配,但设置mempool池时会提前分配一定数量的内存对象, 当内存不足无法从SLAB分配时会从mempool池中分配。

3. biovec_slab结构体

        结构体biovec_slab为分配bio_vec的SLAB缓冲池。默认系统中定义了四种大小的SLAB缓冲池:

  1. biovec-16: biovec数目为16个,当数据的连续内存数目在5~16个时会从此缓冲池申请;
  2. Biovec-64: biovec数目为64个,当数据的连续内存数目在17~64个时会从此缓冲池申请;
  3. biovec-128: biovec数目为128个,当数据的连续内存数目在65~128个时会从此缓冲池申请;
  4. biovec-max: biovec数目为BIO_MAX_VECS个,当数据的连续内存数目在129~BIO_MAX_VECS个时会从此缓冲池申请;

        有人可能会产生疑问:如果biovec数目为1~4时,没有缓存池可以分配,它是怎么分配的?对于这种情况,就是在BIO中内置biovec的,在分配BIO同时也分配了内置biovec。

4. 小结

        对于数据的组织,需要分别分配BIO和biovec,在biovec数目为1~4时,BIO直接使用内置biovec;当超过4时,分配从bio缓冲池和biovec缓冲池申请bio和biovec,并关联起来。

 

  

  • 7
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值