⬢ DragonFlyBSD Kernel Audit
DF-4214 / fix.diff
← back to finding ↓ download raw
--- a/sys/dev/disk/mpt/mpt_raid.c
+++ b/sys/dev/disk/mpt/mpt_raid.c
@@ -133,6 +133,12 @@
 static void mpt_schedule_raid_refresh(struct mpt_softc *mpt);
 
 static uint32_t raid_handler_id = MPT_HANDLER_ID_NONE;
+/*
+ * mpt_reply_handlers[] is global and mpt_register_handler() is idempotent
+ * across controllers (it returns the existing slot), so the handler may
+ * only be deregistered when the LAST mpt_raid personality detaches.
+ */
+static u_int raid_handler_refs;
 
 static const char *
 mpt_vol_type(struct mpt_raid_volume *vol)
@@ -291,6 +297,7 @@
 	handler.reply_handler = mpt_raid_reply_handler;
 	error = mpt_register_handler(mpt, MPT_HANDLER_REPLY, handler,
 				     &raid_handler_id);
+	raid_handler_refs++;
 	if (error != 0) {
 		mpt_prt(mpt, "Unable to register RAID haandler!\n");
 		goto cleanup;
@@ -336,8 +343,9 @@
 	MPT_LOCK(mpt);
 	mpt_terminate_raid_thread(mpt);
 	handler.reply_handler = mpt_raid_reply_handler;
-	mpt_deregister_handler(mpt, MPT_HANDLER_REPLY, handler,
-			       raid_handler_id);
+	if (raid_handler_refs > 0 && --raid_handler_refs == 0)
+		mpt_deregister_handler(mpt, MPT_HANDLER_REPLY, handler,
+				       raid_handler_id);
 	xpt_setup_ccb(&csa->ccb_h, mpt->path, /*priority*/5);
 	csa->ccb_h.func_code = XPT_SASYNC_CB;
 	csa->event_enable = 0;