治肾虚不含糖,专注内核性能优化二十年。 https://github.com/KnightKu
分类:
2018-08-28 15:28:59
原文地址:ZFS磁盘格式(3) 作者:qincp-
数据管理单元(DMU)将块组织成逻辑单元——对象(object)。对象进一步可以被DMU组合为对象集(set)。本章详细描述对象和对象集。
除第一章和第二章里描述基本结构外,ZFS中的一切都是对象。下表列出了ZFS对象类型,其中一些对象在后续章节详细描述。
表9 DMU对象类型
类型 |
描述 |
DMU_OT_NONE |
未分配对象 |
DMU_OT_OBJECT_DIRECTORY |
DSL对象目录 ZAP对象 |
DMU_OT_OBJECT_ARRAY |
用于存储对象编号的数组 |
DMU_OT_PACKED_NVLIST |
打包的nvlist对象 |
DMU_OT_SPACE_MAP |
SPA磁盘块使用链表 |
DMU_OT_INTENT_LOG |
专用日志 |
DMU_OT_DNODE |
Dnode(metadnode)对象 |
DMU_OT_OBJSET |
对象集 |
DMU_OT_DSL_DATASET_CHILD_MAP |
包含DSL目录信息的DSL ZAP对象 |
DMU_OT_DSL_OBJSET_SNAP_MAP |
包含数据集的快照信息的DSL ZAP对象 |
DMU_OT_DSL_PROPS |
包含DSL目录对象的属性的DSL ZAP属性对象 |
DMU_OT_BPLIST |
块指针链表——用于存储“死链表”,这是一个上次快照后被删除的块的块指针的链表。也可以存储“延迟释放链表”用于同步时的汇聚功能 |
DMU_OT_BPLIST_HDR |
BPLIST头,存储bplist_phys_t结构 |
DMU_OT_ACL |
ACL(访问控制链表)对象 |
DMU_OT_PLAIN_FILE |
ZPL简单文件 |
DMU_OT_DIRECTORY_CONTENTS |
ZPL目录 ZAP对象 |
DMU_OT_MASTER_NODE |
ZPL主节点ZAP对象:头对象用于标识根目录,删除队列以及文件系统版本 |
DMU_OT_DELETE_QUEUE |
在文件系统被强制卸载或者断电等原因导致的系统错误时,删除队列提供一个正在进行的删除的链表。在下次文件系统加载时,将删除队列中的文件/目录删除。这个机制用于防止文件系统中泄露文件和目录。 |
DMU_OT_ZVOL |
ZFS卷(ZVOL) |
DMU_OT_ZVOL_PROP |
ZVOL属性 |
对象由[c1] 中的512字节的结构定义。一个dnode管理对象的块集合。Dnode(dnode_phys_t结构)如下图所示,包含一些固定长度的域和两个变长域,每个域在下面进行详细描述。
图9 dnode_phys_t结构
Dn_type
8位数字,表示对象类型。有效的对象类型和对应的8位取值见表8。
Dn_indblkshift和dn_datablkszsec
ZFS支持从512字节到128K字节各种长度的数据块和间接块(参见下面dn_nlevels对间接块的描述)。
Dn_indblkshift:8位数字,表示对象的间接块的尺寸(以2为基数的幂,单位字节)
dn_datablkszsec:16位数字,表示以字节为单位的数据块尺寸/512。取值为1(对应512字节)到256(对应128k字节)。
dn_nblkptr和dn_blkptr
dn_blkptr是一个变长域,包含一到三个块指针。包含指针的个数在对象分配时确定,在dnode生命周期内不会发生变化。
dn_nblkptr:8位数字,dnode中包含的块指针数。
Dn_blkptr:指针数组,包含了dn_nblkptr个块指针。
dn_nlevels
dn_nlevels是一个8位数字,包含了构成对象的层数,即间接块的层数。
Indirection
Dnode有少数块指针指向对象数据域。对于使用最大数据块尺寸(128KB)的dnode,包含三个块指针,不使用间接块可以表示的最大对象的尺寸为3*128KB=384KB。如果要表示更大的对象,需要使用间接块。间接块是包含块指针的块。间接块包含的块指针的数目取决于间接块的大小(dn_indblkshift),可以由间接块大小和blkprt的大小(128字节)相除得到。如果对象尺寸增大到当前间接块级别的最大容量时,则新一级的间接块被创建。ZFS支持最大6级的间接块,最大可以支持大小2的64次方字节的文件。
下图显示了一个有三级间接块的对象(层0,层1,层2)。该对象有三宽块指针(dva1,dva2,dva3)指向元数据,单宽块指针指向数据。层0的块是数据块。
dn_maxblkid
对象块由块id标识。每一个间接层中的块从0到N编号,层的第一个块的id为0,第二个块的id为1,以此类推。
Dnode中的dn_maxblkid域设为对象的最大块id(层0中)。
块Id的说明:给定一个块id和层,ZFS能准确确定包含块的间接块的分支。这个计算使用块id,块层数,间接块中的块指针数来进行。例如,一个对象有128K尺寸的间接块,这个这样的间接块可以包含1024个块指针。给定层0块id 10360,可以确定层1的块15包含到这个块的块指针。
Level1 blkid=16360%1024=15
计算可以在间接块组成的树进行递归,直到达到顶层间接块。
dn_secphys
对象所有的块指针(数据和间接块)的asize值之和
dn_bonus, dn_bonuslen, and dn_bonustype
bonus缓存定义为dnode块指针数组后的空间。空间的大小取决于对象类型,可以为64到320字节。
dn_bonus:数据块,长度由dn_bonuslen定义,数据格式由dn_bonustype定义。
Dn_bonuslen:bonus缓存长度,单位为字节。
Dn_bonustype:8位数字,定义包含在bonus缓存中的数据类型。下表列出有效bonus缓存类型,以及存储在bonus缓存中的结构。每个这些结构的内容将在后面讨论。
Bonus类型 |
描述 |
元数据结构 |
值 |
DMU_OT_PACKED_NVLIST_SIZE |
DMU_OT_PACKED_NVLIST对象的尺寸 |
uint64_t |
4 |
DMU_OT_SPACE_MAP_HEADER |
Spa空间图的头 |
space_map_obj_t |
7 |
DMU_OT_DSL_DIR |
DSL目录对象,用于定义相关数据集之间的关系和属性 |
dsl_dir_phys_t |
12 |
DMU_OT_DSL_DATASET |
DSL数据集对象,用于组织快照和DMU_OT_OBJSET对象的静态使用信息 |
dsl_dataset_phys_t |
16 |
DMU_OT_ZNODE |
ZPL元数据 |
znode_phys_t |
17 |
DMU把一组对象组织为对象集。ZFS使用对象集来组织相关的一些对象,例如文件系统,快照,clone,或者卷。
对象集由1K字节大小的objset_phys_t结构,该结构的每个成员详细定义如下。
图11 objset_phys_t结构
Os_type
DMU支持多种类型的对象集,每个对象集类型对其中的对象的format/layout有自己的定义。对象集的类型使用64位整数表示,os_type。下表列出DMU对象集类型以及相关的os_type整数值。
对象集类型 |
描述 |
值 |
DMU_OST_NONE |
未初始化的对象集 |
0 |
DMU_OST_META |
DSL对象集,参见第四章 |
1 |
DMU_OST_ZFS |
ZPL对象集,参见第六章 |
2 |
DMU_OST_ZVOL |
ZVOL对象集,参见第八章 |
3 |
os_zil_header
ZIL头在第七章详细描述。
Medadnode
如本章前面所述,每个对象由dnode_phys_t描述。对象集有一个单独的dnode_phys_t结构描述对象集中的对象,medadnode就指向这个结构。对象集中的所有对象的dnode_phys_t以数组方式放在metadnode中(一个对象对应数组中一个元素)。
对象集中的每个对象有一个唯一的64位整数标识,称之为对象编号。一个对象的编号标识了在metadnode中的dnode_phys_t数组中该对象的元素下标。
下图展示了一个对象集的metadnode。Metadnode包含了三个块指针,图中将每个指针都展开来显示出其中的内容。对象编号4进一步展开,显示出dnode_phys_t结构的细节和该结构所引用的块结构。
[c1]Dnode类似于UFS中的inode