APFS: Algorithmus zur Datenwiederherstellung des Dateisystems

“ApFS” bietet die Möglichkeit, bestimmte Zustände des Dateisystems wiederherzustellen, einschließlich alter oder gelöschter Versionen von Dateien . Der Container-Superblock enthält einen Link zur Checkpoint-Struktur. Der Prüfpunkt bezieht sich auf den vorherigen Superblock des Containers, der Informationen im älteren Zustand des Dateisystems enthält Auf diese Weise ist es möglich, mehrere alte Zustände wiederherzustellen indem die Container-Superblock-Kette analysiert wird.

APFS: Algorithmus zur Datenwiederherstellung des Dateisystems

Zur Ansicht gehen
🔝 Programme zum Wiederherstellen von Daten von APFS-Partitionen 🍏 Funktionen und Probleme (2021)

🔝 Programme zum Wiederherstellen von Daten von APFS-Partitionen 🍏 Funktionen und Probleme (2021)

Container und Volumen

Die Struktur des APFS-Dateisystems hat die Form eines B-Baums, wobei das Stammdatenverzeichnis die Blätter dieses Baums sind. Alle Zweige speichern nur Links zum nächsten Knoten, bis sie die Blätter erreichen. Das Dateisystem verwendet Container als Speicherorte. Diese Container können mehrere Volumes enthalten. Es ist auch das Hauptobjekt zum Speichern von Daten. Für ein Volume muss die Containergröße mehr als 512 MB betragen, für zwei Volumes mehr als 1024 MB usw.

Die folgende Abbildung zeigt die Struktur des Dateisystems «ApFS».

ApFS

Jedes Element dieser Struktur (mit Ausnahme der Zuordnungsdatei) beginnt mit einem 32-Byte-Blockheader, der einige allgemeine Informationen zum Block enthält. Als nächstes folgt der Hauptteil des Dateisystems. Es besteht aus den folgenden Elementen:

  • 0x01: Container Superblock
  • 0x02: Knoten (Node)
  • 0x05: Raummanager (Space manager)
  • 0x07: Platzierungsdatei (Allocation Info File)
  • 0x0C: Kontrollpunkt (Checkpoint)
  • 0x0D: Superblock Volume (Volume Superblock)

Container sind normalerweise genau die gleichen wie Einträge in einer GUID-Partitionstabelle (GPT). Sie haben ein eigenes Absturzsicherungs- und Festplattenzuweisungsschema. Jeder Container enthält ein oder mehrere Volumes mit jeweils einem eigenen Namespace, einer Reihe von Dateien und Verzeichnissen.

Das Dateisystem «ApFS» unterstützt die Software «RAID»,nicht direkt, kann jedoch mit Apple RAID-Volumes verwendet werden, um Striping (RAID 0), Spiegelung (RAID 1) und Spleißen (JBOD) zu unterstützen.

Mit einem 64-Bit-Index unterstützen Volume «ApFS» bis zu 9 Billionen (1018) Dateien.

Das neue Dateisystem von Apple verwendet Nanosekunden, um Zeitstempel festzulegen. In HFS + wurden Zeitstempel auf die nächste Sekunde gesetzt. Dadurch wird die Anzahl der Fehler bei Datenübertragungen und anderen Dateivorgängen verringert.

«ApFS» verfügt über eine integrierte Verschlüsselung und verwendet je nach Gerät AES-XTS oder AES-CBC. Der Benutzer kann mehrere Verschlüsselungsschlüssel verwenden, um die Datensicherheit auch bei «physischem Hacking» des Mediums zu gewährleisten.

Dies ist keine vollständige Liste der Innovationen, die «ApFS»hat.

Partitionen, die in «ApFS», formatiert sind, werden von OS X 10.11 Yosemite und früheren Versionen des Betriebssystems nicht erkannt.

Block Header

Jede Dateisystemstruktur in «ApFS» beginnt mit einem Blockheader. Und der Header selbst beginnt mit einer Checksumme. Weitere Informationen im Header umfassen die Copy-on-Write-Version des Blocks, die Block-ID und den Blocktyp.

Schiebe Größe Typ ID
0 8 uint64 Checksumme (checksum)
8 8 uint64 Identität (block_id)
16 8 uint64 Version (version)
24 2 uint16 Blocktyp (block_type)
26 2 uint16 Zeroflage (flags)
28 4 uint32 Einrückung (padding)

Aus der Tabelle können wir sehen, dass 1uint = 1 Bit, 8 Bit = 1 Byte, aus diesem uint64 = 8, uint32 = 4 und uint16 = 2 Bytes.

Container Superblock

Der Container-Superblock (Superblock Container) – ist der Einstiegspunkt in das Dateisystem. Aufgrund der Struktur des Dateisystems mit Containern und Diskettenvolumes muss die Verteilung auf Containerebene erfolgen. Der Container-Superblock enthält Informationen zur Größe des Blocks, seiner Anzahl und Zeiger im Space Manager für diese Aufgabe. Darüber hinaus speichert der Superblock Block-IDs für alle Volumes. Um Blockkennungen Verschiebungsblöcken zuzuordnen, wird ein Zeiger auf die B-Baum-Blockkarte gespeichert. Dieser Baum enthält Einträge für jedes Volume mit seiner ID und seinem Schiebe. Der Container-Superblock ist die höchste Ebene des Dateisystems.

Es hat die folgende Form:

Schiebe (HEX) Typ Id Definieren
0 tApFS_Schlafmodus Header Containerobjekt-Header (Container Object Header)
20 uint32 MagicNumber (NXSB) Der Wert, der zum Lesen des Container-Superblocks überprüft werden soll.
24 uint32 BlockSize Containerblockgröße (Bytes)
28 uint64 BlocksCount Anzahl der Containerblöcke
30 uint64 Features Karte (bitmap) der Hauptfunktionen des Containers
38 uint64 ReadOnlyFeatures Karte (bitmap) der Grundfunktionen des Containers (schreibgeschützt)
40 uint64 IncompatibleFeatures Karte (bitmap) der wichtigsten inkompatiblen Containerfunktionen
48 tApFS_Uuid Uuid Container-UUID
58 tApFS_Ident NextIdent Nächste Kennung für neues logisches oder virtuelles Objekt
60 tApFS_Transaction NextTransaction Nächste Transaktionsnummer
68 uint32 DescriptorBlocks Anzahl der vom Deskriptor verwendeten Blöcke
6C uint32 DataBlocks Anzahl der von Daten verwendeten Blöcke
70 tApFS_Address DescriptorBase Basisadresse eines Deskriptors oder Bezeichners eines physischen Objekts mit einem Adressbaum
78 int32 DataBase Datenbankadresse oder Kennung eines physischen Objekts mit einem Adressbaum
80 uint32 DescriptorNext Nächster Deskriptorindex
84 uint32 DataNext Nächster Datenindex
88 uint32 DescriptorIndex Der Index des ersten gültigen Elements im Deskriptorsegment
8C uint32 DescriptorLength Die Anzahl der Blöcke im Deskriptorsegment, die vom Superblock verwendet werden
90 uint32 DataIndex Der Index des ersten gültigen Elements im Datensegment
94 uint32 DataLength Anzahl der Blöcke im Datensegment, die vom Superblock verwendet werden
98 tApFS_Ident SpaceManagerIdent Logische Objektkennung Space Manager
A0 tApFS_Ident ObjectsMapIdent Die Kennung des physischen Kartenobjekts des Containerobjekts
A8 tApFS_Ident ReaperIdent Logische Objektkennung
B0 uint32 ReservedForTesting
B4 uint32 MaximumVolumes Die maximal mögliche Anzahl von Volumes in einem Container
B8 tApFS_Ident VolumesIdents[100] Volumen des Arrays virtueller Objektkennungen
3D8 uint64 Counters[32] Array von Zählern, die Informationen über den Container speichern
4D8 tApFS_BlockRange BlockedOutOfRange Physischer Bereich von Blöcken, die nicht verwendet werden können
4E8 tApFS_Ident MappingTreeIdent Die Kennung eines physischen Objekts im Baum, mit der Objekte verfolgt werden, die aus dem gesperrten Speicher verschoben wurden.
4F0 uint64 OtherFlags Karte anderer Containerfunktionen
4F8 tApFS_Address JumpstartEFI ID eines physischen Objekts mit EFI-Treiberdaten
500 tApFS_Uuid FusionUuid UUID des Fusionscontainers oder Null für Nicht-Fusionscontainer
510 tApFS_BlockRange KeyLocker Standort der Container-Schlüsselmarke
520 uint64 EphemeralInfo[4] Array von Feldern, mit denen logische Daten bearbeitet werden
540 tApFS_Ident ReservedForTesting
548 tApFS_Ident FusionMidleTreeIdent Nur für gepoolte Geräte
550 tApFS_Ident FusionWriteBackIdent Nur für gepoolte Geräte
558 tApFS_BlockRange FusionWriteBackBlocks Blöcke, die für den Cache-Bereich verwendet werden

Mit Typdefinitionen:

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

и

struct tApFS_BlockRange
{
    tApFS_Address       First;          // Erster Block
    uint64              Count;          // Anzahl der Blöcke
}
struct tApFS_COH
{
    uint64              CheckSum;       //CheckSum Blocks
    tApFS_Ident         Ident;          // Kennung
    tApFS_Transaction   Transaction;    // Object change transaction number
    uint16              Type;           // Objekttyp
    uint16              Flags;          // Objektflags
    uint32              SubType;        // Objektuntertyp
};

mit einer Liste von Objekttypen:

enum eApFS_ObjectType
{
    eApFS_ObjectType_01_SuperBlock            = 0x0001, //Superblock des Containers
    eApFS_ObjectType_02_BTreeRoot             = 0x0002, // Bi-Baum: Knoten- Element
    eApFS_ObjectType_03_BTreeNode             = 0x0003, // Bi-Baum: Blatt
    eApFS_ObjectType_05_SpaceManager          = 0x0005, // Raum- Manager
    eApFS_ObjectType_06_SpaceManagerCAB       = 0x0006, // Raum- Manager: Segment Adressen
    eApFS_ObjectType_07_SpaceManagerCIB       = 0x0007, // Raum- Manager: Segment- Informationen
    eApFS_ObjectType_08_SpaceManagerBitmap    = 0x0008, // Karte Frei Raum die vom Space Manager  verwendet wird
    eApFS_ObjectType_09_SpaceManagerFreeQueue = 0x0009, // Freier Speicherplatz der vom Space Manager verwendet wird_ (die Schlüssel - _tApFS_09_SpaceManagerFreeQueue_Key_, Angabe - _tApFS_09_SpaceManagerFreeQueue_Value_)
    eApFS_ObjectType_0A_ExtentListTree        = 0x000A, // Baum der Liste  der Erweiterung (die Schlüssel – Schiebe  der anfänglichen Erweiterung_tApFS_Address_, Angabe – physischer Ort der Daten _tApFS_BlockRange_)
    eApFS_ObjectType_0B_ObjectsMap            = 0x000B, // Typ – Karte der Objekten; subType – Baum des Datensatzes Karte der Objekten (die Schlüssel - _tApFS_0B_ObjectsMap_Key_, Angabe - _tApFS_0B_ObjectsMap_Value_)
    eApFS_ObjectType_0C_CheckPointMap         = 0x000C, // Karte der festen Punkte (CheckPoint)
    eApFS_ObjectType_0D_FileSystem            = 0x000D, // Datei system des Volumes
    eApFS_ObjectType_0E_FileSystemTree        = 0x000E, // Baum  des Datei Systems (die Schlüssel starten mit _tApFS_BTreeKey_, beschreibt den Typ und den Wert des Schlüssels)
    eApFS_ObjectType_0F_BlockReferenceTree    = 0x000F, // Baum  der Verknüpfungen zu den Blöcken (die Schlüssel - _tApFS_BTreeKey_, Angabe - _tApFS_0F_BlockReferenceTree_Value_)
    eApFS_ObjectType_10_SnapshotMetaTree      = 0x0010, // Baum Screenshot (die Schlüssel - _tApFS_BTreeKey_, Angabe - _tApFS_10_SnapshotMetaTree_Value_)
    eApFS_ObjectType_11_Reaper                = 0x0011, // Reaper
    eApFS_ObjectType_12_ReaperList            = 0x0012, // Reaper List
    eApFS_ObjectType_13_ObjectsMapSnapshot    = 0x0013, // Baum Screenshot Karten der Objekten (die Schlüssel - _tApFS_Transaction_, Angabe - _tApFS_13_ObjectsMapSnapshot_Value_)
    eApFS_ObjectType_14_JumpStartEFI          = 0x0014, // EFI Programmlader
    eApFS_ObjectType_15_FusionMiddleTree      = 0x0015, // Baum der kombinierten Geräten zur Nachverfolgung der Blöcken der Festplatten, der zwischengespeicherten SSD (die Schlüssel - _tApFS_Address_, Angabe - _tApFS_15_FusionMiddleTree_Value_)
    eApFS_ObjectType_16_FusionWriteBack       = 0x0016, // Auflösungsstatus des Caches Rück- schreiben  der kombinierten Geräten
    eApFS_ObjectType_17_FusionWriteBackList   = 0x0017, // Listenfeld des Caches Rück- schreiben der kombinierten Geräten
    eApFS_ObjectType_18_EncryptionState       = 0x0018, // Verschlüsseln
    eApFS_ObjectType_19_GeneralBitmap         = 0x0019, // General Bitmap
    eApFS_ObjectType_1A_GeneralBitmapTree     = 0x001A, // Baum General Bitmap (keys - uint64, keys - uint64)
    eApFS_ObjectType_1B_GeneralBitmapBlock    = 0x001B, // Block General Bitmap
    eApFS_ObjectType_00_Invalid               = 0x0000, // Als  Typ ungültig oder  als Subtyp fehlt
    eApFS_ObjectType_FF_Test                  = 0x00FF  // Zum Testen reserviert (nie auf  den Datenträgern gespeichert)
    eApFS_ObjectType_FF_Test                  = 0x00FF  // Zum Testen reserviert (nie auf den Datenträgern gespeichert)
};

enum eApFS_ObjectFlag
{
    eApFS_ObjectFlag_Virtual         = 0x0000, // virtuelles Objekt
    eApFS_ObjectFlag_Ephemeral       = 0x8000, // logisches  Objekt
    eApFS_ObjectFlag_Physical        = 0x4000, // physikalisches Objekt
    eApFS_ObjectFlag_NoHeader        = 0x2000, // Objekt ohne Header _tApFS_ContainerObjectHeader_ (z. B., Karte (bitmap) Raum- Manager)
    eApFS_ObjectFlag_Encrypted       = 0x1000, // Verschlüsseltes Objekt
    eApFS_ObjectFlag_NonPersistent   = 0x0800, // Ein Objekt mit diesem  Flag  wird nie  auf den Datenträgern gespeichert
    eApFS_ObjectFlag_StorageTypeMask = 0xC000, // Bit- (bitmask) maske für den Zugriff auf  Flags Objekt- kategorien
    eApFS_ObjectFlag_ValidMask       = 0xF800  // Gültiger  Flag Der Bit- Maske
};

struct tApFS_0B_ObjectsMap_Key
{
    tApFS_Ident       ObjectIdent; // Identität  des Objekts
    tApFS_Transaction Transaction; // Tan- Nummer
};

struct tApFS_0B_ObjectsMap_Value
{
    uint32       Flags;    // Flags
    uint32       Size;     // Größe des Objekts in Bytes (Vielfaches der Container- Blockgröße)
    tApFS_Address Address; // Adresse des Objekts
};

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;    // Die Kennung des physischen Objekts, des Bi-Baums in dem die Extent-Informationen gespeichert sind
    tApFS_Ident SuperBlockIdent;   // Kennung  des Superblocks
    uint64      CreatedTime;       // Zeit der Schöpfung  der Aufnahme (in Nanosekunden seit Mitternacht 01/01/1970)
    uint64      LastModifiedTime;  // Änderungszeit  des Schnappschusses (in Nanosekunden seit Mitternacht 01/01/1970)
    uint64      iNum;
    uint32      ExtentRefTreeType; // Bi- Baum-Typ, in dem  die Informationen  über Erweiterung gespeichert sind
    uint16      NameLength;        // Länge des Schnappschussnamens (einschließlich  des Symbols Zeilen- Schluß)
    uint8       Name[];            // Schnappschuss- Name (endet mit 0)
};

struct tApFS_13_ObjectsMapSnapshot_Value
{
    uint32      Flags;    // Flags  der Schnappschschüssen
    uint32      Padding;  // Reserviert (für Korrektion)
    tApFS_Ident Reserved; // Reserviert
};

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

Beispiel für eine Dateisystemstruktur:

Ein Beispiel für die Struktur eines ApFS-Dateisystems

Volume Superblock

Volume Superblock - existiert für jedes Volume im Dateisystem. Es enthält den Datenträgernamen, die ID und den Zeitstempel. Wie der Container-Superblock enthält er einen Zeiger auf eine Blockzuordnung, die Block-IDs an ihren Schieben abbildet. Darüber hinaus speichert der Volume-Superblock einen Zeiger auf das Stammverzeichnis, das als Knoten gespeichert wird.

Schiebe (HEX) Typ Id Definieren
0 tApFS_COH Header Containerobjekt-Header (Container Object Header)
20 uint32 MagicNumber (APSB) Ein Wert, mit dem überprüft werden kann, ob eine Instanz Volume Superblock gelesen wird
24 uint32 IndexInSuperBlock Der Index der Objekt-ID dieses Volumes im Volume-Array des Containers
28 uint64 Features Bitmap der vom Volume verwendeten Hauptfunktionen
30 uint64 ReadOnlyFeatures Bitmap der vom Volume verwendeten Grundfunktionen (schreibgeschützt)
38 uint64 IncompatibleFeatures Bitmap inkompatibler Volume-Funktionen
40 uint64 LastUnmountTime Die Zeit, zu der das Volume zuletzt abgemeldet wurde (in Nanosekunden seit Mitternacht, 01.01.1970)
48 uint64 ReservedBlocksCount Anzahl der für die Datenträgerzuweisung reservierten Blöcke
50 uint64 QuotaBlocksCount Die maximale Anzahl von Blöcken, die dieses Volume zuweisen kann
58 uint64 AllocatedCount Die Anzahl der Blöcke, die derzeit dem Dateisystem dieses Volumes zugeordnet sind.
60 uint8 MetaCryptoState[20] Informationen zum Schlüssel, mit dem die Metadaten für dieses Volume verschlüsselt werden (Instanz wrapped_meta_crypto_state_t)
74 uint32 RootTreeType Stammordner-Baumtyp (normalerweise: Typ ( eApFS_ObjectFlag_Virtual << 16) \ eApFS_ObjectType_02_BTreeRoot , Subtyp eApFS_ObjectType_0E_FileSystemTree )
78 uint32 ExtentRefTreeType Bindungsbaumtyp der Erweiterungen (normalerweise: Typ ( eApFS_ObjectFlag_Physical << 16) \ eApFS_ObjectType_02_BTreeRoot , Subtyp OBJECT_TYPE_BLOCKREF )
7C uint32 SnapshotMetaTreeType Snapshot-Metadatenbaumtyp (normalerweise: Typ ( eApFS_ObjectFlag_Physical << 16) \ eApFS_ObjectType_02_BTreeRoot , Subtyp OBJECT_TYPE_BLOCKREF )
80 tApFS_Ident ObjectsMapIdent Physische Objektkennung auf der volumetrischen Objektkarte
88 tApFS_Ident RootTreeIdent ID des virtuellen Objekts des Stammordnerbaums
90 tApFS_Ident ExtentRefTreeIdent Die Kennung des physischen Objekts des Verknüpfungsbaums der Erweiterungen
98 tApFS_Ident SnapshotMetaTreeIdent ID des virtuellen Objekts des Snapshot-Metadatenbaums
A0 tApFS_Transaction RevertToXid Die Transaktionsnummer des Snapshots, an den das Volume zurückgegeben wird
A8 tApFS_Ident RevertToSuperBlock ID des physischen VS-Objekts, auf das das Volume zurückgesetzt wird
B0 uint64 NextObjectIdent Die nächste Kennung, die dem Dateisystemobjekt auf dem Volume zugewiesen wird.
B8 uint64 NumberOfFiles Anzahl der einfachen Dateien in einem Volume
C0 uint64 NumberOfDirectories Anzahl der Ordner in einem Volume
C8 uint64 NumberOfSymbolicLinks Anzahl der symbolischen Links pro Volume
D0 uint64 NumberOfOtherObjects Anzahl anderer Objekte im Volume (nicht inbegriffen x0B8_NumberOfFiles , x0C0_NumberOfDirectories und x0C8_NumberOfSymbolicLinks )
D8 uint64 NumberOfSnapshots Anzahl der Schnappschüsse in diesem Volume
E0 uint64 TotalBlocksAllocated Die Gesamtzahl der von diesem Volume zugewiesenen Blöcke
E8 uint64 TotalBlocksFreed Die Gesamtzahl der von diesem Volume freigegebenen Blöcke
F0 tApFS_Uuid Uuid
100 uint64 LastModifiedTime Zeitpunkt der letzten Änderung dieses Volumens (in Nanosekunden seit Mitternacht 01.01.1970)
108 uint64 Flags
110 tApFS_0D_FSM FormattedBy Informationen zu der Software, die dieses Volume erstellt hat
140 tApFS_0D_FSM ModifiedBy[8] Informationen zu Software, die dieses Volume geändert hat
2C0 uint8 VolumeName[256] Name des Volumes Null der Zeile UTF-8
3C0 uint32 NextDocumentIdent Die nächste zuzuweisende Dokument-ID (im erweiterten Feld APFS_0E_TYPE_DOCUMENT_ID des Dokuments gespeichert)
3C4 uint16 Role Volume Role Bitmap
3C6 uint16 Reserved
3C8 tApFS_Transaction RootToXid Snapshot-Transaktionsnummer für Nicht-Root oder Null für Root
3D0 tApFS_Ident EncryptStateIdent Der aktuelle Status der Ver- oder Entschlüsselung oder Null, wenn keine Verschlüsselung vorhanden ist

Detaillierte Abbildung «APFS»:

Detaillierte Abbildung APFS

Checkpoint

Checkpoint ist ein temporärer Status des Containers. Jeder Prüfpunkt wird im Superblock des Containers initialisiert, und der aktuelle Status ist normalerweise der letzte. Checkpoint enthält Metadaten sowohl für den Container als auch für das Volume. Wiederherstellungspunkte und Schnappschüsse ähneln sich. Der Hauptunterschied zwischen Checkpoint und einem Snapshot besteht in der Fähigkeit des Benutzers, ein Dateisystem aus gespeicherten Snapshots mithilfe der Dateisystem-API wiederherzustellen.

Checkpoint Superblock Descriptor

Dieser Block enthält Informationen zu den Metadatenstrukturen in «ApFS» und ist der vorhergehende Deskriptorblock. Die wichtigste Information in diesem Block ist der Ort Bitmap Structure (BMS), die frühere Verteilungsdatei in в HFS +.

Superblock-Deskriptor des Checkpoints:

Superblock-Deskriptor des Checkpoints

Bitmap Structures

Aufzeichnungen über verwendete und nicht verwendete Blöcke. Es gibt nur eine Volume-Map, die den gesamten Container abdeckt und allen Volumes im Dateisystem gemeinsam ist. ApFS verwendet eine Reihe von Blöcken zum Speichern der Volume Map (Bitmap-Strukturen).

In «ApFS» ist die Karte allen Volumes im Container gemeinsam. Jedes Volume enthält Anführungszeichen für den Block im Container, aber die Blöcke selbst befinden sich nicht in den zugewiesenen Bereichen. Der Verweis auf die Volume Map befindet sich im Superblock Checkpoint Descriptor (CSBD), der Informationen über die oberste Ebene der Struktur, den Bitmap Descriptor (BMD), enthält. Die folgende Abbildung zeigt die Grundstruktur dieser Karte. Es ist in Ebenen unterteilt, wobei BMD an der Spitze steht und Grenzen setzt. Unten liegen «Bitmap Blocks» (BMB), die die Blöcke im Container verfolgen. Ein Byte im BMB verfolgt acht Blöcke, von denen jedes Bit einen Zuordnungsstatus liefert. Jedes Bit ist der Status eines separaten Blocks.

Bitmap Blocks

Tables

Tabellen werden im B-Tree-Katalog und in den Bereichen, der Volumenliste und der Objekt-ID-Zuordnung verwendet.

Tabellen verwendet in «ApFS», sind klein einteilig «Datenbank» mit einem etwas anderen Zweck in den Strukturen des Dateisystems. Das Tabellentypfeld besteht aus 2 Bytes, die sich in einem Block mit dem Offset 0x20 unmittelbar nach dem Knotenheader befinden. Es gibt acht Tabellen von 0 bis 7. Die nächsten 2 Bytes stellen Tabellenebene 0 und höher bereit. Die Tabelle der zweiten Ebene enthält Datensätze, die sich auf die Basistabelle der ersten Ebene beziehen. Tabellen auf Nullebene beziehen sich auf Blöcke, die häufig Dateimetadaten enthalten.

Tabellentypen unterscheiden sich in der Struktur, aber der Tabellenkopf für alle Typen ist 24 Byte.

Die Abbildung zeigt eine Beispieltabellen-Header-Struktur:

Die Abbildung zeigt eine Beispieltabellen-Header-Struktur

Beschreibung der Feldwerte in der Kopfstruktur:

Schiebe (HEX) Rand Datentyp Definieren
20 tableType uint16 Mögliche Werte sind 0-7. Dies ist Tabelle 1
22 tableLevel uint16 Zeigt die Ebene des B-Baums an.
24 tableRecords uint16 Anzahl der Datensätze in der Tabelle
26 Unknown 1 uint16
28 Unknown 2 uint16
2A tableIndexSize uint16 Größe des Tabellenindexbereichs.
2C tableKeyAreaSize uint16 Schlüsselbereichsgröße der Tabelle.
2E tableFreeSpaceSize uint16 Freie Flächengröße. Der Tabellendatenbereich endet mit einem Schiebe
0x38+tableIndexSize+tableKeyAreaSize+tableFreeSpaceSize. 0x38 + 0x80 + 0x170 + 0xd58 .
30 Unknown 3 uint16
32 Unknown 4 uint16
34 Unknown 5 uint16
36 Unknown 6 uint16

Hier ist ein allgemeines Grunddesign der verschiedenen Tabellen:

Hier ist ein allgemeines Grunddesign der verschiedenen Tabellen

Nicht alle Elemente im Bild werden in allen Tabellen verwendet. Die Abbildung zeigt einen vollständigen Block mit dem Header des oberen Knotenblocks. Der Rest des Blocks bildet eine Tabelle.

Der Index des Datensatzes folgt unmittelbar nach dem Tabellenkopf. Es gibt 2 Arten von ihnen. Einer mit zwei Werten: Schiebe in den Schlüsseln und Schiebe im Datenbereich für jeden Uint16. Die zweite verwendet 4 Uint16-Werte mit Schiebe und Länge für Schlüssel- und Datenpartitionen. Der Tabellendatensatzindex enthält Informationen zu den Schlüsseln und Datensätzen in der Tabelle. Ein weiterer Unterschied zwischen den Tabellentypen ist die Verwendung von Fußzeilen.

In den Tabellen 1, 3, 5 und 7 wird am Ende des Blocks eine 0x28-Byte-Fußzeile verwendet. In diesen Tabellen beziehen sich alle Datenschieben auf den Schiebe 0xFD8, und die Fußzeile enthält verschiedene tabellentypspezifische Werte. Andere Tabellentypen haben keine Fußzeile, und alle Verweise auf den Inhalt des Datenabschnitts beziehen sich auf das Ende des Blocks.

In B-Bäume mit mehreren Ebenen - Die Tabellen 1, 3, 5 und 7 befinden sich auf der obersten Ebene, da sie eine Fußzeile haben. Fußzeile, in der Informationen zum gesamten B-Baum gespeichert werden. Einer der Werte in der Fußzeile ist die Gesamtzahl der Datensätze in der Struktur dieses Baums.

Die Tabellendefinition beginnt bei Schiebe 0x20 im Block. Dies zeigt den Tabellentyp, die Anzahl der Zeilen, die Größe des Schlüsselabschnitts und die Lücke zwischen dem Schlüssel und dem Datenabschnitt. Der Schiebe 0x38 wird nach Tabelleneigenschaften, Zeilen- und Spaltendefinitionen beschrieben. Die Tabelle enthält einen Titel, Datensatzdefinitionen, Schlüssel- und Datenabschnitte. Einige Arten von Tabellen haben auch eine Fußzeile. Der Header beginnt bei Schiebe 0x20 und ist 0x18 Byte lang. Der Header dieses Tabellentyps beginnt mit einem 16-Bit-Wert, der den Tabellentyp darstellt. Dann folgen zwei Bytes, die die Ebene im B-Baum darstellen, auf der die Tabelle verwendet wird. Die nächsten zwei Bytes geben die Anzahl der Zeilen in der Tabelle an. Die Länge des Scan-Definitionsdatensatzes liegt bei 0x2A, gefolgt von Uint16, das die Länge des Schlüsselabschnitts aufzeichnet. Als nächstes kommt die Lücke zwischen dem Schlüssel und dem Datenabschnitt. Die Tabellenfußzeile ist immer 0x28 Byte groß und belegt immer das Ende des Blocks. Und Tabellenindizes sind jeweils 4 oder 8 Bytes. Bei 8-Byte-Indizes sind die ersten beiden «Uint16» - der Schiebe und die Länge des Schlüsseleintrags. Die nächsten beiden «Uint16» - sind der Schiebe und die Länge des Datensatzes in der Tabelle. Tabellen mit 4-Byte-Indizes haben zwei Uint16-Werte, die den Schiebe des Schlüssels und der Datensätze enthalten. Die Länge der Daten in zwei Datensätzen ist vordefiniert. In Tabellen mit Fußzeilen der Schiebe des Datensatzes relativ zum Anfang der Fußzeile (0x28 Byte). Bei anderen Tabellentypen bezieht sich dieser Schiebe auf das Ende des Blocks.

Die meisten Bedeutungen in Bezug auf die Kopf- und Fußzeile der Tabelle sind klar, zumindest zum Lesen des Tabellentyps. Der Fußzeilenschiebe 0x18 (Schiebe 0xFF im 4-KB-Block) ist die Anzahl der Datensätze in der Tabelle und in allen Basistabellen (wenn es sich um eine Tabelle mit einer höheren Ebene als 0 handelt, bei Schiebe 0x22). Der Schiebe 0x20 in der Fußzeile ist die Nummer des nächsten Eintrags in der Tabelle.

Tabellenblatt 0

Eine Tabelle vom Typ 0 liegt in der B-Tree-Verzeichnisstruktur zwischen den Blattknoten und dem Wurzelknoten. Unbekannte Werte 3 bis 6 werden als Schiebe und Schlüssellänge dargestellt. Datenversätze und Länge des nächsten verfügbaren Datensatzes. Wenn keine freien Indexdatensätze vorhanden sind, werden die Schieben auf «0xFFFF» und die Länge «0x00»gesetzt.

Die Einträge in der Tabelle sind vier «Uint16»-Werte. Die ersten 2 sind der Schiebe und die Länge des Werts im Schlüsselabschnitt und die nächsten sind der Schiebe und der Wert des Inhalts im Datenabschnitt.

Ein Beispiel für eine Tabelle vom Typ 0 wäre die Katalogknoten-ID, der Namensschlüssel im Schlüsselabschnitt und die Objekt-ID im Datenabschnitt. Diese Tabelle hat keine Fußzeile.

Tabellenblatt 1

Die erste Tabelle hat eine Fußzeile und der Tabellenindex enthält vier 16-Bit-Werte, wobei die ersten beiden Werte den Schiebe des Eintrags im Schlüsselabschnitt und die Länge des Eintrags darstellen. Die nächsten 2 Werte geben den Schiebe des Datensatzes im Datenabschnitt und seine Länge an. Diese Tabelle befindet sich häufig sowohl in der B-Tree-Verzeichnisstruktur als auch im Extent-Tree für den Knoten der obersten Ebene.Ein Beispiel sind die Werte: «Parent ID» und den Schlüsselnamen (den Namen einer Datei oder eines Ordners in der Verzeichnisstruktur und die Startblocknummer im Extent-B-Baum), die Objekt-ID bei Verwendung als Stammknoten in der Verzeichnisstruktur oder die Blocknummer bei Verwendung im Extent-Baum.

Beispiele für diese Tabelle sind unten angegeben:

Beispiele für diese Tabelle sind unten angegeben

Tabellenblatt 2

Tabellenblatt 2. Anfangs ist diese Tabelle mit der vorherigen identisch, hat jedoch keine Fußzeile. Dieser Tabellentyp ist in Blattknoten in der B-Tree-Verzeichnisstruktur sehr verbreitet, in denen der Schlüsselabschnitt mit «Parent ID» und dem Namen des Schlüssels dargestellt wird.

Tabellenblatt 3

Die dritte Tabelle ist identisch mit der vorherigen. Der Tabellenindex entspricht der ersten Tabelle. Typische Werte hängen von der Struktur ab, in der sie verwendet werden. In der B-Baum-Verzeichnisstruktur und im Extent-Baum wird diese Tabelle häufig als Knoten der obersten Ebene in kleinen Volumes verwendet, wobei der Wurzelknoten sowohl der Wurzelknoten als auch der Blattknoten ist. In einem solchen Anwendungsfall könnte der Schlüsseleintrag «Parent ID»sein. Der benannte Schlüssel und Datensatz kann eine Metadatendatei mit großen Größenunterschieden sein.

Die anderen Datensätze in der Tabelle sind «Object ID» und ihr Typ im Schlüsseldatensatz mit Dateieinformationsbereichen und Datensätzen.Tabellenblatt 3 hat eine Fußzeile.

Beispieltabelle:

Beispieltabelle

Tabellenblatt 4

Tabelle 4 unterscheidet sich etwas von den vorherigen. Die Tabelle enthält keine Fußzeile und der Tabellenindex enthält nur zwei Werte: den Datensatzschiebe im Schlüsselabschnitt und einen Wert für den Datenabschnitt. Die Inhaltslänge ist im Schlüsselabschnitt auf 16 Byte und im Datenabschnitt auf 8 Byte festgelegt. Schieben im Datenabschnitt beziehen sich auf das Ende des Blocks.

Tabellenblatt 5

In 5 ist die Tabelle ähnlich zu 4. Der einzige Unterschied besteht darin, dass dieser Typ eine Fußzeile hat und alle Datenversätze mit «offset-0x28» (dem Anfang der Fußzeile) beginnen. Die Einträge im Schlüsselabschnitt sind 16 Bytes und 8 Bytes im Datenabschnitt. Diese Art von Tabelle wird am häufigsten auf Knoten der obersten Ebene in der B-Tree-Verzeichnisstruktur und in großen Containern mit mehrstufigen Bäumen angezeigt.

Tabellenblatt 6

In 6 ähnelt die Tabelle auch 4. Der Index einer Tabelle hat nur einen Schiebe zum Inhalt des Schlüssel- und Datenabschnitts, nicht jedoch zu seiner Länge. Die Länge ist vordefiniert. Jeder Eintrag ist 16 Bytes. Für diese Art von Tabelle gibt es keine Fußzeile. Diese Tabelle befindet sich häufig in den Blattknoten der B-Tree-Verzeichnisstruktur. Typische Inhalte eines Schlüsselabschnitts umfassen die Objekt-ID und die Volume-ID des «Volume Checkpoint Superblock ID», während der Datenabschnitt normalerweise deren Größe und Blocknummer aufzeichnet.

Tabellenblatt 7

Die 7. Tabelle ähnelt der 6. Der einzige Unterschied ist die Fußzeile, die ähnliche Informationen wie in Tabelle 1 enthält. Diese Art von Tabelle ist in einer Vielzahl von Strukturen zu finden und findet sich häufig auf den obersten Ebenen einer Mehrschichtstruktur oder in Einschichtstrukturen wie einer Volumenbeschreibung.

Beispiel

Beispiel

Zusammenfassung der Tabellen

Diese Tabelle zeigt die Haupteigenschaften verschiedener Tabellentypen:

Typ Fußzeile Schiebe des Schlüsselabschnittes Länge des Schlüsselabschnittes Schiebe des Datenabschnittes Länge des Datenabschnittes Schlüssellänge Länge der Daten
0 NEIN uint16 uint16 uint16 uint16 Varies Possible
1 JA uint16 uint16 uint16 uint16 Varies Possible
2 NEIN uint16 uint16 uint16 uint16 Varies Possible
3 JA uint16 uint16 uint16 uint16 Varies Possible
4 NEIN uint16 uint16 16 bytes 8 bytes
5 JA uint16 uint16 16 bytes 8 bytes
6 NEIN uint16 uint16 16 bytes 16 bytes
7 JA uint16 uint16 16 bytes 16 bytes

Einer der wichtigsten Blöcke in der B-Tree-Verzeichnisstruktur ist der Stammknoten, der die höchste Ebene in der Ordnerstruktur darstellt. Dieser Knoten verwendet Suchschlüssel mit variabler Länge. Eine der verbesserten Funktionen von «ApFS» ist die schnelle Verzeichnissuche. Ein Wert, der eng mit dieser Funktion zusammenhängt, ist die Anzahl aller Einträge in der Baumstruktur in der Tabellenfußzeile.

Der Wurzelknoten der B-Baum-Struktur verfügt über zwei Tabellenauswahloptionen, da beide Fußzeilen haben. 3. Tabelle - kann als Stammknoten nur in kleinen Containern mit einer kleinen Anzahl von Dateien beobachtet werden, wobei der Wurzelknoten auch der Index- und der Blattknoten ist.

In der Feature-Map für den Stammknoten wird nur die 5. Tabelle verwendet, mit Ausnahme sehr kleiner Strukturen, in denen die 7. auftreten kann.

Die Interpretation der Tabellen zeigt, dass die Tabellen 0 und 2 dieselbe Bedeutung haben. Dasselbe wird zwischen den Tabellen 1 und 3 beobachtet. Diese Tabellen scheinen je nach Struktur unterschiedliche Zwecke zu haben.

Snapshots

Snapshots sind schreibgeschützte Dateisystem-Snapshots eines Volumes. Das Betriebssystem kann diese Snapshots für effizientere Sicherungen verwenden. Dank ihnen läuf Time Machine schneller. Dank der Unterstützung für Sofortbilder «Time Machine», müssen Sie nicht mehr mehrere vollständige Kopien einer Datei auf der Festplatte speichern, sondern können einfach bestimmte Änderungen verfolgen. Wenn Sie beispielsweise eine mit HFS + geänderte Datei bearbeiten, werden zwei Kopien der Datei gespeichert, wobei die erste die neuen Änderungen aufzeichnet und die zweite, falls Sie zur vorherigen Ansicht zurückkehren möchten. «APFS» behält nur die Originaldatei bei und zeichnet die Unterschiede zwischen der Originaldatei und allen aktualisierten Versionen auf, wodurch weniger Speicherplatz benötigt wird. Wie bei den Verbesserungen in Fusion Drive, beanspruchen Informationen weniger Speicherplatz.

Obwohl «ApFS» in seinen Fähigkeiten 128-Bit-ZFS deutlich unterlegen ist, die von Linux, FreeBSD und anderen kostenlosen Betriebssystemen unterstützt, aber von Apples Seite ist dies ein Schritt in die richtige Richtung.

Wie oben erwähnt, hat Apple lange versucht, ZFS auf OS X zu vertauschen. Später wurde OpenZFS für OS X (O3X) und MacZFX implementiert.

Nodes

Knoten(Nodes) sind flexible Container, in denen verschiedene Arten von Datensätzen gespeichert werden. Sie können Teil des B-Baums sein oder alleine existieren. Knoten können Datensätze mit flexibler oder fester Größe enthalten. Der Knoten beginnt mit einer Liste von Zeigern auf Eingabeschlüssel und Eintragseinträge. Daher enthält der Knoten für jeden Datensatz den Datensatzkopf am Anfang des Knotens, den Eingabeschlüssel in der Mitte des Knotens und den Eintragseintrag am Ende des Knotens.

Nodes
Position Größe 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)

Knoten-Header-Struktur (Node header):

Schiebe Rand Datentyp Kommentare
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

Space Manager

«Space Manager» wird verwendet, um zugewiesene Blöcke in einem Container «ApFS» zu verwalten. Speichert die Anzahl der freien Blöcke und einen Zeiger auf Zuordnungsinformationsdateien.

Position Größe Typ ID
0 4 uint32 Größe des Blocks
16 8 uint64 totalblocks
40 8 uint64 freeblocks
144 8 uint64 prev_allocationinfofile_block
352 8 uint64 allocationinfofile_block

Allocation info file (Verteilungsinformationsdatei)

Die Verteilungsdatei fungiert als fehlender Header. Hier werden die Länge der Platzierungsdateien, die Version und deren Schiebe gespeichert.

Position Größe 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

B-Tree Datei und Ordner

Aufzeichnungen aller Dateien und Ordner auf dem Volume. Sie haben dieselbe Rolle wie Katalogdateien in «HFS+».

Extents (Erweiterungen des B- Baums)

Ein separater B-Baum aller Erweiterungen (Extents) des Volumes. Extents sind Links zum Inhalt einer Datei mit Informationen darüber, wo der Inhalt der Daten beginnt, und deren Länge in Blöcken. Eine Datei mit einigen Inhalten hat mindestens eine Erweiterung. Eine fragmentierte Datei hat mehrere Extents. Der Extent-Baum ist eine separate Struktur.

In jedem Dateieintrag werden Extents für jede dieser Dateien im B-Baum definiert. Diese separate Extent-Struktur ist Teil der Snapshot-Funktion.

64-bit inodes (index descriptors)

64-Bit-Inodes erhöhen den Namespace gegenüber 32-Bit-Bezeichnern in «HFS+»erheblich. Das 64-Bit-Dateisystem «ApFS» unterstützt mehr als 9 Billionen Dateien pro Volume. Wie Bill Gates sagte, sollte dies für alle ausreichen.

«ApFS» bietet die Möglichkeit, bestimmte Zustände des Dateisystems wiederherzustellen, einschließlich alter oder gelöschter Versionen von Dateien. Der Container-Superblock enthält einen Link zur Checkpoint-Struktur. Checkpoint bezieht sich auf den vorherigen Superblock des Containers, der Informationen im älteren Zustand des Dateisystems enthält. Somit ist es möglich, mehrere alte Zustände wiederherzustellen, indem die Container-Superblock-Kette analysiert wird.

Zur Ansicht gehen
💽 So stellen Sie verlorene Daten von 4Kn-Festplatten wieder her (2021)

💽 So stellen Sie verlorene Daten von 4Kn-Festplatten wieder her (2021)

Glib Khomenko

Autor: , Technischer Schreiber

Hlib Khomenko ist Übersetzer und IT-Techniker im Unternehmen „Hetman Software“. Der Autor hat eine spezialisierte Hochschulausbildung und hat langjährige Erfahrung in der deutschen Übersetzung.

Alexandr Shafarenko

Editor: , Technischer Schreiber

Olexander Schafarenko hat langjährige Erfahrungen im Schreiben von Artikeln. Seine Artikel auf dem Blog wurden von Millionen von Benutzern gelesen. Der Autor hat eine spezialisierte Hochschulausbildung und teilt sein Wissen im Bereich IT mit den Lesern.

Für dich empfohlen

Willkommen bei dem KI-gesteuerten Assistenten von Hetman Software.
Chat beginnen