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


Reply via email to