2 // Copyright (c) 2009-2019 Apple Inc. All rights reserved.
4 // lf_cs_disk_format.h - Defines on disk format for Apple_CoreStorage physical
5 // volumes for livefiles Apple_CoreStorage plugin.
7 // This header is copied from CoreStorage project.
10 #ifndef _LF_CS_DISK_FORMAT_H
11 #define _LF_CS_DISK_FORMAT_H
13 #define MAX_CKSUM_NBYTES 8
14 #define CORESTORAGE_FORMAT_VERSION 1
17 // The 'dl_lvg.lvg_signature' in a DiskLabel (mimics 'CORESTOR')
19 #define CORE_STORAGE_SIGNATURE 0xC07E5707
22 // The 'mh_endianness' used to check endianness (non-palindromic 'CS')
24 #define BYTE_ORDER_MARK 0x5343
27 // Metadata block header.
29 struct metadata_header
{
34 uint8_t mh_cksum
[MAX_CKSUM_NBYTES
];
37 // The on-disk format version of CoreStorage.
39 uint16_t mh_format_version
;
42 // Enum metadata_blk_type (BLK_TYPE_*).
47 // Enum metadata_blk_subtype (BLK_SUBTYPE_*), for b-tree/fsck.
49 uint8_t mh_blk_subtype
;
52 // The version of CoreStorage software that wrote this block.
54 uint32_t mh_bundle_version
;
57 // Transaction identification.
64 // Records the owner of the block. The owner of any blocks in a B-Tree
65 // is the root of the tree. The owner of any blocks in a list like
66 // structure (DSD list, attribute blocks) is the first block in the
67 // list. This field can be used for crash recovery by fsck_cs. For
68 // example, if this field has the B-Tree root vaddr that this block
69 // belongs, fsck_cs could reconstruct the B-Tree based on all leaf
72 uint64_t mh_blk_owner
;
75 // Block size (LVG MLV blksz).
80 // Flags (BLK_FLAG_*).
85 // Reserved for future extensions
86 // make blk header 64 bytes (crypto alignment)
89 uint16_t mh_reserved2
;
90 uint64_t mh_reserved8
;
92 typedef struct metadata_header metadata_header_t
;
94 int check_dk_metadata_header_size
[sizeof(metadata_header_t
) == 64 ? 1 : -1];
97 #define NUM_VOL_HEADERS 2
98 #define VOL_HEADER_NBYTES 512
99 #define MAX_DISK_LABELS 4
100 #define MAX_WIPEKEY_NBYTES 64
103 // This structure is padded such that it is of correct size.
105 struct dk_vol_header
{
108 metadata_header_t vh_header
;
111 // PV size in bytes, rounded down to VOL_HEADER_NBYTES
114 uint64_t vh_pv_nbytes
;
117 // If this is not 0, it records a PV resize operation
119 uint64_t vh_pv_resize
;
122 // If this is not 0, it records the old Volume Header
123 // location before the PV resize started; it is again 0
126 uint64_t vh_old_pv_nbytes
;
129 // The cpu-platform endian that formatted this LVG.
131 uint16_t vh_endianness
;
134 // Checksum algorithm of VolHdr metadata header.
136 uint16_t vh_cksum_alg
;
141 uint16_t vh_reserved2
;
144 // Number of disk labels.
146 uint16_t vh_num_labels
;
149 // Label address uses this block size.
154 // Maximum disk label size.
156 uint32_t vh_label_max_nbytes
;
159 // (Physical) Location of the new/old disk labels.
161 uint64_t vh_label_addr
[MAX_DISK_LABELS
];
162 uint64_t vh_move_label_addr
[MAX_DISK_LABELS
];
165 // PV MLV/plist wipe keys ([0] is active, [1] future
168 uint16_t vh_wipe_key_nbytes
[2];
169 uint16_t vh_wipe_key_alg
[2];
170 uint8_t vh_wipe_key
[2][MAX_WIPEKEY_NBYTES
];
173 // UUID of this PV and its LVG (for bootstrap/multi-PV)
175 uint8_t vh_pv_uuid
[16];
176 uint8_t vh_lvg_uuid
[16];
178 uint8_t vh_padding
[VOL_HEADER_NBYTES
];
181 typedef struct dk_vol_header dk_vol_header_t
;
182 int check_dk_vol_header_size
[sizeof(dk_vol_header_t
) == VOL_HEADER_NBYTES
? 1 : -1];
185 // Existing block types cannot be changed!
187 enum metadata_blk_type
{
190 // The values of the B-Tree types are important. They are the results
191 // of the bit operations of BTREE_ROOT, BTREE_NODE, and BTREE_LEAF in
194 BLK_TYPE_BTREE_NODE
= 2, // A B-Tree node that is not a leaf.
195 BLK_TYPE_BTREE_ROOT_NODE
= 3, // A non-leaf B-Tree node that is also root.
196 BLK_TYPE_BTREE_LEAF
= 4, // A B-Tree leaf node that is not a root.
197 BLK_TYPE_BTREE_ROOT_LEAF
= 5, // A B-Tree leaf node that is also root.
199 BLK_TYPE_VOL_HEADER
= 16,
202 // Fixed part of disk label (first MLV block size).
204 BLK_TYPE_DISK_LABEL
= 17,
206 BLK_TYPE_DISK_LABEL_CONT
= 18, // Variable part of disk label.
209 // LFS related blocks
213 // MLV Partial Segment (PS) header block, first block of the first
214 // PS in a Group of Partial Segments (GPS).
216 BLK_TYPE_PS_HEADER
= 19,
219 // MLV Continuation Partial Segment block, first block of a Partial
220 // Segment (PS) in a Group of Partial Segments (GPS), where the PS
221 // is not the first PS in the GPS.
223 BLK_TYPE_PS_CONT_HDR
= 20,
226 // MLV Partial Segment (PS) Overflow header block, which holds
227 // information about added or deleted virtual blocks.
229 BLK_TYPE_PS_OVERFLOW_HDR
= 21,
232 // MLV Virtual Address Table (VAT) blocks, which holds VAT information.
237 // MLV Segment Usage Table (SUT) blocks, which holds SUT information.
244 // MLV super block, the starting point of all MLV metadata.
246 BLK_TYPE_MLV_SUPERBLOCK
= 24,
249 // Logical Volume Family (LVF) super block.
251 BLK_TYPE_LV_FAMILY_SUPERBLOCK
= 25,
254 // Logical Volume (LV) super block.
256 BLK_TYPE_LV_SUPERBLOCK
= 26,
259 // Hold more LV attributes when they don't fit in the LV superblock.
261 BLK_TYPE_LV_XATTR
= 27,
264 // Holds the Physical Volume (PV) information.
266 BLK_TYPE_PV_TABLE
= 28,
269 // Holds the Physical Volume (PV) Freespace Log (FLOG) table
272 BLK_TYPE_PV_FLOG_TABLE
= 29,
274 BLK_TYPE_UNUSED_1
= 30,
275 BLK_TYPE_UNUSED_2
= 31,
276 BLK_TYPE_UNUSED_3
= 32,
279 // Used for space sharing, records the amount of free space not used by
280 // the file system inside the Logical Volume.
282 BLK_TYPE_LV_FREE_SPACE_SUMMARY_DEPRECATED
= 33,
285 // Used for Physical Volume (PV) free space management, records the
286 // amount of free space in each chunk of the PV and has pointers to
287 // the Freespace Log (FLOG).
289 BLK_TYPE_PV_SUMMARY_TABLE
= 34,
291 BLK_TYPE_UNUSED_4
= 35,
294 // Hold more LV Family attributes when they don't fit in the
297 BLK_TYPE_LV_FAMILY_XATTR
= 36,
300 // Hold more Delayed Secure Deletion (DSD) list entries when
301 // they cannot fit in the LVF superblock.
303 BLK_TYPE_DSD_LIST
= 37,
306 // This block type is used to record information about bad sectors
307 // encountered during background encryption/decryption.
309 BLK_TYPE_BAD_SECTOR_LIST
= 38,
312 // For debugging: block is in dummy tree.
317 // New types are added here to preserve compatible on-disk format.
322 BLK_TYPE_UNKNOWN
= 255, // Not used for on-disk blocks.
326 // Existing block subtypes cannot be changed!
328 enum metadata_blk_subtype
{
333 BLK_SUBTYPE_NO_SUBTYPE
= 0,
335 BLK_SUBTYPE_LV_FAMILY_TREE
,
336 BLK_SUBTYPE_LV_SNAPSHOT_TREE
,
337 BLK_SUBTYPE_LV_ADDR_MAP_TREE
,
338 BLK_SUBTYPE_PV_REFCOUNT_TREE
,
339 BLK_SUBTYPE_LV_UNUSED_SPACE_TREE
,
340 BLK_SUBTYPE_LVF_REFCOUNT_TREE
,
343 // The b-tree that holds blocks to populate MLV for testing.
345 BLK_SUBTYPE_DUMMY_TREE
,
348 // New types are added here to preserve compatible on-disk format.
353 BLK_SUBTYPE_UNKNOWN
= 255, // Not used for on-disk blocks.
355 typedef enum metadata_blk_subtype metadata_blk_subtype_t
;
359 // This block should be in the DSD List. It is not in the DSD list when it
360 // is first created. But when it is modified or killed, it will be included
363 #define BLK_FLAG_IN_DSD_LIST 0x02
366 // On-disk information of LVG.
369 uint32_t lvg_signature
; // A signature that CoreStorage recognizes.
372 // Version numbers can help diagnose problems.
376 // The version of CoreStorage that created the LVG.
378 uint32_t lvg_creator_version
;
381 // The version of CoreStorage that modified the LVG the last time.
383 uint32_t lvg_writer_version
;
386 // The interval to sync MLV metadata in milliseconds.
388 uint16_t lvg_sync_interval_ms
;
391 // Checksum algorithm used for all metadata blocks and data blocks.
393 uint8_t lvg_metadata_cksum_alg
;
396 // Do not punch hole in the LVs on trim, so that the sparse LVs can become
397 // less and less sparse over time.
399 uint8_t lvg_no_punch_hole_on_trim
;
402 // These fields control our forwards/backwards compatibility.
403 // Features fall into three categories: compatible, read-only
404 // compatible, and incompatible. For any given version of the
405 // file system code, you can mount a file-system with any set
406 // of compatible features. If the file system encounters bits
407 // that are set in the read-only compatible features field and
408 // it does not know about those features then it must only mount
409 // the file system read-only. If the file system encounters
410 // any bits set in the incompatible features field that it does
411 // not know about, then it must not mount or modify the file
412 // system in any way.
414 // The idea for these compatibility fields is rather shamelessly
415 // stolen from rocky and ext2.
418 uint64_t lvg_compatible_features
;
419 uint64_t lvg_read_only_compatible_features
;
420 uint64_t lvg_incompatible_features
;
423 // When Soft Snapshot is enabled, this is the minimum granularity the
424 // extents will be updated with new timestamp. This is OK to be 0, so a
425 // predefined constant will be used.
427 uint64_t lvg_soft_snapshot_granularity_nbytes
;
430 // When LV checksum is enabled, this is the minimum granularity of data
431 // being checksummed. This is OK to be 0, so a predefined constant will
434 uint64_t lvg_checksum_granularity_nbytes
;
437 // The min/max versions of CoreStorage that ever wrote to the LVG.
439 uint32_t lvg_min_writer_version
;
440 uint32_t lvg_max_writer_version
;
443 // The following unused fields are reserved so we don't need to break
444 // format compatibility too often if we need more per-LVG fields.
446 uint64_t lvg_unused1
;
447 uint64_t lvg_unused2
;
448 uint64_t lvg_unused3
;
450 typedef struct lvg_info lvg_info_t
;
452 #endif /* _LF_CS_DISK_FORMAT_H */