среда, 19 сентября 2012 г.

Анатомия ZFS часть III

При написании данного цикла статей использовался документ ZFS On-Disk Specification,Sun Microsystems


            1.1.3 Загрузочный блок

Непосредственно за метками L0 и L1 следует 3,5 мегабайта зарезервированного пространства (Рис.4).


Рис.4 Зарезервированное пространство блока загрузки

Содержимое указанных 3,5 мегабайт не описано в спецификации, однако можно предположить, что оно зарезервировано под блок загрузки RAID.

1.1 Блочные указатели и косвенные блоки

Указатель корневого блока, описанный в разделе 1.1.3.4, представляет из себя структуру размером 128 байт, содержащую физическое местонахождение блока и данные, описывающие его структуру и содержание.
Точно такую же структуру имеет любой указатель блока в ZFS. Поскольку блок является атомарной единицей ввода-вывода, указатель блока используется для доступа к блоку, его верификации, и полностью описывает блок данных.
В числе прочих данных, указатель блока содержит ссылки на виртуальные устройства, содержащие блок, тип блока, контрольные суммы, счетчик заполнения, принадлежность к групповой транзакции и другие данные.

1.2      Блочные указатели и косвенные блоки

Перенос данных между устройствами хранения и оперативной памятью осуществляется блоками. Блочный указатель является 128-байтной структурой, используемой для физической адресации, верификации, и описания блока данных на устройстве хранения.

Полная 128-битная структура указателя блока приведена на Рис.5. Данная структура является одной из важнейших в ZFS и рассматривается детально в следующих параграфах.



64
56
48
40
32
24
16
8
0
0
vdev1
GRID
asize
1
G
offset1
2
vdev2
GRID
asize
3
G
offset2
4
vdev3
GRID
asize
5
G
offset3
6
E
lvl
type
chksum
comp
psize
lsize
7
padding
8
padding
9
padding
a
birth txg
b
fill count
c
checksum[0]
d
checksum[1]
e
checksum[2]
f
checksum[3]

Рис 5. Побайтная структура блочного указателя

1.2.1    Виртуальные адреса данных – DVA

Виртуальными адресами данных (DVA Data Vurtual Address) называют комбинацию vdev и смещения указателя блока данных. ZFS предоставляет возможность хранения до трех копий блоков данных, адресуемых посредством DVA. Каждая копия адресуется при помощи собственного уникального DVA (dva1, dva2 или dva3 соответственно). Данные всех трех копий идентичны. Количество DVA, использованных на каждый указатель блока, выбирается волевым решением и называется шириной  (wideness) блочного указателя: блочный указатель одиночной ширины (1 DVA), двойной ширины (2 DVA) или тройной ширины (3 DVA).
Часть DVA, представляющая vdev, определяется 32-битным целым числом, являющимся ID виртуального устройства, содержащего данный блок. Смещение DVA является 63-битным целым числом, представляющим позицию на vdev (на которм находится адресуемый блок) после меток L0 и L1 и блока загрузки. Величина смещения задается в физических секторах (512 байт).
Для вычисления смещения в байтах от начала слайса величина смещения должна быть сдвинута влево на 9 разрядов (29 = 512) и сложена со значением 0x400000 (объем двух меток и блока загрузки).

1.2.1       GANG

Gang-блок*- это блок, содержащий только указатели блоков. Gang-блоки используются в случае, если запрашиваемое пространство недоступно в непрерывном блоке. В подобном случае выделяется несколько блоков меньшего размера, суммарным объемом равным объему запрашиваемого пространства, и создается Gang-блок, содержащий указатели на все распределенные блоки.

Gang-блок идентифицируется битом G:
·        0 в случае обычного блока
·        1 в случае Gang-блока

Gang-блок имеет размер 512 байт, содержит до 3 блочных указателей и сопровождается 32-битной контрольной суммой.
Gang-блок содержит магическое число zbt_magic, 0x210da7ab10c7a11(zio-data-bloc-tail), означающее окончание блока данных ZIO.


1.2.3.  Контрольные суммы

По умолчанию в ZFS защищается контрольными суммами все – и данные, и метаданные. Поддерживается несколько алгоритмов контрольных сумм, в частности, fletcher-2, fletcher-4 и SHA-256.
Алгоритм, используемый для расчета контрольных сумм блока, определяется полем chksum блочного указателя.

Значения поля chksum могут быть следующими:

·        1 – on – fletcher-2
·        2 – off – none
·        3 – label – SHA-256
·        4 – gang header – SHA-256
·        5 – zilog – fletcher-2
·        6 – fletcher2 – fletcher-2
·        7 – fletcher-4 – fletcher-4
·        8 – SHA-256 – SHA-256

Таким образом, 256-битная контрольная сумма рассчитывается для каждого блока по алгоритму, определяемому данным полем указателя блока и сохраняется в полях checksum[0], checksum[1], checksum[2] и checksum[3]. Если поле содержит значение 2 (off), контрольные суммы не вычисляются и поля checksum[0], checksum[1], checksum[2] и checksum[3] ничего не содержат.
Контрольные суммы вычисляются для всех блоков, кроме Gang-блоков и zilog-блоков. Данные блоки защищаются собственными контрольными суммами.

1.2.4.  Компрессия

Подобно многим другим файловым системам, ZFS поддерживает компрессию хранимых данных. При этом выполняется компрессирование и декомпрессирование данных «на лету».
Поддерживаются следующие алгоритмы компрессирования:

compression     on | off | lzjb | gzip | gzip-[1-9]

Тип компрессирования определяется полем comp блочного указателя.

1.2.5.  Размер блока

Размер блока определяется в трех различных полях указателя блока: psize, lsize и asize.
lsize – логический размер блока, без учета компрессии, заголовков Gang-блоков или структур RAID-Z
psize – физический размер блока на диске после компрессии
asize – распределенный (allocated) размер всех блоков для хранения данных, с учетом заголовков Gang-блоков и данных четности RAID-Z

Если компрессия на включена или RAID-Z не используется, все три величины равны. Все значения представляют из себя количество 512-байтных блоков (дисковых секторов) минус один.

1.2.6.  Endian (порядок байт)

Порядок байт (endianness) в ZFS не является фиксированным. Так как файловая система принципиально предназначена для переноса пулов между машинами с различной последовательностью байт, блочные указатели имеют соответствующий атрибут «E»,  означающий, в какой последовательности байт произведена запись блока. Блок всегда записывается в «родной» для машины последовательности байт.
Атрибут E имеест следующие возможные значения:

·        1 – Little Endian
·        0 – Big Endian

При перемещении пула между машинами с различной последовательностью байт на основании данного атрибута производится перестановка порядка байт (при необходимости) при считывании блока.

1.2.7.  Тип

Поле 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

1.2.8.  Уровни

Поле level блочного указателя содержит количество уровней – сколько блочных указателей необходимо просмотреть для получения всех данных этого указателя.

1.2.9.  Заполнение

Счетчик заполнения (fill count) определяет количество ненулевых блочных указателей на которые ссылается данный блочный указатель. Счетчик заполнения для собственно блока данных всегда содержит 1 и это означает, что нижележащих блочных указателей не существует.
Счетчик заполнения используется иначе, нежели указатель блока типа DMU_OT_DNODE. Для блочных указателей данного типа счетчик заполнения содержит количество свободных dnodes для данного указателя блока.

1.2.10.  Порождающая транзакция

Поле birth txg определяет номер порождающей транзакционной группы, для которой был распределен данный блочный указатель, и представляет из себя 64-битное целое.

(продолжение следует)




* Gang – банда. Слово «гангстер» происходит от gang. Термин очень подходит по смыслу одноименной структуре данных.
** OT означает Object Type – Тип Объекта.