⬢ DragonFlyBSD Kernel Audit
DF-3983 / fix.diff
← back to finding ↓ download raw
--- a/sys/dev/disk/sbp/sbp.c
+++ b/sys/dev/disk/sbp/sbp.c
@@ -1174,8 +1174,14 @@
 
 	if(fw_asyreq(xfer->fc, -1, xfer) != 0){
 			sbp_xfer_free(xfer);
-			ocb->ccb->ccb_h.status = CAM_REQ_INVALID;
-			xpt_done(ocb->ccb);
+			/* DF-3983: the ocb is still queued on sdev->ocbs with
+			 * its timeout armed and dmamap loaded; complete it
+			 * exactly once via the abort path instead of a bare
+			 * xpt_done that leaves it queued and armed. */
+			crit_enter();
+			STAILQ_REMOVE(&ocb->sdev->ocbs, ocb, sbp_ocb, ocb);
+			crit_exit();
+			sbp_abort_ocb(ocb, CAM_REQ_INVALID);
 	}
 }