diff options
-rw-r--r-- | sys/dev/usb/umass.c | 11 | ||||
-rw-r--r-- | sys/kern/vfs_default.c | 14 | ||||
-rw-r--r-- | sys/kern/vfs_subr.c | 18 | ||||
-rw-r--r-- | sys/scsi/sd.c | 35 | ||||
-rw-r--r-- | sys/scsi/sdvar.h | 3 |
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 */ |