DF-0792 / panic.txt
========================================================================
DF-0792 panic signature (unpatched #0 kernel, before fix.diff applied)
========================================================================
Trigger: cat /mnt/htest/testfile where the testfile's B-Tree leaf
entries were rewritten offline to reference vol_no=7 (which is
not present in this single-volume HAMMER filesystem).
Path:
cat -> VOP_READ -> hammer_vop_read -> hammer_io_direct_read
vol_no = HAMMER_VOL_DECODE(zone2_offset) = 7
volume = hammer_get_volume(hmp, 7, &error); // NULL, error=ENOENT
if (error == 0 && ...) error = EIO; // skipped, error!=0
if (error == 0) { ... } // skipped, error!=0
hammer_rel_volume(volume, 0); // volume==NULL, BUG
-> hammer_rel_interlock(&volume->io.lock, locked); // NULL deref
Captured from dfbsd-qemu/boot.log immediately after the panic, before
the snapshot revert (boot.log is rewritten by vm.sh reset):
HAMMER(htest) mounted clean, no recovery needed
Fatal user address access from kernel mode from cat at ffffffff80951940
Fatal trap 12: page fault while in kernel mode
cpuid = 2; lapic id = 2
fault virtual address = 0x0
fault code = supervisor read data, page not present
instruction pointer = 0x8:0xffffffff80951940
stack pointer = 0x10:0xfffff80118f34308
frame pointer = 0x10:0xfffff80118f34328
code segment = base 0x0, limit 0xfffff, type 0x1b
= DPL 0, pres 1, long 0, def32 0, gran 1
processor eflags = interrupt enabled, resume, IOPL = 0
current process = 1129 (cat)
current thread = pri 6
kernel: type 12 trap, code=0
CPU2 stopping CPUs: 0x0000003b
stopped
Stopped at hammer_rel_interlock+0x20: movl (%r12),%ebx
db>
========================================================================
This is the bug, exactly as claimed by DF-0792: an unconditional
hammer_rel_volume(volume, 0) call after hammer_get_volume() may have
returned NULL. The "Stopped at hammer_rel_interlock+0x20" matches the
first instruction that touches the NULL volume pointer (the lock word
at offset 0 of struct hammer_volume's io member).
========================================================================