APFS: алгоритм восстановления данных файловой системы и ее структура
Суперблок контейнера содержит ссылку на структуру контрольной точки. Контрольная точка ссылается на предыдущий суперблок контейнера, который содержит информацию в более старом состоянии файловой системы. Таким образом, можно восстановить несколько старых состояний путем анализа цепочки суперблока контейнера.

Контейнеры и Тома
Структура файловой системы APFS имеет вид b-дерева, где корневой каталог с данными — это листья этого дерева. Все ветви хранят лишь ссылки на следующий узел пока не дойдут до листьев. Файловая система использует контейнеры в качестве ячеек хранения. Эти контейнера могут содержать несколько томов. Также он является основным объектом для хранения данных. Для одного тома размер контейнера должен быть более 512 МБ, для двух томов — более 1024Мб и т.д.
На рисунке ниже представлена структура файловой системы «ApFS».

Каждый элемент этой структуры (кроме файла распределения) начинается с 32-байтового заголовка блока, который содержит некоторую общую информацию о блоке. Далее следует тело файловой системы. Оно состоит из следующих элементов:
- 0×01: Суперблок контейнера (Container Superblock)
- 0×02: Узел (Node)
- 0×05: Менеджер пространства (Space manager)
- 0×07: Файл размещения (Allocation Info File)
- 0×0C: Контрольная точка (Checkpoint)
- 0×0D: Суперблок тома (Volume Superblock)
Контейнеры обычно точно такие же, как записи в таблице разделов GUID (GPT). У них есть собственная защита от сбоев и схема распределения дискового пространства. Каждый контейнер содержит один или несколько томов, каждый из которых имеет собственное пространство имен, набор файлов и каталогов.
Файловая система «ApFS» не поддерживает напрямую программный «RAID», но его можно использовать с томами Apple RAID для поддержки чередования (RAID 0), зеркалирования (RAID 1) и склейки (JBOD).
С 64-битным индексом тома «ApFS» поддерживают до 9 квинтиллионов (1018) файлов.
Новая файловая система от Apple использует наносекунды для установки меток времени. В HFS + метки времени были установлены с точностью до секунды. Это уменьшит количество сбоев при передаче данных и других файловых операциях.
«ApFS» имеет встроенную систему шифрования и использует системы AES-XTS или AES-CBC, в зависимости от устройства. Пользователь может использовать несколько ключей шифрования для обеспечения безопасности данных даже в случае «физического взлома» носителя.
Это далеко не полный список нововведений, которыми обладает «ApFS».
Разделы, отформатированные в «ApFS», не распознаются OS X 10.11 Yosemite и более ранними версиями операционной системы.
Block Header (Заголовок блока)
Каждая структура файловой системы в «ApFS» начинается с заголовка блока. А сам заголовок начинается с контрольной суммы. Другая информация в заголовке включает в себя версию блока с копией при записи, идентификатор блока и его тип.

Из таблицы мы видим, что 1uint = 1 бит, 8 бит = 1 байту, из этого uint64 = 8, uint32 = 4, и uint16 = 2 байтам.
Container Superblock
Суперблок контейнера (Container Superblock) — это входная точка в файловую систему. Из-за структуры файловой системы с контейнерами и гибкими томами, распределение необходимо обрабатывать на уровне контейнера. Суперблок контейнера содержит информацию о размере блока, их количестве и указателях в менеджере пространства для этой задачи. Кроме того, в суперблоке хранятся идентификаторы (ID) блоков всех томов. Для сопоставления идентификаторов блоков блокам смещения, сохраняется указатель на карту блоков B-дерева. Это дерево содержит записи для каждого тома с его идентификатором и смещением. Суперблок контейнера — это самый высокий уровень файловой системы.
Он имеет следующий вид:







С определением типов:

и

с перечнем типов объектов:
======================
enum eApFS_ObjectType
{
eApFS_ObjectType_01_SuperBlock = 0×0001, //Суперблок контейнера
eApFS_ObjectType_02_BTreeRoot = 0×0002, // Би-дерево: узловой элемент
eApFS_ObjectType_03_BTreeNode = 0×0003, // Би-дерево: лист
eApFS_ObjectType_05_SpaceManager = 0×0005, // Менеджер пространства
eApFS_ObjectType_06_SpaceManagerCAB = 0×0006, // Менеджер пространства: адреса сегментов
eApFS_ObjectType_07_SpaceManagerCIB = 0×0007, // Менеджер пространства: информация сегментов
eApFS_ObjectType_08_SpaceManagerBitmap = 0×0008, // Карта свободного пространства используемая Менеджером пространства
eApFS_ObjectType_09_SpaceManagerFreeQueue = 0×0009, // Свободное место используемое менеджером пространства_ (ключи — _tApFS_09_SpaceManagerFreeQueue_Key_, значения — _tApFS_09_SpaceManagerFreeQueue_Value_)
eApFS_ObjectType_0A_ExtentListTree = 0×000A, // Дерево списка экстентов (ключи — смещение начального экстента_tApFS_Address_, значение — физическое расположение данных _tApFS_BlockRange_)
eApFS_ObjectType_0B_ObjectsMap = 0×000B, // Тип — Карта обьектов; subType — Дерево записей карты обьектов (ключи — _tApFS_0B_ObjectsMap_Key_, значения — _tApFS_0B_ObjectsMap_Value_)
eApFS_ObjectType_0C_CheckPointMap = 0×000C, // Карта контрольных точек (чекпоинтов)
eApFS_ObjectType_0D_FileSystem = 0×000D, // Файловая система тома
eApFS_ObjectType_0E_FileSystemTree = 0×000E, // Дерево файловой системы (ключи начинаются с _tApFS_BTreeKey_, описывает тип и значение ключа)
eApFS_ObjectType_0F_BlockReferenceTree = 0×000F, // Дерево ссылок на блоки (ключи — _tApFS_BTreeKey_, значения — _tApFS_0F_BlockReferenceTree_Value_)
eApFS_ObjectType_10_SnapshotMetaTree = 0×0010, // Дерево снимков (ключи — _tApFS_BTreeKey_, значения — _tApFS_10_SnapshotMetaTree_Value_)
eApFS_ObjectType_11_Reaper = 0×0011, // Reaper
eApFS_ObjectType_12_ReaperList = 0×0012, // Reaper List
eApFS_ObjectType_13_ObjectsMapSnapshot = 0×0013, // Дерево снимков карты обьектов (ключи — _tApFS_Transaction_, значения — _tApFS_13_ObjectsMapSnapshot_Value_)
eApFS_ObjectType_14_JumpStartEFI = 0×0014, // EFI Загрузчик
eApFS_ObjectType_15_FusionMiddleTree = 0×0015, // Дерево объединённых устройств для отслеживания блоков жестких дисков, кэшированных SSD (ключи — _tApFS_Address_, значения — _tApFS_15_FusionMiddleTree_Value_)
eApFS_ObjectType_16_FusionWriteBack = 0×0016, // Состояние кэша обратной записи объединённых устройств
eApFS_ObjectType_17_FusionWriteBackList = 0×0017, // Список кэша обратной записи объединённых устройств
eApFS_ObjectType_18_EncryptionState = 0×0018, // Шифрование
eApFS_ObjectType_19_GeneralBitmap = 0×0019, // General Bitmap
eApFS_ObjectType_1A_GeneralBitmapTree = 0×001A, // Дерево General Bitmap (keys — uint64, keys — uint64)
eApFS_ObjectType_1B_GeneralBitmapBlock = 0×001B, // Блок General Bitmap
eApFS_ObjectType_00_Invalid = 0×0000, // Недействителен как тип или отсутствует как подтип
eApFS_ObjectType_FF_Test = 0×00FF // Зарезервировано для тестирования (никогда не сохраняется на носителе)
eApFS_ObjectType_FF_Test = 0×00FF // Зарезервировано для тестирования (никогда не сохраняется на носителе)
};
enum eApFS_ObjectFlag
{
eApFS_ObjectFlag_Virtual = 0×0000, // Виртуальный объект
eApFS_ObjectFlag_Ephemeral = 0×8000, // Логический объект
eApFS_ObjectFlag_Physical = 0×4000, // Физический объект
eApFS_ObjectFlag_NoHeader = 0×2000, // Объект без заголовка _tApFS_ContainerObjectHeader_ (например, Карта (bitmap) менеджера пространства)
eApFS_ObjectFlag_Encrypted = 0×1000, // Зашифрованный объект
eApFS_ObjectFlag_NonPersistent = 0×0800, // Объект из этим флагом никогда не сохраняется на носителе
eApFS_ObjectFlag_StorageTypeMask = 0xC000, // Битовая (bitmask) маска для доступа к флагам категорий обьектов
eApFS_ObjectFlag_ValidMask = 0xF800 // Действительный флаг битовой маски
};
struct tApFS_0B_ObjectsMap_Key
{
tApFS_Ident ObjectIdent; // Идентификатор объекта
tApFS_Transaction Transaction; // Номер транзакции
};
struct tApFS_0B_ObjectsMap_Value
{
uint32 Flags; // Флаги
uint32 Size; // Размер объекта в байтах (кратный размеру блока контейнера)
tApFS_Address Address; // Адрес объекта
};
struct tApFS_09_SpaceManagerFreeQueue_Key
{
tApFS_Transaction sfqk_xid;
tApFS_Address sfqk_paddr;
};
struct tApFS_09_SpaceManagerFreeQueue_Value
{
uint64 sfq_count;
tApFS_Ident sfq_tree_oid;
tApFS_Transaction sfq_oldest_xid;
uint16 sfq_tree_node_limit;
uint16 sfq_pad16;
uint32 sfq_pad32;
uint64 sfq_reserved;
};
struct tApFS_10_SnapshotMetaTree_Value
{
tApFS_Ident ExtentRefIdent; // Идентификатор физического объекта Би-дерева, в котором хранится информация об экстенте
tApFS_Ident SuperBlockIdent; // Идентификатор суперблока
uint64 CreatedTime; // Время создания снимка (в наносекундах с полуночи 01/01/1970)
uint64 LastModifiedTime; // Время изменения снимка (в наносекундах с полуночи 01/01/1970)
uint64 iNum;
uint32 ExtentRefTreeType; // Тип Би-дерева, в котором хранится информация об экстентах
uint16 NameLength; // Длинна имени снимка (включая символ конца строки)
uint8 Name[]; // Имя снимка (заканчивается на 0)
};
struct tApFS_13_ObjectsMapSnapshot_Value
{
uint32 Flags; // Флаги снимков
uint32 Padding; // Зарезервировано (для корректировки)
tApFS_Ident Reserved; // Зарезервировано
};
struct tApFS_15_FusionMiddleTree_Value
{
tApFS_Address fmv_lba;
uint32 fmv_length;
uint32 fmv_flags;
};
======================
Пример структуры файловой системы ApFS:

Полную версию статьи со всеми дополнительными видео уроками читайте в нашем блоге...