數據在主存和磁盤知己恩的傳輸單元稱爲「塊(block)」。ZFS中,塊指針(blkptr_t)是一個128字節的結構體,用來定位磁盤上數據的物理位置、驗證其合法性以及描述該數據。node
128字節的blkptr_t結構體的佈局以下圖所示:
算法
數據的虛擬地址(DVA)是有塊指針中的vdev和offset兩個部分構成的。好比vdev1和offset1構成了一個DVA(dva1),ZFS的塊指針提供3份DVA,三份DVA所指向的數據是相同的。在實際使用過程當中,使用的DVA個數表示了這個塊指針的寬度:使用一個DVA則是單寬度塊指針;使用兩個DVA則是雙寬度塊指針;使用三個DVA則是三寬度塊指針。 數組
每一個DVA的vdev部分是由一個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) 學習
Raid-Z的佈局信息,留着之後使用 ui
集羣塊(gang block)指的是這個塊的內容包含的是塊指針。當磁盤上的剩餘空間不足以分配一個連續的指定空間大小時就須要使用gang block。當這種狀況發生時,一些小的塊將會被分配(小塊的空間總和是要分配的空間大小),而gang block將包含這些小塊的塊指針,而後將gang block的塊指針返回給請求者,在請求者看來,這是一個完整的塊。 spa
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)
默認狀況下,ZFS checksum全部的數據以及元數據,ZFS支持fletcher二、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 以後存儲)
ZFS是一個可調節字節模式的文件系統,這使得數據能夠在不一樣架構的機器之間傳輸。通常來講,在寫block的過程,會按照當前機器的字節模式來寫。
字節模式 | 值 |
小端模式 | 1 |
大端模式 | 0 |
若是一個pool被移動到另外一個字節模式不一樣的機器上時,讀取的過程須要交換字節。
塊指針中的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 |
塊指針中的level字段用來代表要想找到真正的數據須要經歷幾層塊指針。第三章中將更詳細地說明
塊指針中的fill字段用來描述當前塊指針中的非零塊指針的數目。對於數據塊的塊指針來講,該值爲1。
fill字段在指向DMU_OT_DNODE類型的時稍微有點不一樣,它用來表示這個塊指針下的空閒dnode數目。
塊指針中的「birth txg」字段是一個64位的整數,用來記錄分配這個塊指針的事務組編號。
塊指針中還有三個padding字段,是保留空間,之後可能使用。
最後奉獻一張塊指針的大圖: