CHUNK    = 128*512
LV_START = 5120000*512
BSIZE    = 4096

# We know block 9262 is the root directory data block
# and it reads correctly. Let's find its chunk position.
known_virt = 9262 * BSIZE
group     = known_virt // (5*CHUNK)
in_group  = known_virt % (5*CHUNK)
chunk_idx = in_group // CHUNK
intra     = in_group % CHUNK

print(f'Root dir block 9262: chunk_group={group} chunk_idx={chunk_idx}')

# Now check the 5th chunk in the SAME group
meta_virt = group * 5 * CHUNK + 4 * CHUNK
print(f'5th chunk in same group at phys byte: {LV_START + meta_virt}')

# Read 512 bytes from the 5th chunk
with open('/dev/md0','rb') as f:
    f.seek(LV_START + meta_virt)
    data = f.read(512)
print(f'First 64 bytes: {data[:64].hex()}')
print()

# Compare with what we read from the PERC metadata chunk earlier
# istat showed volumes dir data at block 5251104 (chunk_idx=4)
# Let's check if that block's data might actually be at a different
# physical location - maybe the PERC remapped it

# What if for chunk_idx=4, the data is stored in a DIFFERENT disk's
# corresponding chunk? i.e. the PERC uses the 5th physical chunk
# on a different disk?

# Our disk order: sda(0) sde(1) sdd(2) sdc(3)
# In RAID0: chunk N goes to disk N%4
# For a group of 5 virtual chunks:
# virtual chunk 0 -> disk 0
# virtual chunk 1 -> disk 1  
# virtual chunk 2 -> disk 2
# virtual chunk 3 -> disk 3
# virtual chunk 4 -> ??? (metadata chunk - no disk?)

# BUT: if the physical layout has 5 chunks per group across 4 disks
# maybe it's: disk0 gets chunks 0,4 / disk1 gets chunk1 / etc?
# Or maybe all 5 chunks exist on disk but chunk 4 is PERC metadata
# that happens to occupy the same space as filesystem data?

# The PERC sector-level metadata we found earlier:
# Each 64KB metadata chunk stores 512 bytes per sector of the adjacent data
# That's 128 sectors * 512 bytes = 64KB of per-sector checksums/metadata
# So the 5th chunk IS pure PERC internal data, not filesystem data

# This means: filesystem block 5251104 maps to virtual chunk_idx=4
# BUT the actual filesystem data for that block must be stored differently
# OR the block number in the inode is a VIRTUAL block number
# that the PERC translates differently than we think

# Let's check: what if block numbers in inodes are PERC virtual block numbers?
# PERC virtual block 5251104:
# In PERC virtual space (5 chunks per group):
# group = 5251104*4096 // (5*CHUNK) = ?
perc_virt_byte = 5251104 * BSIZE
perc_group = perc_virt_byte // (5*CHUNK)
perc_in_group = perc_virt_byte % (5*CHUNK)
perc_chunk_idx = perc_in_group // CHUNK
perc_intra = perc_in_group % CHUNK

print(f'If block 5251104 is PERC virtual:')
print(f'  PERC group={perc_group} chunk_idx={perc_chunk_idx} intra={perc_intra}')

# And the physical location would be:
# physical = LV_START + perc_group*4*CHUNK + perc_chunk_idx*CHUNK + perc_intra
if perc_chunk_idx != 4:
    phys = LV_START + perc_group*4*CHUNK + perc_chunk_idx*CHUNK + perc_intra
    print(f'  Physical byte: {phys}')
    with open('/dev/md0','rb') as f:
        f.seek(phys)
        data = f.read(BSIZE)
    nonzero = sum(1 for b in data if b != 0)
    print(f'  Nonzero: {nonzero}/4096')
    print(f'  First 32: {data[:32].hex()}')
    
    # Try to parse as directory
    import struct
    off = 0
    print('  Directory entries:')
    while off < BSIZE-8:
        ino     = struct.unpack_from('<I', data, off)[0]
        rec_len = struct.unpack_from('<H', data, off+4)[0]
        name_len= data[off+6]
        ftype   = data[off+7]
        if rec_len < 8: break
        if ino > 0 and name_len > 0:
            name = data[off+8:off+8+name_len].decode('utf-8',errors='replace')
            tname = {1:'file',2:'dir',7:'link'}.get(ftype,'?')
            print(f'    {tname} inode={ino} {name!r}')
        off += rec_len
else:
    print(f'  Still in metadata chunk!')
