summaryrefslogtreecommitdiff
path: root/sys/scsi/sd.c
diff options
context:
space:
mode:
authorAlexander Bluhm <bluhm@cvs.openbsd.org>2016-03-17 18:05:40 +0000
committerAlexander Bluhm <bluhm@cvs.openbsd.org>2016-03-17 18:05:40 +0000
commit16951446ab99aa9b4a7285486810ca6158564d48 (patch)
tree2afd67224907283ff7dc486f2ae18a62f9fc8a05 /sys/scsi/sd.c
parent10d348fb0422aec8c3ed708d14327d2ab4b0cc2c (diff)
Do not access the scsi link structure in sdclose() if the disk
device is already dying. Delete the sc_timeout when setting the SDF_DYING flag as the timeout delete in sdclose() may not be reached. OK krw@
Diffstat (limited to 'sys/scsi/sd.c')
-rw-r--r--sys/scsi/sd.c19
1 files changed, 17 insertions, 2 deletions
diff --git a/sys/scsi/sd.c b/sys/scsi/sd.c
index 170a191b205..f9f002a5960 100644
--- a/sys/scsi/sd.c
+++ b/sys/scsi/sd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sd.c,v 1.266 2016/03/16 15:01:55 bluhm Exp $ */
+/* $OpenBSD: sd.c,v 1.267 2016/03/17 18:05:39 bluhm Exp $ */
/* $NetBSD: sd.c,v 1.111 1997/04/02 02:29:41 mycroft Exp $ */
/*-
@@ -305,6 +305,7 @@ sdactivate(struct device *self, int act)
break;
case DVACT_DEACTIVATE:
sc->flags |= SDF_DYING;
+ timeout_del(&sc->sc_timeout);
scsi_xsh_del(&sc->sc_xsh);
break;
}
@@ -496,6 +497,7 @@ sdclose(dev_t dev, int flag, int fmt, struct proc *p)
struct scsi_link *link;
struct sd_softc *sc;
int part = DISKPART(dev);
+ int error = 0;
sc = sdlookup(DISKUNIT(dev));
if (sc == NULL)
@@ -514,14 +516,26 @@ sdclose(dev_t dev, int flag, int fmt, struct proc *p)
if ((sc->flags & SDF_DIRTY) != 0)
sd_flush(sc, 0);
+ if (sc->flags & SDF_DYING) {
+ error = ENXIO;
+ goto die;
+ }
if ((link->flags & SDEV_REMOVABLE) != 0)
scsi_prevent(link, PR_ALLOW,
SCSI_IGNORE_ILLEGAL_REQUEST |
SCSI_IGNORE_NOT_READY | SCSI_SILENT);
+ if (sc->flags & SDF_DYING) {
+ error = ENXIO;
+ goto die;
+ }
link->flags &= ~(SDEV_OPEN | SDEV_MEDIA_LOADED);
if (link->flags & SDEV_EJECTING) {
scsi_start(link, SSS_STOP|SSS_LOEJ, 0);
+ if (sc->flags & SDF_DYING) {
+ error = ENXIO;
+ goto die;
+ }
link->flags &= ~SDEV_EJECTING;
}
@@ -529,9 +543,10 @@ sdclose(dev_t dev, int flag, int fmt, struct proc *p)
scsi_xsh_del(&sc->sc_xsh);
}
+die:
disk_unlock(&sc->sc_dk);
device_unref(&sc->sc_dev);
- return 0;
+ return (error);
}
/*