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

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

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

1.4.         ZAP – ZFS Attribute Processor

ZAP – Процессор артибутов ZFS – это модуль, который находится на вершине DMU и управляет объектами ZAP. Объекты ZAP – это объекты DMU, хранящиеся в виде пар «имя-значение». Именная часть имеет размер до 256 байт, включая концевой NULL, часть «значение» является массивом целых чисел, размер которого лимитируется только размером блока ZAP.
ZAP-объекты используются для хранения свойств датасетов, нахождения объектов файловой системы, хранения свойств пулов и других подобных задач.
ZAP-объекты используются в двух формах: микроZAP объекты и большие ZAP-объекты (microzap и fatzap). МикроZAP объекты представляют собой облегченную версию больших ZAP-объектов и предоставляют простой и быстрый механизм доступа к относительно малому количеству атрибутов. В свою очередь, большие ZAP-объекты лучше подходят в ситуациях, когда атрибутов много.
Следующий набор правил определяет, когда будет использована та или иная форма ZAP-объектов:
МикроZAP объекты будут использованы в случае, если выполняются все три правила:
· Все пары «имя-значение» целиком помещаются в один блок. Максимальный размер блока 128 Кбайт и в него помещается 2047 значений микроZAP.
· Значение для всех атрибутов является беззнаковым целым.
· Длина имени в парах «имя-значение» не превышает 50 символов (включая терминирующий NULL).

Если хотя бы одно условие из вышеперечисленных не выполняется, используются большие ZAP-объекты.

1.4.         ZPL – ZFS POSIX Layer

ZPLZFS POSIX Layer – заставляет DMU выглядеть как объекты файловой системы POSIX. ZFS, таким образом, предоставляет все необходимые сервисы POSIX.
ZPL представляет файловые системы как объект DMU_OST_ZFS. Все снапшоты, клоны и файловые системы представлены (и реализованы) как объект данного типа.

Устройство файловой системы ZPL
Объектный набор ZPL представлен одним объектом в фиксированной позиции и фиксированного размера. Этот объект называется главной нодой (master node) и всегда имеет номер объекта, равный 1. Главная нода – это ZAP-объект, содержащий три атрибута: DELETE_QUEUE, VERSION и ROOT.
· DELETE_QUEUE – представляет очередь удаления в случаях, когда файловая система находилась в переходном состоянии, например, в результате принудительного размонтирования или отказа питания. В следующее успешное монтирование очередь удаления применяется к файловой системе с целью приведения ее в целостное состояние. Данный механизм используется с целью предотвращения так называемых утечек файлов и директорий.
· VERSIONZPL-версия, используемая для данной файловой системы. Текущее значение равно 1.
· ROOT – 64-битное целое. Данный атрибут содержит вершинный номер объекта директории верхнего уровня иерархии данной файловой системы, корневой директории.

Директории и обход директорий
Директории файловых систем реализованы в виде ZAP-объекта типа DMU_OT_DIRECTORY. Каждая директория содержит пары «имя-значение», которые водержат имена и номера объектов, содержащихся в директории. Обход дерева директории, таким образом, представляет собой простой просмотр значений и нахождение требуемых номеров объектов.
Все объекты файловой системы содержат физическую структуру znode_phys_t в бонусном буфере своей d-ноды. Данная структура содержит атрибуты объекта файловой системы:
·   zp_atime – два 64-битных целых, содержащие время последнего доступа в секундах(zp_atime[0]) и наносекундах(zp_atime[1]) после 1 января 1970 года
·   zp_mtime - два 64-битных целых, содержащие время последней модификации объекта в секундах(zp_mtime[0]) и наносекундах(zp_mtime[1]) после 1 января 1970 года
·   zp_ctime - два 64-битных целых, содержащие время последнего изменения файла в секундах(zp_ctime[0]) и наносекундах(zp_ctime[1]) после 1 января 1970 года
· zp_crtime - два 64-битных целых, содержащие время создания файла в секундах(zp_crtime[0]) и наносекундах(zp_crtime[1]) после 1 января 1970 года
·   zp_gen 64-битный номер группы транзакции на момент создания объекта
·  zp-mode – 64-битное целое, содержащиее режим (mode) файла и его тип. Младшие 8 бит содержат флаги доступа, например, 755. 9й бит представляет бит-липучку (sticky). Биты 13-16 представляют из себя биты типа файла и описаны в таблице ниже.

Тип
Описание
Битовое значение
S_IFIFO
Fifo
0x1
S_IFCHR
Character Special Device
0x2
S_IFDIR
Directory
0x4
S_IFBLK
Block Special Device
0x6
S_IFREG
Regular file
0x8
S_IFLINK
Symbolic link
0xA
S_IFSOCK
Socket
0xC
S_IFDOOR
Door
0xD
S_IFPORT
Event port
0xE

Рис.8 Таблица типов файлов и ассоциированных битовых значений

·  zp_size – размер файла в байтах
·  zp_parent ID объекта родительской директории, содержащей данный файл
·  zp_linksколичество хардлинков на данный файл
· zp_xattrID ZAP-объекта, содержащий скрытый атрибут директории. Он обрабатывается как нормальный атрибут ZFS, исключая случаи, когда установлен и приложению необходимо войти в него посредством функции openat()
·  zp_rdev dev_t для файлов типа S_IFCHR и S_IFBLK
·  zp_flags – постоянные флаги файлов:
o       ZFS_XATTR – 0x1
o       ZFS_INHERIT_ACE – 0x2
·  zp_uid64-битное целое uid_t владельца файла
·  zp_gid64-битное целое gid_t группы файла
· zp_aclСтруктура zfs_znode_acl, содержащая все ACL данного файла. Данная структура описывается ниже.

Списки контроля доступа ZFS (ZFS Access Control Lists)
Списки контроля доступа (ACL) предоставляют механизм выборочного ограничения и/или предоставления доступа к объектам файловой системы. ACL реализованы в ZFS как таблица, содержащая ACE (Access Control Entries).

Структура zfs_znode_acl следующая:
o       z_acl_extern_obj – Номер (ID) объекта, используемого для хранения ACL, не помещающихся в znode (свыше 6 ACE). Тип объекта внешнего ACL всегда будет DMU_OT_ACL
o       z_acl_countсчетчик ACE для ACL
o       z_acl_versionзарезервировано для будущего использования
o       z_acl_padзарезервировано для будущего использования
o       z_ace_data массив, содержащий до 6 ACE

Структура каждого ACE следующая:

·        a_who -  данное поле имеет смысл лишь тогда, когда флаги ACE_OWNER, ACE_GROUP или ACE_EVERYONE (устанавливаемые для a_flag, описывается ниже) не используются. Если в a_flag установлено значение ACE_IDENTIFIER_GROUP, поле содержит GID. Во всех остальных случаях поле будет содержать UID.
·        a_access_mask32-битная маска доступа. Значения приведены в таблице:
Атрибут
Значение
ACE_READ_DATA
0x00000001
ACE_LIST_DIRECTORY
0x00000001
ACE_WRITE_DATA
0x00000002
ACE_ADD_FILE
0x00000002
ACE_APPEND_DATA
0x00000004
ACE_ADD_SUBDIRECTORY
0x00000004
ACE_READ_NAMED_ATTRS
0x00000008
ACE_WRITE_NAMED_ATTRS
0x00000010
ACE_EXECUTE
0x00000020
ACE_DELETE_CHILD
0x00000040
ACE_READ_ATTRIBUTES
0x00000080
ACE_WRITE_ATTRIBUTES
0x00000100
ACE_DELETE
0x00010000
ACE_READ_ACL
0x00020000
ACE_WRITE_ACL
0x00040000
ACE_WRITE_OWNER
0x00080000
ACE_SYNCHRONIZE
0x00100000

·        a_flags16-битное целое, представляющее тип записи ACL и флаги наследования.
Флаг ACE
Значение
ACE_FILE_INHERIT_ACE
0x0001
ACE_DIRECTORY_INHERIT_ACE
0x0002
ACE_NO_PROPAGATE_INHERIT_ACE
0x0004
ACE_INHERIT_ONLY_ACE
0x0008
ACE_SUCCESSFUL_ACCESS_ACE_FLAG
0x0010
ACE_FAILED_ACCESS_ACE_FLAG
0x0020
ACE_IDENTIFIER_GROUP
0x0040
ACE_OWNER
0x1000
ACE_GROUP
0x2000
ACE_EVERYONE
0x4000
·        a_type – тип ACE:

Тип
Значение
Описание
ACE_ACCESS_ALLOWED_ACE_TYPE
0x0000
Предоставляет доступ как описано в a_access_mask
ACE_ACCESS_DENIED_ACE_TYPE
0x0001
Запрещает доступ как описано в a_access_mask
ACE_ACCESS_AUDIT_ACE_TYPE
0x0002
Флаг аудита – в текущей версии не реализовано
ACE_ACCESS_ALARM_ACE_TYPE
0x0003
Флаг тревоги – в текущей версии не реализовано



1.4.         ZFS Intent Log (ZIL)

Журнал намерений (ZFS Intent Log, ZIL) сохраняет системные вызовы транзакционных записей, изменяющих состояние файловой системы в памяти, с достаточным количеством информации для последующего воспроизведения. Эти изменения сохраняются в памяти до тех пор, пока транзакционная группа DMU не будет сохранена в стабильный пул (тогда записанные изменения могут быть стерты) либо изменения сбрасываются в стабильный лог (также принадлежащий пулу) в рамках вызова fsync или O_DSYNC.
На каждую файловую систему создается один лог. Лог может находиться внутри файловой системы или создан на отдельном устройстве (устройствах):

root @ pegasus / # zpool create data2 c4t0d0 log c4t1d0
root @ pegasus / # zpool status data2
  pool: data2
 state: ONLINE
 scrub: none requested
config:

        NAME        STATE     READ WRITE CKSUM
        data2       ONLINE       0     0     0
          c4t0d0    ONLINE       0     0     0
        logs
          c4t1d0    ONLINE       0     0     0

errors: No known data errors

 Лог содержит три типа записей:
·        Заголовок ZIL (ZIL header)
·        Блоки ZIL
·        Записи ZIL



Записи ZIL содержат системные вызовы дисковых транзакций. Блоки содержат транзакции и образуют цепочки. Каждый блок содержит указатель (blkptr_t) на следующий блок в цепочке. Блоки могут быть разного размера. Заголовок ZIL указывает на первый блок в цепочке. Блоки располагаются не на фиксированных позициях, а динамически выделяются и освобождаются по мере необходимости.
Заголовок журнала один на весь журнал и имеет очень простую структуру. Блоки ZIL содержат записи. Блоки выделяются по необходимости и имеют различный размер. Размер является частью записи блочного указателя blkptr_t. Блоки заполнены записями и содержат трейлер zil_trailer_t в конце каждого блока.
Запись ZIL содержит общую структуру, за которой следует специфичная для записи структура. Каждая транзакция в общей структуре помечается флагом типа транзакции:

Флаг
Значение
Описание
TX_CREATE
1
Create file
TX_MKDIR
2
Make directory
TX_MKXATTR
3
Make XATTR directory
TX_SYMLINK
4
Create symbolic link
TX_REMOVE
5
Remove file
TX_RMDIR
6
Remove directory
TX_LINK
7
Create hard link
TX_RENAME
8
Rename file
TX_WRITE
9
File write
TX_TRUNCATE
10
Truncate file
TX_SETATTR
11
Set file attributes
TX_ACL
12
Set ACL

Для каждой записи (транзакции) перечисленного выше общего типа есть специфическая внутренняя структура с данными, необходимыми для воспроизведения транзакции (обычно один вызов VOP). Уровень VOP ввыполняет передачу указателей из памяти к v-нодам. Затем они конвертируются в объектные идентификаторы стабильного пула. При воспроизведении транзакций уровень VOP вызывается еще раз. Для этого объект повторно открывается и передается к v-нодам. 


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