DF-4063 / fix.diff
--- a/sys/dev/disk/fd/fd.c +++ b/sys/dev/disk/fd/fd.c @@ -2275,16 +2275,21 @@ /* now do the format */ dev_dstrategy(dev, &bp->b_bio1); - /* ...and wait for it to complete */ - rv = biowait_timeout(&bp->b_bio1, "fdform", 20 * hz); - if (rv == EWOULDBLOCK) { - /* timed out */ - rv = EIO; -#if 0 - device_unbusy(fd->dev); -#endif - biodone(&bp->b_bio1); - } + /* + * ...and wait for it to complete. The controller state machine + * always completes every buffer it dequeues (progress is bounded + * by fd_iotimeout and retrier(), and parked states are kicked by + * fd_turnoff every 4 s), and the bio stays linked in + * fdc->bio_queue and owned by the driver until then. It is NOT + * safe to biodone() and relpbuf() the buffer early just because + * we got tired of waiting: the driver would later double-complete + * the bio and the recycled pbuf would be corrupted under it + * (double TAILQ insertion of the same bio -> queue corruption). + * + * DF-4063: the old 20 s biowait_timeout + manual biodone() did + * exactly that and reliably panicked the kernel. + */ + rv = biowait(&bp->b_bio1, "fdform"); if (bp->b_flags & B_ERROR) rv = bp->b_error; /* |