mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging
Block patches # gpg: Signature made Fri 22 Aug 2014 14:47:53 BST using RSA key ID C88F2FD6 # gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>" * remotes/kevin/tags/for-upstream: (29 commits) qemu-img: Allow cache mode specification for amend qemu-img: Allow source cache mode specification vmdk: Use bdrv_nb_sectors() where sectors, not bytes are wanted blkdebug: Delete BH in bdrv_aio_cancel qemu-iotests: add test case 101 for short file I/O raw-posix: fix O_DIRECT short reads block/iscsi: fix memory corruption on iscsi resize block/vvfat.c: remove debugging code to reinit stderr if NULL iotests: Add test for image filename construction quorum: Implement bdrv_refresh_filename() nbd: Implement bdrv_refresh_filename() blkverify: Implement bdrv_refresh_filename() blkdebug: Implement bdrv_refresh_filename() block: Add bdrv_refresh_filename() virtio-blk: fix reference a pointer which might be freed virtio-blk: allow block_resize with dataplane block: acquire AioContext in qmp_block_resize() qemu-iotests: Fix 028 reference output for qed test-coroutine: test cost introduced by coroutine iotests: Add test for qcow2's cache options ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
+3
-3
@@ -283,7 +283,7 @@ static int mig_save_device_bulk(QEMUFile *f, BlkMigDevState *bmds)
|
||||
nr_sectors = total_sectors - cur_sector;
|
||||
}
|
||||
|
||||
blk = g_malloc(sizeof(BlkMigBlock));
|
||||
blk = g_new(BlkMigBlock, 1);
|
||||
blk->buf = g_malloc(BLOCK_SIZE);
|
||||
blk->bmds = bmds;
|
||||
blk->sector = cur_sector;
|
||||
@@ -354,7 +354,7 @@ static void init_blk_migration_it(void *opaque, BlockDriverState *bs)
|
||||
return;
|
||||
}
|
||||
|
||||
bmds = g_malloc0(sizeof(BlkMigDevState));
|
||||
bmds = g_new0(BlkMigDevState, 1);
|
||||
bmds->bs = bs;
|
||||
bmds->bulk_completed = 0;
|
||||
bmds->total_sectors = sectors;
|
||||
@@ -465,7 +465,7 @@ static int mig_save_device_dirty(QEMUFile *f, BlkMigDevState *bmds,
|
||||
} else {
|
||||
nr_sectors = BDRV_SECTORS_PER_DIRTY_CHUNK;
|
||||
}
|
||||
blk = g_malloc(sizeof(BlkMigBlock));
|
||||
blk = g_new(BlkMigBlock, 1);
|
||||
blk->buf = g_malloc(BLOCK_SIZE);
|
||||
blk->bmds = bmds;
|
||||
blk->sector = sector;
|
||||
|
||||
@@ -351,7 +351,7 @@ BlockDriverState *bdrv_new(const char *device_name, Error **errp)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bs = g_malloc0(sizeof(BlockDriverState));
|
||||
bs = g_new0(BlockDriverState, 1);
|
||||
QLIST_INIT(&bs->dirty_bitmaps);
|
||||
pstrcpy(bs->device_name, sizeof(bs->device_name), device_name);
|
||||
if (device_name[0] != '\0') {
|
||||
@@ -964,6 +964,7 @@ static int bdrv_open_common(BlockDriverState *bs, BlockDriverState *file,
|
||||
} else {
|
||||
bs->filename[0] = '\0';
|
||||
}
|
||||
pstrcpy(bs->exact_filename, sizeof(bs->exact_filename), bs->filename);
|
||||
|
||||
bs->drv = drv;
|
||||
bs->opaque = g_malloc0(drv->instance_size);
|
||||
@@ -1505,6 +1506,8 @@ int bdrv_open(BlockDriverState **pbs, const char *filename,
|
||||
}
|
||||
}
|
||||
|
||||
bdrv_refresh_filename(bs);
|
||||
|
||||
/* For snapshot=on, create a temporary qcow2 overlay. bs points to the
|
||||
* temporary snapshot afterwards. */
|
||||
if (snapshot_flags) {
|
||||
@@ -1845,6 +1848,8 @@ void bdrv_close(BlockDriverState *bs)
|
||||
bs->zero_beyond_eof = false;
|
||||
QDECREF(bs->options);
|
||||
bs->options = NULL;
|
||||
QDECREF(bs->full_open_options);
|
||||
bs->full_open_options = NULL;
|
||||
|
||||
if (bs->file != NULL) {
|
||||
bdrv_unref(bs->file);
|
||||
@@ -2628,7 +2633,7 @@ int bdrv_drop_intermediate(BlockDriverState *active, BlockDriverState *top,
|
||||
* into our deletion queue, until we hit the 'base'
|
||||
*/
|
||||
while (intermediate) {
|
||||
intermediate_state = g_malloc0(sizeof(BlkIntermediateStates));
|
||||
intermediate_state = g_new0(BlkIntermediateStates, 1);
|
||||
intermediate_state->bs = intermediate;
|
||||
QSIMPLEQ_INSERT_TAIL(&states_to_delete, intermediate_state, entry);
|
||||
|
||||
@@ -3755,7 +3760,7 @@ void bdrv_iterate_format(void (*it)(void *opaque, const char *name),
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
formats = g_realloc(formats, (count + 1) * sizeof(char *));
|
||||
formats = g_renew(const char *, formats, count + 1);
|
||||
formats[count++] = drv->format_name;
|
||||
it(opaque, drv->format_name);
|
||||
}
|
||||
@@ -5330,7 +5335,7 @@ BdrvDirtyBitmap *bdrv_create_dirty_bitmap(BlockDriverState *bs, int granularity,
|
||||
errno = -bitmap_size;
|
||||
return NULL;
|
||||
}
|
||||
bitmap = g_malloc0(sizeof(BdrvDirtyBitmap));
|
||||
bitmap = g_new0(BdrvDirtyBitmap, 1);
|
||||
bitmap->bitmap = hbitmap_alloc(bitmap_size, ffs(granularity) - 1);
|
||||
QLIST_INSERT_HEAD(&bs->dirty_bitmaps, bitmap, list);
|
||||
return bitmap;
|
||||
@@ -5356,8 +5361,8 @@ BlockDirtyInfoList *bdrv_query_dirty_bitmaps(BlockDriverState *bs)
|
||||
BlockDirtyInfoList **plist = &list;
|
||||
|
||||
QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) {
|
||||
BlockDirtyInfo *info = g_malloc0(sizeof(BlockDirtyInfo));
|
||||
BlockDirtyInfoList *entry = g_malloc0(sizeof(BlockDirtyInfoList));
|
||||
BlockDirtyInfo *info = g_new0(BlockDirtyInfo, 1);
|
||||
BlockDirtyInfoList *entry = g_new0(BlockDirtyInfoList, 1);
|
||||
info->count = bdrv_get_dirty_count(bs, bm);
|
||||
info->granularity =
|
||||
((int64_t) BDRV_SECTOR_SIZE << hbitmap_granularity(bm->bitmap));
|
||||
@@ -5451,7 +5456,7 @@ void bdrv_op_block(BlockDriverState *bs, BlockOpType op, Error *reason)
|
||||
BdrvOpBlocker *blocker;
|
||||
assert((int) op >= 0 && op < BLOCK_OP_TYPE_MAX);
|
||||
|
||||
blocker = g_malloc0(sizeof(BdrvOpBlocker));
|
||||
blocker = g_new0(BdrvOpBlocker, 1);
|
||||
blocker->reason = reason;
|
||||
QLIST_INSERT_HEAD(&bs->op_blockers[op], blocker, list);
|
||||
}
|
||||
@@ -5894,3 +5899,133 @@ void bdrv_flush_io_queue(BlockDriverState *bs)
|
||||
bdrv_flush_io_queue(bs->file);
|
||||
}
|
||||
}
|
||||
|
||||
static bool append_open_options(QDict *d, BlockDriverState *bs)
|
||||
{
|
||||
const QDictEntry *entry;
|
||||
bool found_any = false;
|
||||
|
||||
for (entry = qdict_first(bs->options); entry;
|
||||
entry = qdict_next(bs->options, entry))
|
||||
{
|
||||
/* Only take options for this level and exclude all non-driver-specific
|
||||
* options */
|
||||
if (!strchr(qdict_entry_key(entry), '.') &&
|
||||
strcmp(qdict_entry_key(entry), "node-name"))
|
||||
{
|
||||
qobject_incref(qdict_entry_value(entry));
|
||||
qdict_put_obj(d, qdict_entry_key(entry), qdict_entry_value(entry));
|
||||
found_any = true;
|
||||
}
|
||||
}
|
||||
|
||||
return found_any;
|
||||
}
|
||||
|
||||
/* Updates the following BDS fields:
|
||||
* - exact_filename: A filename which may be used for opening a block device
|
||||
* which (mostly) equals the given BDS (even without any
|
||||
* other options; so reading and writing must return the same
|
||||
* results, but caching etc. may be different)
|
||||
* - full_open_options: Options which, when given when opening a block device
|
||||
* (without a filename), result in a BDS (mostly)
|
||||
* equalling the given one
|
||||
* - filename: If exact_filename is set, it is copied here. Otherwise,
|
||||
* full_open_options is converted to a JSON object, prefixed with
|
||||
* "json:" (for use through the JSON pseudo protocol) and put here.
|
||||
*/
|
||||
void bdrv_refresh_filename(BlockDriverState *bs)
|
||||
{
|
||||
BlockDriver *drv = bs->drv;
|
||||
QDict *opts;
|
||||
|
||||
if (!drv) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* This BDS's file name will most probably depend on its file's name, so
|
||||
* refresh that first */
|
||||
if (bs->file) {
|
||||
bdrv_refresh_filename(bs->file);
|
||||
}
|
||||
|
||||
if (drv->bdrv_refresh_filename) {
|
||||
/* Obsolete information is of no use here, so drop the old file name
|
||||
* information before refreshing it */
|
||||
bs->exact_filename[0] = '\0';
|
||||
if (bs->full_open_options) {
|
||||
QDECREF(bs->full_open_options);
|
||||
bs->full_open_options = NULL;
|
||||
}
|
||||
|
||||
drv->bdrv_refresh_filename(bs);
|
||||
} else if (bs->file) {
|
||||
/* Try to reconstruct valid information from the underlying file */
|
||||
bool has_open_options;
|
||||
|
||||
bs->exact_filename[0] = '\0';
|
||||
if (bs->full_open_options) {
|
||||
QDECREF(bs->full_open_options);
|
||||
bs->full_open_options = NULL;
|
||||
}
|
||||
|
||||
opts = qdict_new();
|
||||
has_open_options = append_open_options(opts, bs);
|
||||
|
||||
/* If no specific options have been given for this BDS, the filename of
|
||||
* the underlying file should suffice for this one as well */
|
||||
if (bs->file->exact_filename[0] && !has_open_options) {
|
||||
strcpy(bs->exact_filename, bs->file->exact_filename);
|
||||
}
|
||||
/* Reconstructing the full options QDict is simple for most format block
|
||||
* drivers, as long as the full options are known for the underlying
|
||||
* file BDS. The full options QDict of that file BDS should somehow
|
||||
* contain a representation of the filename, therefore the following
|
||||
* suffices without querying the (exact_)filename of this BDS. */
|
||||
if (bs->file->full_open_options) {
|
||||
qdict_put_obj(opts, "driver",
|
||||
QOBJECT(qstring_from_str(drv->format_name)));
|
||||
QINCREF(bs->file->full_open_options);
|
||||
qdict_put_obj(opts, "file", QOBJECT(bs->file->full_open_options));
|
||||
|
||||
bs->full_open_options = opts;
|
||||
} else {
|
||||
QDECREF(opts);
|
||||
}
|
||||
} else if (!bs->full_open_options && qdict_size(bs->options)) {
|
||||
/* There is no underlying file BDS (at least referenced by BDS.file),
|
||||
* so the full options QDict should be equal to the options given
|
||||
* specifically for this block device when it was opened (plus the
|
||||
* driver specification).
|
||||
* Because those options don't change, there is no need to update
|
||||
* full_open_options when it's already set. */
|
||||
|
||||
opts = qdict_new();
|
||||
append_open_options(opts, bs);
|
||||
qdict_put_obj(opts, "driver",
|
||||
QOBJECT(qstring_from_str(drv->format_name)));
|
||||
|
||||
if (bs->exact_filename[0]) {
|
||||
/* This may not work for all block protocol drivers (some may
|
||||
* require this filename to be parsed), but we have to find some
|
||||
* default solution here, so just include it. If some block driver
|
||||
* does not support pure options without any filename at all or
|
||||
* needs some special format of the options QDict, it needs to
|
||||
* implement the driver-specific bdrv_refresh_filename() function.
|
||||
*/
|
||||
qdict_put_obj(opts, "filename",
|
||||
QOBJECT(qstring_from_str(bs->exact_filename)));
|
||||
}
|
||||
|
||||
bs->full_open_options = opts;
|
||||
}
|
||||
|
||||
if (bs->exact_filename[0]) {
|
||||
pstrcpy(bs->filename, sizeof(bs->filename), bs->exact_filename);
|
||||
} else if (bs->full_open_options) {
|
||||
QString *json = qobject_to_json(QOBJECT(bs->full_open_options));
|
||||
snprintf(bs->filename, sizeof(bs->filename), "json:%s",
|
||||
qstring_get_str(json));
|
||||
QDECREF(json);
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -750,7 +750,7 @@ static int archipelago_submit_request(BDRVArchipelagoState *s,
|
||||
char *target;
|
||||
void *data = NULL;
|
||||
struct xseg_request *req;
|
||||
AIORequestData *reqdata = g_malloc(sizeof(AIORequestData));
|
||||
AIORequestData *reqdata = g_new(AIORequestData, 1);
|
||||
|
||||
targetlen = strlen(s->volname);
|
||||
req = xseg_get_request(s->xseg, s->srcport, s->vportno, X_ALLOC);
|
||||
@@ -827,7 +827,7 @@ static int archipelago_aio_segmented_rw(BDRVArchipelagoState *s,
|
||||
int i, ret, segments_nr, last_segment_size;
|
||||
ArchipelagoSegmentedRequest *segreq;
|
||||
|
||||
segreq = g_malloc(sizeof(ArchipelagoSegmentedRequest));
|
||||
segreq = g_new(ArchipelagoSegmentedRequest, 1);
|
||||
|
||||
if (op == ARCHIP_OP_FLUSH) {
|
||||
segments_nr = 1;
|
||||
@@ -960,7 +960,7 @@ static int64_t archipelago_volume_info(BDRVArchipelagoState *s)
|
||||
int ret, targetlen;
|
||||
struct xseg_request *req;
|
||||
struct xseg_reply_info *xinfo;
|
||||
AIORequestData *reqdata = g_malloc(sizeof(AIORequestData));
|
||||
AIORequestData *reqdata = g_new(AIORequestData, 1);
|
||||
|
||||
const char *volname = s->volname;
|
||||
targetlen = strlen(volname);
|
||||
|
||||
@@ -26,6 +26,10 @@
|
||||
#include "qemu/config-file.h"
|
||||
#include "block/block_int.h"
|
||||
#include "qemu/module.h"
|
||||
#include "qapi/qmp/qbool.h"
|
||||
#include "qapi/qmp/qdict.h"
|
||||
#include "qapi/qmp/qint.h"
|
||||
#include "qapi/qmp/qstring.h"
|
||||
|
||||
typedef struct BDRVBlkdebugState {
|
||||
int state;
|
||||
@@ -449,6 +453,10 @@ static void error_callback_bh(void *opaque)
|
||||
static void blkdebug_aio_cancel(BlockDriverAIOCB *blockacb)
|
||||
{
|
||||
BlkdebugAIOCB *acb = container_of(blockacb, BlkdebugAIOCB, common);
|
||||
if (acb->bh) {
|
||||
qemu_bh_delete(acb->bh);
|
||||
acb->bh = NULL;
|
||||
}
|
||||
qemu_aio_release(acb);
|
||||
}
|
||||
|
||||
@@ -706,6 +714,98 @@ static int64_t blkdebug_getlength(BlockDriverState *bs)
|
||||
return bdrv_getlength(bs->file);
|
||||
}
|
||||
|
||||
static void blkdebug_refresh_filename(BlockDriverState *bs)
|
||||
{
|
||||
BDRVBlkdebugState *s = bs->opaque;
|
||||
struct BlkdebugRule *rule;
|
||||
QDict *opts;
|
||||
QList *inject_error_list = NULL, *set_state_list = NULL;
|
||||
QList *suspend_list = NULL;
|
||||
int event;
|
||||
|
||||
if (!bs->file->full_open_options) {
|
||||
/* The config file cannot be recreated, so creating a plain filename
|
||||
* is impossible */
|
||||
return;
|
||||
}
|
||||
|
||||
opts = qdict_new();
|
||||
qdict_put_obj(opts, "driver", QOBJECT(qstring_from_str("blkdebug")));
|
||||
|
||||
QINCREF(bs->file->full_open_options);
|
||||
qdict_put_obj(opts, "image", QOBJECT(bs->file->full_open_options));
|
||||
|
||||
for (event = 0; event < BLKDBG_EVENT_MAX; event++) {
|
||||
QLIST_FOREACH(rule, &s->rules[event], next) {
|
||||
if (rule->action == ACTION_INJECT_ERROR) {
|
||||
QDict *inject_error = qdict_new();
|
||||
|
||||
qdict_put_obj(inject_error, "event", QOBJECT(qstring_from_str(
|
||||
BlkdebugEvent_lookup[rule->event])));
|
||||
qdict_put_obj(inject_error, "state",
|
||||
QOBJECT(qint_from_int(rule->state)));
|
||||
qdict_put_obj(inject_error, "errno", QOBJECT(qint_from_int(
|
||||
rule->options.inject.error)));
|
||||
qdict_put_obj(inject_error, "sector", QOBJECT(qint_from_int(
|
||||
rule->options.inject.sector)));
|
||||
qdict_put_obj(inject_error, "once", QOBJECT(qbool_from_int(
|
||||
rule->options.inject.once)));
|
||||
qdict_put_obj(inject_error, "immediately",
|
||||
QOBJECT(qbool_from_int(
|
||||
rule->options.inject.immediately)));
|
||||
|
||||
if (!inject_error_list) {
|
||||
inject_error_list = qlist_new();
|
||||
}
|
||||
|
||||
qlist_append_obj(inject_error_list, QOBJECT(inject_error));
|
||||
} else if (rule->action == ACTION_SET_STATE) {
|
||||
QDict *set_state = qdict_new();
|
||||
|
||||
qdict_put_obj(set_state, "event", QOBJECT(qstring_from_str(
|
||||
BlkdebugEvent_lookup[rule->event])));
|
||||
qdict_put_obj(set_state, "state",
|
||||
QOBJECT(qint_from_int(rule->state)));
|
||||
qdict_put_obj(set_state, "new_state", QOBJECT(qint_from_int(
|
||||
rule->options.set_state.new_state)));
|
||||
|
||||
if (!set_state_list) {
|
||||
set_state_list = qlist_new();
|
||||
}
|
||||
|
||||
qlist_append_obj(set_state_list, QOBJECT(set_state));
|
||||
} else if (rule->action == ACTION_SUSPEND) {
|
||||
QDict *suspend = qdict_new();
|
||||
|
||||
qdict_put_obj(suspend, "event", QOBJECT(qstring_from_str(
|
||||
BlkdebugEvent_lookup[rule->event])));
|
||||
qdict_put_obj(suspend, "state",
|
||||
QOBJECT(qint_from_int(rule->state)));
|
||||
qdict_put_obj(suspend, "tag", QOBJECT(qstring_from_str(
|
||||
rule->options.suspend.tag)));
|
||||
|
||||
if (!suspend_list) {
|
||||
suspend_list = qlist_new();
|
||||
}
|
||||
|
||||
qlist_append_obj(suspend_list, QOBJECT(suspend));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (inject_error_list) {
|
||||
qdict_put_obj(opts, "inject-error", QOBJECT(inject_error_list));
|
||||
}
|
||||
if (set_state_list) {
|
||||
qdict_put_obj(opts, "set-state", QOBJECT(set_state_list));
|
||||
}
|
||||
if (suspend_list) {
|
||||
qdict_put_obj(opts, "suspend", QOBJECT(suspend_list));
|
||||
}
|
||||
|
||||
bs->full_open_options = opts;
|
||||
}
|
||||
|
||||
static BlockDriver bdrv_blkdebug = {
|
||||
.format_name = "blkdebug",
|
||||
.protocol_name = "blkdebug",
|
||||
@@ -715,6 +815,7 @@ static BlockDriver bdrv_blkdebug = {
|
||||
.bdrv_file_open = blkdebug_open,
|
||||
.bdrv_close = blkdebug_close,
|
||||
.bdrv_getlength = blkdebug_getlength,
|
||||
.bdrv_refresh_filename = blkdebug_refresh_filename,
|
||||
|
||||
.bdrv_aio_readv = blkdebug_aio_readv,
|
||||
.bdrv_aio_writev = blkdebug_aio_writev,
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
#include <stdarg.h>
|
||||
#include "qemu/sockets.h" /* for EINPROGRESS on Windows */
|
||||
#include "block/block_int.h"
|
||||
#include "qapi/qmp/qdict.h"
|
||||
#include "qapi/qmp/qstring.h"
|
||||
|
||||
typedef struct {
|
||||
BlockDriverState *test_file;
|
||||
@@ -320,6 +322,32 @@ static void blkverify_attach_aio_context(BlockDriverState *bs,
|
||||
bdrv_attach_aio_context(s->test_file, new_context);
|
||||
}
|
||||
|
||||
static void blkverify_refresh_filename(BlockDriverState *bs)
|
||||
{
|
||||
BDRVBlkverifyState *s = bs->opaque;
|
||||
|
||||
/* bs->file has already been refreshed */
|
||||
bdrv_refresh_filename(s->test_file);
|
||||
|
||||
if (bs->file->full_open_options && s->test_file->full_open_options) {
|
||||
QDict *opts = qdict_new();
|
||||
qdict_put_obj(opts, "driver", QOBJECT(qstring_from_str("blkverify")));
|
||||
|
||||
QINCREF(bs->file->full_open_options);
|
||||
qdict_put_obj(opts, "raw", QOBJECT(bs->file->full_open_options));
|
||||
QINCREF(s->test_file->full_open_options);
|
||||
qdict_put_obj(opts, "test", QOBJECT(s->test_file->full_open_options));
|
||||
|
||||
bs->full_open_options = opts;
|
||||
}
|
||||
|
||||
if (bs->file->exact_filename[0] && s->test_file->exact_filename[0]) {
|
||||
snprintf(bs->exact_filename, sizeof(bs->exact_filename),
|
||||
"blkverify:%s:%s",
|
||||
bs->file->exact_filename, s->test_file->exact_filename);
|
||||
}
|
||||
}
|
||||
|
||||
static BlockDriver bdrv_blkverify = {
|
||||
.format_name = "blkverify",
|
||||
.protocol_name = "blkverify",
|
||||
@@ -329,6 +357,7 @@ static BlockDriver bdrv_blkverify = {
|
||||
.bdrv_file_open = blkverify_open,
|
||||
.bdrv_close = blkverify_close,
|
||||
.bdrv_getlength = blkverify_getlength,
|
||||
.bdrv_refresh_filename = blkverify_refresh_filename,
|
||||
|
||||
.bdrv_aio_readv = blkverify_aio_readv,
|
||||
.bdrv_aio_writev = blkverify_aio_writev,
|
||||
|
||||
+1
-1
@@ -131,7 +131,7 @@ static int bochs_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
return -EFBIG;
|
||||
}
|
||||
|
||||
s->catalog_bitmap = g_try_malloc(s->catalog_size * 4);
|
||||
s->catalog_bitmap = g_try_new(uint32_t, s->catalog_size);
|
||||
if (s->catalog_size && s->catalog_bitmap == NULL) {
|
||||
error_setg(errp, "Could not allocate memory for catalog");
|
||||
return -ENOMEM;
|
||||
|
||||
+4
-4
@@ -291,7 +291,7 @@ static int qemu_gluster_open(BlockDriverState *bs, QDict *options,
|
||||
BDRVGlusterState *s = bs->opaque;
|
||||
int open_flags = 0;
|
||||
int ret = 0;
|
||||
GlusterConf *gconf = g_malloc0(sizeof(GlusterConf));
|
||||
GlusterConf *gconf = g_new0(GlusterConf, 1);
|
||||
QemuOpts *opts;
|
||||
Error *local_err = NULL;
|
||||
const char *filename;
|
||||
@@ -351,12 +351,12 @@ static int qemu_gluster_reopen_prepare(BDRVReopenState *state,
|
||||
assert(state != NULL);
|
||||
assert(state->bs != NULL);
|
||||
|
||||
state->opaque = g_malloc0(sizeof(BDRVGlusterReopenState));
|
||||
state->opaque = g_new0(BDRVGlusterReopenState, 1);
|
||||
reop_s = state->opaque;
|
||||
|
||||
qemu_gluster_parse_flags(state->flags, &open_flags);
|
||||
|
||||
gconf = g_malloc0(sizeof(GlusterConf));
|
||||
gconf = g_new0(GlusterConf, 1);
|
||||
|
||||
reop_s->glfs = qemu_gluster_init(gconf, state->bs->filename, errp);
|
||||
if (reop_s->glfs == NULL) {
|
||||
@@ -486,7 +486,7 @@ static int qemu_gluster_create(const char *filename,
|
||||
int prealloc = 0;
|
||||
int64_t total_size = 0;
|
||||
char *tmp = NULL;
|
||||
GlusterConf *gconf = g_malloc0(sizeof(GlusterConf));
|
||||
GlusterConf *gconf = g_new0(GlusterConf, 1);
|
||||
|
||||
glfs = qemu_gluster_init(gconf, filename, errp);
|
||||
if (!glfs) {
|
||||
|
||||
+3
-2
@@ -1512,7 +1512,8 @@ static int iscsi_truncate(BlockDriverState *bs, int64_t offset)
|
||||
if (iscsilun->allocationmap != NULL) {
|
||||
g_free(iscsilun->allocationmap);
|
||||
iscsilun->allocationmap =
|
||||
bitmap_new(DIV_ROUND_UP(bs->total_sectors,
|
||||
bitmap_new(DIV_ROUND_UP(sector_lun2qemu(iscsilun->num_blocks,
|
||||
iscsilun),
|
||||
iscsilun->cluster_sectors));
|
||||
}
|
||||
|
||||
@@ -1532,7 +1533,7 @@ static int iscsi_create(const char *filename, QemuOpts *opts, Error **errp)
|
||||
/* Read out options */
|
||||
total_size =
|
||||
qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0) / BDRV_SECTOR_SIZE;
|
||||
bs->opaque = g_malloc0(sizeof(struct IscsiLun));
|
||||
bs->opaque = g_new0(struct IscsiLun, 1);
|
||||
iscsilun = bs->opaque;
|
||||
|
||||
bs_options = qdict_new();
|
||||
|
||||
+36
@@ -31,8 +31,10 @@
|
||||
#include "block/block_int.h"
|
||||
#include "qemu/module.h"
|
||||
#include "qemu/sockets.h"
|
||||
#include "qapi/qmp/qdict.h"
|
||||
#include "qapi/qmp/qjson.h"
|
||||
#include "qapi/qmp/qint.h"
|
||||
#include "qapi/qmp/qstring.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
@@ -338,6 +340,37 @@ static void nbd_attach_aio_context(BlockDriverState *bs,
|
||||
nbd_client_session_attach_aio_context(&s->client, new_context);
|
||||
}
|
||||
|
||||
static void nbd_refresh_filename(BlockDriverState *bs)
|
||||
{
|
||||
BDRVNBDState *s = bs->opaque;
|
||||
QDict *opts = qdict_new();
|
||||
const char *path = qemu_opt_get(s->socket_opts, "path");
|
||||
const char *host = qemu_opt_get(s->socket_opts, "host");
|
||||
const char *port = qemu_opt_get(s->socket_opts, "port");
|
||||
const char *export = qemu_opt_get(s->socket_opts, "export");
|
||||
|
||||
qdict_put_obj(opts, "driver", QOBJECT(qstring_from_str("nbd")));
|
||||
|
||||
if (path) {
|
||||
snprintf(bs->exact_filename, sizeof(bs->exact_filename),
|
||||
"nbd+unix:%s", path);
|
||||
qdict_put_obj(opts, "path", QOBJECT(qstring_from_str(path)));
|
||||
} else if (export) {
|
||||
snprintf(bs->exact_filename, sizeof(bs->exact_filename),
|
||||
"nbd:%s:%s/%s", host, port, export);
|
||||
qdict_put_obj(opts, "host", QOBJECT(qstring_from_str(host)));
|
||||
qdict_put_obj(opts, "port", QOBJECT(qstring_from_str(port)));
|
||||
qdict_put_obj(opts, "export", QOBJECT(qstring_from_str(export)));
|
||||
} else {
|
||||
snprintf(bs->exact_filename, sizeof(bs->exact_filename),
|
||||
"nbd:%s:%s", host, port);
|
||||
qdict_put_obj(opts, "host", QOBJECT(qstring_from_str(host)));
|
||||
qdict_put_obj(opts, "port", QOBJECT(qstring_from_str(port)));
|
||||
}
|
||||
|
||||
bs->full_open_options = opts;
|
||||
}
|
||||
|
||||
static BlockDriver bdrv_nbd = {
|
||||
.format_name = "nbd",
|
||||
.protocol_name = "nbd",
|
||||
@@ -352,6 +385,7 @@ static BlockDriver bdrv_nbd = {
|
||||
.bdrv_getlength = nbd_getlength,
|
||||
.bdrv_detach_aio_context = nbd_detach_aio_context,
|
||||
.bdrv_attach_aio_context = nbd_attach_aio_context,
|
||||
.bdrv_refresh_filename = nbd_refresh_filename,
|
||||
};
|
||||
|
||||
static BlockDriver bdrv_nbd_tcp = {
|
||||
@@ -368,6 +402,7 @@ static BlockDriver bdrv_nbd_tcp = {
|
||||
.bdrv_getlength = nbd_getlength,
|
||||
.bdrv_detach_aio_context = nbd_detach_aio_context,
|
||||
.bdrv_attach_aio_context = nbd_attach_aio_context,
|
||||
.bdrv_refresh_filename = nbd_refresh_filename,
|
||||
};
|
||||
|
||||
static BlockDriver bdrv_nbd_unix = {
|
||||
@@ -384,6 +419,7 @@ static BlockDriver bdrv_nbd_unix = {
|
||||
.bdrv_getlength = nbd_getlength,
|
||||
.bdrv_detach_aio_context = nbd_detach_aio_context,
|
||||
.bdrv_attach_aio_context = nbd_attach_aio_context,
|
||||
.bdrv_refresh_filename = nbd_refresh_filename,
|
||||
};
|
||||
|
||||
static void bdrv_nbd_init(void)
|
||||
|
||||
+1
-1
@@ -409,7 +409,7 @@ static int nfs_file_create(const char *url, QemuOpts *opts, Error **errp)
|
||||
{
|
||||
int ret = 0;
|
||||
int64_t total_size = 0;
|
||||
NFSClient *client = g_malloc0(sizeof(NFSClient));
|
||||
NFSClient *client = g_new0(NFSClient, 1);
|
||||
|
||||
client->aio_context = qemu_get_aio_context();
|
||||
|
||||
|
||||
+1
-1
@@ -121,7 +121,7 @@ static int parallels_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
ret = -EFBIG;
|
||||
goto fail;
|
||||
}
|
||||
s->catalog_bitmap = g_try_malloc(s->catalog_size * 4);
|
||||
s->catalog_bitmap = g_try_new(uint32_t, s->catalog_size);
|
||||
if (s->catalog_size && s->catalog_bitmap == NULL) {
|
||||
ret = -ENOMEM;
|
||||
goto fail;
|
||||
|
||||
+1
-1
@@ -182,7 +182,7 @@ static int qcow_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
}
|
||||
|
||||
s->l1_table_offset = header.l1_table_offset;
|
||||
s->l1_table = g_try_malloc(s->l1_size * sizeof(uint64_t));
|
||||
s->l1_table = g_try_new(uint64_t, s->l1_size);
|
||||
if (s->l1_table == NULL) {
|
||||
error_setg(errp, "Could not allocate memory for L1 table");
|
||||
ret = -ENOMEM;
|
||||
|
||||
+9
-4
@@ -48,9 +48,12 @@ Qcow2Cache *qcow2_cache_create(BlockDriverState *bs, int num_tables)
|
||||
Qcow2Cache *c;
|
||||
int i;
|
||||
|
||||
c = g_malloc0(sizeof(*c));
|
||||
c = g_new0(Qcow2Cache, 1);
|
||||
c->size = num_tables;
|
||||
c->entries = g_malloc0(sizeof(*c->entries) * num_tables);
|
||||
c->entries = g_try_new0(Qcow2CachedTable, num_tables);
|
||||
if (!c->entries) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
for (i = 0; i < c->size; i++) {
|
||||
c->entries[i].table = qemu_try_blockalign(bs->file, s->cluster_size);
|
||||
@@ -62,8 +65,10 @@ Qcow2Cache *qcow2_cache_create(BlockDriverState *bs, int num_tables)
|
||||
return c;
|
||||
|
||||
fail:
|
||||
for (i = 0; i < c->size; i++) {
|
||||
qemu_vfree(c->entries[i].table);
|
||||
if (c->entries) {
|
||||
for (i = 0; i < c->size; i++) {
|
||||
qemu_vfree(c->entries[i].table);
|
||||
}
|
||||
}
|
||||
g_free(c->entries);
|
||||
g_free(c);
|
||||
|
||||
@@ -711,7 +711,7 @@ int qcow2_alloc_cluster_link_l2(BlockDriverState *bs, QCowL2Meta *m)
|
||||
trace_qcow2_cluster_link_l2(qemu_coroutine_self(), m->nb_clusters);
|
||||
assert(m->nb_clusters > 0);
|
||||
|
||||
old_cluster = g_try_malloc(m->nb_clusters * sizeof(uint64_t));
|
||||
old_cluster = g_try_new(uint64_t, m->nb_clusters);
|
||||
if (old_cluster == NULL) {
|
||||
ret = -ENOMEM;
|
||||
goto err;
|
||||
|
||||
@@ -350,7 +350,7 @@ static int alloc_refcount_block(BlockDriverState *bs,
|
||||
uint64_t meta_offset = (blocks_used * refcount_block_clusters) *
|
||||
s->cluster_size;
|
||||
uint64_t table_offset = meta_offset + blocks_clusters * s->cluster_size;
|
||||
uint64_t *new_table = g_try_malloc0(table_size * sizeof(uint64_t));
|
||||
uint64_t *new_table = g_try_new0(uint64_t, table_size);
|
||||
uint16_t *new_blocks = g_try_malloc0(blocks_clusters * s->cluster_size);
|
||||
|
||||
assert(table_size > 0 && blocks_clusters > 0);
|
||||
@@ -1524,7 +1524,7 @@ int qcow2_check_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
|
||||
return -EFBIG;
|
||||
}
|
||||
|
||||
refcount_table = g_try_malloc0(nb_clusters * sizeof(uint16_t));
|
||||
refcount_table = g_try_new0(uint16_t, nb_clusters);
|
||||
if (nb_clusters && refcount_table == NULL) {
|
||||
res->check_errors++;
|
||||
return -ENOMEM;
|
||||
@@ -1605,8 +1605,8 @@ int qcow2_check_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
|
||||
/* increase refcount_table size if necessary */
|
||||
int old_nb_clusters = nb_clusters;
|
||||
nb_clusters = (new_offset >> s->cluster_bits) + 1;
|
||||
refcount_table = g_realloc(refcount_table,
|
||||
nb_clusters * sizeof(uint16_t));
|
||||
refcount_table = g_renew(uint16_t, refcount_table,
|
||||
nb_clusters);
|
||||
memset(&refcount_table[old_nb_clusters], 0, (nb_clusters
|
||||
- old_nb_clusters) * sizeof(uint16_t));
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ int qcow2_read_snapshots(BlockDriverState *bs)
|
||||
}
|
||||
|
||||
offset = s->snapshots_offset;
|
||||
s->snapshots = g_malloc0(s->nb_snapshots * sizeof(QCowSnapshot));
|
||||
s->snapshots = g_new0(QCowSnapshot, s->nb_snapshots);
|
||||
|
||||
for(i = 0; i < s->nb_snapshots; i++) {
|
||||
/* Read statically sized part of the snapshot header */
|
||||
@@ -381,7 +381,7 @@ int qcow2_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)
|
||||
sn->l1_table_offset = l1_table_offset;
|
||||
sn->l1_size = s->l1_size;
|
||||
|
||||
l1_table = g_try_malloc(s->l1_size * sizeof(uint64_t));
|
||||
l1_table = g_try_new(uint64_t, s->l1_size);
|
||||
if (s->l1_size && l1_table == NULL) {
|
||||
ret = -ENOMEM;
|
||||
goto fail;
|
||||
@@ -417,7 +417,7 @@ int qcow2_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)
|
||||
}
|
||||
|
||||
/* Append the new snapshot to the snapshot list */
|
||||
new_snapshot_list = g_malloc((s->nb_snapshots + 1) * sizeof(QCowSnapshot));
|
||||
new_snapshot_list = g_new(QCowSnapshot, s->nb_snapshots + 1);
|
||||
if (s->snapshots) {
|
||||
memcpy(new_snapshot_list, s->snapshots,
|
||||
s->nb_snapshots * sizeof(QCowSnapshot));
|
||||
@@ -661,7 +661,7 @@ int qcow2_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab)
|
||||
return s->nb_snapshots;
|
||||
}
|
||||
|
||||
sn_tab = g_malloc0(s->nb_snapshots * sizeof(QEMUSnapshotInfo));
|
||||
sn_tab = g_new0(QEMUSnapshotInfo, s->nb_snapshots);
|
||||
for(i = 0; i < s->nb_snapshots; i++) {
|
||||
sn_info = sn_tab + i;
|
||||
sn = s->snapshots + i;
|
||||
|
||||
+110
-10
@@ -442,6 +442,22 @@ static QemuOptsList qcow2_runtime_opts = {
|
||||
.type = QEMU_OPT_BOOL,
|
||||
.help = "Check for unintended writes into an inactive L2 table",
|
||||
},
|
||||
{
|
||||
.name = QCOW2_OPT_CACHE_SIZE,
|
||||
.type = QEMU_OPT_SIZE,
|
||||
.help = "Maximum combined metadata (L2 tables and refcount blocks) "
|
||||
"cache size",
|
||||
},
|
||||
{
|
||||
.name = QCOW2_OPT_L2_CACHE_SIZE,
|
||||
.type = QEMU_OPT_SIZE,
|
||||
.help = "Maximum L2 table cache size",
|
||||
},
|
||||
{
|
||||
.name = QCOW2_OPT_REFCOUNT_CACHE_SIZE,
|
||||
.type = QEMU_OPT_SIZE,
|
||||
.help = "Maximum refcount block cache size",
|
||||
},
|
||||
{ /* end of list */ }
|
||||
},
|
||||
};
|
||||
@@ -457,6 +473,61 @@ static const char *overlap_bool_option_names[QCOW2_OL_MAX_BITNR] = {
|
||||
[QCOW2_OL_INACTIVE_L2_BITNR] = QCOW2_OPT_OVERLAP_INACTIVE_L2,
|
||||
};
|
||||
|
||||
static void read_cache_sizes(QemuOpts *opts, uint64_t *l2_cache_size,
|
||||
uint64_t *refcount_cache_size, Error **errp)
|
||||
{
|
||||
uint64_t combined_cache_size;
|
||||
bool l2_cache_size_set, refcount_cache_size_set, combined_cache_size_set;
|
||||
|
||||
combined_cache_size_set = qemu_opt_get(opts, QCOW2_OPT_CACHE_SIZE);
|
||||
l2_cache_size_set = qemu_opt_get(opts, QCOW2_OPT_L2_CACHE_SIZE);
|
||||
refcount_cache_size_set = qemu_opt_get(opts, QCOW2_OPT_REFCOUNT_CACHE_SIZE);
|
||||
|
||||
combined_cache_size = qemu_opt_get_size(opts, QCOW2_OPT_CACHE_SIZE, 0);
|
||||
*l2_cache_size = qemu_opt_get_size(opts, QCOW2_OPT_L2_CACHE_SIZE, 0);
|
||||
*refcount_cache_size = qemu_opt_get_size(opts,
|
||||
QCOW2_OPT_REFCOUNT_CACHE_SIZE, 0);
|
||||
|
||||
if (combined_cache_size_set) {
|
||||
if (l2_cache_size_set && refcount_cache_size_set) {
|
||||
error_setg(errp, QCOW2_OPT_CACHE_SIZE ", " QCOW2_OPT_L2_CACHE_SIZE
|
||||
" and " QCOW2_OPT_REFCOUNT_CACHE_SIZE " may not be set "
|
||||
"the same time");
|
||||
return;
|
||||
} else if (*l2_cache_size > combined_cache_size) {
|
||||
error_setg(errp, QCOW2_OPT_L2_CACHE_SIZE " may not exceed "
|
||||
QCOW2_OPT_CACHE_SIZE);
|
||||
return;
|
||||
} else if (*refcount_cache_size > combined_cache_size) {
|
||||
error_setg(errp, QCOW2_OPT_REFCOUNT_CACHE_SIZE " may not exceed "
|
||||
QCOW2_OPT_CACHE_SIZE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (l2_cache_size_set) {
|
||||
*refcount_cache_size = combined_cache_size - *l2_cache_size;
|
||||
} else if (refcount_cache_size_set) {
|
||||
*l2_cache_size = combined_cache_size - *refcount_cache_size;
|
||||
} else {
|
||||
*refcount_cache_size = combined_cache_size
|
||||
/ (DEFAULT_L2_REFCOUNT_SIZE_RATIO + 1);
|
||||
*l2_cache_size = combined_cache_size - *refcount_cache_size;
|
||||
}
|
||||
} else {
|
||||
if (!l2_cache_size_set && !refcount_cache_size_set) {
|
||||
*l2_cache_size = DEFAULT_L2_CACHE_BYTE_SIZE;
|
||||
*refcount_cache_size = *l2_cache_size
|
||||
/ DEFAULT_L2_REFCOUNT_SIZE_RATIO;
|
||||
} else if (!l2_cache_size_set) {
|
||||
*l2_cache_size = *refcount_cache_size
|
||||
* DEFAULT_L2_REFCOUNT_SIZE_RATIO;
|
||||
} else if (!refcount_cache_size_set) {
|
||||
*refcount_cache_size = *l2_cache_size
|
||||
/ DEFAULT_L2_REFCOUNT_SIZE_RATIO;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int qcow2_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
Error **errp)
|
||||
{
|
||||
@@ -470,6 +541,7 @@ static int qcow2_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
uint64_t l1_vm_state_index;
|
||||
const char *opt_overlap_check;
|
||||
int overlap_check_template = 0;
|
||||
uint64_t l2_cache_size, refcount_cache_size;
|
||||
|
||||
ret = bdrv_pread(bs->file, 0, &header, sizeof(header));
|
||||
if (ret < 0) {
|
||||
@@ -706,9 +778,45 @@ static int qcow2_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
}
|
||||
}
|
||||
|
||||
/* get L2 table/refcount block cache size from command line options */
|
||||
opts = qemu_opts_create(&qcow2_runtime_opts, NULL, 0, &error_abort);
|
||||
qemu_opts_absorb_qdict(opts, options, &local_err);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
ret = -EINVAL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
read_cache_sizes(opts, &l2_cache_size, &refcount_cache_size, &local_err);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
ret = -EINVAL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
l2_cache_size /= s->cluster_size;
|
||||
if (l2_cache_size < MIN_L2_CACHE_SIZE) {
|
||||
l2_cache_size = MIN_L2_CACHE_SIZE;
|
||||
}
|
||||
if (l2_cache_size > INT_MAX) {
|
||||
error_setg(errp, "L2 cache size too big");
|
||||
ret = -EINVAL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
refcount_cache_size /= s->cluster_size;
|
||||
if (refcount_cache_size < MIN_REFCOUNT_CACHE_SIZE) {
|
||||
refcount_cache_size = MIN_REFCOUNT_CACHE_SIZE;
|
||||
}
|
||||
if (refcount_cache_size > INT_MAX) {
|
||||
error_setg(errp, "Refcount cache size too big");
|
||||
ret = -EINVAL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* alloc L2 table/refcount block cache */
|
||||
s->l2_table_cache = qcow2_cache_create(bs, L2_CACHE_SIZE);
|
||||
s->refcount_block_cache = qcow2_cache_create(bs, REFCOUNT_CACHE_SIZE);
|
||||
s->l2_table_cache = qcow2_cache_create(bs, l2_cache_size);
|
||||
s->refcount_block_cache = qcow2_cache_create(bs, refcount_cache_size);
|
||||
if (s->l2_table_cache == NULL || s->refcount_block_cache == NULL) {
|
||||
error_setg(errp, "Could not allocate metadata caches");
|
||||
ret = -ENOMEM;
|
||||
@@ -798,14 +906,6 @@ static int qcow2_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
}
|
||||
|
||||
/* Enable lazy_refcounts according to image and command line options */
|
||||
opts = qemu_opts_create(&qcow2_runtime_opts, NULL, 0, &error_abort);
|
||||
qemu_opts_absorb_qdict(opts, options, &local_err);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
ret = -EINVAL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
s->use_lazy_refcounts = qemu_opt_get_bool(opts, QCOW2_OPT_LAZY_REFCOUNTS,
|
||||
(s->compatible_features & QCOW2_COMPAT_LAZY_REFCOUNTS));
|
||||
|
||||
|
||||
+11
-2
@@ -64,10 +64,16 @@
|
||||
#define MIN_CLUSTER_BITS 9
|
||||
#define MAX_CLUSTER_BITS 21
|
||||
|
||||
#define L2_CACHE_SIZE 16
|
||||
#define MIN_L2_CACHE_SIZE 1 /* cluster */
|
||||
|
||||
/* Must be at least 4 to cover all cases of refcount table growth */
|
||||
#define REFCOUNT_CACHE_SIZE 4
|
||||
#define MIN_REFCOUNT_CACHE_SIZE 4 /* clusters */
|
||||
|
||||
#define DEFAULT_L2_CACHE_BYTE_SIZE 1048576 /* bytes */
|
||||
|
||||
/* The refblock cache needs only a fourth of the L2 cache size to cover as many
|
||||
* clusters */
|
||||
#define DEFAULT_L2_REFCOUNT_SIZE_RATIO 4
|
||||
|
||||
#define DEFAULT_CLUSTER_SIZE 65536
|
||||
|
||||
@@ -85,6 +91,9 @@
|
||||
#define QCOW2_OPT_OVERLAP_SNAPSHOT_TABLE "overlap-check.snapshot-table"
|
||||
#define QCOW2_OPT_OVERLAP_INACTIVE_L1 "overlap-check.inactive-l1"
|
||||
#define QCOW2_OPT_OVERLAP_INACTIVE_L2 "overlap-check.inactive-l2"
|
||||
#define QCOW2_OPT_CACHE_SIZE "cache-size"
|
||||
#define QCOW2_OPT_L2_CACHE_SIZE "l2-cache-size"
|
||||
#define QCOW2_OPT_REFCOUNT_CACHE_SIZE "refcount-cache-size"
|
||||
|
||||
typedef struct QCowHeader {
|
||||
uint32_t magic;
|
||||
|
||||
+1
-2
@@ -227,8 +227,7 @@ int qed_check(BDRVQEDState *s, BdrvCheckResult *result, bool fix)
|
||||
};
|
||||
int ret;
|
||||
|
||||
check.used_clusters = g_try_malloc0(((check.nclusters + 31) / 32) *
|
||||
sizeof(check.used_clusters[0]));
|
||||
check.used_clusters = g_try_new0(uint32_t, (check.nclusters + 31) / 32);
|
||||
if (check.nclusters && check.used_clusters == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
@@ -16,7 +16,12 @@
|
||||
#include <gnutls/gnutls.h>
|
||||
#include <gnutls/crypto.h>
|
||||
#include "block/block_int.h"
|
||||
#include "qapi/qmp/qbool.h"
|
||||
#include "qapi/qmp/qdict.h"
|
||||
#include "qapi/qmp/qint.h"
|
||||
#include "qapi/qmp/qjson.h"
|
||||
#include "qapi/qmp/qlist.h"
|
||||
#include "qapi/qmp/qstring.h"
|
||||
#include "qapi-event.h"
|
||||
|
||||
#define HASH_LENGTH 32
|
||||
@@ -945,6 +950,39 @@ static void quorum_attach_aio_context(BlockDriverState *bs,
|
||||
}
|
||||
}
|
||||
|
||||
static void quorum_refresh_filename(BlockDriverState *bs)
|
||||
{
|
||||
BDRVQuorumState *s = bs->opaque;
|
||||
QDict *opts;
|
||||
QList *children;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < s->num_children; i++) {
|
||||
bdrv_refresh_filename(s->bs[i]);
|
||||
if (!s->bs[i]->full_open_options) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
children = qlist_new();
|
||||
for (i = 0; i < s->num_children; i++) {
|
||||
QINCREF(s->bs[i]->full_open_options);
|
||||
qlist_append_obj(children, QOBJECT(s->bs[i]->full_open_options));
|
||||
}
|
||||
|
||||
opts = qdict_new();
|
||||
qdict_put_obj(opts, "driver", QOBJECT(qstring_from_str("quorum")));
|
||||
qdict_put_obj(opts, QUORUM_OPT_VOTE_THRESHOLD,
|
||||
QOBJECT(qint_from_int(s->threshold)));
|
||||
qdict_put_obj(opts, QUORUM_OPT_BLKVERIFY,
|
||||
QOBJECT(qbool_from_int(s->is_blkverify)));
|
||||
qdict_put_obj(opts, QUORUM_OPT_REWRITE,
|
||||
QOBJECT(qbool_from_int(s->rewrite_corrupted)));
|
||||
qdict_put_obj(opts, "children", QOBJECT(children));
|
||||
|
||||
bs->full_open_options = opts;
|
||||
}
|
||||
|
||||
static BlockDriver bdrv_quorum = {
|
||||
.format_name = "quorum",
|
||||
.protocol_name = "quorum",
|
||||
@@ -953,6 +991,7 @@ static BlockDriver bdrv_quorum = {
|
||||
|
||||
.bdrv_file_open = quorum_open,
|
||||
.bdrv_close = quorum_close,
|
||||
.bdrv_refresh_filename = quorum_refresh_filename,
|
||||
|
||||
.bdrv_co_flush_to_disk = quorum_co_flush,
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user