- 论坛徽章:
- 0
|
第二章 块指针和间接块
数据在磁盘和主存之间以块为单位进行传送。块指针blkptr_t是一个128字节大小的ZFS结构,用于对磁盘上数据块进行定位,验证和描述。
128字节的Blkptr_t结构如下图:
图8 块指针结构
2.1 DVA——数据虚地址
块指针中的Vdev和offset字段部分构成了数据虚地址,例如vdev1和offset1组成DVA1。ZFS的块指针提供了指向三份数据的重复拷贝的能力,每一份拷贝由单独一个DVA指向。每个块指针中使用几个DVA是文件系统的实际策略,称为块指针的宽度:单宽块指针,双宽块指针,三宽块指针。
每个DVA的vdev部分是32位整数,唯一描述该数据块所在的vdevid;offset部分是63位整数,包含数据在所在设备上的偏移(从boot 块之后开始计算)。二者合在一起,唯一表示了数据的物理位置。
Offset的值以扇区为单位(512字节)。物理块以字节为单位的偏移需要进行左移位(移9位)并加上0x400000(L0+L1+boot)。
physical block address = (offset + 0x400000 (4MB)
2.2 GRID
Raid-Z布局信息,留作将来使用。
2.3 GANG
包含块指针的块叫做GANG块,在请求的空间无法在连续块中申请时,此时需要申请一些不连续的更小的块,此时需要创建一个gang块对这些块进行维护,将指向gang块的指针返回给请求者,请求者看到的是一个单独的(gang)块。
Gang块由“G”位标志。
表4 gang块标志
“G”位
描述
0
非gang块
1
Gang块
Gang块为512字节,有自己的效验和。Gang块包含最多3个块指针加上32字节的效验和。Gang块的格式描述如下。
typedef struct zio_gbh {
blkptr_t zg_blkptr[SPA_GBH_NBLKPTRS];
uint64_t zg_filler[SPA_GBH_FILLER];
zio_block_tail_t zg_tail.;
} zio_gbh_phys_t;
zg_blkptr: 块指针数组,最多可以有三个块指针
zg_filler: 填充
typedef struct zio_block_tail {
uint64_t zbt_magic;
zio_cksum_t zbt_cksum;
}
zbt_magic: ZIO块尾魔数,0x210da7ab10c7a11 (zio-data-bloc-tail).
typedef zio_cksum {
uint64_t zc_word[4];
}zio_cksum_t;
zc_word: 四个8字节整数包含gang块的效验和
2.4 效验和
ZFS缺省对所有数据和元数据进行效验。ZFS支持多种效验和算法,包括fletcher2,fltecher4以及SHA-256。用于该块的效验和算法由块指针的8位整数cksum标识。下标对这些取值给出说明。
表5 cksum取值和对应算法
描述
值
算法
on
1
fletcher2
off
2
none
label
3
SHA-256
gang
4
SHA-256
zilog
5
fletcher2
fletcher2
6
fletcher2
fletcher4
7
fletcher4
SHA-256
8
SHA-256
使用cksum规定的算法,每一块计算出256位效验和,放入checksum[0], checksum[1], hecksum[2], 和checksum[3]中;如果cksum是2,则不进行效验和计算,此时checksum[0], checksum[1], hecksum[2], 和checksum[3]为0。
注意,计算的效验和都是针对数据进行的,gang块和zilog块都是自带效验和的。
2.5 压缩
ZFS支持多种压缩算法,块使用的压缩算法在块指针的comp中指示,如下表
表6 压缩算法
描述
值
算法
on
1
lzjb
off
2
none
lzjb
3
lzjb
2.6 块尺寸
在块指针中,有三个不同域描述块尺寸:psize,lsize,asize。
Lsize:逻辑尺寸,未压缩的数据大小,不包括gang,raidz开销。
Psize:压缩后的数据的物理尺寸
asize:申请尺寸,保存该数据申请的所有块的总尺寸,包括gang和raidz信息。
如果压缩被关闭,并且ZFS不使用raidZ存储,则lsize,asize,psize三者相同。
所有尺寸的取值按512字节的扇区为单位。
2.7 字节序
ZFS的字节序可以设置(第一章对此有限制除外),允许将pool在不同架构的机器间移动。块指针的“E”指示写块时的字节序。块总是按照机器的字节序写入。
表7 字节序
字节序
值
小尾
1
大尾
0
如果pool被移动到另外不同字节序的机器下,块内容在读的时候需要做字节转换。
2.8 类型
块指针的type指示块中存储的数据类型。下表列出各种类型。
表8 对象类型
类型
值
DMU_OT_NONE
0
DMU_OT_OBJECT_DIRECTORY
1
DMU_OT_OBJECT_ARRAY
2
DMU_OT_PACKED_NVLIST
3
DMU_OT_NVLIST_SIZE
4
DMU_OT_BPLIST
5
DMU_OT_BPLIST_HDR
6
DMU_OT_SPACE_MAP_HEADER
7
DMU_OT_SPACE_MAP
8
DMU_OT_INTENT_LOG
9
DMU_OT_DNODE
10
DMU_OT_OBJSET
11
DMU_OT_DSL_DATASET
12
DMU_OT_DSL_DATASET_CHILD_MAP
13
DMU_OT_OBJSET_SNAP_MAP
14
DMU_OT_DSL_PROPS
15
DMU_OT_DSL_OBJSET
16
DMU_OT_ZNODE
17
DMU_OT_ACL
18
DMU_OT_PLAIN_FILE_CONTENTS
19
DMU_OT_DIRECTORY_CONTENTS
20
DMU_OT_MASTER_NODE
21
DMU_OT_DELETE_QUEUE
22
DMU_OT_ZVOL
23
DMU_OT_ZVOL_PROP
24
2.9 层
块指针的level是块指针寻址到数据块需要经历的层数。第三章对层进行了更为完整的定义。
2.10 Fill
该块指针下子树中非零块指针的数量。对于数据块的块指针,fill为1,因为其下面已没有其他块指针了。
Fill在DMU_OT_DNODE类型的块指针中用法稍有不同,该值是指块指针下包含的空闲dnode数量,参见第三章。
2.11 出生事务
申请该块指针是的事务组编号。
2.12 填充
填充字段。
本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u3/103238/showart_2057677.html |
|