Chinaunix首页 | 论坛 | 博客
  • 博客访问: 160762
  • 博文数量: 17
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 342
  • 用 户 组: 普通用户
  • 注册时间: 2014-03-19 11:38
个人简介

A ZFS fan

文章分类
文章存档

2014年(17)

分类: 服务器与存储

2014-04-10 20:02:42

(翻译 《ZFS On-Disk Specification》, 由于是2006年给出的文档,与当前ZFS系统肯定有很多的不同,但是也是一份相当有帮助的ZFS学习文档)

数据在主存和磁盘知己恩的传输单元称为块(blockZFS中,块指针(blkptr_t)是一个128字节的结构体,用来定位磁盘上数据的物理位置、验证其合法性以及描述该数据。

128字节的blkptr_t结构体的布局如下图所示:

2.1 DVAData Virtual Address

数据的虚拟地址(DVA)是有块指针中的vdevoffset两个部分构成的。比如vdev1offset1构成了一个DVAdva1),ZFS的块指针提供3DVA,三份DVA所指向的数据是相同的。在实际使用过程中,使用的DVA个数表示了这个块指针的宽度:使用一个DVA则是单宽度块指针;使用两个DVA则是双宽度块指针;使用三个DVA则是三宽度块指针。

每个DVAvdev部分是由一个32位的整数表示,用来唯一标识包含这个块的vdev IDDVAoffset部分是由一个63位的整数表示,用来表示这个块在vdev所指定的设备内的偏移(从L0L1以及Boot block之后开始算起,即4M之后),这样通过vdevoffset组合,来唯一表示数据块在的位置。

offset中存储的值是一扇区(512bit的块)来计算的,要想得到数据块激励磁盘开头的位置的具体字节数,首先要将offset中的数据左移9位(29=512)然后再将得到的值加上0x4000004M)。

    physical block address = (offset << 9) + 0x400000(4M)

2.2 GRID

Raid-Z的布局信息,留着以后使用

2.3 GANG

集群块(gang block)指的是这个块的内容包含的是块指针。当磁盘上的剩余空间不足以分配一个连续的指定空间大小时就需要使用gang block。当这种情况发生时,一些小的块将会被分配(小块的空间总和是要分配的空间大小),而gang block将包含这些小块的块指针,然后将gang block的块指针返回给请求者,在请求者看来,这是一个完整的块。

Gang block是通过“G”标志位表明。

G 标志位值

描述

          0

不是gang block

          1

gang block

gang block的大小为512字节,并且自身checksumgang block中, 32字节的紧随是3个块指针之后。下面给出gang block的具体描述。

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:块指针数组。每个512字节的gangblock3个块指针。

zg_filler:用来字节对齐

typedef struct zio_block_tail{

    uint64_t    zbt_magic;

    zio_cksum_t zbt_cksum;

}

zbt_magic魔数,值为0x210da7ab10c7a11(zio-data-blc-tail)

2.4 checksum

默认情况下,ZFS checksum所有的数据以及元数据,ZFS支持fletcher2fletcher4以及SHA-256在内的多种checksum算法。下表给出块指针中的8cksum指定的checksum算法类型:

描述

算法

 on

       1

   fletcher2

 off

       2

   none

 label

       3

   SHA-256

  gang header

       4

   SHA-256

  zilog

       5

   fletcher2

  fletcher2

       6

   fletcher2

  fletcher4

       7

   fletcher4

  SHA-256

       8

   SHA-256

每个数据都将会被按照块指针中的cksum制定的算法计算一个256位的checksum值。如果cksum的值是2,那么将不会计算checksum,块指针中的checksum[0], checksum[1], checksum[2], checksum[3]都为0,否则256位的checksum值将会被分别存储到这四个checksum中。

2.5 压缩

ZFS支持多种压缩算法。具体的压缩算法通过块指针的comp字段指定。

描述

算法

       on

       1

       lzjb

       off

       2

       none

       lzjb

       3

       lzjb

2.6 块大小

块的大小有三种描述,分别为psizelsizeasize

lsize:逻辑大小,没有经过压缩、raidzgang覆盖的数据的大小。

psize:数据压缩之后,在磁盘上的存储空间。

asize:分配空间大小。用于存储该数据的所分配的所有块的总大小,包括gang header等。

如果关闭ZFS的压缩功能,而且没有使用Raid-Z存储,那么lsizepsizeasize应该是相同的值。

所有的大小都以512字节扇区的形式来存储。(size >> 9 之后存储)

2.7 字节模式

ZFS是一个可调节字节模式的文件系统,这使得数据可以在不同架构的机器之间传输。一般来说,在写block的过程,会按照当前机器的字节模式来写。

字节模式

   小端模式

        1

   大端模式

        0

如果一个pool被移动到另一个字节模式不同的机器上时,读取的过程需要交换字节。

2.8 类型

块指针中的type字段用来表示所指的数据块的类型。type可以是以下类型,第三章中将会详细介绍对象的类型。

                      类型

                         值 

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

块指针中的level字段用来表明要想找到真正的数据需要经历几层块指针。第三章中将更详细地说明

2.10 Fill

块指针中的fill字段用来描述当前块指针中的非零块指针的数目。对于数据块的块指针来说,该值为1

fill字段在指向DMU_OT_DNODE类型的时稍微有点不同,它用来表示这个块指针下的空闲dnode数目

2.11 Birth Transaction

块指针中的“birth txg”字段是一个64位的整数,用来记录分配这个块指针的事务组编号。

2.12 Padding

块指针中还有三个padding字段,是保留空间,以后可能使用。

最后奉献一张块指针的大图:

阅读(3255) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~