Commit da0eb242 authored by Vladimir Sementsov-Ogievskiy's avatar Vladimir Sementsov-Ogievskiy Committed by Max Reitz
Browse files

qcow2: add .bdrv_can_store_new_dirty_bitmap



Realize .bdrv_can_store_new_dirty_bitmap interface.

Signed-off-by: default avatarVladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Reviewed-by: default avatarJohn Snow <jsnow@redhat.com>
Reviewed-by: default avatarMax Reitz <mreitz@redhat.com>
Message-id: 20170628120530.31251-23-vsementsov@virtuozzo.com
Signed-off-by: default avatarMax Reitz <mreitz@redhat.com>
parent 67b792f5
Loading
Loading
Loading
Loading
+51 −0
Original line number Diff line number Diff line
@@ -1388,3 +1388,54 @@ int qcow2_reopen_bitmaps_ro(BlockDriverState *bs, Error **errp)

    return 0;
}

bool qcow2_can_store_new_dirty_bitmap(BlockDriverState *bs,
                                      const char *name,
                                      uint32_t granularity,
                                      Error **errp)
{
    BDRVQcow2State *s = bs->opaque;
    bool found;
    Qcow2BitmapList *bm_list;

    if (check_constraints_on_bitmap(bs, name, granularity, errp) != 0) {
        goto fail;
    }

    if (s->nb_bitmaps == 0) {
        return true;
    }

    if (s->nb_bitmaps >= QCOW2_MAX_BITMAPS) {
        error_setg(errp,
                   "Maximum number of persistent bitmaps is already reached");
        goto fail;
    }

    if (s->bitmap_directory_size + calc_dir_entry_size(strlen(name), 0) >
        QCOW2_MAX_BITMAP_DIRECTORY_SIZE)
    {
        error_setg(errp, "Not enough space in the bitmap directory");
        goto fail;
    }

    bm_list = bitmap_list_load(bs, s->bitmap_directory_offset,
                               s->bitmap_directory_size, errp);
    if (bm_list == NULL) {
        goto fail;
    }

    found = find_bitmap_by_name(bm_list, name);
    bitmap_list_free(bm_list);
    if (found) {
        error_setg(errp, "Bitmap with the same name is already stored");
        goto fail;
    }

    return true;

fail:
    error_prepend(errp, "Can't make bitmap '%s' persistent in '%s': ",
                  name, bdrv_get_device_or_node_name(bs));
    return false;
}
+1 −0
Original line number Diff line number Diff line
@@ -3989,6 +3989,7 @@ BlockDriver bdrv_qcow2 = {
    .bdrv_attach_aio_context  = qcow2_attach_aio_context,

    .bdrv_reopen_bitmaps_rw = qcow2_reopen_bitmaps_rw,
    .bdrv_can_store_new_dirty_bitmap = qcow2_can_store_new_dirty_bitmap,
};

static void bdrv_qcow2_init(void)
+4 −0
Original line number Diff line number Diff line
@@ -649,5 +649,9 @@ bool qcow2_load_autoloading_dirty_bitmaps(BlockDriverState *bs, Error **errp);
int qcow2_reopen_bitmaps_rw(BlockDriverState *bs, Error **errp);
void qcow2_store_persistent_dirty_bitmaps(BlockDriverState *bs, Error **errp);
int qcow2_reopen_bitmaps_ro(BlockDriverState *bs, Error **errp);
bool qcow2_can_store_new_dirty_bitmap(BlockDriverState *bs,
                                      const char *name,
                                      uint32_t granularity,
                                      Error **errp);

#endif