--- a/sys/vfs/hammer2/hammer2_io.c +++ b/sys/vfs/hammer2/hammer2_io.c @@ -356,6 +356,19 @@ 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. */ for (;;) {