转载:https://blog.csdn.net/PANGHAIFEI/article/details/99726004
Btrfs b-tree是一种通用的数据结构,包括三种数据结构:keys,items,block headers. block header 是固定大小且持有一些域checksum,flags,filesystem ids,generation number等。 Key用结构描述对象的地址。
item is a key with additional offset and size filelds.
内部tree节点仅仅持有[key,block-pointer]对。叶子节点持有[item,data]键值对的arrays。 item数据是可变尺寸。叶子在开始存储items的阵列,在结尾是一个反向排序的数据阵列。这些阵列向对方互相增长。下表展示saneitems{I0,I1,I2}的叶子,和三个对应的数据元素{D2,D1,D0}。
叶子节点有三个items。Items是固定大小的,但是数据元素是可变长度的。
Item数据是可变长度的,多样的文件系统数据被定义成不同的item数据类型。key中的域声明在item中存储的数据类型。
文件系统由objects组成,每个object有一个抽象的64bit object_id。但一个object被创建,之前的未被使用的object_id被选择。
object_id 构成了key最重要的bits,允许给定文件系统对象的所有的items在逻辑上组合在b-tree中。type域描述了被一个item拥有的data。一个object典型的包含几个items。offset域描述了在一个extent中的数据。
下图展示了更为详细的叶子节点的结构。
Inode存储在inode item中,type值为BTRFS_INODE_ITEM_KEY=1,offset为0。inode item总是一个给定的object的最低值的key,并且他们为文件和目录存储了传统的状态数据。Inode 结构相对比较小,不会包含嵌入的文件数据或者extended 属性数据。这些东西存储在其他类型的item里面。
小文件占用小于一个叶子块可能在extent item里面被装到b-tree中。 在这种情况下,key偏移量是文件中的数据的字节偏移量,这个item的size field 声明了多少数据被存储。 这些可能不止一个。
大文件存储在extents中。这些是包含用户数据的连续的磁盘空间,不会有额外的headers或者formatting。一个extent-item为一个extent记录了一个generation number(下面解释),一个[disk block, disk num blocks] 对记录了磁盘区域对应的文件。Extents 也存储了逻辑偏移量和在磁盘上被这个extent record使用到extent中的块的数量。 这允许执行一个重写到一个extent中间而不需要先读取旧文件的数据。比如说,写10MB数据到extent 0- 64MB中可以引起三个不同extents的创建:0-10MB,10-20MB,20-64MB.
一些文件系统使用固定尺寸的块而不是extents。使用extent表示可以提高空间效率,无论如何,这会以更复杂的代价来实现。
一个目录维护一个dir_items 元素的列表。 一个dir_items映射一个文件名(string) 到一个64位的object_id。目录也包含两个索引,一个用于lookup查找,另一个用于iteration迭代。Lookup索引是一些[dir_item key, filename 64bit hash]对的列表,它用于满足路径查找。 迭代的索引是[dir_item key, inode sequence number]对的列表,用于BUILK目录操作。inode sequence number存储在目录中,每个文件或者目录被添加的时候递增。它近似于底层文件inode的磁盘顺序,因此在访问他们的时候保存了disk seeks。BUILK性能对操作比如备份,拷贝,文件系统校验来说很重要。