Files
ext4recovery/test/patch_gdt.py
2026-04-30 11:04:05 +00:00

55 lines
1.5 KiB
Python

#!/usr/bin/env python3
"""
Patch superblock to disable metadata_csum feature flag,
and zero GDT checksum fields for groups 0-12.
All writes go to dm-0 (overlay), nbd0 untouched.
"""
import struct
DEV = '/dev/dm-0'
BLOCK = 4096
BACKUP_SB_BLOCK = 32768
# Feature flag constants
INCOMPAT_64BIT = 0x80
RO_COMPAT_METADATA_CSUM = 0x400
with open(DEV, 'r+b') as f:
# Read primary superblock (already patched to block 0)
f.seek(1024)
sb = bytearray(f.read(1024))
# Check current feature flags
ro_compat = struct.unpack_from('<I', sb, 100)[0]
print(f"ro_compat_features: {ro_compat:#010x}")
print(f"metadata_csum set: {bool(ro_compat & RO_COMPAT_METADATA_CSUM)}")
# Clear metadata_csum
ro_compat &= ~RO_COMPAT_METADATA_CSUM
struct.pack_into('<I', sb, 100, ro_compat)
# Zero superblock checksum
struct.pack_into('<I', sb, 1020, 0)
# Write patched superblock back
f.seek(1024)
f.write(sb)
print("Patched superblock: metadata_csum cleared")
# Now zero bg_checksum in GDT entries for groups 0-12
# bg_checksum is at offset 30 in each 64-byte descriptor
f.seek(BLOCK) # GDT starts at block 1
gdt = bytearray(f.read(13 * 64)) # groups 0-12 only
for grp in range(13):
off = grp * 64
old_csum = struct.unpack_from('<H', gdt, off + 30)[0]
struct.pack_into('<H', gdt, off + 30, 0)
print(f" group {grp:2d}: cleared checksum {old_csum:#06x}")
f.seek(BLOCK)
f.write(gdt)
print("Patched GDT checksums for groups 0-12")
print("Done - try debugfs again")