Index: sys/dev/md/md.c =================================================================== --- sys/dev/md/md.c +++ sys/dev/md/md.c @@ -164,6 +164,9 @@ static int md_malloc_wait; SYSCTL_INT(_vm, OID_AUTO, md_malloc_wait, CTLFLAG_RW, &md_malloc_wait, 0, "Allow malloc to wait for memory allocations"); +static int md_direct; +SYSCTL_INT(_vm, OID_AUTO, md_direct, CTLFLAG_RW, &md_direct, 0, + "XXX"); #if defined(MD_ROOT) && !defined(MD_ROOT_FSTYPE) #define MD_ROOT_FSTYPE "ufs" @@ -471,10 +474,29 @@ g_md_start(struct bio *bp) { struct md_s *sc; + int error; sc = bp->bio_to->geom->softc; if ((bp->bio_cmd == BIO_READ) || (bp->bio_cmd == BIO_WRITE)) { devstat_start_transaction_bio(sc->devstat, bp); + if (md_direct != 0) { + error = sc->start(sc, bp); + + /* + * Devstat uses (bio_bcount, bio_resid) for + * determining the length of the completed part + * of the i/o. g_io_deliver() will translate + * from bio_completed to that, but it also + * destroys the bio so we must do our own + * translation. + */ + bp->bio_bcount = bp->bio_length; + devstat_end_transaction_bio(sc->devstat, bp); + + bp->bio_completed = bp->bio_length - bp->bio_resid; + g_io_deliver(bp, error); + return; + } } mtx_lock(&sc->queue_mtx); bioq_disksort(&sc->bio_queue, bp);