EXFS的块分配策略

经过进一步的阅读代码,现昨天的一些观点似乎有些问题,把我的一些结论贴出来,请师兄指正。

1.在函数 exfs_blocklayout_get()中,有如下代码

 

Exfs_alloc_blocks()定义如下:

这里面涉及到三个概念

Blocks;segment blocks; alloc_bits;

这三个概念在代码中如下注释

Blocks是物理磁盘块,大小为4K

Segment是三级间址的粒度(和郭博交流后得出的结论,不是非常确定),默认大小是64k

Alloc bits 是描述每次layout分配的粒度参照值为1M

 

则 segment_length ==1 << allocbits << segment bits << 12(即为block bits)

 

造成之前的误解,主要是segment_length命名导致将其理解为 1 << segment bits << 12(即为blockbits);

最好改为alloc_length;

 

 

2在函数exfs_blocklayout_get()中,把要分配的长度截取为一个一个的segment_length之后,调用下面这个函数;

 

Exfs_get_blocknr_offset()入口参数是经过处理的被分配线性地址尾部的逻辑块的块号。

在 Exfs_get_blocknr_offset()中,

 

 

Segno是通过把iblock(逻辑块号)转换为以segment为粒度的偏移(如果把segment称为段,则为段号)

Exfs_block_to_path()函数是把此段号转换为三级间址编码,将每一级的偏移量放到offset[4]数组中。

其代码如下:

其中,各变量含义如下

ptrs:一个物理块上可以存放多少个物理地址。

ptrs_bits :ptrs有多少位 相等于sizeof(ptrs)

direct_blocks:三级间址的数组中,表示直接地址的数量

indirect和double分别代表二级和三级的数量。

若一个地址需要三级索引来表示。

offset[0]= EXFS_TIND_BLOCK;在i_data[]数组中的偏移量,即为三间址的一级地址

offset[1] 表示的是在第一级中的偏移量

offset[2]表示 第二级中的偏移量

offset[3]表示的是第三级中的偏移量

 

回到Exfs_get_blocknr_offset()函数,

 

此函数中,根据offset[] 和depth,解析三级间址,并把物理地址存到一个chain[]中,chain[]的类型为

typedef struct {

       u32     *p;

       u32     key;

       struct buffer_head *bh;

} Indirect

其中,bh 指向间接索引块的内存缓存,p 指向此索引块中的某一个entry(一个entry对应一个物理块地址),而KEY的值为物理块(或者应该叫物理segment)的地址。

 

若exfs_get_branch()发现当前的逻辑地址已经在三级间址中,则返回NULL;否则返回查找过程的断点(即为现在文件的末尾),然后由后面的代码完成真正的分配。


你可能感兴趣的:(struct,layout,buffer,Path,branch,磁盘)