When encountering SCSI error status (ret > 0), accounting is left to scsi_handle_rw_error(), but the BLOCK_ERROR_ACTION_IGNORE path in turn leaves accounting (block_acct_done()) to the caller, so neither side does it. Fix this by unconditionally calling block_acct_done() in the IGNORE path. Yes, this will often result in it being called twice, but that is a no-op, as block_acct_done() resets the cookie type to BLOCK_ACCT_NONE, and will only do accounting if the type is not BLOCK_ACCT_NONE.
(And given that the conditions on who does what accounting are quite confusing in scsi-disk, for me at least, I prefer this unconditional call rather than guard it with a condition that has no obvious reason.) Signed-off-by: Hanna Czenczek <[email protected]> --- hw/scsi/scsi-disk.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c index 1b0cce128c5..92b63b64d56 100644 --- a/hw/scsi/scsi-disk.c +++ b/hw/scsi/scsi-disk.c @@ -318,6 +318,13 @@ static bool scsi_handle_rw_error(SCSIDiskReq *r, int ret, bool acct_failed) return true; case BLOCK_ERROR_ACTION_IGNORE: + /* + * The caller may have already finalized the accounting cookie + * (e.g. scsi_dma_complete() for ret < 0), but calling + * block_acct_done() afterwards is fine (just a no-op). Just + * make sure all cookies are indeed accounted at some point. + */ + block_acct_done(blk_get_stats(s->qdev.conf.blk), &r->acct); return false; case BLOCK_ERROR_ACTION_STOP: -- 2.55.0
