Improve detach handling: close races, flush queue.

This commit is contained in:
Alexander Motin 2008-11-23 14:02:06 +00:00
parent b56ca46588
commit 249b0e8586

View File

@ -184,9 +184,10 @@ mmcsd_detach(device_t dev)
msleep(sc, &sc->sc_mtx, PRIBIO, "detach", 0);
MMCSD_UNLOCK(sc);
/* Flush the request queue. */
bioq_flush(&sc->bio_queue, NULL, ENXIO);
/* kill disk */
disk_destroy(sc->disk);
/* XXX destroy anything in queue */
MMCSD_LOCK_DESTROY(sc);
@ -212,9 +213,14 @@ mmcsd_strategy(struct bio *bp)
sc = (struct mmcsd_softc *)bp->bio_disk->d_drv1;
MMCSD_LOCK(sc);
if (sc->running > 0) {
bioq_disksort(&sc->bio_queue, bp);
wakeup(sc);
MMCSD_UNLOCK(sc);
} else {
MMCSD_UNLOCK(sc);
biofinish(bp, NULL, ENXIO);
}
}
static daddr_t
@ -380,18 +386,16 @@ mmcsd_task(void *arg)
device_t dev;
dev = sc->dev;
while (sc->running) {
while (1) {
MMCSD_LOCK(sc);
do {
bp = bioq_first(&sc->bio_queue);
if (sc->running == 0)
goto out;
bp = bioq_takefirst(&sc->bio_queue);
if (bp == NULL)
msleep(sc, &sc->sc_mtx, PRIBIO, "jobqueue", 0);
} while (bp == NULL && sc->running);
if (bp)
bioq_remove(&sc->bio_queue, bp);
} while (bp == NULL);
MMCSD_UNLOCK(sc);
if (!sc->running)
break;
if (bp->bio_cmd != BIO_READ && mmc_get_read_only(dev)) {
bp->bio_error = EROFS;
bp->bio_resid = bp->bio_bcount;
@ -419,9 +423,8 @@ mmcsd_task(void *arg)
}
biodone(bp);
}
out:
/* tell parent we're done */
MMCSD_LOCK(sc);
sc->running = -1;
wakeup(sc);
MMCSD_UNLOCK(sc);