APFS: algorytm odzyskiwania danych z systemu plików i jego struktura

“ApFS oferuje możliwość przywrócenia niektórych stanów systemu plików, w tym starych lub usuniętych wersji plików. Superblok kontenerowy zawiera odniesienie do struktury punktu kontrolnego. Punkt kontrolny odnosi się do poprzedniego superbloku kontenera, który zawiera informacje w starszym stanie systemu plików. Więc, można przywrócić kilka starych stanów poprzez analizę łańcucha superbloków kontenera.

APFS: algorytm odzyskiwania danych z systemu plików i jego struktura

Przejdź do widoku
🍏 Najlepsze programy do odzyskiwania danych z dysku APFS lub jak odzyskać dysk Apple MacOS w Windows

🍏 Najlepsze programy do odzyskiwania danych z dysku APFS lub jak odzyskać dysk Apple MacOS w Windows

Kontenery i Toma

Odzyskiwanie danych z napędów flash, kart pamięci, dysków twardych i napędów SSD w systemie MacOS.

Struktura systemu plików APFS ma postać drzewa b, gdzie katalog główny z danymi jest liśćmi tego drzewa. Wszystkie gałęzie przechowują tylko odniesienia do następnego węzła, dopóki nie dotrą do liści. System plików wykorzystuje pojemniki jako komórki pamięci masowej. Pojemniki te mogą zawierać kilka objętości. Jest to również podstawowy obiekt do przechowywania danych. Pojemnik musi być większy niż 512MB na jedną objętość, większy niż 1024MB na dwie objętości itp.

Poniższy rysunek przedstawia strukturę systemu plików «ApFS».

ApFS

Każdy element tej struktury (z wyjątkiem pliku dystrybucyjnego) zaczyna się od 32-bajtowego nagłówka bloku, który zawiera pewne ogólne informacje o bloku. Po tym następuje korpus systemu plików. Składa się on z następujących elementów:

  • 0x01: Superblok kontenera (Container Superblock)
  • 0x02: Węzeł (Node)
  • 0x05: Menedżer przestrzeni (Space manager)
  • 0x07: Plik lokacyjny(Allocation Info File)
  • 0x0C: Punkt kontrolny (Checkpoint)
  • 0x0D: Superblok objętości (Volume Superblock)

Kontenery są zazwyczaj takie same jak zapisy w tabeli partycji GUID (GPT). Mają one swój własny system ochrony przed awariami i przydział przestrzeni dyskowej. Każdy pojemnik zawiera jeden lub więcej tomów, z których każdy posiada własną przestrzeń nazw, zestaw plików i katalogów.

System plików “ApFS” nie obsługuje bezpośrednio oprogramowania “RAID”, ale może być używany z woluminami Apple RAID do obsługi pasowania (RAID 0), mirroringu (RAID 1) i łączenia (JBOD).

Przy 64-bitowym indeksie “ApFS” wolumenu, obsługiwanych jest do 9 kwintilionów (1018) plików.

Nowy system plików Apple wykorzystuje nanosekundy do ustawiania znaczników czasowych. W HFS + znaczniki czasu zostały ustawione na najbliższą sekundę. Pozwoli to na zmniejszenie liczby awarii w przesyłaniu danych i innych operacjach związanych z plikami.

“ApFS” posiada wbudowany system szyfrowania i używa AES-XTS lub AES-CBC, w zależności od urządzenia. Użytkownik może użyć wielu kluczy szyfrujących do zabezpieczenia danych nawet w przypadku “fizycznego hakowania” nośnika.

To w nie jest kompletna lista innowacji, które on ma «ApFS».

Partycje sformatowane w “ApFS” nie są rozpoznawane przez OS X 10.11 Yosemite i wcześniejsze wersje systemu operacyjnego.

Block Header (Nagłówek bloku)

Każda struktura systemu plików w “ApFS” zaczyna się od nagłówka bloku. A sam nagłówek zaczyna się od sumy kontrolnej. Pozostałe informacje w nagłówku obejmują wersję bloku z kopią podczas zapisu, identyfikator bloku oraz jego typ.

Przesunięcie Rozmiar Typ ID
0 8 uint64 Suma kontrolna (checksum)
8 8 uint64 Identyfikator (block_id)
16 8 uint64 Wersja (version)
24 2 uint16 Typ bloku (block_type)
26 2 uint16 Flagi (flags)
28 4 uint32 Odstęp (padding)

Z tabeli widać, że 1uint = 1 bit, 8 bitów = 1 bajt, z czego uint64 = 8, uint32 = 4, a uint16 = 2 bajty.

Container Superblock

Superblock kontenera (Container Superblock) jest punktem wejściowym do systemu plików. Ze względu na strukturę systemu plików z pojemnikami i elastyczne objętości, dystrybucja musi być prowadzona na poziomie kontenerów. Superblock kontenera zawiera informacje o wielkości bloku, jego numerze i wskazówkach w menedżerze przestrzeni kosmicznej dla tego zadania. Dodatkowo, superblok zawiera identyfikatory (ID) bloków wszystkich woluminów. W celu porównania identyfikatorów bloków w celu odsunięcia bloków, wskaźnik na mapie bloków z drzewa B jest zapisywany. To drzewo zawiera wpisy dla każdego tomu z jego identyfikatorem i przesunięciem. Superblok kontenerowy jest najwyższym poziomem systemu plików.

Ma on następujący wygląd:

Przesunięcie (HEX) Typ Id Opis
0 tApFS_COH Header Nagłówek obiektu kontenera (Container Object Header)
20 uint32 MagicNumber (NXSB) Wartość do sprawdzania odczytu Super Block kontenera.
24 uint32 BlockSize Wielkość bloku kontenerowego (w bajtach)
28 uint64 BlocksCount Liczba bloków kontenerowych
30 uint64 Features Mapa (bitmapa) głównych funkcji kontenera
38 uint64 ReadOnlyFeatures Mapa (bitmapa) podstawowych funkcji kontenera (tylko do odczytu)
40 uint64 IncompatibleFeatures Mapa (bitmapa) głównych niekompatybilnych funkcji kontenera
48 tApFS_Uuid Uuid UUID kontenera
58 tApFS_Ident NextIdent Poniższy identyfikator dla nowego obiektu logicznego lub wirtualnego
60 tApFS_Transaction NextTransaction Numer kolejnej transakcji
68 uint32 DescriptorBlocks Liczba bloków użytych przez deskryptora
6C uint32 DataBlocks Liczba bloków wykorzystywanych przez dane
70 tApFS_Address DescriptorBase Adres bazowy deskryptora lub identyfikatora obiektu fizycznego z drzewem adresowym
78 int32 DataBase Adres bazy danych lub identyfikator obiektu fizycznego z drzewem adresowym
80 uint32 DescriptorNext Indeks kolejnego deskryptora
84 uint32 DataNext Następny indeks danych
88 uint32 DescriptorIndex Indeks pierwszego elementu rzeczywistego w segmencie deskryptora
8C uint32 DescriptorLength Liczba bloków w segmencie deskryptora używanych przez superblok
90 uint32 DataIndex Indeks pierwszego rzeczywistego elementu w segmencie danych
94 uint32 DataLength Liczba bloków w segmencie danych używanych przez superblok
98 tApFS_Ident SpaceManagerIdent Identyfikator obiektu logicznego Space Manager
A0 tApFS_Ident ObjectsMapIdent Identyfikator fizycznego obiektu na mapie obiektu kontenerowego
A8 tApFS_Ident ReaperIdent Identyfikator obiektu logicznego
B0 uint32 ReservedForTesting
B4 uint32 MaximumVolumes Maksymalna możliwa ilość objętości w pojemniku
B8 tApFS_Ident VolumesIdents[100] Objętość macierzy wirtualnych identyfikatorów obiektów
3D8 uint64 Counters[32] Szereg liczników, w których przechowywane są informacje o kontenerach
4D8 tApFS_BlockRange BlockedOutOfRange Zakres fizyczny bloków, które nie mogą być używane
4E8 tApFS_Ident MappingTreeIdent Identyfikator obiektu fizycznego w drzewie używany do śledzenia obiektów przeniesionych z zablokowanego magazynu.
4F0 uint64 OtherFlags Mapa innych funkcji kontenera
4F8 tApFS_Address JumpstartEFI Id obiekta fizycznego z danymi EFI-systemu
500 tApFS_Uuid FusionUuid UUID kontener fuzji jądrowej lub zero dla kontenerów innych niż Fusion
510 tApFS_BlockRange KeyLocker Umiejscowienie znacznika klucza na pojemniku
520 uint64 EphemeralInfo[4] Tablica pól używanych do zarządzania danymi logicznymi
540 tApFS_Ident ReservedForTesting
548 tApFS_Ident FusionMidleTreeIdent Tylko dla zunifikowanych urządzeń
550 tApFS_Ident FusionWriteBackIdent Tylko dla zunifikowanych urządzeń
558 tApFS_BlockRange FusionWriteBackBlocks Bloki stosowane w obszarze pamięci podręcznej

Z definiowaniem typów:

uint8  tApFS_Uuid;
uint64 tApFS_Ident;
uint64 tApFS_Transaction;
int64  tApFS_Address;
uint64 tApFS_BTreeKey;

i

struct tApFS_BlockRange
{
    tApFS_Address       First;          // Pierwszy blok
    uint64              Count;          // Ilość bloków
}
struct tApFS_COH
{
    uint64              CheckSum;       // Suma kontrolna bloku
    tApFS_Ident         Ident;          // Identyfikator
    tApFS_Transaction   Transaction;    // Object change transaction number
    uint16              Type;           // Typ objektu
    uint16              Flags;          // Flagi obiektu
    uint32              SubType;        // Podtyp obiektu
};

z listą typów obiektów:

enum eApFS_ObjectType
{
    eApFS_ObjectType_01_SuperBlock            = 0x0001, //Superblok kontenera
    eApFS_ObjectType_02_BTreeRoot             = 0x0002, // B dzerwo: węzełowy element
    eApFS_ObjectType_03_BTreeNode             = 0x0003, // B dzerwo: lista
    eApFS_ObjectType_05_SpaceManager          = 0x0005, // Menedzer przestrzeni
    eApFS_ObjectType_06_SpaceManagerCAB       = 0x0006, // Menedzer przestrzeni: adres segmentów
    eApFS_ObjectType_07_SpaceManagerCIB       = 0x0007, // Menedzer przestrzeni: informacja segmentów
    eApFS_ObjectType_08_SpaceManagerBitmap    = 0x0008, // Karta swobodnej przestrzeni wykorzystująca Menedzerem przestrzeni
    eApFS_ObjectType_09_SpaceManagerFreeQueue = 0x0009, // Wolne miejsce wykorzystujące menedzerem przestrzeni_ (klucze - _tApFS_09_SpaceManagerFreeQueue_Key_, znaczenia - _tApFS_09_SpaceManagerFreeQueue_Value_)
    eApFS_ObjectType_0A_ExtentListTree        = 0x000A, // Dzrewo listy rozmiarów (klucze – przesunięcie początkowego rozmiaru_tApFS_Address_, znaczenie – fizyczne miejsce danych _tApFS_BlockRange_)
    eApFS_ObjectType_0B_ObjectsMap            = 0x000B, // Typ – Karta objektów; subType – Drzewo zapisów karty objektów (klucze - _tApFS_0B_ObjectsMap_Key_, znaczenie - _tApFS_0B_ObjectsMap_Value_)
    eApFS_ObjectType_0C_CheckPointMap         = 0x000C, // Karta kontrolnych punktów (punktów czekowych)
    eApFS_ObjectType_0D_FileSystem            = 0x000D, // System plików wolumena
    eApFS_ObjectType_0E_FileSystemTree        = 0x000E, // Dzrzewo systemu plików (klucze zaczynająsię c _tApFS_BTreeKey_, opisywać typ oraz wartość klucza)
    eApFS_ObjectType_0F_BlockReferenceTree    = 0x000F, // Drzewo linków na bloki (klucze - _tApFS_BTreeKey_, znaczenie - _tApFS_0F_BlockReferenceTree_Value_)
    eApFS_ObjectType_10_SnapshotMetaTree      = 0x0010, // Drzewo obrazów (klucze - _tApFS_BTreeKey_, znaczenie - _tApFS_10_SnapshotMetaTree_Value_)
    eApFS_ObjectType_11_Reaper                = 0x0011, // Reaper
    eApFS_ObjectType_12_ReaperList            = 0x0012, // Reaper List
    eApFS_ObjectType_13_ObjectsMapSnapshot    = 0x0013, // Drzewo obrazów karty objektów (klucze - _tApFS_Transaction_, znaczenia - _tApFS_13_ObjectsMapSnapshot_Value_)
    eApFS_ObjectType_14_JumpStartEFI          = 0x0014, // EFI Pobieracz
    eApFS_ObjectType_15_FusionMiddleTree      = 0x0015, // Dzrzewo łączących urządzeń dla sledzenia bloków twardych dysków, buforowanych SSD (klucze - _tApFS_Address_, wartości - _tApFS_15_FusionMiddleTree_Value_)
    eApFS_ObjectType_16_FusionWriteBack       = 0x0016, // Stan kesza zwrotnego zapisu zintegrowanych urządzeń
    eApFS_ObjectType_17_FusionWriteBackList   = 0x0017, // Lista  pamięci podręcznej zapisu łączących urządzeń
    eApFS_ObjectType_18_EncryptionState       = 0x0018, // Szyfrowanie
    eApFS_ObjectType_19_GeneralBitmap         = 0x0019, // General Bitmap
    eApFS_ObjectType_1A_GeneralBitmapTree     = 0x001A, // Drzewo General Bitmap (keys - uint64, keys - uint64)
    eApFS_ObjectType_1B_GeneralBitmapBlock    = 0x001B, // Blok General Bitmap
    eApFS_ObjectType_00_Invalid               = 0x0000, // Nie istnieje jak typ albo nie istnieje jak podtyp
    eApFS_ObjectType_FF_Test                  = 0x00FF  // Zarezerwowano dla testowania (nigdy nie zapisuje się na nośniku)
    eApFS_ObjectType_FF_Test                  = 0x00FF  // Zarezerwowano dla testowania (nigdy nie zapisuje się na nośniku)
};

enum eApFS_ObjectFlag
{
    eApFS_ObjectFlag_Virtual         = 0x0000, // Wirtualny objekt
    eApFS_ObjectFlag_Ephemeral       = 0x8000, // Logiczny objekt
    eApFS_ObjectFlag_Physical        = 0x4000, // Fizyczny objekt
    eApFS_ObjectFlag_NoHeader        = 0x2000, // Objekt bez nagłowka _tApFS_ContainerObjectHeader_ (naprzykład, Karta (bitmap) menedzera przestrzeni)
    eApFS_ObjectFlag_Encrypted       = 0x1000, // Zaszyfrowany objekt
    eApFS_ObjectFlag_NonPersistent   = 0x0800, // Objekt z tym flagiem nigdy nie zapisuje się na nośniku
    eApFS_ObjectFlag_StorageTypeMask = 0xC000, // Bitowa (bitmask) maska dla dostępa do flagi kategorii objektów
    eApFS_ObjectFlag_ValidMask       = 0xF800  // Istniejąca flaga bitowej maski
};

struct tApFS_0B_ObjectsMap_Key
{
    tApFS_Ident       ObjectIdent; // Identyfikator objektu
    tApFS_Transaction Transaction; // Numer tranzakcji
};

struct tApFS_0B_ObjectsMap_Value
{
    uint32       Flags;    // Флаги
    uint32       Size;     // Rozmiar objektu w bajtach (wielokrotny rozmiaru bloku kontenera)
    tApFS_Address Address; // Adres objektu
};

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;    // Identyfikator  fizycznego ;objektu drzewa B, w którym zapisane informacje o rozmiarze
    tApFS_Ident SuperBlockIdent;   // Identyfikator superbloku
    uint64      CreatedTime;       // Czas stworzenia obrazu (w nanosekundach z północy 01/01/1970)
    uint64      LastModifiedTime;  // Czas zmiany obrazu (w nanosekundach z północy 01/01/1970)
    uint64      iNum;
    uint32      ExtentRefTreeType; // Typ drzewo B, w którym zapisywane informacje o rozmiarach
    uint16      NameLength;        // Długość nazwy obrazu (włącząc symbol końca smyczki)
    uint8       Name[];            // Imię obrazu (konczy się na 0)
};

struct tApFS_13_ObjectsMapSnapshot_Value
{
    uint32      Flags;    // Flagi obrazów
    uint32      Padding;  // Zarezerwowano (dla korekty)
    tApFS_Ident Reserved; // Zarezerwowano
};

struct tApFS_15_FusionMiddleTree_Value
{
    tApFS_Address fmv_lba;
    uint32        fmv_length;
    uint32        fmv_flags;
};

Przykładowa struktura systemu plików ApFS:

Przykładowa struktura systemu plików ApFS

Volume Superblock (Superblok wolumina)

Superblock wolumina - istnieje dla każdego woluminu w systemie plików. Zawiera on nazwę objętości, identyfikator i znacznik czasu. Podobnie jak Container Superblock, zawiera on wskaźnik na mapie bloków, który wyświetla identyfikatory bloków na ich przesunięciach. Dodatkowo, superblokada wolumenu zawiera wskaźnik do katalogu głównego, który jest przechowywany jako węzeł.

Przesunięcie(HEX) Typ Id Opis
0 tApFS_COH Header Nagłowek objektu kontenera (Container Object Header)
20 uint32 MagicNumber (APSB) Wartość, która może być użyta do sprawdzenia, czy czytamy kopię Volume Superblock
24 uint32 IndexInSuperBlock Indeks identyfikatora obiektu tego wolumenu w tablicy wolumenu kontenera
28 uint64 Features Bitmap kluczowych funkcji wykorzystywanych przez objętość
30 uint64 ReadOnlyFeatures Bitowa mapa podstawowych funkcji (tylko do odczytu) wykorzystywanych przez wolumen
38 uint64 IncompatibleFeatures Bitmapa (Bitmapa) niekompatybilnych funkcji objętościowych
40 uint64 LastUnmountTime Czas ostatniego ustawienia objętości (w nanosekundach od północy) 01.01.1970)
48 uint64 ReservedBlocksCount Liczba bloków zarezerwowanych do wyboru objętości
50 uint64 QuotaBlocksCount Maksymalna liczba bloków, które ten wolumen może przydzielić
58 uint64 AllocatedCount Liczba bloków aktualnie przypisanych do systemu plików tego woluminu.
60 uint8 MetaCryptoState[20] Informacje o kluczu używanym do szyfrowania metadanych dla tego woluminu (np. wrapped_meta_crypto_state_t)
74 uint32 RootTreeType Typ drzewa katalogu głównego (zazwyczaj: typ drzewa katalogu głównego) ( eApFS_ObjectFlag_Virtual << 16) \ eApFS_ObjectType_02_BTreeRoot , podtyp eApFS_ObjectType_0E_FileSystemTree )
78 uint32 ExtentRefTreeType Typ drzewa wiązania rozszerzonego (zazwyczaj: typ ( eApFS_ObjectFlag_Physical << 16) \ eApFS_ObjectType_02_BTreeRoot , podtyp OBJECT_TYPE_BLOCKREF )
7C uint32 SnapshotMetaTreeType Typ drzewa metadanych obrazu (zazwyczaj: typ ( eApFS_ObjectFlag_Physical << 16) \ eApFS_ObjectType_02_BTreeRoot , podtyp OBJECT_TYPE_BLOCKREF )
80 tApFS_Ident ObjectsMapIdent Identyfikator obiektu fizycznego na objętościowej mapie obiektów
88 tApFS_Ident RootTreeIdent Identyfikator obiektu wirtualnego w głównym drzewie folderów
90 tApFS_Ident ExtentRefTreeIdent Identyfikator obiektu fizycznego w drzewie powiązań Extents
98 tApFS_Ident SnapshotMetaTreeIdent Identyfikator obiektu wirtualnego w drzewie metadanych obrazu
A0 tApFS_Transaction RevertToXid Numer transakcji, do której zostanie zwrócony wolumen
A8 tApFS_Ident RevertToSuperBlock Identyfikator fizycznego obiektu VS, do którego powróci wolumen
B0 uint64 NextObjectIdent Następny identyfikator, który zostanie przypisany do obiektu systemu plików na woluminie.
B8 uint64 NumberOfFiles Liczba zwykłych plików w tomie
C0 uint64 NumberOfDirectories Liczba folderów w tomie
C8 uint64 NumberOfSymbolicLinks Liczba linków symbolicznych w tomie
D0 uint64 NumberOfOtherObjects Liczba innych obiektów w tomie (nie licząc x0B8_NumberOfFiles , x0C0_NumberOfDirectories и x0C8_NumberOfSymbolicLinks )
D8 uint64 NumberOfSnapshots Liczba ujęć w tym tomie
E0 uint64 TotalBlocksAllocated Całkowita liczba bloków przypisanych do tego wolumenu
E8 uint64 TotalBlocksFreed Całkowita liczba bloków wydanych przez ten tom
F0 tApFS_Uuid Uuid
100 uint64 LastModifiedTime Czas ostatniej zmiany tego tomu (w nanosekundach od północy 01.01.1970)
108 uint64 Flags
110 tApFS_0D_FSM FormattedBy Informacje na temat oprogramowania, które stworzyło ten tom
140 tApFS_0D_FSM ModifiedBy[8] Informacje o oprogramowaniu, które zmieniło tę ilość
2C0 uint8 VolumeName[256] Nazwa zerowej objętości łańcucha UTF-8
3C0 uint32 NextDocumentIdent Należy przypisać następujący identyfikator dokumentu (zapisany w rozszerzonym polu APFS_0E_TYPE_DOCUMENT_ID)
3C4 uint16 Role Rastrowy obraz roli tomu
3C6 uint16 Reserved
3C8 tApFS_Transaction RootToXid Numer transakcji Snapshot dla transakcji non-root lub zero dla root.
3D0 tApFS_Ident EncryptStateIdent Aktualny stan szyfrowania lub odszyfrowywania, lub zero, jeśli nie ma szyfrowania

Szczegółowa ilustracja «APFS»:

Szczegółowa ilustracjaAPFS

Checkpoint (Punkt czekowy)

Punkt kontrolny to tymczasowy stan kontenera. Każdy punkt kontrolny jest inicjowany w Superblocku kontenera, a aktualny stan jest zazwyczaj ostatnim z nich. Punkt kontrolny zawiera metadane zarówno pojemnika, jak i jego objętości. Punkty odzyskiwania i ujęcia są podobne do siebie. Główną różnicą pomiędzy punktem kontrolnym a zrzutem jest możliwość przywrócenia systemu plików z zapisanych zrzutów za pomocą API systemu plików.

Checkpoint Superblock Descriptor (Deskryptor punktów kontrolnych superbloków)

Blok ten zawiera informacje o strukturach metadanych w "ApFS" i jest poprzednim blokiem Descriptor. Najważniejszą informacją w tym bloku jest lokalizacja Bitmap Structure (BMS), dawnego pliku dystrybucyjnego w HFS +.

Superblokowy deskryptor punktu odniesienia:

Superblokowy deskryptor punktu odniesienia

Bitmap Structures (Karta bitowa lub woluminowa)

Zapisy używanych i nieużywanych obiektów. Istnieje tylko jedna karta woluminów, która obejmuje cały pojemnik i jest wspólna dla wszystkich woluminów w systemie plików. "ApFS" używa zestawu bloków do przechowywania map objętościowych (Bitmap Structures).

W "ApFS" mapa jest wspólna dla wszystkich objętości w kontenerze. Każdy tom zawiera cytaty z bloków w pojemniku, ale same bloki nie znajdują się w wybranych obszarach. Odniesienie do mapy woluminu znajduje się w Super Block Checkpoint Descriptor (CSBD), który zawiera informacje o najwyższym poziomie struktury, Bitmap Descriptor (BMD). Poniższy rysunek przedstawia podstawową strukturę tego BMD. Jest on podzielony na poziomy, na których BMD znajduje się na górze i wyznacza granice. Na dole znajdują się "Bloki Bitmapy" (BMB), które śledzą bloki w kontenerze. Jeden bajt w BMB śledzi osiem bloków, z których każdy zapewnia status dystrybucji. Każdy bit jest statusem pojedynczego bloku.

Bitmap Blocks

Tabele (Tables)

Tabele są używane w rozszerzeniach katalogu i drzewa B, liście objętości i karcie identyfikacyjnej obiektu.

"Tabele używane w "ApFS" są małymi jednoblokowymi "bazami danych" o nieco innych celach w strukturach systemu plików. Pole typu tabela składa się z 2 bajtów umieszczonych w bloku z przesunięciem 0x20 bezpośrednio za nagłówkiem węzła. Istnieje osiem tabel od 0 do 7. Poniższe 2 bajty zapewniają poziom tabeli od 0 i więcej. Tabela drugiego poziomu będzie zawierać wpisy związane z tabelą poziomu podstawowego 1. A tabele poziomu zerowego odnoszą się do bloków, które często zawierają metadane plików.

Tabele różnią się strukturą, ale nagłówek tabeli dla wszystkich typów jest 24-bajtowy.

Rysunek przedstawia przykładową strukturę nagłówka tabeli:

Rysunek przedstawia przykładową strukturę nagłówka tabeli

Opis wartości pól w strukturze nagłówka:

Przesunięcie (HEX) Pole Typ danych Opis
20 tableType uint16 Możliwe wartości to 0-7. To jest tabela 1.
22 tableLevel uint16 Wskazuje poziom drzewa B.
24 tableRecords uint16 Liczba zapisów w tabeli
26 Unknown 1 uint16
28 Unknown 2 uint16
2A tableIndexSize uint16 Wielkość obszaru indeksu tabeli.
2C tableKeyAreaSize uint16 Wielkość obszaru kluczowego tabeli.
2E tableFreeSpaceSize uint16 Wielkość wolnego obszaru. Obszar danych w tabeli kończy się przesunięciem
0x38+tableIndexSize+tableKeyAreaSize+tableFreeSpaceSize. 0x38 + 0x80 + 0x170 + 0xd58 .
30 Unknown 3 uint16
32 Unknown 4 uint16
34 Unknown 5 uint16
36 Unknown 6 uint16

Tutaj pokazany ogólny układ poszczególnych tabel:

Tutaj pokazany ogólny układ poszczególnych tabel

Nie wszystkie elementy na zdjęciu są używane we wszystkich tabelach. Zdjęcie przedstawia kompletny blok z nagłówkiem górnego bloku węzłowego. Reszta bloku to tabela.

Indeks zapisu pojawia się natychmiast po nagłówku tabeli. Są dwa rodzaje. Jeden z dwoma wartościami: przesunięcie w klawiszach, i przesunięcie w sekcji danych dla każdego z Uint16. Drugi wykorzystuje 4 wartości Uint16 z przesunięciem i długością zarówno dla kluczy jak i sekcji danych. Indeks zapisów tabeli zawiera informacje na temat kluczy i zapisów danych w tabeli. Kolejną różnicą pomiędzy typami tabel jest użycie stopek.

Tabele 1, 3, 5 i 7 zawierają stopkę 0x28 bajtów na końcu bloku. W tych tabelach wszystkie przesunięcia danych odnoszą się do przesunięcia 0xFD8, a stopka zawiera różne wartości specyficzne dla danego typu tabeli. Inne rodzaje tabel nie posiadają stopki, a wszystkie odniesienia do zawartości sekcji danych należą do końca bloku.

B Drzewa z kilkoma poziomami - Tabele 1, 3, 5 i 7 są na najwyższym poziomie, ponieważ mają stopkę. Dolna stopka, służąca do przechowywania informacji o pełnym drzewie B. Jedną z wartości w stopce jest całkowita liczba zapisów w tej strukturze drzewa.

Definicja tabeli zaczyna się od przesunięcia 0x20 w bloku. Określa typ tabeli, liczbę wierszy, rozmiar partycji klucza oraz odstęp między kluczem a partycją danych. Po właściwości tabeli, definicjach wierszy i kolumn opisane jest przesunięcie 0x38. Tabela zawiera nagłówek, definicje zapisów, klucze i partycje danych. Niektóre rodzaje tablic mają również stopkę. Nagłówek zaczyna się z przesunięciem 0x20 i ma długość 0x18 bajtów. Nagłówek tego typu tabeli zaczyna się od wartości 16-bitowej, która reprezentuje dany typ tabeli. Po nim następują dwa bajty reprezentujące poziom w drzewie B, na którym znajduje się tabela. Kolejne dwa bajty reprezentują liczbę wierszy w tabeli. Długość zapisu definicji skanowania wynosi 0x2A, a następnie Uint16, który zapisuje długość partycji kluczowej. Po tym następuje luka pomiędzy kluczem a partycją danych. Stopka stołu jest zawsze 0x28 bajtów i zawsze zajmuje koniec bloku. A indeksy tabel mają po 4 lub 8 bajtów każdy. Na 8-bajtowych indeksach pierwsze dwa "Uint16" są przesunięte i długość zapisu kluczowego. Kolejne dwa "Uint16" to przesunięcie i długość zapisu danych w tabeli. Tabele z indeksami 4-bajtowymi mają dwie wartości Uint16, które zawierają przesunięcie klucza i zapisy danych. Długość danych w obu zapisach jest z góry określona. W tabelach ze stopką, przesunięcie zapisu danych jest względne w stosunku do początku stopki (0x28 bajtów). A dla innych typów tabel przesunięcie to jest względne w stosunku do końca bloku.

Większość wartości dotyczących nagłówka i stopki tabeli jest czytelna, przynajmniej w przypadku odczytu typu tabeli. Przesunięcie stopki 0x18 (przesunięcie 0xFF w bloku 4 Kb) jest liczbą zapisów w tabeli i we wszystkich tabelach bazowych (jeśli jest to tabela z poziomem powyżej 0, przy przesunięciu 0x22). Przesunięcie 0x20 w stopce jest numerem kolejnego zapisu w tabeli.

Tabela 0

Tabela 0 typu leży w strukturze katalogu B-drzewa pomiędzy węzłami liści i węzłem głównym. Nieznane wartości od 3 do 6 są przedstawiane jako przesunięcia i długości kluczy. Przesunięcia danych i długość następnego dostępnego zapisu. Jeśli nie ma wolnych rekordów indeksowych, przesunięcia są ustawiane na "0xFFFF" i długość "0x00".

Wpisy w tabeli to cztery wartości "Uint16". Pierwsze 2 to przesunięcie i długość wartości w sekcji klucza, a następne 2 to przesunięcie i wartość zawartości w sekcji danych.

Przykładem tabeli typu 0 jest identyfikator węzła katalogowego, klucz nazwy w sekcji klucza oraz identyfikator obiektu w sekcji danych. Ta tabela nie ma stopki.

Tabela 1

Pierwsza tabela posiada stopkę, a indeks tabeli zawiera cztery wartości 16-bitowe, gdzie pierwsze 2 wartości są przesunięciem zapisu w sekcji klucza i długości zapisu. Poniższe 2 wartości określają przesunięcie zapisu w sekcji danych i jego długość. Tabela ta często znajduje się zarówno w strukturze katalogów drzewa B, jak i w drzewie rozszerzeń dla węzła górnego poziomu. Przykładami są: "Identyfikator rodzica" i nazwa klucza (nazwa pliku lub folderu w strukturze katalogów oraz początkowy numer bloku w drzewie B-rozmiarów), identyfikator obiektu w przypadku użycia jako węzeł główny w strukturze katalogów lub numer bloku w przypadku użycia w drzewie-rozmiarów.

Przykłady z tej tabeli są podane poniżej:

Przykłady z tej tabeli są podane poniżej

Tabela 2

Drugi tabela. Pierwotnie ta tabela jest identyczna z poprzednią, ale nie ma stopki. Ten typ tabeli jest bardzo popularny w węzłach końcowych struktury katalogów B-drzewa, gdzie sekcja klucza jest reprezentowana przez "Parent ID" oraz nazwę klucza.

Tabela 3

Tabela 3 jest identyczna z poprzedną. Indeks tabeli jest taki sam jak w przypadku pierwszej tabeli. Typowe wartości zależą od struktury, w której są stosowane. W strukturze katalogu B-drzewa i drzewa Extents, tabela ta jest często używana jako węzeł górnego poziomu w małych tomach, gdzie węzeł główny jest zarówno węzłem korzeniowym jak i liścia. W tym przykładzie użycia, zapisem kluczowym może być "Parent ID". Klucz nazwy, a rekord danych może być plikiem metadanych z dużymi zmianami rozmiaru.

Inne pozycje tabeli to identyfikator obiektu "Object ID" oraz jego typ w rekordzie klucza, z zakresem informacji o pliku i rekordami danych. 3 tabela ma stopkę.

Przykład tabeli:

Przykład tabeli

Tabela 4

4 tabela jest nieco inna od poprzednich. W tabeli nie ma stopki, a indeks tabeli ma tylko 2 wartości: odsunięcie zapisu w sekcji kluczowej i 1 wartość dla sekcji danych. Długość zawartości jest stała i wynosi 16 bajtów w partycji kluczowej i 8 bajtów w partycji danych. Przesunięcia w sekcji danych znajdują się na końcu bloku.

Tabela 5

5 tabela jest podobna do 4. Jedyna różnica polega na tym, że ten typ ma stopkę, a wszystkie zmiany danych zaczynają się od "offset-0x28" (początek stopki). Zapisy w sekcji kluczowej to 16 bajtów i 8 bajtów w sekcji danych. Ten typ tabeli jest najczęściej obserwowany w węzłach górnego poziomu w strukturze katalogów drzewa B oraz w dużych kontenerach z drzewami wielopoziomowymi.

Tabela 6

6 tabela jest również podobna do 4. Indeks tabeli ma tylko przesunięcie względem zawartości w sekcji klucza i danych, ale nie jego długość. Długość jest ustalana z góry. Każdy zapis to 16 bajtów. Nie ma stopki dla tego typu stołów. Tabela ta często znajduje się w węzłach końcowych struktury katalogu B-drzewa. Typową zawartością partycji kluczowej jest identyfikator obiektu i identyfikator Superblokada punktu kontrolnego objętości "Identyfikator Superblokada punktu kontrolnego objętości", podczas gdy partycja danych zazwyczaj zapisuje ich rozmiar i numer bloku.

Tabela 7

7 Stół wygląda jak szósty. Jedyną różnicą jest stopka, która zawiera informacje podobne do tej opisanej dla 1 tabeli. Ten rodzaj tabeli jest obserwowany w szerokim zakresie struktur i często znajduje się na najwyższych poziomach struktury wielowarstwowej lub w strukturze jednowarstwowej, np. w opisie objętości.

Przykład

Przykład

Zestawienie tabel

Ta tabela pokazuje główne właściwości różnych typów tabel:

Typ Stopka Przesunięcie sekcji kluczowej Długość sekcji klucza Sekcja danych przesunięcia Długość sekcji danych Długość klucza Długość danych
0 NIE uint16 uint16 uint16 uint16 Varies Possible
1 TAK uint16 uint16 uint16 uint16 Varies Possible
2 NIE uint16 uint16 uint16 uint16 Varies Possible
3 TAK uint16 uint16 uint16 uint16 Varies Possible
4 NIE uint16 uint16 16 bajtów 8 bajtów
5 TAK uint16 uint16 16 bajtów 8 bajtów
6 NIE uint16 uint16 16 bajtów 16 bajtów
7 TAK uint16 uint16 16 bajtów 16 bajtów

Jednym z najważniejszych bloków w strukturze katalogów drzewa B jest węzeł główny, który jest najwyższym poziomem w strukturze katalogów. Ten węzeł wykorzystuje klucze wyszukiwania o zmiennej długości. Jedną z ulepszonych funkcji "ApFS" jest szybkie wyszukiwanie w katalogach. Jedną z wartości, która jest ściśle związana z tą funkcją jest liczba wszystkich wpisów w strukturze drzewa znajdujących się w dolnej stopce tabeli.

Węzeł główny struktury drzewa B ma 2 możliwości wyboru tabeli, ponieważ obie mają stopki. 3 Tabela - jako węzeł główny, obserwowany tylko w małych pojemnikach z małą ilością plików, gdzie węzeł główny jest również węzłem indeksu i arkusza.

W mapie obiektów dla węzła głównego wykorzystywana jest tylko 5 tabel, za wyjątkiem bardzo małych struktur, gdzie może wystąpić 7.

Tabela Interpretacja pokazuje, że tabele 0 i 2 mają te same wartości. To samo można zobaczyć między tabelami 1 i 3. Tabele te wydają się mieć różne cele w zależności od struktury, w której się znajdują.

Zdjęcia migawkowe (Snapshots)

Zdjęcia migawkowe są zdjęciami systemu plików woluminowych tylko do odczytu. System operacyjny może korzystać z tych migawek w celu uzyskania bardziej efektywnej procedury tworzenia kopii zapasowych. Dzięki nim Time Machine będzie działać szybciej. A dzięki obsłudze "Time Machine" migawkowych obrazów, nie trzeba już zapisywać kilku pełnych kopii pliku na dysk - może on po prostu śledzić pewne zmiany. Na przykład, jeśli edytujecie plik, zmianę za pomocą HFS +, zapisuje on dwie kopie pliku, pierwsza zapisuje nowe zmiany, a druga w przypadku, gdy chcecie wrócić do poprzedniego widoku. W "APFS" zapisywany jest tylko plik źródłowy i zapisywane są różnice między plikiem źródłowym a każdą zaktualizowaną wersją, co zajmuje mniej miejsca na dysku. Podobnie jak w przypadku ulepszeń w Fusion Drive, informacje zajmują mniej miejsca na dysku.

Podczas gdy "ApFS" i znacznie gorsze w swoich możliwościach do 128-bitowego ZFS, który jest obsługiwany przez Linux, FreeBSD i innych wolnych systemów operacyjnych, ale po stronie Apple jest to krok w dobrym kierunku.

Jak wspomniano powyżej, Apple od dawna stara się przenieść ZFS na OS X. Później OpenZFS został zaimplementowany dla OS X (O3X) i MacZFX.

Nodes (węzły)

Węzły są elastycznymi pojemnikami, które służą do przechowywania różnego rodzaju zapisów. Mogą one być częścią drzewa B lub istnieć same z siebie. Węzły mogą zawierać zapisy o elastycznych lub stałych rozmiarach. Węzeł rozpoczyna się od listy wskaźników do kluczy logowania i zapisu logowania. Tak więc, dla każdego zapisu, węzeł zawiera nagłówek zapisu na początku węzła, klucz zapisu w środku węzła i zapis logowania na końcu węzła.

Nodes (węzły)
pozycja rozmiar typ ID
0 4 uint32 alignment
4 4 uint32 ENTRY_COUNT
10 2 uint16 HEAD_SIZE
16 8 entry meta_entry
24 ... entry entries (repeat entry_count times)

Struktura nagłówka węzła (Node header):

Przesunięcie pole Typ danych Komentarze
0 Checksum Uint64 Fletchers Checksum Algorithm
8 identyfikator Uint64 Object-ID lub 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

Menedzer przestszeni (Space Manager)

«Space Manager» (Manager przestrzeni) jest używany do kontroli przydzielonych bloków w kontenerze "ApFS". Przechowuje on liczbę wolnych bloków i wskaźnik do plików z informacjami o lokalizacji.

pozycja rozmiar typ ID
0 4 uint32 rozmiar bloku
16 8 uint64 totalblocks
40 8 uint64 freeblocks
144 8 uint64 prev_allocationinfofile_block
352 8 uint64 alokacjainfofile_block

Allocation info file (Plik z informacjami o dystrybucji)

Plik dystrybucyjny działa jak brakujący nagłówek. Przechowuje on długość plików alokacji, wersję i jej przesunięcie.

pozycja rozmiar typ 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

Plik i folder drzewa B

Zapisy wszystkich plików i folderów na woluminie. Odgrywają one taką samą rolę jak pliki katalogowe w "HFS+".

Extents (B-drzewa extenty)

Oddzielne drzewo B wszystkich zakresów objętościowych. Rozszerzeniem są linki do zawartości pliku z informacją o miejscu rozpoczęcia zawartości danych i ich długości w blokach. Plik z pewną zawartością będzie miał co najmniej jeden zakres. A fragmentaryczny plik będzie miał kilka rozszerzeń. Drzewo ekstensywne jest odrębną strukturą.

W każdym zapisie pliku, rozszerzenia są zdefiniowane dla każdego z tych plików w drzewie B. Ta odrębna struktura fragmentów jest częścią funkcji migawkowej.

64-bitowe inody (index descriptors) - deskryptory indeksów

64-bitowe inody znacząco zwiększają przestrzeń nazw w porównaniu z 32-bitowymi identyfikatorami w "HFS+". 64-bitowy system plików "ApFS" obsługuje więcej niż 9 ekranów typu quintiles plików na każdym woluminie. Jak powiedział Bill Gates, to powinno wystarczyć dla wszystkich.

"ApFS" oferuje możliwość przywrócenia niektórych stanów systemu plików, w tym starych lub usuniętych wersji plików. Superblok kontenerowy zawiera odniesienie do struktury punktu kontrolnego. Punkt kontrolny odnosi się do poprzedniego superbloku kontenera, który zawiera informacje w starszym stanie systemu plików. Dzięki temu można przywrócić kilka starych stanów, analizując łańcuch superbloków kontenera.

Przejdź do widoku
🍏 Odzyskiwanie danych po aktualizacji, ponownej instalacji systemu MacOS lub sformatowaniu dysku 🍏

🍏 Odzyskiwanie danych po aktualizacji, ponownej instalacji systemu MacOS lub sformatowaniu dysku 🍏

Oksana Volyniuk

Autor: , Pisarz techniczny

Oksana Volyniuk jest autorem pracującym w Hetman Software. Ma prawie trzyletnie doświadczenie w zakresie technologii IT, a wcześniej pracowała jako HR menedżer w IT kompanii. Oksana kocha technologię i jest zapalona tworzeniem każdego aktykułu, który może pomóć ludziom.

Michał Mirosznyczenko

Redaktor: , Pisarz techniczny

Michał Mirosznyczenko jest jednym z czołowych programistów firmy Hetman Software. Bazując na piętnastoletnim doświadczeniu w tworzeniu oprogramowania, dzieli się swoją wiedzą z czytelnikami naszego bloga. Oprócz programowania Michał jest ekspertem w dziedzinie odzyskiwania danych, systemów plików, urządzeń do przechowywania danych i macierzy RAID.

Rekomendujemy

Witamy w asystencie Hetman Software opartym na sztucznej inteligencji.
Rozpocznij czat