--- a/sys/vfs/hammer2/hammer2_io.c +++ b/sys/vfs/hammer2/hammer2_io.c @@ -353,14 +353,26 @@ dio->bp->b_flags &= ~B_AGE; /* dio->bp->b_debug_info2 = dio; */ } if (hammer2_df2661_fail_inode_read > 0 && btype == HAMMER2_BREF_TYPE_INODE && hmp->voldata.volu_size == 0x20000000ULL) { /* DF-2661 fault injection: only the 512MB test volume, * never the guest root fs */ --hammer2_df2661_fail_inode_read; error = EIO; } dio->error = error; + /* + * DF-2661: If the I/O failed, dispose of the buffer now. Leaving + * dio->bp set with DIO_GOOD clear violates the DIO state machine: + * any subsequent accessor that acquires DIO_INPROG expects + * dio->bp == NULL (and asserts it), and on non-INVARIANTS kernels + * the DOP_NEW path would overwrite the pointer without releasing + * the buffer, orphaning a buffer-lock. + */ + if (error && dio->bp) { + brelse(dio->bp); + dio->bp = NULL; + } /* * Clear INPROG and WAITING, set GOOD wake up anyone waiting.