--- a/sys/dev/raid/ida/ida_disk.c +++ b/sys/dev/raid/ida/ida_disk.c @@ -107,6 +107,7 @@ drv = idad_getsoftc(dev); if (drv == NULL) return (ENXIO); + drv->opencount++; #if 0 bzero(&info, sizeof(info)); info.d_media_blksize = drv->secsize; /* mandatory */ @@ -132,6 +133,7 @@ drv = idad_getsoftc(dev); if (drv == NULL) return (ENXIO); + drv->opencount--; return (0); } @@ -305,6 +307,16 @@ struct idad_softc *drv; drv = (struct idad_softc *)device_get_softc(dev); + + /* + * DF-5046: do not free the softc under open descriptors or + * in-flight bios; disk_destroy() does not drain them. + */ + if (drv->opencount > 0) { + device_printf(dev, "disk is open (count %d)\n", + drv->opencount); + return (EBUSY); + } devstat_remove_entry(&drv->stats); disk_destroy(&drv->disk); return (0); --- a/sys/dev/raid/ida/idavar.h +++ b/sys/dev/raid/ida/idavar.h @@ -179,6 +179,7 @@ int secsize; int secperunit; int flags; + int opencount; /* DF-5046: open fds gate detach */ }; struct ida_board {