ext4 节点inode.i_block描述

The Contents of inode.i_block 

Depending on the type of file an inode describes, the 60 bytes of storage in inode.i_block can be used in different ways. In general, regular files and directories will use it for file block indexing information, and special files will use it for special purposes.

Symbolic Links

The target of a symbolic link will be stored in this field if the target string is less than 60 bytes long. Otherwise, either extents or block maps will be used to allocate data blocks to store the link target.

Direct/Indirect Block Addressing

In 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 OffsetWhere It Points
0 to 11Direct map to file blocks 0 to 11.
12Indirect block: (file blocks 12 to ($block_size / 4) + 11, or 12 to 1035 if 4KiB blocks)
Indirect Block OffsetWhere It Points
0 to ($block_size / 4)Direct map to ($block_size / 4) blocks (1024 if 4KiB blocks)
13Double-indirect block: (file blocks $block_size/4 + 12 to ($block_size / 4) ^ 2 + ($block_size / 4) + 11, or 1036 to 1049611 if 4KiB blocks)
Double Indirect Block OffsetWhere It Points
0 to ($block_size / 4)Map to ($block_size / 4) indirect blocks (1024 if 4KiB blocks)
Indirect Block OffsetWhere It Points
0 to ($block_size / 4)Direct map to ($block_size / 4) blocks (1024 if 4KiB blocks)
14Triple-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)
Triple Indirect Block OffsetWhere It Points
0 to ($block_size / 4)Map to ($block_size / 4) double indirect blocks (1024 if 4KiB blocks)
Double Indirect Block OffsetWhere It Points
0 to ($block_size / 4)Map to ($block_size / 4) indirect blocks (1024 if 4KiB blocks)
Indirect Block OffsetWhere It Points
0 to ($block_size / 4)Direct map to ($block_size / 4) blocks (1024 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.

Extent Tree

In ext4, the file to logical block map has been replaced with an extent tree. Under the old scheme, allocating a contiguous run of 1,000 blocks requires an indirect block to map all 1,000 entries; with extents, the mapping is reduced to a single struct ext4_extent with ee_len = 1000. If flex_bg is enabled, it is possible to allocate very large files with a single extent, at a considerable reduction in metadata block use, and some improvement in disk efficiency. The inode must have the extents flag (0x80000) flag set for this feature to be in use.

Extents are arranged as a tree. Each node of the tree begins with a struct ext4_extent_header. If the node is an interior node (eh.eh_depth > 0), the header is followed by eh.eh_entries instances of struct ext4_extent_idx; each of these index entries points to a block containing more nodes in the extent tree. If the node is a leaf node (eh.eh_depth == 0), then the header is followed by eh.eh_entries instances of struct ext4_extent; these instances point to the file's data blocks. The root node of the extent tree is stored in inode.i_block, which allows for the first four extents to be recorded without the use of extra metadata blocks.

The extent tree header is recorded in struct ext4_extent_header, which is 12 bytes long:

OffsetSizeNameDescription
0x0__le16eh_magicMagic number, 0xF30A.
0x2__le16eh_entriesNumber of valid entries following the header.
0x4__le16eh_maxMaximum number of entries that could follow the header.
0x6__le16eh_depthDepth of this extent node in the extent tree. 0 = this extent node points to data blocks; otherwise, this extent node points to other extent nodes. The extent tree can be at most 5 levels deep: a logical block number can be at most 2^32, and the smallest n that satisfies 4*(((blocksize - 12)/12)^n) >= 2^32 is 5.
0x8__le32eh_generationGeneration of the tree. (Used by Lustre, but not standard ext4).

Internal nodes of the extent tree, also known as index nodes, are recorded as struct ext4_extent_idx, and are 12 bytes long:

OffsetSizeNameDescription
0x0__le32ei_blockThis index node covers file blocks from 'block' onward.
0x4__le32ei_leaf_loLower 32-bits of the block number of the extent node that is the next level lower in the tree. The tree node pointed to can be either another internal node or a leaf node, described below.
0x8__le16ei_leaf_hiUpper 16-bits of the previous field.
0xA__u16ei_unused 

Leaf nodes of the extent tree are recorded as struct ext4_extent, and are also 12 bytes long:

OffsetSizeNameDescription
0x0__le32ee_blockFirst file block number that this extent covers.
0x4__le16ee_lenNumber of blocks covered by extent. If the value of this field is <= 32768, the extent is initialized. If the value of the field is > 32768, the extent is uninitialized and the actual extent length is ee_len - 32768. Therefore, the maximum length of a initialized extent is 32768 blocks, and the maximum length of an uninitialized extent is 32767.
0x6__le16ee_start_hiUpper 16-bits of the block number to which this extent points.
0x8__le32ee_start_loLower 32-bits of the block number to which this extent points.

Prior to the introduction of metadata checksums, the extent header + extent entries always left at least 4 bytes of unallocated space at the end of each extent tree data block (because (2^x % 12) >= 4). Therefore, the 32-bit checksum is inserted into this space. The 4 extents in the inode do not need checksumming, since the inode is already checksummed. The checksum is calculated against the FS UUID, the inode number, the inode generation, and the entire extent block leading up to (but not including) the checksum itself.

struct ext4_extent_tail is 4 bytes long:

OffsetSizeNameDescription
0x0__le32eb_checksumChecksum of the extent block, crc32c(uuid+inum+igeneration+extentblock)

Inline Data

If the inline data feature is enabled for the filesystem and the flag is set for the inode, it is possible that the first 60 bytes of the file data are stored here.


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值