Direct/Indirect Block AddressingIn ext2/3, file block numbers were mapped to logical block numbers by means of an (up to) three level 1-1 block map.
To find the logical block that stores a particular file block, the code would navigate through this increasingly complicated structure.
Notice that there is neither a magic number nor a checksum to provide any level of confidence that the block isn't full of garbage.
i.i_block Offset | Where It Points | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 to 11 | Direct map to file blocks 0 to 11. | ||||||||||||
12 | Indirect block: (file blocks 12 to ($block_size / 4) + 11, or 12
to 1035 if 4KiB blocks)
| ||||||||||||
13 | Double-indirect
block: (file blocks $block_size /4 + 12 to ($block_size / 4) ^ 2 + ($block_size / 4) + 11, or 1036 to 1049611 if 4KiB blocks)
| ||||||||||||
14 | Triple-indirect block: (file blocks ($block_size / 4) ^ 2 + ($block_size
/ 4) + 12 to ($block_size / 4) ^ 3 + ($block_size / 4) ^ 2 + ($block_size / 4) + 12, or 1049612 to 1074791436 if 4KiB blocks)
|
Note that with this block mapping scheme, it is necessary to fill out a lot of mapping data even for a large contiguous file!
This inefficiency led to the creation of the extent mapping scheme, discussed below.
Notice also that a file using this mapping scheme cannot be placed higher than 2^32 blocks.
这种利用类似指针形式寻址块的方式也是一种基本的寻址方式,严格的说,这种寻址还是比较直接的,没有什么拐弯抹角的地方。我们下面对这个寻址
方式解读一下:
首先我们假定每个块大小为4K,即4096字节。涉及到的主要数据结构是ext4_inode,其是节点在磁盘中的描述,主要牵涉到i_block成员,注意此成员的类型
__le32 i_block[EXT4_N_BLOCKS]
相关定义如下:
#define EXT4_NDIR_BLOCKS 12 #define EXT4_IND_BLOCK EXT4_NDIR_BLOCKS #define EXT4_DIND_BLOCK (EXT4_IND_BLOCK + 1) #define EXT4_TIND_BLOCK (EXT4_DIND_BLOCK + 1) #define EXT4_N_BLOCKS (EXT4_TIND_BLOCK + 1) 在这些数据定义中,首先看到,如果文件数据小于等于12块,则可以采用直接映射方式,即数组里面i_block的前面12项直接给出块的地址。ai
如果文件数据大于12个块,则需要采用间接块寻址,这里分为一级块寻址和两级块寻址抑或三级块寻址。
i_block[0] ----- i_block[11] 对应直接寻址,给出块号
i_block[12] 这开始间接寻址,这个内容是给出一个块地址,这个指向的块的大小为4K,即4096字节,由于每个块采用32位编址,也就是4个字节,所以 也就是这个块一共可以放1024个块号。范围是12-1035.前面12个是直接映射的块。1024 1024 1024 1024 1024 1024i_block[13] 这个是间接寻址,并且采用二级间接寻址方式,即这个数值给出的是块地址,并且块内容也是一个块地址,形式如下:| | | | | | | | | |i_block[13]---->| ID0 | -------------------------------------------------->| | | ID1 | --------------------------------->| | | | | ID2 | ----------------------->| | | | | | | ID3 | -------------->| | | | | | | | | ID4 | --->| | | | | | | | | || | | | | | | | | |
在这个寻址方案中,1024 * 1024 = 2^20= 1048576个块。如果再加上前面12和1024个,总共有1049612个,最大编号为1049611
i_block[14] 这个方案是三级映射,总共有1024 * 1024 * 1024 =2^30.如果在加上前面的总共有 1074791436 块。也就是2^32个块。
这样如果考虑利用i_block来寻址块,即利用整个数组,这样有2^32个块,考虑到每个块大小为4K,这样,ext4采用直接和间接映射方式能
让文件最大为2^32 * 4k = 2^44即 16TB。这点对于先前的ext3来说,应该能让文件达到16TB,但是网上很多都说4TB,这点可能是在间接映射时候,
只采用最后一级方式,而不用前面的数组。就是说用i_block[14]时,而i_block[0-13]都不再使用,这有点说不过去。我们在Linux 内核中再来详细
看这点。