Commit 6af4e9ea authored by Paolo Bonzini's avatar Paolo Bonzini Committed by Kevin Wolf
Browse files

qcow2: always operate caches in writeback mode



Writethrough does not need special-casing anymore in the qcow2 caches.
The block layer adds flushes after every guest-initiated data write,
and these will also flush the qcow2 caches to the OS.

Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
Signed-off-by: default avatarKevin Wolf <kwolf@redhat.com>
parent 7cdd481c
Loading
Loading
Loading
Loading
+2 −23
Original line number Diff line number Diff line
@@ -40,11 +40,9 @@ struct Qcow2Cache {
    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;
@@ -53,7 +51,6 @@ Qcow2Cache *qcow2_cache_create(BlockDriverState *bs, int num_tables,
    c = g_malloc0(sizeof(*c));
    c->size = num_tables;
    c->entries = g_malloc0(sizeof(*c->entries) * num_tables);
    c->writethrough = writethrough;

    for (i = 0; i < c->size; i++) {
        c->entries[i].table = qemu_blockalign(bs, s->cluster_size);
@@ -307,13 +304,8 @@ found:
    *table = NULL;

    assert(c->entries[i].ref >= 0);

    if (c->writethrough) {
        return qcow2_cache_entry_flush(bs, c, i);
    } else {
    return 0;
}
}

void qcow2_cache_entry_mark_dirty(Qcow2Cache *c, void *table)
{
@@ -329,16 +321,3 @@ void qcow2_cache_entry_mark_dirty(Qcow2Cache *c, void *table)
found:
    c->entries[i].dirty = true;
}

bool qcow2_cache_set_writethrough(BlockDriverState *bs, Qcow2Cache *c,
    bool enable)
{
    bool old = c->writethrough;

    if (!old && enable) {
        qcow2_cache_flush(bs, c);
    }

    c->writethrough = enable;
    return old;
}
+0 −12
Original line number Diff line number Diff line
@@ -726,13 +726,6 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
    int64_t old_offset, old_l2_offset;
    int i, j, l1_modified = 0, nb_csectors, refcount;
    int ret;
    bool old_l2_writethrough, old_refcount_writethrough;

    /* Switch caches to writeback mode during update */
    old_l2_writethrough =
        qcow2_cache_set_writethrough(bs, s->l2_table_cache, false);
    old_refcount_writethrough =
        qcow2_cache_set_writethrough(bs, s->refcount_block_cache, false);

    l2_table = NULL;
    l1_table = NULL;
@@ -856,11 +849,6 @@ fail:
        qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table);
    }

    /* Enable writethrough cache mode again */
    qcow2_cache_set_writethrough(bs, s->l2_table_cache, old_l2_writethrough);
    qcow2_cache_set_writethrough(bs, s->refcount_block_cache,
        old_refcount_writethrough);

    /* Update L1 only if it isn't deleted anyway (addend = -1) */
    if (addend >= 0 && l1_modified) {
        for(i = 0; i < l1_size; i++)
+2 −5
Original line number Diff line number Diff line
@@ -220,7 +220,6 @@ static int qcow2_open(BlockDriverState *bs, int flags)
    int len, i, ret = 0;
    QCowHeader header;
    uint64_t ext_end;
    bool writethrough;

    ret = bdrv_pread(bs->file, 0, &header, sizeof(header));
    if (ret < 0) {
@@ -367,10 +366,8 @@ static int qcow2_open(BlockDriverState *bs, int flags)
    }

    /* alloc L2 table/refcount block cache */
    writethrough = ((flags & BDRV_O_CACHE_WB) == 0);
    s->l2_table_cache = qcow2_cache_create(bs, L2_CACHE_SIZE, writethrough);
    s->refcount_block_cache = qcow2_cache_create(bs, REFCOUNT_CACHE_SIZE,
        writethrough);
    s->l2_table_cache = qcow2_cache_create(bs, L2_CACHE_SIZE);
    s->refcount_block_cache = qcow2_cache_create(bs, REFCOUNT_CACHE_SIZE);

    s->cluster_cache = g_malloc(s->cluster_size);
    /* one more sector for decompressed data alignment */
+1 −4
Original line number Diff line number Diff line
@@ -297,11 +297,8 @@ void qcow2_free_snapshots(BlockDriverState *bs);
int qcow2_read_snapshots(BlockDriverState *bs);

/* qcow2-cache.c functions */
Qcow2Cache *qcow2_cache_create(BlockDriverState *bs, int num_tables,
    bool writethrough);
Qcow2Cache *qcow2_cache_create(BlockDriverState *bs, int num_tables);
int qcow2_cache_destroy(BlockDriverState* bs, Qcow2Cache *c);
bool qcow2_cache_set_writethrough(BlockDriverState *bs, Qcow2Cache *c,
    bool enable);

void qcow2_cache_entry_mark_dirty(Qcow2Cache *c, void *table);
int qcow2_cache_flush(BlockDriverState *bs, Qcow2Cache *c);