DragonFlyBSD Kernel Audit
DF-1699 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/dev/disk/vn/vn.c b/sys/dev/disk/vn/vn.c
--- a/sys/dev/disk/vn/vn.c
+++ b/sys/dev/disk/vn/vn.c
@@ -127,6 +127,7 @@
 	struct vnode	*sc_vp;		/* vnode if not NULL		*/
 	vm_object_t	sc_object;	/* backing object if not NULL	*/
 	struct ucred	*sc_cred;	/* credentials 			*/
+	struct lwkt_token sc_tok;	/* serializes strategy vs detach	*/
 	int		 sc_maxactive;	/* max # of active requests 	*/
 	struct buf	 sc_tab;	/* transfer queue 		*/
 	u_long		 sc_options;	/* options 			*/
@@ -194,6 +195,7 @@
 	struct vn_softc *vn;
 
 	vn = kmalloc(sizeof *vn, M_VN, M_WAITOK | M_ZERO);
+	lwkt_token_init(&vn->sc_tok, "vn tok");
 	return vn;
 }
 
@@ -272,12 +274,15 @@
 	vn = dev->si_drv1;
 	KKASSERT(vn != NULL);
 
+	lwkt_gettoken(&vn->sc_tok);
+
 	bp = bio->bio_buf;
 
 	IFOPT(vn, VN_DEBUG)
 		kprintf("vnstrategy(%p): unit %d\n", bp, unit);
 
 	if ((vn->sc_flags & VNF_INITED) == 0) {
+		lwkt_reltoken(&vn->sc_tok);
 		bp->b_error = ENXIO;
 		bp->b_flags |= B_ERROR;
 		biodone(bio);
@@ -720,6 +725,7 @@
 static void
 vnclear(struct vn_softc *vn)
 {
+	lwkt_gettoken(&vn->sc_tok);
 	IFOPT(vn, VN_FOLLOW)
 		kprintf("vnclear(%p): vp=%p\n", vn, vn->sc_vp);
 	vn->sc_flags &= ~VNF_INITED;
@@ -742,6 +748,7 @@
 	disk_unprobe(&vn->sc_disk);
 
 	vn->sc_size = 0;
+	lwkt_reltoken(&vn->sc_tok);
 }
 
 /*