summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordlg <dlg@openbsd.org>2014-09-29 00:07:55 +0000
committerdlg <dlg@openbsd.org>2014-09-29 00:07:55 +0000
commit8bc857bd7bc9bcad1c1e2f1e471da9e5ce59706c (patch)
tree56fef15fda07f6aea4d67dd432ac9d1a2e28767d
parentProperly serialize closing our vnode. Fixes the occasional panic during (diff)
downloadwireguard-openbsd-8bc857bd7bc9bcad1c1e2f1e471da9e5ce59706c.tar.xz
wireguard-openbsd-8bc857bd7bc9bcad1c1e2f1e471da9e5ce59706c.zip
correctly decrement the C_SCSIXFER reference count in wdc_xfer flags
if the ata stack xfer free path is called before teh scsi xfer free path. this fixes a leak. in the vast majority of uses (eg, filesystems mounted on cd(4) via atapiscsi(4)) the scsi xfer free is always done first. however, if you're doing ioctls (eg, cdio(1)), the scsi ref is held over to the ioctl completion path, so the ata xfer free happens first. problem found by patrick keshishian who did some excellent work debugging this and providing the right fix for it. ok jmatthew@
-rw-r--r--sys/dev/ic/wdc.c7
1 files changed, 5 insertions, 2 deletions
diff --git a/sys/dev/ic/wdc.c b/sys/dev/ic/wdc.c
index 6ba24bab0b0..696131f4da5 100644
--- a/sys/dev/ic/wdc.c
+++ b/sys/dev/ic/wdc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: wdc.c,v 1.126 2014/09/14 14:17:25 jsg Exp $ */
+/* $OpenBSD: wdc.c,v 1.127 2014/09/29 00:07:55 dlg Exp $ */
/* $NetBSD: wdc.c,v 1.68 1999/06/23 19:00:17 bouyer Exp $ */
/*
* Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved.
@@ -1974,7 +1974,10 @@ wdc_free_xfer(struct channel_softc *chp, struct wdc_xfer *xfer)
s = splbio();
chp->ch_flags &= ~WDCF_ACTIVE;
TAILQ_REMOVE(&chp->ch_queue->sc_xfer, xfer, c_xferchain);
- put = !ISSET(xfer->c_flags, C_SCSIXFER);
+ if (ISSET(xfer->c_flags, C_SCSIXFER))
+ CLR(xfer->c_flags, C_SCSIXFER);
+ else
+ put = 1;
splx(s);
if (put)