Improve detach handling: close races, flush queue.
This commit is contained in:
parent
b56ca46588
commit
249b0e8586
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user