60 lines
2.3 KiB
Python
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 '')
|
|
|