zoukankan      html  css  js  c++  java
  • 【翻译】ZFS

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

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

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

     

    2.1 DVAData Virtual Address

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

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

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

        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字节,并且自身checksum。gang 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字节的gangblock有3个块指针。

    zg_filler:用来字节对齐

    typedef struct zio_block_tail{

        uint64_t    zbt_magic;

        zio_cksum_tzbt_cksum;

    }

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

    2.4 checksum

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

    描述 算法
    on 1 fletcher2
    off 2 one
    label 3 SHA-256
    gang header 4 SHA-256
    zilog 5 fletcher2
    fletcher2 6 fletcher2
    fletcher4 7 fletcher4
    SHA-256 8 SHA-256


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

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

    描述 算法
    on 1 lzjb
    off 2 none
    lzjb 3 lzjb

    2.6 块大小

    块的大小有三种描述,分别为psize、lsize、asize。

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

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

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

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

    所有的大小都以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字段,是保留空间,以后可能使用。

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

  • 相关阅读:
    利用Turtle绘制各种图形
    turtle库元素语法分析
    python中input()函数与print()函数
    python代码编写规范
    如何将python下载源地址修改为国内镜像源
    探秘AutoCAD中的组
    ObjectARX开发教程(转)——第2课:AutoCAD数据库
    ObjectARX开发教程(转)——第1课:概述
    探秘AutoCAD中的标注关联
    AutoCAD快速开发框架之日志Logging
  • 原文地址:https://www.cnblogs.com/SunChina/p/3657296.html
Copyright © 2011-2022 走看看