:py:mod:`dissect.apfs.c_apfs` ============================= .. py:module:: dissect.apfs.c_apfs Module Contents --------------- .. py:data:: apfs_def :value: Multiline-String .. raw:: html
Show Value .. code-block:: python """ /* * Common types */ typedef uint16_t mode_t; typedef uint32_t uid_t; typedef uint32_t gid_t; typedef uint32_t cp_key_class_t; typedef uint32_t cp_key_os_version_t; typedef uint16_t cp_key_revision_t; typedef uint32_t crypto_flags_t; typedef int64_t paddr_t; struct prange { paddr_t pr_start_paddr; uint64_t pr_block_count; }; typedef struct prange prange_t; typedef uint64_t oid_t; typedef uint64_t xid_t; /* * Objects */ /* Object Identifier Constants */ #define OID_NX_SUPERBLOCK 1 #define OID_INVALID 0 #define OID_RESERVED_COUNT 1024 /* Object Type Masks */ #define OBJECT_TYPE_MASK 0x0000ffff #define OBJECT_TYPE_FLAGS_MASK 0xffff0000 #define OBJ_STORAGETYPE_MASK 0xc0000000 #define OBJECT_TYPE_FLAGS_DEFINED_MASK 0xf8000000 /* Object Types */ #define OBJECT_TYPE_NX_SUPERBLOCK 0x00000001 #define OBJECT_TYPE_BTREE 0x00000002 #define OBJECT_TYPE_BTREE_NODE 0x00000003 #define OBJECT_TYPE_SPACEMAN 0x00000005 #define OBJECT_TYPE_SPACEMAN_CAB 0x00000006 #define OBJECT_TYPE_SPACEMAN_CIB 0x00000007 #define OBJECT_TYPE_SPACEMAN_BITMAP 0x00000008 #define OBJECT_TYPE_SPACEMAN_FREE_QUEUE 0x00000009 #define OBJECT_TYPE_EXTENT_LIST_TREE 0x0000000a #define OBJECT_TYPE_OMAP 0x0000000b #define OBJECT_TYPE_CHECKPOINT_MAP 0x0000000c #define OBJECT_TYPE_FS 0x0000000d #define OBJECT_TYPE_FSTREE 0x0000000e #define OBJECT_TYPE_BLOCKREFTREE 0x0000000f #define OBJECT_TYPE_SNAPMETATREE 0x00000010 #define OBJECT_TYPE_NX_REAPER 0x00000011 #define OBJECT_TYPE_NX_REAP_LIST 0x00000012 #define OBJECT_TYPE_OMAP_SNAPSHOT 0x00000013 #define OBJECT_TYPE_EFI_JUMPSTART 0x00000014 #define OBJECT_TYPE_FUSION_MIDDLE_TREE 0x00000015 #define OBJECT_TYPE_NX_FUSION_WBC 0x00000016 #define OBJECT_TYPE_NX_FUSION_WBC_LIST 0x00000017 #define OBJECT_TYPE_ER_STATE 0x00000018 #define OBJECT_TYPE_GBITMAP 0x00000019 #define OBJECT_TYPE_GBITMAP_TREE 0x0000001a #define OBJECT_TYPE_GBITMAP_BLOCK 0x0000001b #define OBJECT_TYPE_ER_RECOVERY_BLOCK 0x0000001c #define OBJECT_TYPE_SNAP_META_EXT 0x0000001d #define OBJECT_TYPE_INTEGRITY_META 0x0000001e #define OBJECT_TYPE_FEXT_TREE 0x0000001f #define OBJECT_TYPE_RESERVED_20 0x00000020 #define OBJECT_TYPE_INVALID 0x00000000 #define OBJECT_TYPE_TEST 0x000000ff #define OBJECT_TYPE_CONTAINER_KEYBAG 0x6b657973 // 'keys' #define OBJECT_TYPE_VOLUME_KEYBAG 0x72656373 // 'recs' #define OBJECT_TYPE_MEDIA_KEYBAG 0x6d6b6579 // 'mkey' // As a cstruct enum enum OBJECT_TYPE { NX_SUPERBLOCK = 0x00000001, BTREE = 0x00000002, BTREE_NODE = 0x00000003, SPACEMAN = 0x00000005, SPACEMAN_CAB = 0x00000006, SPACEMAN_CIB = 0x00000007, SPACEMAN_BITMAP = 0x00000008, SPACEMAN_FREE_QUEUE = 0x00000009, EXTENT_LIST_TREE = 0x0000000a, OMAP = 0x0000000b, CHECKPOINT_MAP = 0x0000000c, FS = 0x0000000d, FSTREE = 0x0000000e, BLOCKREFTREE = 0x0000000f, SNAPMETATREE = 0x00000010, NX_REAPER = 0x00000011, NX_REAP_LIST = 0x00000012, OMAP_SNAPSHOT = 0x00000013, EFI_JUMPSTART = 0x00000014, FUSION_MIDDLE_TREE = 0x00000015, NX_FUSION_WBC = 0x00000016, NX_FUSION_WBC_LIST = 0x00000017, ER_STATE = 0x00000018, GBITMAP = 0x00000019, GBITMAP_TREE = 0x0000001a, GBITMAP_BLOCK = 0x0000001b, ER_RECOVERY_BLOCK = 0x0000001c, SNAP_META_EXT = 0x0000001d, INTEGRITY_META = 0x0000001e, FEXT_TREE = 0x0000001f, RESERVED_20 = 0x00000020, INVALID = 0x00000000, TEST = 0x000000ff, CONTAINER_KEYBAG = 0x6b657973, // 'keys' VOLUME_KEYBAG = 0x72656373, // 'recs' MEDIA_KEYBAG = 0x6d6b6579, // 'mkey' }; /* Object type flags */ #define OBJ_VIRTUAL 0x00000000 #define OBJ_EPHEMERAL 0x80000000 #define OBJ_PHYSICAL 0x40000000 #define OBJ_NOHEADER 0x20000000 #define OBJ_ENCRYPTED 0x10000000 #define OBJ_NONPERSISTENT 0x08000000 // As a cstruct enum enum OBJ { VIRTUAL = 0x00000000, EPHEMERAL = 0x80000000, PHYSICAL = 0x40000000, NOHEADER = 0x20000000, ENCRYPTED = 0x10000000, NONPERSISTENT = 0x08000000, }; #define MAX_CKSUM_SIZE 8 struct obj_phys { char o_cksum[MAX_CKSUM_SIZE]; oid_t o_oid; xid_t o_xid; uint32_t o_type; uint32_t o_subtype; }; typedef struct obj_phys obj_phys_t; /* * Object Map */ /* Object Map Value Flags */ #define OMAP_VAL_DELETED 0x00000001 #define OMAP_VAL_SAVED 0x00000002 #define OMAP_VAL_ENCRYPTED 0x00000004 #define OMAP_VAL_NOHEADER 0x00000008 #define OMAP_VAL_CRYPTO_GENERATION 0x00000010 /* Snapshot Flags */ #define OMAP_SNAPSHOT_DELETED 0x00000001 #define OMAP_SNAPSHOT_REVERTED 0x00000002 /* Object Map Flags */ #define OMAP_MANUALLY_MANAGED 0x00000001 #define OMAP_ENCRYPTING 0x00000002 #define OMAP_DECRYPTING 0x00000004 #define OMAP_KEYROLLING 0x00000008 #define OMAP_CRYPTO_GENERATION 0x00000010 #define OMAP_VALID_FLAGS 0x0000001f /* Object Map Constants */ #define OMAP_MAX_SNAP_COUNT 0xffffffff /* Object Map Reaper Phases */ #define OMAP_REAP_PHASE_MAP_TREE 1 #define OMAP_REAP_PHASE_SNAPSHOT_TREE 2 struct omap_phys { obj_phys_t om_o; uint32_t om_flags; uint32_t om_snap_count; uint32_t om_tree_type; uint32_t om_snapshot_tree_type; oid_t om_tree_oid; oid_t om_snapshot_tree_oid; xid_t om_most_recent_snap; xid_t om_pending_revert_min; xid_t om_pending_revert_max; }; typedef struct omap_phys omap_phys_t; struct omap_key { oid_t ok_oid; xid_t ok_xid; }; typedef struct omap_key omap_key_t; struct omap_val { uint32_t ov_flags; uint32_t ov_size; paddr_t ov_paddr; }; typedef struct omap_val omap_val_t; struct omap_snapshot { uint32_t oms_flags; uint32_t oms_pad; oid_t oms_oid; }; typedef struct omap_snapshot omap_snapshot_t; /* * B-Trees */ /* B-Tree flags */ #define BTREE_UINT64_KEYS 0x00000001 #define BTREE_SEQUENTIAL_INSERT 0x00000002 #define BTREE_ALLOW_GHOSTS 0x00000004 #define BTREE_EPHEMERAL 0x00000008 #define BTREE_PHYSICAL 0x00000010 #define BTREE_NONPERSISTENT 0x00000020 #define BTREE_KV_NONALIGNED 0x00000040 #define BTREE_HASHED 0x00000080 #define BTREE_NOHEADER 0x00000100 // As a cstruct flag flag BTREE { UINT64_KEYS = 0x00000001, SEQUENTIAL_INSERT = 0x00000002, ALLOW_GHOSTS = 0x00000004, EPHEMERAL = 0x00000008, PHYSICAL = 0x00000010, NONPERSISTENT = 0x00000020, KV_NONALIGNED = 0x00000040, HASHED = 0x00000080, NOHEADER = 0x00000100, }; /* B-Tree Table of Contents Constants */ #define BTREE_TOC_ENTRY_INCREMENT 8 #define BTREE_TOC_ENTRY_MAX_UNUSED (2 * BTREE_TOC_ENTRY_INCREMENT) /* B-Tree Node Flags */ #define BTNODE_ROOT 0x0001 #define BTNODE_LEAF 0x0002 #define BTNODE_FIXED_KV_SIZE 0x0004 #define BTNODE_HASHED 0x0008 #define BTNODE_NOHEADER 0x0010 #define BTNODE_CHECK_KOFF_INVAL 0x8000 // As a cstruct flag flag BTNODE { ROOT = 0x0001, LEAF = 0x0002, FIXED_KV_SIZE = 0x0004, HASHED = 0x0008, NOHEADER = 0x0010, CHECK_KOFF_INVAL = 0x8000, }; /* B-Tree Node Constants */ #define BTREE_NODE_SIZE_DEFAULT 4096 #define BTREE_NODE_MIN_ENTRY_COUNT 4 struct nloc { uint16_t off; uint16_t len; }; typedef struct nloc nloc_t; struct btree_node_phys { obj_phys_t btn_o; uint16_t btn_flags; uint16_t btn_level; uint32_t btn_nkeys; nloc_t btn_table_space; nloc_t btn_free_space; nloc_t btn_key_free_list; nloc_t btn_val_free_list; // uint64_t btn_data[]; }; typedef struct btree_node_phys btree_node_phys_t; struct btree_info_fixed { uint32_t bt_flags; uint32_t bt_node_size; uint32_t bt_key_size; uint32_t bt_val_size; }; typedef struct btree_info_fixed btree_info_fixed_t; struct btree_info { btree_info_fixed_t bt_fixed; uint32_t bt_longest_key; uint32_t bt_longest_val; uint64_t bt_key_count; uint64_t bt_node_count; }; typedef struct btree_info btree_info_t; #define BTREE_NODE_HASH_SIZE_MAX 64 struct btn_index_node_val { oid_t binv_child_oid; char binv_child_hash[BTREE_NODE_HASH_SIZE_MAX]; }; typedef struct btn_index_node_val btn_index_node_val_t; #define BTOFF_INVALID 0xffff struct kvloc { nloc_t k; nloc_t v; }; typedef struct kvloc kvloc_t; struct kvoff { uint16_t k; uint16_t v; }; typedef struct kvoff kvoff_t; /* * File-System Objects */ struct j_key { uint64_t obj_id_and_type; }; typedef struct j_key j_key_t; #define OBJ_ID_MASK 0x0fffffffffffffff #define OBJ_TYPE_MASK 0xf000000000000000 #define OBJ_TYPE_SHIFT 60 #define SYSTEM_OBJ_ID_MARK 0x0fffffff00000000 struct j_inode_key { j_key_t hdr; }; typedef struct j_inode_key j_inode_key_t; struct j_inode_val { uint64_t parent_id; uint64_t private_id; uint64_t create_time; uint64_t mod_time; uint64_t change_time; uint64_t access_time; uint64_t internal_flags; union { int32_t nchildren; int32_t nlink; }; cp_key_class_t default_protection_class; uint32_t write_generation_counter; uint32_t bsd_flags; uid_t owner; gid_t group; mode_t mode; uint16_t pad1; uint64_t uncompressed_size; // uint8_t xfields[]; }; typedef struct j_inode_val j_inode_val_t; struct j_drec_key { j_key_t hdr; uint16_t name_len; char name[name_len]; }; typedef struct j_drec_key j_drec_key_t; #define J_DREC_LEN_MASK 0x000003ff #define J_DREC_HASH_MASK 0xfffffc00 #define J_DREC_HASH_SHIFT 10 struct j_drec_hashed_key { j_key_t hdr; uint32_t name_len_and_hash; char name[name_len_and_hash & J_DREC_LEN_MASK]; }; typedef struct j_drec_hashed_key j_drec_hashed_key_t; struct j_drec_val { uint64_t file_id; uint64_t date_added; uint16_t flags; // uint8_t xfields[]; }; typedef struct j_drec_val j_drec_val_t; struct j_dir_stats_key { j_key_t hdr; }; typedef struct j_dir_stats_key j_dir_stats_key_t; struct j_dir_stats_val { uint64_t num_children; uint64_t total_size; uint64_t chained_key; uint64_t gen_count; }; typedef struct j_dir_stats_val j_dir_stats_val_t; struct j_xattr_key { j_key_t hdr; uint16_t name_len; char name[name_len]; }; typedef struct j_xattr_key j_xattr_key_t; struct j_xattr_val { uint16_t flags; uint16_t xdata_len; char xdata[xdata_len]; }; typedef struct j_xattr_val j_xattr_val_t; /* File-System Contants */ enum APFS_TYPE { ANY = 0, SNAP_METADATA = 1, EXTENT = 2, INODE = 3, XATTR = 4, SIBLING_LINK = 5, DSTREAM_ID = 6, CRYPTO_STATE = 7, FILE_EXTENT = 8, DIR_REC = 9, DIR_STATS = 10, SNAP_NAME = 11, SIBLING_MAP = 12, FILE_INFO = 13, MAX_VALID = 13, MAX = 15, INVALID = 15, }; /* typedef enum j_obj_types; */ enum APFS_KIND { ANY = 0, NEW = 1, UPDATE = 2, DEAD = 3, UPDATE_REFCNT = 4, INVALID = 255 }; /* typedef enum j_obj_kinds; */ flag INODE { IS_APFS_PRIVATE = 0x00000001, MAINTAIN_DIR_STATS = 0x00000002, DIR_STATS_ORIGIN = 0x00000004, PROT_CLASS_EXPLICIT = 0x00000008, WAS_CLONED = 0x00000010, FLAG_UNUSED = 0x00000020, HAS_SECURITY_EA = 0x00000040, BEING_TRUNCATED = 0x00000080, HAS_FINDER_INFO = 0x00000100, IS_SPARSE = 0x00000200, WAS_EVER_CLONED = 0x00000400, ACTIVE_FILE_TRIMMED = 0x00000800, PINNED_TO_MAIN = 0x00001000, PINNED_TO_TIER2 = 0x00002000, HAS_RSRC_FORK = 0x00004000, NO_RSRC_FORK = 0x00008000, ALLOCATION_SPILLEDOVER = 0x00010000, FAST_PROMOTE = 0x00020000, HAS_UNCOMPRESSED_SIZE = 0x00040000, IS_PURGEABLE = 0x00080000, WANTS_TO_BE_PURGEABLE = 0x00100000, IS_SYNC_ROOT = 0x00200000, SNAPSHOT_COW_EXEMPTION = 0x00400000, INHERITED_INTERNAL_FLAGS = 0x00400002, CLONED_INTERNAL_FLAGS = 0x0000c000, }; /* typedef enum j_inode_flags */ #define APFS_INODE_PINNED_MASK INODE.PINNED_TO_MAIN | INODE.PINNED_TO_TIER2 /* Super-user and owner changeable flags. */ #define UF_NODUMP 0x00000001 /* do not dump file */ #define UF_IMMUTABLE 0x00000002 /* file may not be changed */ #define UF_APPEND 0x00000004 /* writes to file may only append */ #define UF_OPAQUE 0x00000008 /* directory is opaque wrt. union */ #define UF_NOUNLINK 0x00000010 /* file may not be removed or renamed */ #define UF_COMPRESSED 0x00000020 /* file is compressed (some file-systems) */ #define UF_TRACKED 0x00000040 #define UF_DATAVAULT 0x00000080 /* entitlement required for reading and writing */ #define UF_HIDDEN 0x00008000 /* hint that this item should not be displayed in a GUI */ /* Super-user changeable flags. */ #define SF_SUPPORTED 0x009f0000 /* mask of superuser supported flags */ #define SF_SETTABLE 0x3fff0000 /* mask of superuser changeable flags */ #define SF_SYNTHETIC 0xc0000000 /* mask of system read-only synthetic flags */ #define SF_ARCHIVED 0x00010000 /* file is archived */ #define SF_IMMUTABLE 0x00020000 /* file may not be changed */ #define SF_APPEND 0x00040000 /* writes to file may only append */ #define SF_RESTRICTED 0x00080000 /* entitlement required for writing */ #define SF_NOUNLINK 0x00100000 /* Item may not be removed, renamed or mounted on */ #define SF_SNAPSHOT 0x00200000 /* snapshot inode */ #define SF_FIRMLINK 0x00800000 /* file is a firmlink */ #define SF_DATALESS 0x40000000 /* file is dataless object */ flag XATTR { DATA_STREAM = 0x00000001, DATA_EMBEDDED = 0x00000002, FILE_SYSTEM_OWNED = 0x00000004, RESERVED_8 = 0x00000008, RESERVED_10 = 0x00000010, }; /* typedef enum j_xattr_flags; */ #define DREC_TYPE_MASK 0x000f // typedef enum { // DREC_TYPE_MASK = 0x000f, // RESERVED_10 = 0x0010 // } dir_rec_flags; /* Inode Numbers */ #define INVALID_INO_NUM 0 #define ROOT_DIR_PARENT 1 #define ROOT_DIR_INO_NUM 2 #define PRIV_DIR_INO_NUM 3 #define SNAP_DIR_INO_NUM 6 #define PURGEABLE_DIR_INO_NUM 7 #define MIN_USER_INO_NUM 16 #define UNIFIED_ID_SPACE_MARK 0x0800000000000000 /* Extended Attributes Constants */ #define XATTR_MAX_EMBEDDED_SIZE 3804 #define SYMLINK_EA_NAME "com.apple.fs.symlink" #define FIRMLINK_EA_NAME "com.apple.fs.firmlink" #define APFS_COW_EXEMPT_COUNT_NAME "com.apple.fs.cow-exempt-file-count" /* File-System Object Constants */ #define OWNING_OBJ_ID_INVALID ~0ULL #define OWNING_OBJ_ID_UNKNOWN ~1ULL #define JOBJ_MAX_KEY_SIZE 832 #define JOBJ_MAX_VALUE_SIZE 3808 #define MIN_DOC_ID 3 /* File Extent Constants */ #define FEXT_CRYPTO_ID_IS_TWEAK 0x01 /* Directory Entry File Types */ enum DT { UNKNOWN = 0, FIFO = 1, CHR = 2, DIR = 4, BLK = 6, REG = 8, LNK = 10, SOCK = 12, WHT = 14, }; /* * Compression */ struct decmpfs_header { uint32_t magic; uint32_t algorithm; uint64_t uncompressed_size; }; #define DECMPFS_MAGIC b"cmpf" #define DECMPFS_BLOCK_SIZE 0x10000 #define DECMPFS_ZLIB_ATTR 3 #define DECMPFS_ZLIB_RSRC 4 #define DECMPFS_LZVN_ATTR 7 #define DECMPFS_LZVN_RSRC 8 #define DECMPFS_PLAIN_ATTR 9 #define DECMPFS_PLAIN_RSRC 10 #define DECMPFS_LZFSE_ATTR 11 #define DECMPFS_LZFSE_RSRC 12 #define DECMPFS_LZBITMAP_ATTR 13 #define DECMPFS_LZBITMAP_RSRC 14 /* * Data Streams */ struct j_phys_ext_key { j_key_t hdr; }; typedef struct j_phys_ext_key j_phys_ext_key_t; struct j_phys_ext_val { uint64_t len_and_kind; uint64_t owning_obj_id; int32_t refcnt; }; typedef struct j_phys_ext_val j_phys_ext_val_t; #define PEXT_LEN_MASK 0x0fffffffffffffff #define PEXT_KIND_MASK 0xf000000000000000 #define PEXT_KIND_SHIFT 60 struct j_file_extent_key { j_key_t hdr; uint64_t logical_addr; }; typedef struct j_file_extent_key j_file_extent_key_t; struct j_file_extent_val { uint64_t len_and_flags; uint64_t phys_block_num; uint64_t crypto_id; }; typedef struct j_file_extent_val j_file_extent_val_t; #define J_FILE_EXTENT_LEN_MASK 0x00ffffffffffffff #define J_FILE_EXTENT_FLAG_MASK 0xff00000000000000 #define J_FILE_EXTENT_FLAG_SHIFT 56 struct j_dstream_id_key { j_key_t hdr; }; typedef struct j_dstream_id_key j_dstream_id_key_t; struct j_dstream_id_val { uint32_t refcnt; }; typedef struct j_dstream_id_val j_dstream_id_val_t; struct j_dstream { uint64_t size; uint64_t alloced_size; uint64_t default_crypto_id; uint64_t total_bytes_written; uint64_t total_bytes_read; }; typedef struct j_dstream j_dstream_t; struct j_xattr_dstream { uint64_t xattr_obj_id; j_dstream_t dstream; }; typedef struct j_xattr_dstream j_xattr_dstream_t; /* * Extended fields */ struct x_field { uint8_t x_type; uint8_t x_flags; uint16_t x_size; }; typedef struct x_field x_field_t; struct xf_blob { uint16_t xf_num_exts; uint16_t xf_used_data; x_field_t xf_exts[xf_num_exts]; char xf_data[xf_used_data]; }; typedef struct xf_blob xf_blob_t; /* Extended Field Types */ enum DREC_EXT_TYPE { SIBLING_ID = 1, }; enum INO_EXT_TYPE { SNAP_XID = 1, DELTA_TREE_OID = 2, DOCUMENT_ID = 3, NAME = 4, PREV_FSIZE = 5, RESERVED_6 = 6, FINDER_INFO = 7, DSTREAM = 8, RESERVED_9 = 9, DIR_STATS_KEY = 10, FS_UUID = 11, RESERVED_12 = 12, SPARSE_BYTES = 13, RDEV = 14, PURGEABLE_FLAGS = 15, ORIG_SYNC_ROOT_ID = 16, }; /* Extended Field Flags */ flag XF { DATA_DEPENDENT = 0x0001, DO_NOT_COPY = 0x0002, RESERVED_4 = 0x0004, CHILDREN_INHERIT = 0x0008, USER_FIELD = 0x0010, SYSTEM_FIELD = 0x0020, RESERVED_40 = 0x0040, RESERVED_80 = 0x0080, }; /* * Siblings */ struct j_sibling_key { j_key_t hdr; uint64_t sibling_id; }; typedef struct j_sibling_key j_sibling_key_t; struct j_sibling_val { uint64_t parent_id; uint16_t name_len; char name[name_len]; }; typedef struct j_sibling_val j_sibling_val_t; struct j_sibling_map_key { j_key_t hdr; }; typedef struct j_sibling_map_key j_sibling_map_key_t; struct j_sibling_map_val { uint64_t file_id; }; typedef struct j_sibling_map_val j_sibling_map_val_t; /* * Snapshot Metadata */ struct j_snap_metadata_key { j_key_t hdr; }; typedef struct j_snap_metadata_key j_snap_metadata_key_t; struct j_snap_metadata_val { oid_t extentref_tree_oid; oid_t sblock_oid; uint64_t create_time; uint64_t change_time; uint64_t inum; uint32_t extentref_tree_type; uint32_t flags; uint16_t name_len; char name[name_len]; }; typedef struct j_snap_metadata_val j_snap_metadata_val_t; struct j_snap_name_key { j_key_t hdr; uint16_t name_len; char name[name_len]; }; typedef struct j_snap_name_key j_snap_name_key_t; struct j_snap_name_val { xid_t snap_xid; }; typedef struct j_snap_name_val j_snap_name_val_t; enum SNAP_META { PENDING_DATALESS = 0x00000001, MERGE_IN_PROGRESS = 0x00000002, }; /* typedef enum snap_meta_flags; */ typedef struct snap_meta_ext { uint32_t sme_version; uint32_t sme_flags; xid_t sme_snap_xid; char sme_uuid[16]; uint64_t sme_token; }; typedef struct snap_meta_ext snap_meta_ext_t; struct snap_meta_ext_obj_phys { obj_phys_t smeop_o; snap_meta_ext_t smeop_sme; }; typedef struct snap_meta_ext_obj_phys snap_meta_ext_obj_phys_t; /* * Encryption */ #define CRYPTO_SW_ID 4 #define CRYPTO_RESERVED_5 5 #define APFS_UNASSIGNED_CRYPTO_ID (~0) struct keybag_entry { char ke_uuid[16]; uint16_t ke_tag; uint16_t ke_keylen; uint8_t padding[4]; char ke_keydata[0]; }; typedef struct keybag_entry keybag_entry_t; #define APFS_VOL_KEYBAG_ENTRY_MAX_SIZE 512 #define APFS_FV_PERSONAL_RECOVERY_KEY_UUID "EBC6C064-0000-11AA-AA11-00306543ECAC" struct kb_locker { uint16_t kl_version; uint16_t kl_nkeys; uint32_t kl_nbytes; uint8_t padding[8]; keybag_entry_t kl_entries[0]; }; typedef struct kb_locker kb_locker_t; #define APFS_KEYBAG_VERSION 2 struct media_keybag { obj_phys_t mk_obj; kb_locker_t mk_locker; }; typedef struct media_keybag media_keybag_t; enum KB_TAG { UNKNOWN = 0, RESERVED_1 = 1, VOLUME_KEY = 2, VOLUME_UNLOCK_RECORDS = 3, VOLUME_PASSPHRASE_HINT = 4, WRAPPING_M_KEY = 5, KB_TAG_VOLUME_M_KEY = 6, KB_TAG_RESERVED_F8 = 0xF8, }; enum PROTECTION_CLASS { DIR_NONE = 0, A = 1, B = 2, C = 3, D = 4, F = 6, M = 14, }; #define CP_EFFECTIVE_CLASSMASK 0x0000001f struct wrapped_meta_crypto_state { uint16_t major_version; uint16_t minor_version; crypto_flags_t cpflags; cp_key_class_t persistent_class; cp_key_os_version_t key_os_version; cp_key_revision_t key_revision; uint16_t unused; }; typedef struct wrapped_meta_crypto_state wrapped_meta_crypto_state_t; struct wrapped_crypto_state { uint16_t major_version; uint16_t minor_version; crypto_flags_t cpflags; cp_key_class_t persistent_class; cp_key_os_version_t key_os_version; cp_key_revision_t key_revision; uint16_t key_len; char persistent_key[key_len]; }; typedef struct wrapped_crypto_state wrapped_crypto_state_t; struct j_crypto_key { j_key_t hdr; }; typedef struct j_crypto_key j_crypto_key_t; struct j_crypto_val { uint32_t refcnt; wrapped_crypto_state_t state; }; typedef struct j_crypto_val j_crypto_val_t; /* * Encryption Rolling */ enum ER_PHASE { OMAP_ROLL = 1, DATA_ROLL = 2, SNAP_ROLL = 3, }; enum { ER_512B_BLOCKSIZE = 0, ER_2KiB_BLOCKSIZE = 1, ER_4KiB_BLOCKSIZE = 2, ER_8KiB_BLOCKSIZE = 3, ER_16KiB_BLOCKSIZE = 4, ER_32KiB_BLOCKSIZE = 5, ER_64KiB_BLOCKSIZE = 6, }; /* Encryption Rolling Flags */ #define ERSB_FLAG_ENCRYPTING 0x00000001 #define ERSB_FLAG_DECRYPTING 0x00000002 #define ERSB_FLAG_KEYROLLING 0x00000004 #define ERSB_FLAG_PAUSED 0x00000008 #define ERSB_FLAG_FAILED 0x00000010 #define ERSB_FLAG_CID_IS_TWEAK 0x00000020 #define ERSB_FLAG_FREE_1 0x00000040 #define ERSB_FLAG_FREE_2 0x00000080 #define ERSB_FLAG_CM_BLOCK_SIZE_MASK 0x00000F00 #define ERSB_FLAG_CM_BLOCK_SIZE_SHIFT 8 #define ERSB_FLAG_ER_PHASE_MASK 0x00003000 #define ERSB_FLAG_ER_PHASE_SHIFT 12 #define ERSB_FLAG_FROM_ONEKEY 0x00004000 /* Encryption Rolling Constants */ #define ER_CHECKSUM_LENGTH 8 #define ER_MAGIC b'FLAB' #define ER_VERSION 1 #define ER_MAX_CHECKSUM_COUNT_SHIFT 16 #define ER_CUR_CHECKSUM_COUNT_MASK 0x0000FFFF struct er_state_phys_header { obj_phys_t ersb_o; uint32_t ersb_magic; uint32_t ersb_version; }; typedef struct er_state_phys_header er_state_phys_header_t; struct er_state_phys { er_state_phys_header_t ersb_header; uint64_t ersb_flags; uint64_t ersb_snap_xid; uint64_t ersb_current_fext_obj_id; uint64_t ersb_file_offset; uint64_t ersb_progress; uint64_t ersb_total_blk_to_encrypt; oid_t ersb_blockmap_oid; uint64_t ersb_tidemark_obj_id; uint64_t ersb_recovery_extents_count; oid_t ersb_recovery_list_oid; uint64_t ersb_recovery_length; }; typedef struct er_state_phys er_state_phys_t; struct er_state_phys_v1 { er_state_phys_header_t ersb_header; uint64_t ersb_flags; uint64_t ersb_snap_xid; uint64_t ersb_current_fext_obj_id; uint64_t ersb_file_offset; uint64_t ersb_fext_pbn; uint64_t ersb_paddr; uint64_t ersb_progress; uint64_t ersb_total_blk_to_encrypt; uint64_t ersb_blockmap_oid; uint32_t ersb_checksum_count; uint32_t ersb_reserved; uint64_t ersb_fext_cid; uint8_t ersb_checksum[0]; }; typedef struct er_state_phys_v1 er_state_phys_v1_t; struct er_recovery_block_phys { obj_phys_t erb_o; uint64_t erb_offset; oid_t erb_next_oid; char erb_data[0]; }; typedef struct er_recovery_block_phys er_recovery_block_phys_t; struct gbitmap_block_phys { obj_phys_t bmb_o; uint64_t bmb_field[0]; }; typedef struct gbitmap_block_phys gbitmap_block_phys_t; struct gbitmap_phys { obj_phys_t bm_o; oid_t bm_tree_oid; uint64_t bm_bit_count; uint64_t bm_flags; }; typedef struct gbitmap_phys gbitmap_phys_t; /* * EFI Jumpstart */ #define NX_EFI_JUMPSTART_MAGIC b'RDSJ' #define NX_EFI_JUMPSTART_VERSION 1 struct nx_efi_jumpstart { obj_phys_t nej_o; uint32_t nej_magic; uint32_t nej_version; uint32_t nej_efi_file_len; uint32_t nej_num_extents; uint64_t nej_reserved[16]; prange_t nej_rec_extents[]; }; typedef struct nx_efi_jumpstart nx_efi_jumpstart_t; /* * Container */ #define NX_MAGIC b'BSXN' #define NX_MAX_FILE_SYSTEMS 100 #define NX_EPH_INFO_COUNT 4 #define NX_EPH_MIN_BLOCK_COUNT 8 #define NX_MAX_FILE_SYSTEM_EPH_STRUCTS 4 #define NX_TX_MIN_CHECKPOINT_COUNT 4 #define NX_EPH_INFO_VERSION_1 1 #define NX_MINIMUM_BLOCK_SIZE 4096 #define NX_DEFAULT_BLOCK_SIZE 4096 #define NX_MAXIMUM_BLOCK_SIZE 65536 #define NX_MINIMUM_CONTAINER_SIZE 1048576 #define NX_RESERVED_1 0x00000001 #define NX_RESERVED_2 0x00000002 #define NX_CRYPTO_SW 0x00000004 flag NX_FEATURE { DEFRAG = 0x0000000000000001, LCFD = 0x0000000000000002, }; flag NX_INCOMPAT { VERSION1 = 0x0000000000000001, VERSION2 = 0x0000000000000002, FUSION = 0x0000000000000100, }; enum { NX_CNTR_OBJ_CKSUM_SET = 0, NX_CNTR_OBJ_CKSUM_FAIL = 1, NX_NUM_COUNTERS = 32, }; struct nx_superblock { obj_phys_t nx_o; uint32_t nx_magic; uint32_t nx_block_size; uint64_t nx_block_count; uint64_t nx_features; uint64_t nx_readonly_compatible_features; uint64_t nx_incompatible_features; char nx_uuid[16]; oid_t nx_next_oid; xid_t nx_next_xid; uint32_t nx_xp_desc_blocks; uint32_t nx_xp_data_blocks; paddr_t nx_xp_desc_base; paddr_t nx_xp_data_base; uint32_t nx_xp_desc_next; uint32_t nx_xp_data_next; uint32_t nx_xp_desc_index; uint32_t nx_xp_desc_len; uint32_t nx_xp_data_index; uint32_t nx_xp_data_len; oid_t nx_spaceman_oid; oid_t nx_omap_oid; oid_t nx_reaper_oid; uint32_t nx_test_type; uint32_t nx_max_file_systems; oid_t nx_fs_oid[NX_MAX_FILE_SYSTEMS]; uint64_t nx_counters[NX_NUM_COUNTERS]; prange_t nx_blocked_out_prange; oid_t nx_evict_mapping_tree_oid; uint64_t nx_flags; paddr_t nx_efi_jumpstart; char nx_fusion_uuid[16]; prange_t nx_keylocker; uint64_t nx_ephemeral_info[NX_EPH_INFO_COUNT]; oid_t nx_test_oid; oid_t nx_fusion_mt_oid; oid_t nx_fusion_wbc_oid; prange_t nx_fusion_wbc; uint64_t nx_newest_mounted_version; prange_t nx_mkb_locker; }; #define CHECKPOINT_MAP_LAST 0x00000001 struct checkpoint_mapping { uint32_t cpm_type; uint32_t cpm_subtype; uint32_t cpm_size; uint32_t cpm_pad; oid_t cpm_fs_oid; oid_t cpm_oid; oid_t cpm_paddr; }; typedef struct checkpoint_mapping checkpoint_mapping_t; struct checkpoint_map_phys { obj_phys_t cpm_o; uint32_t cpm_flags; uint32_t cpm_count; checkpoint_mapping_t cpm_map[cpm_count]; }; typedef struct checkpoint_map_phys checkpoint_map_phys_t; struct evict_mapping_val { paddr_t dst_paddr; uint64_t len; }; typedef struct evict_mapping_val evict_mapping_val_t; /* * Volume */ #define APFS_MAGIC b'BSPA' #define APFS_MAX_HIST 8 #define APFS_VOLNAME_LEN 256 #define APFS_MODIFIED_NAMELEN 32 struct apfs_modified_by { char id[APFS_MODIFIED_NAMELEN]; uint64_t timestamp; xid_t last_xid; }; typedef struct apfs_modified_by apfs_modified_by_t; struct apfs_superblock { obj_phys_t apfs_o; uint32_t apfs_magic; uint32_t apfs_fs_index; uint64_t apfs_features; uint64_t apfs_readonly_compatible_features; uint64_t apfs_incompatible_features; uint64_t apfs_unmount_time; uint64_t apfs_fs_reserve_block_count; uint64_t apfs_fs_quota_block_count; uint64_t apfs_fs_alloc_count; wrapped_meta_crypto_state_t apfs_meta_crypto; uint32_t apfs_root_tree_type; uint32_t apfs_extentref_tree_type; uint32_t apfs_snap_meta_tree_type; oid_t apfs_omap_oid; oid_t apfs_root_tree_oid; oid_t apfs_extentref_tree_oid; oid_t apfs_snap_meta_tree_oid; xid_t apfs_revert_to_xid; oid_t apfs_revert_to_sblock_oid; uint64_t apfs_next_obj_id; uint64_t apfs_num_files; uint64_t apfs_num_directories; uint64_t apfs_num_symlinks; uint64_t apfs_num_other_fsobjects; uint64_t apfs_num_snapshots; uint64_t apfs_total_blocks_alloced; uint64_t apfs_total_blocks_freed; char apfs_vol_uuid[16]; uint64_t apfs_last_mod_time; uint64_t apfs_fs_flags; apfs_modified_by_t apfs_formatted_by; apfs_modified_by_t apfs_modified_by[APFS_MAX_HIST]; char apfs_volname[APFS_VOLNAME_LEN]; uint32_t apfs_next_doc_id; uint16_t apfs_role; uint16_t reserved; xid_t apfs_root_to_xid; oid_t apfs_er_state_oid; uint64_t apfs_cloneinfo_id_epoch; xid_t apfs_cloneinfo_xid; oid_t apfs_snap_meta_ext_oid; char apfs_volume_group_id[16]; oid_t apfs_integrity_meta_oid; oid_t apfs_fext_tree_oid; uint32_t apfs_fext_tree_type; uint32_t apfs_pfkur_tree_type; oid_t apfs_pfkur_tree_oid; // Undocumented from here on xid_t apfs_doc_id_index_xid; uint32_t apfs_doc_id_index_flags; uint32_t apfs_doc_id_tree_type; oid_t apfs_doc_id_tree_oid; oid_t apfs_prev_doc_id_tree_oid; uint64_t apfs_doc_id_fixup_cursor; oid_t apfs_sec_root_tree_oid; uint32_t apfs_sec_root_tree_type; uint32_t apfs_clone_group_tree_flags; }; typedef struct apfs_superblock apfs_superblock_t; flag APFS_FEATURE { DEFRAG_PRERELEASE = 0x00000001, HARDLINK_MAP_RECORDS = 0x00000002, DEFRAG = 0x00000004, STRICTATIME = 0x00000008, VOLGRP_SYSTEM_INO_SPACE = 0x00000010, }; flag APFS_INCOMPAT { CASE_INSENSITIVE = 0x00000001, DATALESS_SNAPS = 0x00000002, ENC_ROLLED = 0x00000004, NORMALIZATION_INSENSITIVE = 0x00000008, INCOMPLETE_RESTORE = 0x00000010, SEALED_VOLUME = 0x00000020, PFK = 0x00000040, // Undocumented name RESERVED_80 = 0x00000080, // Maybe EXTENT_PREALLOC according to linux-apfs-rw SECONDARY_FSROOT = 0x00000100, // Undocumented name }; #define APFS_VOLUME_ENUM_SHIFT 6 flag APFS_FS { UNENCRYPTED = 0x00000001, RESERVED_2 = 0x00000002, RESERVED_4 = 0x00000004, ONEKEY = 0x00000008, SPILLEDOVER = 0x00000010, RUN_SPILLOVER_CLEANER = 0x00000020, ALWAYS_CHECK_EXTENTREF = 0x00000040, PREVIOUSLY_SEALED = 0x00000080, // Undocumented name PFK = 0x00000100, // Undocumented name RESERVED_200 = 0x00000200, RESERVED_400 = 0x00000400, RESERVED_800 = 0x00000800, }; enum APFS_VOL_ROLE { NONE = 0x0000, SYSTEM = 0x0001, USER = 0x0002, RECOVERY = 0x0004, VM = 0x0008, PREBOOT = 0x0010, INSTALLER = 0x0020, DATA = (1 << APFS_VOLUME_ENUM_SHIFT), BASEBAND = (2 << APFS_VOLUME_ENUM_SHIFT), UPDATE = (3 << APFS_VOLUME_ENUM_SHIFT), XART = (4 << APFS_VOLUME_ENUM_SHIFT), HARDWARE = (5 << APFS_VOLUME_ENUM_SHIFT), BACKUP = (6 << APFS_VOLUME_ENUM_SHIFT), RESERVED_7 = (7 << APFS_VOLUME_ENUM_SHIFT), RESERVED_8 = (8 << APFS_VOLUME_ENUM_SHIFT), ENTERPRISE = (9 << APFS_VOLUME_ENUM_SHIFT), RESERVED_10 = (10 << APFS_VOLUME_ENUM_SHIFT), PRELOGIN = (11 << APFS_VOLUME_ENUM_SHIFT), }; /* * Sealed Volumes */ enum apfs_hash_type_t : uint32_t { APFS_HASH_INVALID = 0, APFS_HASH_SHA256 = 0x1, APFS_HASH_SHA512_256 = 0x2, APFS_HASH_SHA384 = 0x3, APFS_HASH_SHA512 = 0x4, }; #define APFS_HASH_CCSHA256_SIZE 32 #define APFS_HASH_CCSHA512_256_SIZE 32 #define APFS_HASH_CCSHA384_SIZE 48 #define APFS_HASH_CCSHA512_SIZE 64 #define APFS_HASH_MAX_SIZE 64 struct integrity_meta_phys { obj_phys_t im_o; uint32_t im_version; uint32_t im_flags; apfs_hash_type_t im_hash_type; uint32_t im_root_hash_offset; xid_t im_broken_xid; uint64_t im_reserved[9]; }; typedef struct integrity_meta_phys integrity_meta_phys_t; /* Integrity Metadata Flags */ #define APFS_SEAL_BROKEN (1 << 0) struct fext_tree_key { uint64_t private_id; uint64_t logical_addr; }; typedef struct fext_tree_key fext_tree_key_t; struct fext_tree_val { uint64_t len_and_flags; uint64_t phys_block_num; }; typedef struct fext_tree_val fext_tree_val_t; struct j_file_info_key { j_key_t hdr; uint64_t info_and_lba; }; typedef struct j_key_t j_file_info_key_t; #define J_FILE_INFO_LBA_MASK 0x00ffffffffffffff #define J_FILE_INFO_TYPE_MASK 0xff00000000000000 #define J_FILE_INFO_TYPE_SHIFT 56 struct j_file_data_hash_val { uint16_t hashed_len; uint8_t hash_size; char hash[hash_size]; }; typedef struct j_file_data_hash_val j_file_data_hash_val_t; struct j_file_info_val { union { j_file_data_hash_val_t dhash; }; }; typedef struct j_file_data_hash_val_t j_file_info_val_t; enum APFS_FILE_INFO { DATA_HASH = 1, }; /* typedef enum j_obj_file_info_type; */ /* * Space Manager */ typedef uint64_t spaceman_free_queue_val_t; #define SM_ALLOCZONE_INVALID_END_BOUNDARY 0 #define SM_ALLOCZONE_NUM_PREVIOUS_BOUNDARIES 7 #define SM_DATAZONE_ALLOCZONE_COUNT 8 #define SM_FLAG_VERSIONED 0x00000001 enum { SFQ_IP = 0, SFQ_MAIN = 1, SFQ_TIER2 = 2, SFQ_COUNT = 3 }; enum { SD_MAIN = 0, SD_TIER2 = 1, SD_COUNT = 2 }; /* Chunk Info Block Constants */ #define CI_COUNT_MASK 0x000fffff #define CI_COUNT_RESERVED_MASK 0xfff00000 /* Internal-Pool Bitmap */ #define SPACEMAN_IP_BM_TX_MULTIPLIER 16 #define SPACEMAN_IP_BM_INDEX_INVALID 0xffff #define SPACEMAN_IP_BM_BLOCK_COUNT_MAX 0xfffe struct chunk_info { uint64_t ci_xid; uint64_t ci_addr; uint32_t ci_block_count; uint32_t ci_free_count; paddr_t ci_bitmap_addr; }; typedef struct chunk_info chunk_info_t; struct chunk_info_block { obj_phys_t cib_o; uint32_t cib_index; uint32_t cib_chunk_info_count; chunk_info_t cib_chunk_info[cib_chunk_info_count]; }; typedef struct chunk_info_block chunk_info_block_t; struct cib_addr_block { obj_phys_t cab_o; uint32_t cab_index; uint32_t cab_cib_count; paddr_t cab_cib_addr[cab_cib_count]; }; typedef struct cib_addr_block cib_addr_block_t; struct spaceman_free_queue_key { xid_t sfqk_xid; paddr_t sfqk_paddr; }; typedef struct spaceman_free_queue_key spaceman_free_queue_key_t; struct spaceman_free_queue_entry { spaceman_free_queue_key_t sfqe_key; spaceman_free_queue_val_t sfqe_count; }; typedef struct spaceman_free_queue_entry spaceman_free_queue_entry_t; struct spaceman_free_queue { uint64_t sfq_count; oid_t sfq_tree_oid; xid_t sfq_oldest_xid; uint16_t sfq_tree_node_limit; uint16_t sfq_pad16; uint32_t sfq_pad32; uint64_t sfq_reserved; }; typedef struct spaceman_free_queue spaceman_free_queue_t; struct spaceman_device { uint64_t sm_block_count; uint64_t sm_chunk_count; uint32_t sm_cib_count; uint32_t sm_cab_count; uint64_t sm_free_count; uint32_t sm_addr_offset; uint32_t sm_reserved; uint64_t sm_reserved2; }; typedef struct spaceman_device spaceman_device_t; struct spaceman_allocation_zone_boundaries { uint64_t saz_zone_start; uint64_t saz_zone_end; }; typedef struct spaceman_allocation_zone_boundaries spaceman_allocation_zone_boundaries_t; struct spaceman_allocation_zone_info_phys { spaceman_allocation_zone_boundaries_t saz_current_boundaries; spaceman_allocation_zone_boundaries_t saz_previous_boundaries[SM_ALLOCZONE_NUM_PREVIOUS_BOUNDARIES]; uint16_t saz_zone_id; uint16_t saz_previous_boundary_index; uint32_t saz_reserved; }; typedef struct spaceman_allocation_zone_info_phys spaceman_allocation_zone_info_phys_t; struct spaceman_datazone_info_phys { spaceman_allocation_zone_info_phys_t sdz_allocation_zones[SD_COUNT][SM_DATAZONE_ALLOCZONE_COUNT]; }; typedef struct spaceman_datazone_info_phys spaceman_datazone_info_phys_t; struct spaceman_phys { obj_phys_t sm_o; uint32_t sm_block_size; uint32_t sm_blocks_per_chunk; uint32_t sm_chunks_per_cib; uint32_t sm_cibs_per_cab; spaceman_device_t sm_dev[SD_COUNT]; uint32_t sm_flags; uint32_t sm_ip_bm_tx_multiplier; uint64_t sm_ip_block_count; uint32_t sm_ip_bm_size_in_blocks; uint32_t sm_ip_bm_block_count; paddr_t sm_ip_bm_base; paddr_t sm_ip_base; uint64_t sm_fs_reserve_block_count; uint64_t sm_fs_reserve_alloc_count; spaceman_free_queue_t sm_fq[SFQ_COUNT]; uint16_t sm_ip_bm_free_head; uint16_t sm_ip_bm_free_tail; uint32_t sm_ip_bm_xid_offset; uint32_t sm_ip_bitmap_offset; uint32_t sm_ip_bm_free_next_offset; uint32_t sm_version; uint32_t sm_struct_size; spaceman_datazone_info_phys_t sm_datazone; }; typedef struct spaceman_phys spaceman_phys_t; /* * Reaper */ /* Volume Reaper States */ enum APFS_REAP_PHASE { START = 0, SNAPSHOTS = 1, ACTIVE_FS = 2, DESTROY_OMAP = 3, DONE = 4 }; /* Reaper Flags */ #define NR_BHM_FLAG 0x00000001 #define NR_CONTINUE 0x00000002 /* Reaper List Entry Flags */ #define NRLE_VALID 0x00000001 #define NRLE_REAP_ID_RECORD 0x00000002 #define NRLE_CALL 0x00000004 #define NRLE_COMPLETION 0x00000008 #define NRLE_CLEANUP 0x00000010 /* Reaper List Flags */ #define NRL_INDEX_INVALID 0xffffffff struct nx_reaper_phys { obj_phys_t nr_o; uint64_t nr_next_reap_id; uint64_t nr_completed_id; oid_t nr_head; oid_t nr_tail; uint32_t nr_flags; uint32_t nr_rlcount; uint32_t nr_type; uint32_t nr_size; oid_t nr_fs_oid; oid_t nr_oid; xid_t nr_xid; uint32_t nr_nrle_flags; uint32_t nr_state_buffer_size; uint8_t nr_state_buffer[]; }; typedef struct nx_reaper_phys nx_reaper_phys_t; struct nx_reap_list_entry { uint32_t nrle_next; uint32_t nrle_flags; uint32_t nrle_type; uint32_t nrle_size; oid_t nrle_fs_oid; oid_t nrle_oid; xid_t nrle_xid; }; typedef struct nx_reap_list_entry nx_reap_list_entry_t; struct nx_reap_list_phys { obj_phys_t nrl_o; oid_t nrl_next; uint32_t nrl_flags; uint32_t nrl_max; uint32_t nrl_count; uint32_t nrl_first; uint32_t nrl_last; uint32_t nrl_free; // nx_reap_list_entry_t nrl_entries[]; }; typedef struct nx_reap_list_phys nx_reap_list_phys_t; struct omap_reap_state { uint32_t omr_phase; omap_key_t omr_ok; }; typedef struct omap_reap_state omap_reap_state_t; struct omap_cleanup_state { uint32_t omc_cleaning; uint32_t omc_omsflags; xid_t omc_sxidprev; xid_t omc_sxidstart; xid_t omc_sxidend; xid_t omc_sxidnext; omap_key_t omc_curkey; }; typedef struct omap_cleanup_state omap_cleanup_state_t; struct apfs_reap_state { uint64_t last_pbn; xid_t cur_snap_xid; uint32_t phase; }; typedef struct apfs_reap_state apfs_reap_state_t; /* * Fusion */ typedef paddr_t fusion_mt_key_t; #define FUSION_TIER2_DEVICE_BYTE_ADDR 0x4000000000000000 struct fusion_wbc_phys { obj_phys_t fwp_objHdr; uint64_t fwp_version; oid_t fwp_listHeadOid; oid_t fwp_listTailOid; uint64_t fwp_stableHeadOffset; uint64_t fwp_stableTailOffset; uint32_t fwp_listBlocksCount; uint32_t fwp_reserved; uint64_t fwp_usedByRC; prange_t fwp_rcStash; }; typedef struct fusion_wbc_phys fusion_wbc_phys_t; struct fusion_wbc_list_entry { paddr_t fwle_wbcLba; paddr_t fwle_targetLba; uint64_t fwle_length; }; typedef struct fusion_wbc_list_entry fusion_wbc_list_entry_t; struct fusion_wbc_list_phys { obj_phys_t fwlp_objHdr; uint64_t fwlp_version; uint64_t fwlp_tailOffset; uint32_t fwlp_indexBegin; uint32_t fwlp_indexEnd; uint32_t fwlp_indexMax; uint32_t fwlp_reserved; fusion_wbc_list_entry_t fwlp_listEntries[]; }; typedef struct fusion_wbc_list_phys fusion_wbc_list_phys_t; struct fusion_mt_val { paddr_t fmv_lba; uint32_t fmv_length; uint32_t fmv_flags; }; typedef struct fusion_mt_val fusion_mt_val_t; #define FUSION_MT_DIRTY (1 << 0) #define FUSION_MT_TENANT (1 << 1) #define FUSION_MT_ALLFLAGS (FUSION_MT_DIRTY | FUSION_MT_TENANT) """ .. raw:: html
.. py:data:: c_apfs .. py:data:: FILESYSTEM_OBJECT_TYPE_MAP .. py:data:: XF_MAP