APFS: Algoritmo de Recuperação de Dados do Sistema de Ficheiros e Estrutura do Sistema de Ficheiros
ApFS fornece a capacidade de restaurar estados específicos do sistema de arquivos, incluindo versões antigas ou excluídas de arquivos. O superbloco de contêineres contém um link para a estrutura do ponto de controle. O ponto de verificação refere-se ao superbloco anterior do recipiente, que contém informações sobre o estado anterior do sistema de arquivo. É possível, portanto, restaurar vários estados antigos, analisando a cadeia de superbloqueio do recipiente.
- Contêineres e Volume
- Cabeçalho de Bloco
- Superbloqueio de contentor
- Volume Superbloqueio (Superbloqueio de Volume)
- Checkpoint (Ponto de controlo)
- Checkpoint Superblock Descriptor (Descritor do Superbloco do Ponto de Controlo)
- Estruturas de bitmap (Bitmap ou mapa de volume)
- Tabelas (Tabelas)
- Síntese da tabela
- Instantaneous (Snapshots)
- Nós
- Gestor de espaço (Space Manager)
- Allocation info file (Ficheiro de informação de distribuição)
- Ficheiro e pasta de árvore B
- Extensões (extensões de árvore B)
- 64-bit inodes (descritores de índice) - descritores de índice
- Perguntas e respostas
- Comentários
Contêineres e Volume
A estrutura do sistema de arquivos APFS tem a forma de uma árvore b, onde o diretório de dados raiz são as folhas desta árvore. Todas as filiais armazenam apenas links para o próximo nó até alcançarem as folhas. O sistema de arquivo usa recipientes como locais de armazenamento. Estes recipientes podem conter vários volumes. É também o principal objeto para o armazenamento de dados. Para um volume, o tamanho do recipiente deve ser superior a 512 MB, para dois volumes, mais de 1024 MB, etc.
A figura seguinte mostra a estrutura do sistema de ficheiros “ApFS”.
Cada elemento desta estrutura (excepto o ficheiro de atribuição) começa com um cabeçalho de bloco de 32 bytes contendo informações gerais sobre o bloco. O seguinte é o corpo do sistema de arquivo. É composto pelos seguintes elementos:
- 0x01: Superbloco de contêiner
- 0x02: Nó (Nó)
- 0x05: Gerenciador de espaço (gerenciador de espaço)
- 0x07: Localização do arquivo (arquivo de informações de alocação)
- 0x0C: Checkpoint (Checkpoint)
- 0x0D: Superbloco de Volume (Superbloco de Volume)
Os contentores são normalmente exactamente os mesmos que as entradas numa tabela de partição GUID (GPT). Têm o seu próprio esquema de atribuição de discos e protecção em caso de falha. Cada contentor contém um ou mais volumes, cada um com o seu próprio espaço de nomes, conjunto de ficheiros e directórios.
O “ApFS” sistema de ficheiros não é directamente compatível com o programa “RAID”, mas pode ser usado com volumes RAID da Apple para suportar striping (RAID 0), mirroring (RAID 1), e splicing (JBOD).
Com um índice de 64 bits o “ApFS” volumes suporta até 9 quintilhões (1018) de ficheiros.
O novo sistema de ficheiros da Apple utiliza nanossegundos para definir os carimbos temporais. No HFS+, os carimbos temporais foram definidos para o segundo mais próximo. Isto reduzirá o número de falhas durante as transferências de dados e outras operações de arquivo.
“ApFS” tem encriptação incorporada e utiliza AES-XTS ou AES-CBC, dependendo do dispositivo. O utilizador pode utilizar múltiplas chaves de encriptação para manter a segurança dos dados mesmo no caso de “Ataque Cibernético Físico” do meio.
Esta não é uma lista completa das inovações possuídas por “ApFS”.
Seções formatadas em “ApFS”, não são reconhecidas pelo OS X 10.11 Yosemite ou sistemas operativos anteriores.
Cabeçalho de Bloco
Cada estrutura de sistema de ficheiros em “ApFS” começa com um cabeçalho de bloco. E o cabeçalho em si começa com uma soma de controlo. Outras informações no cabeçalho incluem a versão copy-on-write do bloco, o ID do bloco, e o seu tipo.
Parcialidad | Tamaño | Tipo | ID |
---|---|---|---|
0 | 8 | uint64 | Suma de control (checksum) |
8 | 8 | uint64 | Identificador (block_id) |
16 | 8 | uint64 | Versión (version) |
24 | 2 | uint16 | Tipo de bloque (block_type) |
26 | 2 | uint16 | Banderas (flags) |
28 | 4 | uint32 | Relleno (padding) |
Da tabela podemos ver que 1uint = 1 bit, 8 bits = 1 byte, desse uint64 = 8, uint32 = 4 e uint16 = 2 bytes.
Superbloqueio de contentor
Container Superblock (Container Superblock) – é o ponto de entrada para o sistema de ficheiros. Devido à estrutura do sistema de arquivo com contentores e volumes flexíveis, a distribuição deve ser feita ao nível do contentor. O super bloco de contentores contém informações sobre o tamanho do bloco, o seu número e indicações no gestor do espaço para esta tarefa. Além disso, o superbloco armazena identificações de blocos para todos os volumes. Para atribuir identificações de blocos a blocos de deslocamento, é armazenado um ponteiro para o mapa de blocos da árvore B. Esta árvore contém entradas para cada volume com a sua identificação e offset. O superbloco de contentores é o nível mais alto no sistema de ficheiros. O superbloco de contentores é o nível mais alto no sistema de ficheiros.
Possui o seguinte tipo:
Parcialidade (HEX) | Tipo | Id | Descrição |
---|---|---|---|
0 | tApFS_COH | Cabeçalho | Cabeçalho do objeto Container |
20 | uint32 | MagicNumber (NXSB) | O valor a ser verificado para ler o Superblock do contêiner. |
24 | uint32 | BlockSize | Tamanho do bloco de contêiner (em bytes) |
28 | uint64 | BlocksCount | Número de blocos de contêiner |
30 | uint64 | Recursos | Bitmap das principais funções do contêiner |
38 | uint64 | ReadOnlyFeatures | Bitmap de funções de base do contêiner (somente leitura) |
40 | uint64 | IncompatibleFeatures | Bitmap das principais funções incompatíveis do contêiner |
48 | tApFS_Uuid | Uuid | UUID do contêiner |
58 | tApFS_Ident | NextIdent | Próximo identificador para novo objeto lógico ou virtual |
60 | tApFS_Transaction | NextTransaction | Número da próxima transação |
68 | uint32 | DescriptorBlocks | Número de blocos usados pelo descritor |
6C | uint32 | DataBlocks | Número de blocos usados pelos dados |
70 | tApFS_Address | DescriptorBase | Endereço básico de um descritor ou identificador de um objeto físico com uma árvore de endereço |
78 | int32 | Banco de dados | Endereço do banco de dados ou identificador de um objeto físico com árvore de endereços |
80 | uint32 | DescriptorNext | Índice do próximo descritor |
84 | uint32 | DataNext | Próximo índice de dados |
88 | uint32 | DescriptorIndex | O índice do primeiro elemento válido no segmento do descritor. |
8C | uint32 | DescriptorLength | O número de blocos no segmento descritor usado pelo superbloco |
90 | uint32 | DataIndex | O índice do primeiro elemento válido no segmento de dados |
94 | uint32 | DataLength | Número de blocos no segmento de dados usado pelo superbloco |
98 | tApFS_Ident | SpaceManagerIdent | Gerenciador de espaço para ID de entidade |
A0 | tApFS_Ident | ObjectsMapIdent | O identificador de objeto físico do mapa de objeto do contêiner |
A8 | tApFS_Ident | ReaperIdent | Identificador de entidade |
B0 | uint32 | ReservedForTesting | |
B4 | uint32 | MaximumVolumes | O número máximo possível de volumes em um contêiner |
B8 | tApFS_Ident | VolumesIdents [100] | Volume da matriz do identificador de objeto virtual |
3D8 | uint64 | Contadores [32] | Matriz de contadores que armazenam informações sobre o contêiner |
4D8 | tApFS_BlockRange | BlockedOutOfRange | Intervalo físico de blocos que não podem ser usados |
4E8 | tApFS_Ident | MappingTreeIdent | O identificador de um objeto físico na árvore que é usado para rastrear objetos que são movidos do armazenamento bloqueado. |
4F0 | uint64 | OtherFlags | Mapa de outras funções de contêiner |
4F8 | tApFS_Address | JumpstartEFI | Identificação de um objeto físico com dados do controlador EFI |
500 | tApFS_Uuid | FusionUuid | UUID para contêineres Fusion ou zero para contêineres não Fusion |
510 | tApFS_BlockRange | KeyLocker | Localização da marca da chave do contêiner |
520 | uint64 | EphemeralInfo [4] | Matriz de campos usados para manipular dados lógicos |
540 | tApFS_Ident | ReservedForTesting | |
548 | tApFS_Ident | FusionMidleTreeIdent | Apenas para dispositivos vinculados |
550 | tApFS_Ident | FusionWriteBackIdent | Apenas para dispositivos vinculados |
558 | tApFS_BlockRange | FusionWriteBackBlocks | Blocos usados para a área de cache |
Com definição de tipo:
uint8 & nbsp; & nbsp; tApFS_Uuid;
uint64 & nbsp; tApFS_Ident;
uint64 & nbsp; tApFS_Transaction;
int64 & nbsp; & nbsp; tApFS_Address;
uint64 & nbsp; tApFS_BTreeKey;
u
struct tApFS_BlockRange
{
& nbsp; & nbsp; & nbsp; & nbsp; tApFS_Address & nb
sp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; Primeiro; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; // Primeiro bloco
& nbsp; & nbsp; & nbsp; & nbsp; uint64 & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; Contagem & nbsp; & nbsp; & nbsp; & nbsp; // Número de blocos
}
struct tApFS_COH
{
uint64 CheckSum; // Bloquear checksum
tApFS_Ident Ident; // Identificador
tApFS_Transaction Transaction; // Número da transação de alteração do objeto
uint16 Type; // Tipo de objeto
uint16 Flags; // Sinalizador de objeto
& nbsp; & nbsp; & nbsp; & nbsp; uint32 & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; Subtipo & nbsp; & nbsp; // Subtipo de objeto
};
com uma lista de tipos de objetos:
enum & nbsp; eApFS_ObjectType
{
eApFS_ObjectType_01_SuperBlock = 0x0001, //Superbloque del contenedor
eApFS_ObjectType_02_BTreeRoot = 0x0002, // Árbol-B: nodal elemento
eApFS_ObjectType_03_BTreeNode = 0x0003, // Árbol-B: lista
eApFS_ObjectType_05_SpaceManager = 0x0005, // Administrador de espacio
eApFS_ObjectType_06_SpaceManagerCAB = 0x0006, // Administrador de espacio: dirección de segmentos
eApFS_ObjectType_07_SpaceManagerCIB = 0x0007, // Administrador de espacio: información de segmentos
eApFS_ObjectType_08_SpaceManagerBitmap = 0x0008, // Mapa de espacio libre utilizado por el Administrador de espacio
eApFS_ObjectType_09_SpaceManagerFreeQueue = 0x0009, // Espacio libre utilizado por el administrador de espacio_ (llaves - _tApFS_09_SpaceManagerFreeQueue_Key_, significado - _tApFS_09_SpaceManagerFreeQueue_Value_)
eApFS_ObjectType_0A_ExtentListTree = 0x000A, // Árbol lista extensiones (llaves – Parcialidad del principio экстента_tApFS_Address_, significado – ubicación física de datos _tApFS_BlockRange_)
eApFS_ObjectType_0B_ObjectsMap = 0x000B, // Tipo – Mapa de objetos; subType – Árbol registros mapas de objetos (llaves - _tApFS_0B_ObjectsMap_Key_, significado - _tApFS_0B_ObjectsMap_Value_)
eApFS_ObjectType_0C_CheckPointMap = 0x000C, // Mapa de puntos de control (puntos de control)
eApFS_ObjectType_0D_FileSystem = 0x000D, // Sistema de archivos volumen
eApFS_ObjectType_0E_FileSystemTree = 0x000E, // Árbol sistema de archivos (llaves comienzan с _tApFS_BTreeKey_, describe Tipo и valor de la llave)
eApFS_ObjectType_0F_BlockReferenceTree = 0x000F, // Árbol enlace a bloques (llaves - _tApFS_BTreeKey_, valor - _tApFS_0F_BlockReferenceTree_Value_)
eApFS_ObjectType_10_SnapshotMetaTree = 0x0010, // Árbol instantáneas (llaves - _tApFS_BTreeKey_, valor - _tApFS_10_SnapshotMetaTree_Value_)
eApFS_ObjectType_11_Reaper = 0x0011, // Reaper
eApFS_ObjectType_12_ReaperList = 0x0012, // Reaper List
eApFS_ObjectType_13_ObjectsMapSnapshot = 0x0013, // Árbol instantáneas mapas objetos (llaves - _tApFS_Transaction_, valor - _tApFS_13_ObjectsMapSnapshot_Value_)
eApFS_ObjectType_14_JumpStartEFI = 0x0014, // EFI Cargador
eApFS_ObjectType_15_FusionMiddleTree = 0x0015, // Árbol dispositivos conectados para el seguimiento de bloques de discos duros, SSD en caché (llave - _tApFS_Address_, valor - _tApFS_15_FusionMiddleTree_Value_)
eApFS_ObjectType_16_FusionWriteBack = 0x0016, // Estado de caché respuesta de dispositivos conectados
eApFS_ObjectType_17_FusionWriteBackList = 0x0017, // Lista de caché respuesta de dispositivos conectados
eApFS_ObjectType_18_EncryptionState = 0x0018, // Cifrado
eApFS_ObjectType_19_GeneralBitmap = 0x0019, // General Bitmap
eApFS_ObjectType_1A_GeneralBitmapTree = 0x001A, // Árbol General Bitmap (keys - uint64, keys - uint64)
eApFS_ObjectType_1B_GeneralBitmapBlock = 0x001B, // Bloque General Bitmap
eApFS_ObjectType_00_Invalid = 0x0000, // No es válido como tipo o no está como subtipo
eApFS_ObjectType_FF_Test = 0x00FF // Reservado para pruebas (nunca se guarda en dispositivo)
eApFS_ObjectType_FF_Test = 0x00FF // Reservado para pruebas (nunca se guarda en dispositivo)
};
enum eApFS_ObjectFlag
{
eApFS_ObjectFlag_Virtual = 0x0000, // Objeto virtual
eApFS_ObjectFlag_Ephemeral = 0x8000, // Objeto lógico
eApFS_ObjectFlag_Physical = 0x4000, // Objeto físico
eApFS_ObjectFlag_NoHeader = 0x2000, // Objeto sin título _tApFS_ContainerObjectHeader_ (por ejemplo, mapa (bitmap) administrador de espacio)
eApFS_ObjectFlag_Encrypted = 0x1000, // Objeto cifrado
eApFS_ObjectFlag_NonPersistent = 0x0800, // Objeto con estas banderas nunca se guardaran en dispositivo
eApFS_ObjectFlag_StorageTypeMask = 0xC000, // Битовая (bitmask) máscara para permiso a banderas de objetos de categoría
eApFS_ObjectFlag_ValidMask = 0xF800 // Bandera real de máscara de bits
};
struct tApFS_0B_ObjectsMap_Key
{
tApFS_Ident ObjectIdent; // Identificador de Objeto
tApFS_Transaction Transaction; // Número de transacción
};
struct tApFS_0B_ObjectsMap_Value
{
uint32 Flags; // Bandera
uint32 Size; // tamaño objeto en bites (tamaño corto de bloque del contenedor)
tApFS_Address Address; // Dirección del objeto
};
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; // Identificador de objeto físico árbol-B, en el que se guarda la información sobre la extención
tApFS_Ident SuperBlockIdent; // Identificador del superbloque
uint64 CreatedTime; // Hora de instantánea (en nanosegundos desde medianoche de 01/01/1970)
uint64 LastModifiedTime; // Hora de instantánea (en nanosegundos desde medianoche de 01/01/1970)
uint64 iNum;
uint32 ExtentRefTreeType; // Tipo árbol-B, en el que se guarda la información sobre la extención
uint16 NameLength; // Largo de nombre de la instantánea incluye símbolos al final de la fila)
uint8 Name; // Nombre instantánea (termina en 0)
};
struct tApFS_13_ObjectsMapSnapshot_Value
{
uint32 Flags; // Banderas de instantaneas
uint32 Padding; // Reservado (para correcciones)
tApFS_Ident Reserved; // Reservado
};
struct tApFS_15_FusionMiddleTree_Value
{
tApFS_Address fmv_lba;
uint32 fmv_length;
uint32 fmv_flags;
};
Exemplo da estrutura de um sistema de ficheiros ApFS:
Volume Superbloqueio (Superbloqueio de Volume)
Superbloqueio de Volume (Volume Superblock)- existe para cada volume no sistema de arquivo. Contém o nome do volume, ID e carimbo da hora. Como um Container Superblock, contém um ponteiro para um mapa de blocos que atribui um ID de bloco aos seus offsets. Além disso, o superbloco de volume armazena um ponteiro no directório raiz, que é armazenado como um nó.
Parcialidad (HEX) | Tipo | Id | Descripción |
---|---|---|---|
0 | tApFS_COH | Header | Cabeçalho do objecto do contentorr (Container Object Header) |
20 | uint32 | MagicNumber (APSB) | Um valor que pode ser usado para verificar se estamos a ler uma instância. Superbloco de volume |
24 | uint32 | IndexInSuperBlock | O índice do ID do objecto deste volume na matriz de volume do contentor. |
28 | uint64 | Features | Mapa de bits de las principales funciones utilizadas por volumen |
>30 | uint64 | ReadOnlyFeatures | Bitmap das funções básicas (apenas de leitura) utilizadas por volume |
38 | uint64 | IncompatibleFeatures | Bitmap de funções de volume incompatíveis /td> |
40 | uint64 | LastUnmountTime | A hora em que o volume foi desmontado pela última vez (em nanossegundos a partir da meia-noite de 01/01/1970) |
48 | uint64 | ReservedBlocksCount | Número de blocos reservados para atribuição de volume. |
50 | uint64 | QuotaBlocksCount | O número máximo de blocos que este volume pode atribuir. |
58 | uint64 | AllocatedCount | O número de blocos actualmente atribuídos ao sistema de ficheiros neste volume. |
60 | uint8 | MetaCryptoState[20] | Informação sobre a chave utilizada para encriptar os metadados deste volume (ejemplar wrapped_meta_crypto_state_t) |
74 | uint32 | RootTreeType | Tipo de raiz de árvore de pasta (geralmente): Tipo ( eApFS_ObjectFlag_Virtual << 16) \ eApFS_ObjectType_02_BTreeRoot , subtipo eApFS_ObjectType_0E_FileSystemTree ) |
78 | uint32 | ExtentRefTreeType | Tipo de árvore de Spanning (geralmente): Tipo ( eApFS_ObjectFlag_Physical << 16) \ eApFS_ObjectType_02_BTreeRoot , subtipo OBJECT_TYPE_BLOCKREF ) |
7C | uint32 | SnapshotMetaTreeType | Tipo de árvore de metadados do instantâneo (tipicamente): Tipo ( eApFS_ObjectFlag_Physical << 16) \ eApFS_ObjectType_02_BTreeRoot , subtipo OBJECT_TYPE_BLOCKREF ) |
80 | tApFS_Ident | ObjectsMapIdent | IIdentificador físico do objecto no mapa volumétrico de objectos |
88 | tApFS_Ident | RootTreeIdent | Root Folder Árvore Identificador de Objecto Virtual |
90 | tApFS_Ident | ExtentRefTreeIdent | Identificador físico do objecto da árvore de ligação. |
98 | tApFS_Ident | SnapshotMetaTreeIdent | Identificador de Objecto Virtual de Árvore de Metadados do instantâneo |
)">A0 | tApFS_Transaction | RevertToXid | O número da transacção do instantâneo ao qual o volume deve ser devolvido. |
>A8 | tApFS_Ident | RevertToSuperBlock | Identificador del objeto VS físico al que se revertirá el volumen |
B0 | uint64 | NextObjectIdent | O próximo identificador a ser atribuído ao objecto do sistema de ficheiros de volume. |
B8 | uint64 | NumberOfFiles | Número de ficheiros regulares em volume |
C0 | uint64 | NumberOfDirectories | Número de pastas em volume |
C8 | uint64 | NumberOfSymbolicLinks | Número de ligações simbólicas em volume |
D0 | uint64 | NumberOfOtherObjects | Número de outros objectos no volume (não da chave x0B8_NumberOfFiles , x0C0_NumberOfDirectories и x0C8_NumberOfSymbolicLinks ) |
D8 | uint64 | NumberOfSnapshots | Número de instantâneos neste volume |
E0 | uint64 | TotalBlocksAllocated | Cantidad total de bloques asignados por este volumen |
E8 | uint64 | TotalBlocksFreed | Cantidad total de bloques liberados por este volumen |
F0 | tApFS_Uuid | Uuid | |
100 | uint64 | LastModifiedTime | Hora da última mudança deste volume (em nanossegundos desde a meia-noite de 01/01/1970) |
108 | uint64 | Flags | |
110 | tApFS_0D_FSM | FormattedBy | Informação sobre o software que criou este volume |
140 | tApFS_0D_FSM | ModifiedBy[8] | Informação sobre o software que alterou este volume |
2C0 | uint8 | VolumeName[256] | Nome do volume zero da linha UTF-8 |
3C0 | uint32 | NextDocumentIdent | Próximo identificador de documento a asignar (almacenado en el campo ampliado) APFS_0E_TYPE_DOCUMENT_ID del documento) |
3C4 | uint16 | Role | Bitmap do papel do volume |
3C6 | uint16 | Reserved | |
3C8 | tApFS_Transaction | RootToXid | Número de transacção instantânea para não-root ou zero para root |
3D0 | tApFS_Ident | EncryptStateIdent | O estado actual de encriptação ou desencriptação, ou zero se não houver encriptação |
Ilustração detalhada de «APFS»:
Checkpoint (Ponto de controlo)
Ponto de controlo - este é o estado temporário do recipiente. Cada ponto de controlo é rubricado no Superbloco do contentor, e o estado actual é normalmente o último. O ponto de controlo contém metadados tanto para o recipiente como para o volume. Os pontos e instantâneos de recuperação são semelhantes entre si. A principal diferença entre um ponto de controlo e um instantâneo é a capacidade do utilizador de restaurar o sistema de ficheiros a partir de instantâneos guardados utilizando o API do sistema de ficheiros.
Checkpoint Superblock Descriptor (Descritor do Superbloco do Ponto de Controlo)
Este bloco contém informação sobre as estruturas de metadados em "ApFS" e é o bloco Descritor anterior. A informação mais importante neste bloco é a localização da estrutura do bitmap (BMS), o ficheiro de distribuição anterior em HFS+.
Descritor de super-bloco do ponto de verificação:
Estruturas de bitmap (Bitmap ou mapa de volume)
Registos de blocos usados e não utilizados. Existe apenas um mapa de volume que cobre todo o contentor e é comum a todos os volumes do sistema de ficheiros. "ApFS" utiliza um conjunto de blocos para armazenar o mapa de volume (Estruturas Bitmap).
Em "ApFS" o mapa é comum a todos os volumes no contentor. Cada volume contém citações para o bloco no contentor, mas os blocos em si não se encontram nas áreas cartografadas. A ligação ao mapa do volume está no Superblock Checkpoint Descriptor (CSBD), que contém informação sobre o nível superior da estrutura, o Bitmap Descriptor (BMD). A figura abaixo mostra a estrutura básica deste mapa. Está dividido em níveis, com BMD no topo e estabelecendo limites. Por baixo estão "Blocos de Bitmap" (BMB), que mantêm um registo dos blocos no contentor. Um byte na pista BMB oito blocos, cada um dos quais fornece um estado de atribuição. Cada bit é o estado de um bloco independente.
Tabelas (Tabelas)
Tabelas são utilizadas no catálogo e nas extensões das árvores B, na lista de volumes e no mapa de ID de objectos.
Tabelas utilizadas em "ApFS", são pequenas "bases de dados" de um bloco com uma finalidade ligeiramente diferente nas estruturas do sistema de ficheiros. O campo tipo tabela consiste em 2 bytes localizados no bloco com partição 0x20 imediatamente a seguir ao cabeçalho do nó. Há oito tabelas de 0 a 7. Os 2 bytes seguintes fornecem a tabela de nível 0 e superior. A tabela do segundo nível conterá registos relacionados com a tabela base do primeiro nível. E as tabelas de nível zero referem-se a blocos que frequentemente contêm metadados de ficheiros.
Tipos de mesa variam em estrutura, mas o cabeçalho da tabela para todos os tipos é de 24 bytes.
A figura mostra uma estrutura de cabeçalho da tabela de amostras:
Descrição dos valores de campo na estrutura de cabeçalho:
Parcialidade (HEX) | Campo | Tipo de dados | Descrição |
---|---|---|---|
20 | tableType | uint16 | Los valores posibles son 0-7. Esta eé a tabela 1 |
22 | tableLevel | uint16 | Indica o nível da árvore B. |
24 | tableRecords | uint16 | Número de registos na tabela |
26 | Unknown 1 | uint16 | |
28 | Unknown 2 | uint16 | |
2A | tableIndexSize | uint16 | tamanho das áreas de índice da tabela. |
2C | tableKeyAreaSize | uint16 | tamanho da área da tabela chave. |
2E | tableFreeSpaceSize | uint16 | tamanho da área livre. A área de dados da tabela termina com um enviesamento 0x38+tableIndexSize+tableKeyAreaSize+tableFreeSpaceSize. 0x38 + 0x80 + 0x170 + 0xd58 . |
30 | Unknown 3 | uint16 | |
32 | Unknown 4 | uint16 | |
34 | Unknown 5 | uint16 | |
36 | Unknown 6 | uint16 |
Aqui está um esquema geral das diferentes tabelas:
Nem todos os elementos da imagem são utilizados em todas as tabelas. A figura mostra um bloco completo com o cabeçalho do bloco do nó superior. O resto do bloco é uma tabela.
O índice de registo segue-se imediatamente após o cabeçalho da tabela. Existem 2 tipos deles. Um com dois valores: Parcialidade na chave, e Parcialidade na secção de dados para cada um dos Uint16. O segundo utiliza 4 valores Uint16 com Parcialidade e comprimento para as chaves e partições de dados. O índice de registos da tabela contém informações sobre a chave e os registos de dados na tabela. Outra diferença entre os tipos de tabelas é a utilização de rodapés.
Tabelas 1, 3, 5 e 7 utilizam rodapés de 0x28 bytes no final do bloco. Nestas tabelas, todos os offsets de dados referem-se ao offset 0xFD8 e o rodapé contém vários valores específicos do tipo de tabela. Outros tipos de tabelas não têm um rodapé, e todas as referências ao conteúdo da secção de dados referem-se ao fim do bloco.
In B-trees com múltiplos níveis, - тTables 1, 3, 5 e 7 estão ao mais alto nível, uma vez que têm rodapés. O rodapé, utilizado para armazenar informação sobre toda a árvore B. Um dos valores no rodapé é o número total de entradas nesta estrutura de árvore.
A definição da tabela começa em offset 0x20 no bloco. Mostra o tipo da tabela, o número de filas, o tamanho da secção da chave e o espaçamento entre a chave e a secção de dados. Após as propriedades da tabela, o offset 0x38 descreve as definições de linha e coluna. O quadro contém o título, definições de registos, secções-chave e dados. Alguns tipos de mesas também têm um rodapé. O cabeçalho começa em offset 0x20 e tem um comprimento de 0x18 bytes. O cabeçalho deste tipo de tabela começa com um valor de 16 bits que representa o tipo da tabela. Seguem-se dois bytes, representando o nível na árvore B em que a tabela é utilizada. Os dois bytes seguintes representam o número de filas na tabela. O comprimento do registo de definição de scan é 0x2A, seguido de Uint16, que regista o comprimento da chave da secção. A seguir vem a lacuna entre a chave e a secção de dados. O rodapé da mesa é sempre 0x28 bytes e ocupa sempre o fim do bloco. E os índices da tabela ou são de 4 ou 8 bytes cada. Nos índices de 8 bytes, os dois primeiros "Uint16" são a parcialidade e o comprimento do registo chave. Os dois seguintes "Uint16" são registos de parcialidade e comprimento de dados na tabela. As tabelas com índices de 4 bytes têm dois valores Uint16 que contêm o enviesamento de chaves e registos de dados. O comprimento dos dados em duas entradas é o valor por defeito. Nas tabelas de rodapé de partialidade, os registos de dados são relativos ao início do rodapé (0x28 bytes). E para outros tipos de tabelas, esta parcialidade refere-se ao fim do bloco.
A maior parte dos significados relacionados com o cabeçalho e rodapé de uma tabela são claros, pelo menos de um tipo de leitura de tabela. Parcialidade 0x18 no rodapé (parcialidade 0xFF num bloco de 4 KB) é o número de registos na tabela e em todas as tabelas de base (se for uma tabela com um nível superior a 0, em offset 0x22). O offset 0x20 no rodapé é o número da entrada seguinte na tabela.
Tabela 0
Uma tabela de tipo 0 está localizada na estrutura do directório da árvore B entre os nós da folha e o nó de raiz. Os valores desconhecidos de 3 a 6 são apresentados como desvio e comprimento da chave. Compensações de dados e duração do próximo registo disponível. Se não houver entradas de índice livres, os offsets são definidos para "0xFFFFFF" e o comprimento "0x00".
As entradas da tabela são quatro "Uint16" valores. Os primeiros 2 - estes são os valores de enviesamento e comprimento na secção chave, e os 2 seguintes são os valores de enviesamento e conteúdo na secção de dados.
Um exemplo de tabela tipo 0 seria um identificador de nó de catálogo, uma chave de nome na secção de chave, e um identificador de objecto na secção de dados. Esta tabela não tem um rodapé.
Tabela 1
A primeira tabela tem um rodapé e o índice da tabela contém quatro valores de 16 bits, onde os 2 primeiros valores são o viés de registo da secção chave e o comprimento do registo. Os 2 valores seguintes fornecem a entrada de enviesamento da secção de dados e o seu comprimento. Esta tabela é frequentemente encontrada tanto na estrutura do directório da árvore B como na árvore de cobertura do nó de nível superior. Um exemplo são os valores: "Parent ID" e nome chave (o nome de um ficheiro ou pasta na estrutura do directório e o número de bloco inicial na árvore B de extensão), o identificador do objecto quando usado como nó raiz na estrutura do directório ou o número de bloco quando usado na árvore de extensão.
Exemplos desta tabela são mostrados abaixo:
Tabela 2
A segunda tabela. Inicialmente, esta tabela é idêntica à anterior, mas não tem rodapé. Este tipo de tabela é muito comum em nós de folhas na estrutura do directório da árvore B onde a secção chave é representada com "Parent ID" e o nome chave.
Tabela 3
A terceira tabela é idêntica à anterior. O índice da tabela é o mesmo que a primeira tabela. Os valores típicos dependem da estrutura em que são utilizados. Na estrutura de directório de árvore B e de árvore de extensão, esta tabela é frequentemente utilizada como um nó de nível superior em pequenos volumes, onde o nó de raiz é a raiz e os nós de folha. Neste caso, a entrada chave poderia ser "Parent ID". A chave do nome e a entrada de dados pode ser um ficheiro de metadados com grande variação de tamanho.
A chave do nome e a entrada de dados pode ser um ficheiro de metadados com grande variação de tamanho.
Outras entradas da tabela são identificadores de objectos "ID do objecto" e o seu tipo no registo chave, com extensão de informação do ficheiro e registos de dados. A terceira tabela tem uma página зie.
Exemplo de tabela:
Tabela 4
Tabela 4 é ligeiramente diferente das anteriores. Não há nenhum rodapé na tabela e o índice da tabela tem apenas 2 valores: Parcialidade da entrada na secção chave e 1 valor para a secção de dados. O comprimento do conteúdo é fixado em 16 bytes na secção chave e 8 bytes na secção de dados. Os offsets na secção de dados referem-se ao fim do bloco.
Tabela 5
Tabela 5 é semelhante à tabela 4. A única diferença é que este tipo tem um rodapé e todos os offsets de dados começam com "offset-0x28" (início do rodapé). As entradas na secção chave são 16 bytes e 8 bytes na secção de dados. Este tipo de tabela é mais comumente visto em nós de nível superior na estrutura do directório de árvores B e em grandes contentores com árvores escalonadas.
Tabela 6
Tabela 6 também se parece com a tabela 4. O índice da tabela é apenas parcial ao conteúdo da chave e da secção de dados, mas não ao seu comprimento. O comprimento é pré-definido. Cada entrada tem um comprimento de 16 bytes. Não existe um rodapé para este tipo de mesa. Esta tabela encontra-se frequentemente nos nós de folhas da estrutura do directório B-tree. O conteúdo típico da secção chave da tabela inclui o identificador do objecto e o ID do volume do Ponto de Controlo do Superbloco "Volume Checkpoint Superbloco ID", enquanto a secção de dados regista normalmente o tamanho e o número do bloco.
Tabela 7
Tabela 7 é semelhante à tabela 6. A única diferença é o rodapé, que contém informação semelhante à descrita para o Quadro 1. Este tipo de tabela é visto numa vasta gama de estruturas e encontra-se frequentemente nos níveis mais elevados de uma estrutura de várias camadas ou em estruturas de camada única, tais como a descrição do volume.
Exemplo
Síntese da tabela
Esta tabela mostra as principais propriedades de vários tipos de tabelas:
Tipo | Rodapé | Parcialidade da secção chave | Comprimento da secção chave | Parcialidade da secção de dados | Comprimento da secção de dados | Comprimento da chave | Comprimento dos dados |
---|---|---|---|---|---|---|---|
0 | NO | uint16 | uint16 | uint16 | uint16 | Varies | Possible |
1 | SI | uint16 | uint16 | uint16 | uint16 | Varies | Possible |
2 | NO | uint16 | uint16 | uint16 | uint16 | Varies | Possible |
3 | SI | uint16 | uint16 | uint16 | uint16 | Varies | Possible |
4 | NO | uint16 | uint16 | >16 bytes | 16 bytes | ||
5 | SI | uint16 | uint16 | 16 bytes | >8 bytes | ||
6 | NO | uint16 | uint16 | 16 bytes | 16 bytes | ||
7 | SI | uint16 | uint16 | 16 bytes | 16 bytes |
Um dos blocos mais importantes na estrutura de directório da árvore B é o nó raiz, que é o nível mais alto na estrutura de pastas. Este nó utiliza chaves de pesquisa de comprimento variável. Uma das características melhoradas de "ApFS" é uma pesquisa rápida de directório. Um valor que está intimamente relacionado com esta característica é o número de todos os registos na estrutura em árvore localizados no rodapé da tabela.
O nó raiz da estrutura de árvore B tem 2 opções de selecção de tabela, uma vez que ambos têm rodapés. Quadro 3: como um nó raiz, visto apenas em pequenos recipientes com uma pequena quantidade de ficheiros, onde o nó raiz é também um nó índice e nós foliares.
No mapa de características para o nó raiz, apenas a quinta tabela é utilizada, excepto para estruturas muito pequenas onde se pode encontrar a sétima.
A interpretação das tabelas mostra que as tabelas 0 e 2 têm o mesmo significado. O mesmo é observado entre os quadros 1 e 3. Estes quadros parecem ter objectivos diferentes dependendo da estrutura em que se encontram.
Instantaneous (Snapshots)
Snapshots são instantâneos de um sistema de arquivo só de leitura de um volume. O sistema operativo pode utilizar estes instantâneos para backups mais eficientes. Graças à "Máquina do Tempo" funcionará mais rapidamente. E graças a Time Machine suporte de instantâneo, já não precisa de manter múltiplas cópias completas de um ficheiro em disco, pode simplesmente manter um registo das alterações específicas. Por exemplo, se editar um ficheiro modificado usando HFS+, mantém duas cópias do ficheiro, a primeira regista as novas alterações e a segunda no caso de querer voltar à vista anterior. Em "APFS" apenas o ficheiro original é retido e as diferenças entre o ficheiro original e as versões actualizadas são registadas, ocupando menos espaço em disco. Tal como com os melhoramentos a Fusion Drive, a informação ocupa menos espaço em disco.
Al embora "ApFS" seja significativamente inferior nas suas capacidades ao ZFS de 128 bits, que é compatível com Linux, FreeBSD e outros sistemas operativos livres, este é um passo na direcção certa da Apple.
Como mencionado acima, a Apple tem vindo a tentar mudar o ZFS para OS X há muito tempo. Mais tarde, o OpenZFS foi implementado para OS X (O3X) e MacZFX.
Nós
Nós são recipientes flexíveis utilizados para armazenar vários tipos de registos. Podem fazer parte da árvore B ou podem existir por si próprios. Os nós podem conter entradas de tamanho fixo ou flexível. O nó começa com uma lista de apontadores para introduzir chaves e entradas. Portanto, para cada registo, o nó contém o cabeçalho de entrada no início do nó, a chave de entrada no meio do nó, e o registo de entrada no fim do nó.
Posição | tamanho | Tipo | ID |
---|---|---|---|
0 | 4 | uint32 | alinhamento |
4 | 4 | uint32 | ENTRY_COUNT |
10 | 2 | uint16 | HEAD_SIZE |
16 | 8 | entry | meta_entry |
24 | ... | entry | entries (repeat entry_count times) |
Estrutura de cabeçalho do nó (Node header):
Parcialidade | Campo | Tipo de dados | Comentário |
---|---|---|---|
0 | Checksum | Uint64 | Fletchers Checksum Algorithm |
8 | ID | Uint64 | Object-ID or Block# |
10 | Checkpoint | Uint64 | |
18 | Unknown | Uint16 | Possible level in B-Tree |
1A | Unknown | Uint16 | All observations shows value 0x4000 |
1C | Unknown | Uint16 | Flag? |
1E | Unknown | Uint16 | Often seen value 0x0b, 0x0e and 0x0f |
Gestor de espaço (Space Manager)
«Space Manager» (Gestor de espaço) é utilizado para gerir blocos atribuídos num recipiente "ApFS". Armazena o número de blocos livres e um ponteiro para os ficheiros de informação de localização.
Posição | tamanho | Tipo | ID |
---|---|---|---|
0 | 4 | uint32 | tamanho do bloco |
16 | 8 | uint64 | totalblocks |
40 | 8 | uint64 | freeblocks |
144 | 8 | uint64 | prev_allocationinfofile_block |
352 | 8 | uint64 | allocationinfofile_block |
Allocation info file (Ficheiro de informação de distribuição)
O ficheiro de distribuição funciona como um cabeçalho em falta. É aqui que são armazenados o comprimento dos ficheiros, a versão e a sua parcialidade.
Posição | tamanho | Tipo | ID |
---|---|---|---|
4 | 4 | uint32 | alloc_file_length |
8 | 4 | uint32 | alloc_file_version |
24 | 4 | uint32 | TOTAL_BLOCKS |
28 | 4 | uint32 | free_blocks |
32 | 4 | uint32 | allocationfile_block |
Ficheiro e pasta de árvore B
Registos de todos os ficheiros e pastas sobre o volume. Têm a mesma função que os ficheiros de directório em "HFS+".
Extensões (extensões de árvore B)
Uma árvore B dividida de todas as extensões no volume. As extensões são links para o conteúdo de um ficheiro com informação sobre onde começa o conteúdo dos dados e a sua extensão em blocos. Um ficheiro com algum conteúdo terá pelo menos uma extensão. Um ficheiro fragmentado terá várias extensões. A árvore de extensão é uma estrutura separada.
Em cada entrada de ficheiro, são definidas extensões para cada um destes ficheiros na árvore B. Esta estrutura de extensão separada faz parte da funcionalidade snapshot.
64-bit inodes (descritores de índice) - descritores de índice
inódios de 64 bits aumentam significativamente o espaço de nomes sobre identificadores de 32 bits em "HFS+". Sistema de ficheiros de 64 bits em "ApFS" suporta mais de 9 quintilhões de ficheiros por volume. Como Bill Gates disse, isto deve ser suficiente para todos.
"ApFS" proporciona a capacidade de restaurar certos estados do sistema de ficheiros, incluindo versões antigas ou apagadas de ficheiros. O superbloco de contentores contém uma ligação à estrutura do ponto de controlo. O ponto de controlo refere-se ao anterior superbloco do contentor, que contém informação no estado anterior do sistema de arquivo. Por conseguinte, é possível restaurar vários estados antigos através da análise da cadeia de super-bloqueio do contentor.