Files
ext4recovery/misc_tools/interleave_check.py
2026-04-30 11:04:05 +00:00

81 lines
3.2 KiB
Python

CHUNK = 128*512
LV_START = 5120000*512
BSIZE = 4096
# The directory data block is at virtual block 5251104
# virt_byte = 5251104 * 4096 = 21508521984
virt_byte = 5251104 * BSIZE
group = virt_byte // (5*CHUNK)
in_group = virt_byte % (5*CHUNK)
chunk_idx = in_group // CHUNK
intra = in_group % CHUNK
print(f'Virtual byte: {virt_byte}')
print(f'Chunk group: {group}')
print(f'Chunk index: {chunk_idx}')
print(f'Intra: {intra}')
print()
# This is chunk_idx=4 - a PERC metadata chunk
# The PERC stored filesystem data here
# Physical location:
# In our translation, we skip chunk_idx=4
# But if the PERC stored data there, it's at:
# phys = LV_START + group*5*CHUNK + chunk_idx*CHUNK + intra
# (5 chunks per group including metadata chunk)
phys_with_meta = LV_START + group*5*CHUNK + chunk_idx*CHUNK + intra
print(f'Physical byte if 5-chunk groups: {phys_with_meta}')
print(f'Physical sector: {phys_with_meta//512}')
# Also try: physical = LV_START + group*4*CHUNK + ... but for chunk 4
# In our current scheme chunk 4 has no mapping
# But the data must be somewhere on disk
# The PERC presents 5 virtual chunks = 5*64KB = 320KB per group
# Of these, 4 are data and 1 is PERC metadata
# But what if it's the OPPOSITE?
# What if 4 are PERC metadata and only 1 is data? No - we verified 4/5 ratio
# What if the metadata chunk IS stored on disk but at a different offset?
# The PERC stores its own metadata in those chunk positions
# For reading filesystem data that falls there, it must use the metadata chunk
# storage differently
# Let's read what's physically at that location
# The virtual block 5251104 is in chunk group 'group' at chunk position 4
# In the physical layout (5 chunks per group):
# group X physical layout: [data0][data1][data2][data3][meta4]
# Our translation: physical chunk = group*4 + chunk_idx (skipping meta)
# So physical chunk for data chunks 0-3 = group*4 + 0,1,2,3
# And physical chunk for meta = stored AFTER the 4 data chunks = group*4+4?
# But that would mean physical layout is: data0,data1,data2,data3,meta4
# which IS 5 consecutive chunks on disk
# So the physical byte for chunk_idx=4 would be:
phys_consecutive = LV_START + group*5*CHUNK + 4*CHUNK + intra
print(f'Physical byte (consecutive 5-chunk): {phys_consecutive}')
# Read it
with open('/dev/md0','rb') as f:
f.seek(phys_consecutive)
data = f.read(512)
nonzero = sum(1 for b in data if b != 0)
print(f'Nonzero bytes: {nonzero}/512')
print(f'First 32: {data[:32].hex()}')
# Also check: maybe the metadata chunk is interleaved differently
# What if physical layout per group is: [meta0][data1][data2][data3][data4]?
# i.e. metadata chunk is FIRST, not last?
for meta_pos in range(5):
# If metadata is at position meta_pos within each group of 5 physical chunks
# Then for virtual chunk_idx=4 (the one we skip):
# virtual chunks 0,1,2,3 map to physical chunks skipping meta_pos
# virtual chunk 4 IS the metadata chunk
phys_test = LV_START + group*5*CHUNK + meta_pos*CHUNK + intra
with open('/dev/md0','rb') as f:
f.seek(phys_test)
data = f.read(64)
nonzero = sum(1 for b in data if b != 0)
print(f'meta_pos={meta_pos}: phys={phys_test} nonzero={nonzero} first8={data[:8].hex()}')