Otrzymaj zniżkę

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

Treść:

Kontenery i Toma

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ęcieRozmiarTypID
08uint64Suma kontrolna (checksum)
88uint64Identyfikator (block_id)
168uint64Wersja (version)
242uint16Typ bloku (block_type)
262uint16Flagi (flags)
284uint32Odstę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)TypIdOpis
0tApFS_COHHeaderNagłówek obiektu kontenera (Container Object Header)
20uint32MagicNumber (NXSB)Wartość do sprawdzania odczytu Super Block kontenera.
24uint32BlockSizeWielkość bloku kontenerowego (w bajtach)
28uint64BlocksCountLiczba bloków kontenerowych
30uint64FeaturesMapa (bitmapa) głównych funkcji kontenera
38uint64ReadOnlyFeaturesMapa (bitmapa) podstawowych funkcji kontenera (tylko do odczytu)
40uint64IncompatibleFeaturesMapa (bitmapa) głównych niekompatybilnych funkcji kontenera
48tApFS_UuidUuidUUID kontenera
58tApFS_IdentNextIdentPoniższy identyfikator dla nowego obiektu logicznego lub wirtualnego
60tApFS_TransactionNextTransactionNumer kolejnej transakcji
68uint32DescriptorBlocksLiczba bloków użytych przez deskryptora
6Cuint32DataBlocksLiczba bloków wykorzystywanych przez dane
70tApFS_AddressDescriptorBaseAdres bazowy deskryptora lub identyfikatora obiektu fizycznego z drzewem adresowym
78int32DataBaseAdres bazy danych lub identyfikator obiektu fizycznego z drzewem adresowym
80uint32DescriptorNextIndeks kolejnego deskryptora
84uint32DataNextNastępny indeks danych
88uint32DescriptorIndexIndeks pierwszego elementu rzeczywistego w segmencie deskryptora
8Cuint32DescriptorLengthLiczba bloków w segmencie deskryptora używanych przez superblok
90uint32DataIndexIndeks pierwszego rzeczywistego elementu w segmencie danych
94uint32DataLengthLiczba bloków w segmencie danych używanych przez superblok
98tApFS_IdentSpaceManagerIdentIdentyfikator obiektu logicznego Space Manager
A0tApFS_IdentObjectsMapIdentIdentyfikator fizycznego obiektu na mapie obiektu kontenerowego
A8tApFS_IdentReaperIdentIdentyfikator obiektu logicznego
B0uint32ReservedForTesting
B4uint32MaximumVolumesMaksymalna możliwa ilość objętości w pojemniku
B8tApFS_IdentVolumesIdents[100]Objętość macierzy wirtualnych identyfikatorów obiektów
3D8uint64Counters[32]Szereg liczników, w których przechowywane są informacje o kontenerach
4D8tApFS_BlockRangeBlockedOutOfRangeZakres fizyczny bloków, które nie mogą być używane
4E8tApFS_IdentMappingTreeIdentIdentyfikator obiektu fizycznego w drzewie używany do śledzenia obiektów przeniesionych z zablokowanego magazynu.
4F0uint64OtherFlagsMapa innych funkcji kontenera
4F8tApFS_AddressJumpstartEFIId obiekta fizycznego z danymi EFI-systemu
500tApFS_UuidFusionUuidUUID kontener fuzji jądrowej lub zero dla kontenerów innych niż Fusion
510tApFS_BlockRangeKeyLockerUmiejscowienie znacznika klucza na pojemniku
520uint64EphemeralInfo[4]Tablica pól używanych do zarządzania danymi logicznymi
540tApFS_IdentReservedForTesting
548tApFS_IdentFusionMidleTreeIdentTylko dla zunifikowanych urządzeń
550tApFS_IdentFusionWriteBackIdentTylko dla zunifikowanych urządzeń
558tApFS_BlockRangeFusionWriteBackBlocksBloki 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)TypIdOpis
0tApFS_COHHeader Nagłowek objektu kontenera (Container Object Header)
20uint32 MagicNumber (APSB) Wartość, która może być użyta do sprawdzenia, czy czytamy kopię Volume Superblock
24uint32IndexInSuperBlock Indeks identyfikatora obiektu tego wolumenu w tablicy wolumenu kontenera
28uint64Features Bitmap kluczowych funkcji wykorzystywanych przez objętość
30uint64ReadOnlyFeatures Bitowa mapa podstawowych funkcji (tylko do odczytu) wykorzystywanych przez wolumen
38uint64IncompatibleFeatures Bitmapa (Bitmapa) niekompatybilnych funkcji objętościowych
40uint64LastUnmountTime Czas ostatniego ustawienia objętości (w nanosekundach od północy) 01.01.1970)
48uint64ReservedBlocksCount Liczba bloków zarezerwowanych do wyboru objętości
50uint64QuotaBlocksCount Maksymalna liczba bloków, które ten wolumen może przydzielić
58uint64AllocatedCount Liczba bloków aktualnie przypisanych do systemu plików tego woluminu.
60uint8 MetaCryptoState[20] Informacje o kluczu używanym do szyfrowania metadanych dla tego woluminu (np. wrapped_meta_crypto_state_t)
74uint32RootTreeType Typ drzewa katalogu głównego (zazwyczaj: typ drzewa katalogu głównego) ( eApFS_ObjectFlag_Virtual << 16) \ eApFS_ObjectType_02_BTreeRoot , podtyp eApFS_ObjectType_0E_FileSystemTree )
78uint32ExtentRefTreeType Typ drzewa wiązania rozszerzonego (zazwyczaj: typ ( eApFS_ObjectFlag_Physical << 16) \ eApFS_ObjectType_02_BTreeRoot , podtyp OBJECT_TYPE_BLOCKREF )
7Cuint32SnapshotMetaTreeType Typ drzewa metadanych obrazu (zazwyczaj: typ ( eApFS_ObjectFlag_Physical << 16) \ eApFS_ObjectType_02_BTreeRoot , podtyp OBJECT_TYPE_BLOCKREF )
80tApFS_IdentObjectsMapIdent Identyfikator obiektu fizycznego na objętościowej mapie obiektów
88tApFS_IdentRootTreeIdent Identyfikator obiektu wirtualnego w głównym drzewie folderów
90tApFS_IdentExtentRefTreeIdent Identyfikator obiektu fizycznego w drzewie powiązań Extents
98tApFS_IdentSnapshotMetaTreeIdent Identyfikator obiektu wirtualnego w drzewie metadanych obrazu
A0tApFS_TransactionRevertToXid Numer transakcji, do której zostanie zwrócony wolumen
A8tApFS_IdentRevertToSuperBlock Identyfikator fizycznego obiektu VS, do którego powróci wolumen
B0uint64NextObjectIdent Następny identyfikator, który zostanie przypisany do obiektu systemu plików na woluminie.
B8uint64NumberOfFiles Liczba zwykłych plików w tomie
C0uint64NumberOfDirectories Liczba folderów w tomie
C8uint64NumberOfSymbolicLinks Liczba linków symbolicznych w tomie
D0uint64NumberOfOtherObjects Liczba innych obiektów w tomie (nie licząc x0B8_NumberOfFiles , x0C0_NumberOfDirectories и x0C8_NumberOfSymbolicLinks )
D8uint64NumberOfSnapshots Liczba ujęć w tym tomie
E0uint64TotalBlocksAllocated Całkowita liczba bloków przypisanych do tego wolumenu
E8uint64TotalBlocksFreed Całkowita liczba bloków wydanych przez ten tom
F0tApFS_UuidUuid
100uint64LastModifiedTime Czas ostatniej zmiany tego tomu (w nanosekundach od północy 01.01.1970)
108uint64Flags
110tApFS_0D_FSMFormattedByInformacje na temat oprogramowania, które stworzyło ten tom
140tApFS_0D_FSMModifiedBy[8] Informacje o oprogramowaniu, które zmieniło tę ilość
2C0uint8 VolumeName[256]Nazwa zerowej objętości łańcucha UTF-8
3C0uint32NextDocumentIdent Należy przypisać następujący identyfikator dokumentu (zapisany w rozszerzonym polu APFS_0E_TYPE_DOCUMENT_ID)
3C4uint16Role Rastrowy obraz roli tomu
3C6uint16Reserved
3C8 tApFS_TransactionRootToXid Numer transakcji Snapshot dla transakcji non-root lub zero dla root.
3D0tApFS_IdentEncryptStateIdent 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)PoleTyp danychOpis
20tableTypeuint16Możliwe wartości to 0-7. To jest tabela 1.
22tableLeveluint16Wskazuje poziom drzewa B.
24tableRecordsuint16Liczba zapisów w tabeli
26Unknown 1uint16
28Unknown 2uint16
2AtableIndexSizeuint16Wielkość obszaru indeksu tabeli.
2CtableKeyAreaSizeuint16Wielkość obszaru kluczowego tabeli.
2EtableFreeSpaceSizeuint16Wielkość wolnego obszaru. Obszar danych w tabeli kończy się przesunięciem
0x38+tableIndexSize+tableKeyAreaSize+tableFreeSpaceSize. 0x38 + 0x80 + 0x170 + 0xd58 .
30Unknown 3uint16
32Unknown 4uint16
34Unknown 5uint16
36Unknown 6uint16

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)
pozycjarozmiartypID
04uint32alignment
44uint32ENTRY_COUNT
102uint16HEAD_SIZE
168entrymeta_entry
24entryentries (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 Uint16Often 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.

pozycjarozmiartypID
44uint32alloc_file_length
84uint32alloc_file_version
244uint32TOTAL_BLOCKS
284uint32free_blocks
324uint32allocationfile_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.

Rekomendujemy