summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/dev/usb/umass.c11
-rw-r--r--sys/kern/vfs_default.c14
-rw-r--r--sys/kern/vfs_subr.c18
-rw-r--r--sys/scsi/sd.c35
-rw-r--r--sys/scsi/sdvar.h3
5 files changed, 55 insertions, 26 deletions
diff --git a/sys/dev/usb/umass.c b/sys/dev/usb/umass.c
index 294c7bdd1b8..0752071aeae 100644
--- a/sys/dev/usb/umass.c
+++ b/sys/dev/usb/umass.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: umass.c,v 1.52 2007/06/14 10:11:16 mbalmer Exp $ */
+/* $OpenBSD: umass.c,v 1.53 2007/09/15 19:22:18 bluhm Exp $ */
/* $NetBSD: umass.c,v 1.116 2004/06/30 05:53:46 mycroft Exp $ */
/*
@@ -669,6 +669,15 @@ umass_detach(struct device *self, int flags)
/* Wait for processes to go away. */
usb_detach_wait(&sc->sc_dev);
}
+
+ /* Free the buffers via callback. */
+ if (sc->transfer_state != TSTATE_IDLE && sc->transfer_priv) {
+ sc->transfer_state = TSTATE_IDLE;
+ sc->transfer_cb(sc, sc->transfer_priv,
+ sc->transfer_datalen,
+ STATUS_WIRE_FAILED);
+ sc->transfer_priv = NULL;
+ }
splx(s);
scbus = sc->bus;
diff --git a/sys/kern/vfs_default.c b/sys/kern/vfs_default.c
index b36090ffcb7..df06e7a0358 100644
--- a/sys/kern/vfs_default.c
+++ b/sys/kern/vfs_default.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vfs_default.c,v 1.34 2007/06/01 23:47:56 deraadt Exp $ */
+/* $OpenBSD: vfs_default.c,v 1.35 2007/09/15 19:22:18 bluhm Exp $ */
/*
* Portions of this code are:
@@ -68,6 +68,18 @@ vop_generic_revoke(void *v)
vp = ap->a_vp;
+ if (vp->v_type == VBLK && vp->v_specinfo != 0) {
+ struct mount *mp = vp->v_specmountpoint;
+
+ /*
+ * If we have a mount point associated with the vnode, we must
+ * flush it out now, as to not leave a dangling zombie mount
+ * point laying around in VFS.
+ */
+ if (mp != NULL && !vfs_busy(mp, VB_WRITE|VB_WAIT))
+ dounmount(mp, MNT_FORCE | MNT_DOOMED, p, NULL);
+ }
+
if (vp->v_flag & VALIASED) {
/*
* If a vgone (or vclean) is already in progress,
diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c
index 7f192fc9767..752b7bbc652 100644
--- a/sys/kern/vfs_subr.c
+++ b/sys/kern/vfs_subr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vfs_subr.c,v 1.156 2007/09/07 15:00:20 art Exp $ */
+/* $OpenBSD: vfs_subr.c,v 1.157 2007/09/15 19:22:18 bluhm Exp $ */
/* $NetBSD: vfs_subr.c,v 1.53 1996/04/22 01:39:13 christos Exp $ */
/*
@@ -1006,8 +1006,6 @@ vgonel(struct vnode *vp, struct proc *p)
{
struct vnode *vq;
struct vnode *vx;
- struct mount *mp;
- int flags;
/*
* If a vgone (or vclean) is already in progress,
@@ -1061,20 +1059,6 @@ vgonel(struct vnode *vp, struct proc *p)
vx->v_flag &= ~VALIASED;
vp->v_flag &= ~VALIASED;
}
-
- /*
- * If we have a mount point associated with the vnode, we must
- * flush it out now, as to not leave a dangling zombie mount
- * point laying around in VFS.
- */
- mp = vp->v_specmountpoint;
- if (mp != NULL) {
- if (!vfs_busy(mp, VB_WRITE|VB_WAIT)) {
- flags = MNT_FORCE | MNT_DOOMED;
- dounmount(mp, flags, p, NULL);
- }
- }
-
FREE(vp->v_specinfo, M_VNODE);
vp->v_specinfo = NULL;
}
diff --git a/sys/scsi/sd.c b/sys/scsi/sd.c
index 37253fd686b..ea85c9bb31a 100644
--- a/sys/scsi/sd.c
+++ b/sys/scsi/sd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sd.c,v 1.136 2007/06/23 19:19:49 krw Exp $ */
+/* $OpenBSD: sd.c,v 1.137 2007/09/15 19:22:18 bluhm Exp $ */
/* $NetBSD: sd.c,v 1.111 1997/04/02 02:29:41 mycroft Exp $ */
/*-
@@ -257,6 +257,7 @@ sdattach(struct device *parent, struct device *self, void *aux)
int
sdactivate(struct device *self, enum devact act)
{
+ struct sd_softc *sd = (struct sd_softc *)self;
int rv = 0;
switch (act) {
@@ -264,9 +265,8 @@ sdactivate(struct device *self, enum devact act)
break;
case DVACT_DEACTIVATE:
- /*
- * Nothing to do; we key off the device's DVF_ACTIVATE.
- */
+ sd->flags |= SDF_DYING;
+ sd_kill_buffers(sd);
break;
}
@@ -320,6 +320,10 @@ sdopen(dev_t dev, int flag, int fmt, struct proc *p)
sd = sdlookup(unit);
if (sd == NULL)
return (ENXIO);
+ if (sd->flags & SDF_DYING) {
+ device_unref(&sd->sc_dev);
+ return (ENXIO);
+ }
sc_link = sd->sc_link;
SC_DEBUG(sc_link, SDEV_DB1,
@@ -443,7 +447,11 @@ sdclose(dev_t dev, int flag, int fmt, struct proc *p)
sd = sdlookup(DISKUNIT(dev));
if (sd == NULL)
- return ENXIO;
+ return (ENXIO);
+ if (sd->flags & SDF_DYING) {
+ device_unref(&sd->sc_dev);
+ return (ENXIO);
+ }
if ((error = sdlock(sd)) != 0) {
device_unref(&sd->sc_dev);
@@ -499,6 +507,10 @@ sdstrategy(struct buf *bp)
bp->b_error = ENXIO;
goto bad;
}
+ if (sd->flags & SDF_DYING) {
+ bp->b_error = ENXIO;
+ goto bad;
+ }
SC_DEBUG(sd->sc_link, SDEV_DB2, ("sdstrategy: %ld bytes @ blk %d\n",
bp->b_bcount, bp->b_blkno));
@@ -598,6 +610,9 @@ sdstart(void *v)
int nblks, cmdlen, error;
struct partition *p;
+ if (sd->flags & SDF_DYING)
+ return;
+
SC_DEBUG(sc_link, SDEV_DB2, ("sdstart\n"));
splassert(IPL_BIO);
@@ -827,7 +842,11 @@ sdioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
sd = sdlookup(DISKUNIT(dev));
if (sd == NULL)
- return ENXIO;
+ return (ENXIO);
+ if (sd->flags & SDF_DYING) {
+ device_unref(&sd->sc_dev);
+ return (ENXIO);
+ }
SC_DEBUG(sd->sc_link, SDEV_DB2, ("sdioctl 0x%lx\n", cmd));
@@ -1140,6 +1159,10 @@ sdsize(dev_t dev)
sd = sdlookup(DISKUNIT(dev));
if (sd == NULL)
return -1;
+ if (sd->flags & SDF_DYING) {
+ size = -1;
+ goto exit;
+ }
part = DISKPART(dev);
omask = sd->sc_dk.dk_openmask & (1 << part);
diff --git a/sys/scsi/sdvar.h b/sys/scsi/sdvar.h
index b82666ba5f2..e525098edaa 100644
--- a/sys/scsi/sdvar.h
+++ b/sys/scsi/sdvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: sdvar.h,v 1.11 2007/06/23 19:19:49 krw Exp $ */
+/* $OpenBSD: sdvar.h,v 1.12 2007/09/15 19:22:18 bluhm Exp $ */
/* $NetBSD: sdvar.h,v 1.7 1998/08/17 00:49:03 mycroft Exp $ */
/*-
@@ -68,6 +68,7 @@ struct sd_softc {
#define SDF_ANCIENT 0x10 /* disk is ancient; for minphys */
#define SDF_DIRTY 0x20 /* disk is dirty; needs cache flush */
#define SDF_FLUSHING 0x40 /* flushing, for sddone() */
+#define SDF_DYING 0x80 /* dying, when deactivated */
struct scsi_link *sc_link; /* contains our targ, lun, etc. */
struct disk_parms {
u_long heads; /* number of heads */