diff options
author | 2014-09-29 00:07:55 +0000 | |
---|---|---|
committer | 2014-09-29 00:07:55 +0000 | |
commit | 8bc857bd7bc9bcad1c1e2f1e471da9e5ce59706c (patch) | |
tree | 56fef15fda07f6aea4d67dd432ac9d1a2e28767d | |
parent | Properly serialize closing our vnode. Fixes the occasional panic during (diff) | |
download | wireguard-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.c | 7 |
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) |