diff options
Diffstat (limited to 'block')
| -rw-r--r-- | block/nfs.c | 49 | ||||
| -rw-r--r-- | block/qapi.c | 99 | ||||
| -rw-r--r-- | block/qcow2-refcount.c | 24 | ||||
| -rw-r--r-- | block/qcow2.c | 1 | ||||
| -rw-r--r-- | block/qcow2.h | 1 | ||||
| -rw-r--r-- | block/vmdk.c | 4 |
6 files changed, 95 insertions, 83 deletions
diff --git a/block/nfs.c b/block/nfs.c index a564340d15..689eaa792e 100644 --- a/block/nfs.c +++ b/block/nfs.c @@ -108,12 +108,13 @@ static int nfs_parse_uri(const char *filename, QDict *options, Error **errp) qdict_put(options, "path", qstring_from_str(uri->path)); for (i = 0; i < qp->n; i++) { + unsigned long long val; if (!qp->p[i].value) { error_setg(errp, "Value for NFS parameter expected: %s", qp->p[i].name); goto out; } - if (parse_uint_full(qp->p[i].value, NULL, 0)) { + if (parse_uint_full(qp->p[i].value, &val, 0)) { error_setg(errp, "Illegal value for NFS parameter: %s", qp->p[i].name); goto out; @@ -358,27 +359,27 @@ static QemuOptsList runtime_opts = { .help = "Path of the image on the host", }, { - .name = "uid", + .name = "user", .type = QEMU_OPT_NUMBER, .help = "UID value to use when talking to the server", }, { - .name = "gid", + .name = "group", .type = QEMU_OPT_NUMBER, .help = "GID value to use when talking to the server", }, { - .name = "tcp-syncnt", + .name = "tcp-syn-count", .type = QEMU_OPT_NUMBER, .help = "Number of SYNs to send during the session establish", }, { - .name = "readahead", + .name = "readahead-size", .type = QEMU_OPT_NUMBER, .help = "Set the readahead size in bytes", }, { - .name = "pagecache", + .name = "page-cache-size", .type = QEMU_OPT_NUMBER, .help = "Set the pagecache size in bytes", }, @@ -507,29 +508,29 @@ static int64_t nfs_client_open(NFSClient *client, QDict *options, goto fail; } - if (qemu_opt_get(opts, "uid")) { - client->uid = qemu_opt_get_number(opts, "uid", 0); + if (qemu_opt_get(opts, "user")) { + client->uid = qemu_opt_get_number(opts, "user", 0); nfs_set_uid(client->context, client->uid); } - if (qemu_opt_get(opts, "gid")) { - client->gid = qemu_opt_get_number(opts, "gid", 0); + if (qemu_opt_get(opts, "group")) { + client->gid = qemu_opt_get_number(opts, "group", 0); nfs_set_gid(client->context, client->gid); } - if (qemu_opt_get(opts, "tcp-syncnt")) { - client->tcp_syncnt = qemu_opt_get_number(opts, "tcp-syncnt", 0); + if (qemu_opt_get(opts, "tcp-syn-count")) { + client->tcp_syncnt = qemu_opt_get_number(opts, "tcp-syn-count", 0); nfs_set_tcp_syncnt(client->context, client->tcp_syncnt); } #ifdef LIBNFS_FEATURE_READAHEAD - if (qemu_opt_get(opts, "readahead")) { + if (qemu_opt_get(opts, "readahead-size")) { if (open_flags & BDRV_O_NOCACHE) { error_setg(errp, "Cannot enable NFS readahead " "if cache.direct = on"); goto fail; } - client->readahead = qemu_opt_get_number(opts, "readahead", 0); + client->readahead = qemu_opt_get_number(opts, "readahead-size", 0); if (client->readahead > QEMU_NFS_MAX_READAHEAD_SIZE) { error_report("NFS Warning: Truncating NFS readahead " "size to %d", QEMU_NFS_MAX_READAHEAD_SIZE); @@ -544,13 +545,13 @@ static int64_t nfs_client_open(NFSClient *client, QDict *options, #endif #ifdef LIBNFS_FEATURE_PAGECACHE - if (qemu_opt_get(opts, "pagecache")) { + if (qemu_opt_get(opts, "page-cache-size")) { if (open_flags & BDRV_O_NOCACHE) { error_setg(errp, "Cannot enable NFS pagecache " "if cache.direct = on"); goto fail; } - client->pagecache = qemu_opt_get_number(opts, "pagecache", 0); + client->pagecache = qemu_opt_get_number(opts, "page-cache-size", 0); if (client->pagecache > QEMU_NFS_MAX_PAGECACHE_SIZE) { error_report("NFS Warning: Truncating NFS pagecache " "size to %d pages", QEMU_NFS_MAX_PAGECACHE_SIZE); @@ -803,22 +804,22 @@ static void nfs_refresh_filename(BlockDriverState *bs, QDict *options) qdict_put(opts, "path", qstring_from_str(client->path)); if (client->uid) { - qdict_put(opts, "uid", qint_from_int(client->uid)); + qdict_put(opts, "user", qint_from_int(client->uid)); } if (client->gid) { - qdict_put(opts, "gid", qint_from_int(client->gid)); + qdict_put(opts, "group", qint_from_int(client->gid)); } if (client->tcp_syncnt) { - qdict_put(opts, "tcp-syncnt", - qint_from_int(client->tcp_syncnt)); + qdict_put(opts, "tcp-syn-cnt", + qint_from_int(client->tcp_syncnt)); } if (client->readahead) { - qdict_put(opts, "readahead", - qint_from_int(client->readahead)); + qdict_put(opts, "readahead-size", + qint_from_int(client->readahead)); } if (client->pagecache) { - qdict_put(opts, "pagecache", - qint_from_int(client->pagecache)); + qdict_put(opts, "page-cache-size", + qint_from_int(client->pagecache)); } if (client->debug) { qdict_put(opts, "debug", qint_from_int(client->debug)); diff --git a/block/qapi.c b/block/qapi.c index a62e862f3c..ac480aa93c 100644 --- a/block/qapi.c +++ b/block/qapi.c @@ -237,8 +237,8 @@ void bdrv_query_image_info(BlockDriverState *bs, size = bdrv_getlength(bs); if (size < 0) { - error_setg_errno(errp, -size, "Can't get size of device '%s'", - bdrv_get_device_name(bs)); + error_setg_errno(errp, -size, "Can't get image size '%s'", + bs->exact_filename); goto out; } @@ -357,10 +357,6 @@ static void bdrv_query_info(BlockBackend *blk, BlockInfo **p_info, qapi_free_BlockInfo(info); } -static BlockStats *bdrv_query_stats(BlockBackend *blk, - const BlockDriverState *bs, - bool query_backing); - static void bdrv_query_blk_stats(BlockDeviceStats *ds, BlockBackend *blk) { BlockAcctStats *stats = blk_get_stats(blk); @@ -428,9 +424,18 @@ static void bdrv_query_blk_stats(BlockDeviceStats *ds, BlockBackend *blk) } } -static void bdrv_query_bds_stats(BlockStats *s, const BlockDriverState *bs, +static BlockStats *bdrv_query_bds_stats(const BlockDriverState *bs, bool query_backing) { + BlockStats *s = NULL; + + s = g_malloc0(sizeof(*s)); + s->stats = g_malloc0(sizeof(*s->stats)); + + if (!bs) { + return s; + } + if (bdrv_get_node_name(bs)[0]) { s->has_node_name = true; s->node_name = g_strdup(bdrv_get_node_name(bs)); @@ -440,32 +445,12 @@ static void bdrv_query_bds_stats(BlockStats *s, const BlockDriverState *bs, if (bs->file) { s->has_parent = true; - s->parent = bdrv_query_stats(NULL, bs->file->bs, query_backing); + s->parent = bdrv_query_bds_stats(bs->file->bs, query_backing); } if (query_backing && bs->backing) { s->has_backing = true; - s->backing = bdrv_query_stats(NULL, bs->backing->bs, query_backing); - } - -} - -static BlockStats *bdrv_query_stats(BlockBackend *blk, - const BlockDriverState *bs, - bool query_backing) -{ - BlockStats *s; - - s = g_malloc0(sizeof(*s)); - s->stats = g_malloc0(sizeof(*s->stats)); - - if (blk) { - s->has_device = true; - s->device = g_strdup(blk_name(blk)); - bdrv_query_blk_stats(s->stats, blk); - } - if (bs) { - bdrv_query_bds_stats(s, bs, query_backing); + s->backing = bdrv_query_bds_stats(bs->backing->bs, query_backing); } return s; @@ -494,42 +479,44 @@ BlockInfoList *qmp_query_block(Error **errp) return head; } -static bool next_query_bds(BlockBackend **blk, BlockDriverState **bs, - bool query_nodes) -{ - if (query_nodes) { - *bs = bdrv_next_node(*bs); - return !!*bs; - } - - *blk = blk_next(*blk); - *bs = *blk ? blk_bs(*blk) : NULL; - - return !!*blk; -} - BlockStatsList *qmp_query_blockstats(bool has_query_nodes, bool query_nodes, Error **errp) { BlockStatsList *head = NULL, **p_next = &head; - BlockBackend *blk = NULL; - BlockDriverState *bs = NULL; + BlockBackend *blk; + BlockDriverState *bs; /* Just to be safe if query_nodes is not always initialized */ - query_nodes = has_query_nodes && query_nodes; - - while (next_query_bds(&blk, &bs, query_nodes)) { - BlockStatsList *info = g_malloc0(sizeof(*info)); - AioContext *ctx = blk ? blk_get_aio_context(blk) - : bdrv_get_aio_context(bs); + if (has_query_nodes && query_nodes) { + for (bs = bdrv_next_node(NULL); bs; bs = bdrv_next_node(bs)) { + BlockStatsList *info = g_malloc0(sizeof(*info)); + AioContext *ctx = bdrv_get_aio_context(bs); - aio_context_acquire(ctx); - info->value = bdrv_query_stats(blk, bs, !query_nodes); - aio_context_release(ctx); + aio_context_acquire(ctx); + info->value = bdrv_query_bds_stats(bs, false); + aio_context_release(ctx); - *p_next = info; - p_next = &info->next; + *p_next = info; + p_next = &info->next; + } + } else { + for (blk = blk_next(NULL); blk; blk = blk_next(blk)) { + BlockStatsList *info = g_malloc0(sizeof(*info)); + AioContext *ctx = blk_get_aio_context(blk); + BlockStats *s; + + aio_context_acquire(ctx); + s = bdrv_query_bds_stats(blk_bs(blk), true); + s->has_device = true; + s->device = g_strdup(blk_name(blk)); + bdrv_query_blk_stats(s->stats, blk); + aio_context_release(ctx); + + info->value = s; + *p_next = info; + p_next = &info->next; + } } return head; diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c index cbfb3fe064..3dbde18612 100644 --- a/block/qcow2-refcount.c +++ b/block/qcow2-refcount.c @@ -83,6 +83,16 @@ static Qcow2SetRefcountFunc *const set_refcount_funcs[] = { /*********************************************************/ /* refcount handling */ +static void update_max_refcount_table_index(BDRVQcow2State *s) +{ + unsigned i = s->refcount_table_size - 1; + while (i > 0 && (s->refcount_table[i] & REFT_OFFSET_MASK) == 0) { + i--; + } + /* Set s->max_refcount_table_index to the index of the last used entry */ + s->max_refcount_table_index = i; +} + int qcow2_refcount_init(BlockDriverState *bs) { BDRVQcow2State *s = bs->opaque; @@ -111,6 +121,7 @@ int qcow2_refcount_init(BlockDriverState *bs) } for(i = 0; i < s->refcount_table_size; i++) be64_to_cpus(&s->refcount_table[i]); + update_max_refcount_table_index(s); } return 0; fail: @@ -439,6 +450,10 @@ static int alloc_refcount_block(BlockDriverState *bs, } s->refcount_table[refcount_table_index] = new_block; + /* If there's a hole in s->refcount_table then it can happen + * that refcount_table_index < s->max_refcount_table_index */ + s->max_refcount_table_index = + MAX(s->max_refcount_table_index, refcount_table_index); /* The new refcount block may be where the caller intended to put its * data, so let it restart the search. */ @@ -580,6 +595,7 @@ static int alloc_refcount_block(BlockDriverState *bs, s->refcount_table = new_table; s->refcount_table_size = table_size; s->refcount_table_offset = table_offset; + update_max_refcount_table_index(s); /* Free old table. */ qcow2_free_clusters(bs, old_table_offset, old_table_size * sizeof(uint64_t), @@ -2171,6 +2187,7 @@ write_refblocks: s->refcount_table = on_disk_reftable; s->refcount_table_offset = reftable_offset; s->refcount_table_size = reftable_size; + update_max_refcount_table_index(s); return 0; @@ -2383,7 +2400,11 @@ int qcow2_check_metadata_overlap(BlockDriverState *bs, int ign, int64_t offset, } if ((chk & QCOW2_OL_REFCOUNT_BLOCK) && s->refcount_table) { - for (i = 0; i < s->refcount_table_size; i++) { + unsigned last_entry = s->max_refcount_table_index; + assert(last_entry < s->refcount_table_size); + assert(last_entry + 1 == s->refcount_table_size || + (s->refcount_table[last_entry + 1] & REFT_OFFSET_MASK) == 0); + for (i = 0; i <= last_entry; i++) { if ((s->refcount_table[i] & REFT_OFFSET_MASK) && overlaps_with(s->refcount_table[i] & REFT_OFFSET_MASK, s->cluster_size)) { @@ -2871,6 +2892,7 @@ int qcow2_change_refcount_order(BlockDriverState *bs, int refcount_order, /* Now update the rest of the in-memory information */ old_reftable = s->refcount_table; s->refcount_table = new_reftable; + update_max_refcount_table_index(s); s->refcount_bits = 1 << refcount_order; s->refcount_max = UINT64_C(1) << (s->refcount_bits - 1); diff --git a/block/qcow2.c b/block/qcow2.c index 96fb8a8f16..3e274bd1ba 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -2743,6 +2743,7 @@ static int make_completely_empty(BlockDriverState *bs) s->refcount_table_offset = s->cluster_size; s->refcount_table_size = s->cluster_size / sizeof(uint64_t); + s->max_refcount_table_index = 0; g_free(s->refcount_table); s->refcount_table = new_reftable; diff --git a/block/qcow2.h b/block/qcow2.h index 182341483a..f8aeb08794 100644 --- a/block/qcow2.h +++ b/block/qcow2.h @@ -251,6 +251,7 @@ typedef struct BDRVQcow2State { uint64_t *refcount_table; uint64_t refcount_table_offset; uint32_t refcount_table_size; + uint32_t max_refcount_table_index; /* Last used entry in refcount_table */ uint64_t free_cluster_index; uint64_t free_byte_offset; diff --git a/block/vmdk.c b/block/vmdk.c index 7750212969..393c84d8b1 100644 --- a/block/vmdk.c +++ b/block/vmdk.c @@ -1361,8 +1361,8 @@ static int vmdk_write_extent(VmdkExtent *extent, int64_t cluster_offset, goto out; } - data->lba = offset >> BDRV_SECTOR_BITS; - data->size = buf_len; + data->lba = cpu_to_le64(offset >> BDRV_SECTOR_BITS); + data->size = cpu_to_le32(buf_len); n_bytes = buf_len + sizeof(VmdkGrainMarker); iov = (struct iovec) { |