@@ -29,15 +29,41 @@ class NxSuperblock(Object):
2929 __struct__ = c_apfs .nx_superblock
3030 object : c_apfs .nx_superblock
3131
32- def __init__ (self , * args , ** kwargs ):
33- super ().__init__ (* args , ** kwargs )
32+ def check (self ) -> None :
33+ """Check the validity of the superblock."""
34+ if not self .is_valid ():
35+ raise Error ("Invalid nx_superblock checksum" )
36+
37+ if self .type != c_apfs .OBJECT_TYPE .NX_SUPERBLOCK :
38+ raise Error ("Invalid nx_superblock type" )
39+
40+ if not self .is_ephemeral :
41+ raise Error ("Invalid nx_superblock storage type" )
3442
3543 if self .object .nx_magic .to_bytes (4 , "big" ) != c_apfs .NX_MAGIC :
3644 raise Error (
3745 "Invalid nx_superblock magic "
3846 f"(expected { c_apfs .NX_MAGIC !r} , got { self .object .nx_magic .to_bytes (4 , 'big' )!r} )"
3947 )
4048
49+ def compare (self , other : NxSuperblock ) -> None :
50+ """Compare this superblock to another superblock."""
51+ if self .header .o_xid < other .header .o_xid :
52+ raise Error ("Lower xid than other superblock" )
53+
54+ for attr in (
55+ "nx_uuid" ,
56+ "nx_fusion_uuid" ,
57+ "nx_block_size" ,
58+ "nx_block_count" ,
59+ "nx_xp_desc_blocks" ,
60+ "nx_xp_data_blocks" ,
61+ "nx_xp_desc_base" ,
62+ "nx_xp_data_base" ,
63+ ):
64+ if getattr (self .object , attr ) != getattr (other .object , attr ):
65+ raise Error (f"Mismatch on { attr } " )
66+
4167 @cached_property
4268 def block_size (self ) -> int :
4369 """The block size of the container."""
@@ -66,14 +92,20 @@ def uuid(self) -> UUID:
6692 @cached_property
6793 def checkpoint_objects (self ) -> list [CheckpointMap | NxSuperblock ]:
6894 """All checkpoint objects in the container."""
69- return list (_read_checkpoint_objects (self .container , self .object .nx_xp_desc_base , self .object .nx_xp_desc_len ))
95+ # TODO: Rework this a bit to be more accurate
96+ return list (
97+ _read_checkpoint_objects (self .container , self .object .nx_xp_desc_base , self .object .nx_xp_desc_blocks )
98+ )
7099
71100 @cached_property
72101 def ephemeral_objects (self ) -> dict [int , Object ]:
73102 """All ephemeral objects in the container."""
103+ # TODO: I don't think this is correct
74104 return {
75105 obj .oid : obj
76- for obj in _read_checkpoint_objects (self .container , self .object .nx_xp_data_base , self .object .nx_xp_data_len )
106+ for obj in _read_checkpoint_objects (
107+ self .container , self .object .nx_xp_data_base , self .object .nx_xp_data_blocks
108+ )
77109 }
78110
79111 @cached_property
0 commit comments