From 6f13e1d9468edb79908b120923d3f4f2b7b02a20 Mon Sep 17 00:00:00 2001 From: bde Date: Sat, 22 Dec 2018 22:59:11 +0000 Subject: [PATCH] Fix devstat on md devices, second attempt. r341765 depends on g_io_deliver() finishing initialization of the bio, but g_io_deliver() actually destroys the bio. INVARIANTS makes the bug obvious by overwriting the bio with garbage. Restore the old order for calling devstat (except don't restore not calling it for the error case), and translate to the devstat KPI so that this order works. Reviewed by: kib --- sys/dev/md/md.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/sys/dev/md/md.c b/sys/dev/md/md.c index b2f6f912fa62..f138bad5cc5d 100644 --- a/sys/dev/md/md.c +++ b/sys/dev/md/md.c @@ -1241,12 +1241,22 @@ md_kthread(void *arg) error = sc->start(sc, bp); } + if (bp->bio_cmd == BIO_READ || bp->bio_cmd == BIO_WRITE) { + /* + * 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; + bp->bio_resid = (error == -1 ? bp->bio_bcount : 0); + devstat_end_transaction_bio(sc->devstat, bp); + } if (error != -1) { bp->bio_completed = bp->bio_length; g_io_deliver(bp, error); } - if (bp->bio_cmd == BIO_READ || bp->bio_cmd == BIO_WRITE) - devstat_end_transaction_bio(sc->devstat, bp); } }