* THE SOFTWARE.
*/
-#include "block_int.h"
+#include "block/block_int.h"
#include "qemu-common.h"
#include "qcow2.h"
+#include "trace.h"
typedef struct Qcow2CachedTable {
void* table;
struct Qcow2Cache* depends;
int size;
bool depends_on_flush;
- bool writethrough;
};
-Qcow2Cache *qcow2_cache_create(BlockDriverState *bs, int num_tables,
- bool writethrough)
+Qcow2Cache *qcow2_cache_create(BlockDriverState *bs, int num_tables)
{
BDRVQcowState *s = bs->opaque;
Qcow2Cache *c;
int i;
- c = qemu_mallocz(sizeof(*c));
+ c = g_malloc0(sizeof(*c));
c->size = num_tables;
- c->entries = qemu_mallocz(sizeof(*c->entries) * num_tables);
- c->writethrough = writethrough;
+ c->entries = g_malloc0(sizeof(*c->entries) * num_tables);
for (i = 0; i < c->size; i++) {
c->entries[i].table = qemu_blockalign(bs, s->cluster_size);
qemu_vfree(c->entries[i].table);
}
- qemu_free(c->entries);
- qemu_free(c);
+ g_free(c->entries);
+ g_free(c);
return 0;
}
return 0;
}
+ trace_qcow2_cache_entry_flush(qemu_coroutine_self(),
+ c == s->l2_table_cache, i);
+
if (c->depends) {
ret = qcow2_cache_flush_dependency(bs, c);
} else if (c->depends_on_flush) {
int qcow2_cache_flush(BlockDriverState *bs, Qcow2Cache *c)
{
+ BDRVQcowState *s = bs->opaque;
int result = 0;
int ret;
int i;
+ trace_qcow2_cache_flush(qemu_coroutine_self(), c == s->l2_table_cache);
+
for (i = 0; i < c->size; i++) {
ret = qcow2_cache_entry_flush(bs, c, i);
if (ret < 0 && result != -ENOSPC) {
int i;
int ret;
+ trace_qcow2_cache_get(qemu_coroutine_self(), c == s->l2_table_cache,
+ offset, read_from_disk);
+
/* Check if the table is already cached */
for (i = 0; i < c->size; i++) {
if (c->entries[i].offset == offset) {
/* If not, write a table back and replace it */
i = qcow2_cache_find_entry_to_replace(c);
+ trace_qcow2_cache_get_replace_entry(qemu_coroutine_self(),
+ c == s->l2_table_cache, i);
if (i < 0) {
return i;
}
return ret;
}
+ trace_qcow2_cache_get_read(qemu_coroutine_self(),
+ c == s->l2_table_cache, i);
c->entries[i].offset = 0;
if (read_from_disk) {
if (c == s->l2_table_cache) {
c->entries[i].cache_hits++;
c->entries[i].ref++;
*table = c->entries[i].table;
+
+ trace_qcow2_cache_get_done(qemu_coroutine_self(),
+ c == s->l2_table_cache, i);
+
return 0;
}
*table = NULL;
assert(c->entries[i].ref >= 0);
-
- if (c->writethrough) {
- return qcow2_cache_entry_flush(bs, c, i);
- } else {
- return 0;
- }
+ return 0;
}
void qcow2_cache_entry_mark_dirty(Qcow2Cache *c, void *table)
found:
c->entries[i].dirty = true;
}
-