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

60 lines
2.3 KiB
Python

CHUNK = 128*512
LV_START = 5120000*512
BSIZE = 4096
# Root dir data block = 9262
# We read this successfully, so our translation works for it
# Let's verify: block 9262 as filesystem block (offset from LV start)
# vs block 9262 as PERC virtual block
fs_virt_byte = 9262 * BSIZE # filesystem block offset from LV start
perc_virt_byte = 9262 * BSIZE # same number, different interpretation
# As filesystem block (what our NBD server does):
# The NBD server presents a virtual address space where block N = byte N*4096
# And applies the 4/5 chunk translation to convert to physical
fs_group = fs_virt_byte // (5*CHUNK)
fs_in_group = fs_virt_byte % (5*CHUNK)
fs_chunk_idx = fs_in_group // CHUNK
fs_intra = fs_in_group % CHUNK
print(f'Block 9262 as filesystem virtual (via NBD translation):')
print(f' virt_byte={fs_virt_byte}')
print(f' chunk_group={fs_group} chunk_idx={fs_chunk_idx} intra={fs_intra}')
if fs_chunk_idx != 4:
phys = LV_START + fs_group*4*CHUNK + fs_chunk_idx*CHUNK + fs_intra
print(f' physical={phys}')
with open('/dev/md0','rb') as f:
f.seek(phys)
data = f.read(64)
print(f' first 32: {data[:32].hex()}')
# We know from istat that block 9262 contains the root directory
# and we verified it has valid directory entries
# So the block numbers ARE filesystem-level, and our translation IS correct
# Now: why does block 5251104 (var dir data) fall in a metadata chunk?
# 5251104 * 4096 = 21508521984
# group = 21508521984 // (5*65536) = 65638
# in_group = 21508521984 % (5*65536) = 262144 = 4*65536
# chunk_idx = 4 -> METADATA
# This means the /var directory data genuinely falls in a PERC metadata slot
# The PERC would have stored its OWN metadata there
# and the filesystem data for block 5251104 would need to be
# at a DIFFERENT physical location
# Unless... the ext4 filesystem uses block numbers differently
# In ext4 with flex_bg, block numbers might be relative to something else
# Let's check: what block does istat say for /var?
# We need to run istat on inode 1310721
import subprocess
r = subprocess.run(['istat', '/dev/nbd0', '1310721'],
capture_output=True, text=True)
print()
print('istat output for /var (inode 1310721):')
print(r.stdout)
print(r.stderr[:200] if r.stderr else '')