Collecting block device statistics, by Richard W.M. Jones.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3760 c046a42c-6fe2-441c-8c8c-71466251a162
diff --git a/block.c b/block.c
index ca8d8c1..3cb3cc2 100644
--- a/block.c
+++ b/block.c
@@ -521,8 +521,11 @@
             return ret;
         else if (ret != len)
             return -EINVAL;
-        else
+        else {
+	    bs->rd_bytes += (unsigned) len;
+	    bs->rd_ops ++;
             return 0;
+	}
     } else {
         return drv->bdrv_read(bs, sector_num, buf, nb_sectors);
     }
@@ -553,8 +556,11 @@
             return ret;
         else if (ret != len)
             return -EIO;
-        else
+        else {
+	    bs->wr_bytes += (unsigned) len;
+	    bs->wr_ops ++;
             return 0;
+	}
     } else {
         return drv->bdrv_write(bs, sector_num, buf, nb_sectors);
     }
@@ -902,6 +908,24 @@
         term_printf("\n");
     }
 }
+
+/* The "info blockstats" command. */
+void bdrv_info_stats (void)
+{
+    BlockDriverState *bs;
+
+    for (bs = bdrv_first; bs != NULL; bs = bs->next) {
+	term_printf ("%s:"
+		     " rd_bytes=%" PRIu64
+		     " wr_bytes=%" PRIu64
+		     " rd_operations=%" PRIu64
+		     " wr_operations=%" PRIu64
+		     "\n",
+		     bs->device_name,
+		     bs->rd_bytes, bs->wr_bytes,
+		     bs->rd_ops, bs->wr_ops);
+    }
+}
 #endif
 
 void bdrv_get_backing_filename(BlockDriverState *bs,
@@ -1064,6 +1088,7 @@
                                 BlockDriverCompletionFunc *cb, void *opaque)
 {
     BlockDriver *drv = bs->drv;
+    BlockDriverAIOCB *ret;
 
     if (!drv)
         return NULL;
@@ -1076,7 +1101,15 @@
         buf += 512;
     }
 
-    return drv->bdrv_aio_read(bs, sector_num, buf, nb_sectors, cb, opaque);
+    ret = drv->bdrv_aio_read(bs, sector_num, buf, nb_sectors, cb, opaque);
+
+    if (ret) {
+	/* Update stats even though technically transfer has not happened. */
+	bs->rd_bytes += (unsigned) nb_sectors * SECTOR_SIZE;
+	bs->rd_ops ++;
+    }
+
+    return ret;
 }
 
 BlockDriverAIOCB *bdrv_aio_write(BlockDriverState *bs, int64_t sector_num,
@@ -1084,6 +1117,7 @@
                                  BlockDriverCompletionFunc *cb, void *opaque)
 {
     BlockDriver *drv = bs->drv;
+    BlockDriverAIOCB *ret;
 
     if (!drv)
         return NULL;
@@ -1093,7 +1127,15 @@
         memcpy(bs->boot_sector_data, buf, 512);
     }
 
-    return drv->bdrv_aio_write(bs, sector_num, buf, nb_sectors, cb, opaque);
+    ret = drv->bdrv_aio_write(bs, sector_num, buf, nb_sectors, cb, opaque);
+
+    if (ret) {
+	/* Update stats even though technically transfer has not happened. */
+	bs->wr_bytes += (unsigned) nb_sectors * SECTOR_SIZE;
+	bs->wr_ops ++;
+    }
+
+    return ret;
 }
 
 void bdrv_aio_cancel(BlockDriverAIOCB *acb)