关于 Btrfs 的一些概念和约定
https://btrfs.wiki.kernel.org/index.php/Data_Structures
https://btrfs.wiki.kernel.org/index.php/File:References.png
https://btrfs.wiki.kernel.org/index.php/Trees
https://btrfs.wiki.kernel.org/index.php/File:Directory-structure.png
Btrfs Terms
https://btrfs.wiki.kernel.org/index.php/Glossary
DUP
DUP is btrfs default RAID level for metadata on a single device.
Regular data cannot be assigned DUP level.
single
A "RAID" level in btrfs, storing a single copy of each piece of data.
The default for data (as opposed to metadata) in btrfs.
reflink
Parameter to cp, allowing it to take advantage of the capabilities
of CoW-capable filesystems. Allows for files to be copied and modified,
with only the modifications taking up additional storage space.
May be considered as snapshots on a single file rather than a subvolume.
Example:
cp --reflink file1 file2
subvolume
All subvolumes share the same pool of free space in the filesystem.
scrub
An online filesystem checking tool. Reads all the data and metadata on
the filesystem, and uses checksums and the duplicate copies from RAID
storage to identify and repair any corrupt data.
restriper
A development name for the rewritten balance code implemented in the
v3.3 kernel. Allows to change RAID profiles of the filesystem, online.
Block Reserves
Block reserves (struct btrfs_block_rsv) are a means to make sure no operation
runs out of space after it started.
They obey to the following rules:
* Every operation has to reserve upfront every single byte
it needs to complete its operation fully.
* If an operation cannot determine how much space it will need,
it has to be able to cope with running out of space. Normally
it does it by inserting an orphan item, doing its work in
multiple transactions, and removing the orphan item. The commits
in between normally free up enough space to continue the operation.
* All other ENOSPC situations are errors in program logic and
should result in BUG_ON.
ITEM Type 和 Tree 分类
root tree
btrfs_root_item ROOT_ITEM
btrfs_root_ref ROOT_REF / ROOT_BACKREF
fs tree
btrfs_inode_item INODE_ITEM
btrfs_inode_ref INODE_REF
btrfs_dir_item DIR_ITEM / DIR_INDEX
btrfs_file_extent_item EXTENT_DATA
extent tree
btrfs_extent_item EXTENT_ITEM
btrfs_extent_inline_ref EXTENT_DATA_REF / SHARED_DATA_REF / SHARED_BLOCK_REF / TREE_BLOCK_REF
btrfs_shared_data_ref
btrfs_extent_data_ref
btrfs_block_group_item BLOCK_GROUP_ITEM
chunk tree
btrfs_dev_item DEV_ITEM
btrfs_chunk CHUNK_ITEM
btrfs_stripe
device tree
btrfs_dev_extent DEV_EXTENT
csum tree
btrfs_csum_item CSUM_ITEM
I fs tree 对应的是 subvolume
每个 subvolume 对应一个 filesystem tree;一个 btrfs 文件系统中可以有多个 subvolume
top-level subvolume 的 ID 是 5;之后创建的 subvolume 的 ID 从 256 开始
#define BTRFS_FS_TREE_OBJECTID 5ULL
每个 fs tree 中的文件有自己独立的 inode num,从 257 开始;256 用于第一个创建的 subvolume,
subvolume 本身是一个目录,也需要有 ino
#define BTRFS_FIRST_FREE_OBJECTID 256ULL
每个 fs tree (subvolume) 的 inode num 空间应该是独立的,应该有自己的 free inode-map inode
每个对象组织一组 key 在一起,最先的是 inode 本身,每个对象至少要有 INODE_ITEM 和 INODE_REF key,
如果有更多的内容,则 key 的数量还会增多
inode 的 key.offset 为 0,表示放在对应对象的起始位置
每个 fs tree (subvolume) 可以通过在 root tree 中利用 subvolume objectid 来定位
inode
对应 key 为 (inode, INODE_ITEM, 0);type 为 INODE_ITEM,offset 为 0
inode key 后面跟的是 inode ref key
ino 将一组 key 组织在一起;在 fs tree 中查找 inode
inode ref —— 硬链接
对应 key 为 (inode, INODE_REF, parent_dir_inode);offset 为 inode 所在目录的 ino
每个硬链接会有一个单独的 INODE_REF 表项;对应表项内容为“对象的名字”和“该对象在目录中的索引”;
目录不能有硬链接(POSIX);只能有一个 INODE_REF 表项,而对于其他文件,可以有多个硬链接 INODE_REF 表项
找到 inode 后,可以找到其后的 inode refs,这样可以快速找到所有的硬链接;
一个文件可以有多个 inode ref
文件
有多个 EXTENT_DATA_REF 来描述文件的不同部分;每个 item 的 offset 字段表示当前 extent 在文件中的位置
目录
两个 key 列表:
DIR_ITEM 按照名字的哈希值进行排序(存放在 offset 字段)
DIR_INDEX 按照创建时间进行排序
两种 key 存放信息相同:
引用 inode 的 key 和目录下的名字;
type 为 INODE_ITEM(对应 POSIX 文件系统对象,可以在 tree 中检索),
或者 ROOT_ITEM(对应 subvolume,需要在 root tree 中查找 subvolume objectid 来定位对应的 fs tree)
II extent tree
存放两种 extent(不涉及 inode 等)
block group extents
对应 key 为 (start, BLOCK_GROUP_ITEM, length),表示文件系统地址空间的一块,
对应的 data item 包含 chunk 的 objectid,可以在 chunk tree 中检索
data extents
从 block group extent 中分配,用于存放 data/metadata
对应 key 表示在文件地址空间中的偏移量和长度