summaryrefslogtreecommitdiffstats
path: root/block
diff options
context:
space:
mode:
Diffstat (limited to 'block')
-rw-r--r--block/blkdebug.c2
-rw-r--r--block/crypto.c2
-rw-r--r--block/crypto.h2
-rw-r--r--block/dmg-lzfse.c1
-rw-r--r--block/dmg.c2
-rw-r--r--block/export/export.c4
-rw-r--r--block/export/meson.build5
-rw-r--r--block/export/vhost-user-blk-server.c28
-rw-r--r--block/file-posix.c1
-rw-r--r--block/io_uring.c2
-rw-r--r--block/nfs.c13
-rw-r--r--block/qcow2-cluster.c5
-rw-r--r--block/qcow2.c23
-rw-r--r--block/qcow2.h25
-rw-r--r--block/quorum.c5
-rw-r--r--block/vpc.c10
16 files changed, 83 insertions, 47 deletions
diff --git a/block/blkdebug.c b/block/blkdebug.c
index 54da719dd1..5fe6172da9 100644
--- a/block/blkdebug.c
+++ b/block/blkdebug.c
@@ -173,7 +173,7 @@ static int add_rule(void *opaque, QemuOpts *opts, Error **errp)
{
struct add_rule_data *d = opaque;
BDRVBlkdebugState *s = d->s;
- const char* event_name;
+ const char *event_name;
int event;
struct BlkdebugRule *rule;
int64_t sector;
diff --git a/block/crypto.c b/block/crypto.c
index 0807557763..aef5a5721a 100644
--- a/block/crypto.c
+++ b/block/crypto.c
@@ -6,7 +6,7 @@
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
diff --git a/block/crypto.h b/block/crypto.h
index c72c3dec61..72e792c9af 100644
--- a/block/crypto.h
+++ b/block/crypto.h
@@ -6,7 +6,7 @@
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
diff --git a/block/dmg-lzfse.c b/block/dmg-lzfse.c
index 19d25bc646..6798cf4fbf 100644
--- a/block/dmg-lzfse.c
+++ b/block/dmg-lzfse.c
@@ -22,7 +22,6 @@
* THE SOFTWARE.
*/
#include "qemu/osdep.h"
-#include "qemu-common.h"
#include "dmg.h"
#include <lzfse.h>
diff --git a/block/dmg.c b/block/dmg.c
index 0d6c317296..ef35a505f2 100644
--- a/block/dmg.c
+++ b/block/dmg.c
@@ -559,7 +559,7 @@ static void dmg_refresh_limits(BlockDriverState *bs, Error **errp)
bs->bl.request_alignment = BDRV_SECTOR_SIZE; /* No sub-sector I/O */
}
-static inline int is_sector_in_chunk(BDRVDMGState* s,
+static inline int is_sector_in_chunk(BDRVDMGState *s,
uint32_t chunk_num, uint64_t sector_num)
{
if (chunk_num >= s->n_chunks || s->sectors[chunk_num] > sector_num ||
diff --git a/block/export/export.c b/block/export/export.c
index c3478c6c97..bad6f21b1c 100644
--- a/block/export/export.c
+++ b/block/export/export.c
@@ -22,13 +22,13 @@
#include "qapi/qapi-commands-block-export.h"
#include "qapi/qapi-events-block-export.h"
#include "qemu/id.h"
-#if defined(CONFIG_LINUX) && defined(CONFIG_VHOST_USER)
+#ifdef CONFIG_VHOST_USER_BLK_SERVER
#include "vhost-user-blk-server.h"
#endif
static const BlockExportDriver *blk_exp_drivers[] = {
&blk_exp_nbd,
-#if defined(CONFIG_LINUX) && defined(CONFIG_VHOST_USER)
+#ifdef CONFIG_VHOST_USER_BLK_SERVER
&blk_exp_vhost_user_blk,
#endif
};
diff --git a/block/export/meson.build b/block/export/meson.build
index 9fb4fbf81d..135b356775 100644
--- a/block/export/meson.build
+++ b/block/export/meson.build
@@ -1,2 +1,5 @@
blockdev_ss.add(files('export.c'))
-blockdev_ss.add(when: ['CONFIG_LINUX', 'CONFIG_VHOST_USER'], if_true: files('vhost-user-blk-server.c'))
+
+if have_vhost_user_blk_server
+ blockdev_ss.add(files('vhost-user-blk-server.c'))
+endif
diff --git a/block/export/vhost-user-blk-server.c b/block/export/vhost-user-blk-server.c
index 41f4933d6e..62672d1cb9 100644
--- a/block/export/vhost-user-blk-server.c
+++ b/block/export/vhost-user-blk-server.c
@@ -264,9 +264,11 @@ static uint64_t vu_blk_get_protocol_features(VuDev *dev)
static int
vu_blk_get_config(VuDev *vu_dev, uint8_t *config, uint32_t len)
{
- /* TODO blkcfg must be little-endian for VIRTIO 1.0 */
VuServer *server = container_of(vu_dev, VuServer, vu_dev);
VuBlkExport *vexp = container_of(server, VuBlkExport, vu_server);
+
+ g_return_val_if_fail(len <= sizeof(struct virtio_blk_config), -1);
+
memcpy(config, &vexp->blkcfg, len);
return 0;
}
@@ -343,18 +345,18 @@ vu_blk_initialize_config(BlockDriverState *bs,
uint32_t blk_size,
uint16_t num_queues)
{
- config->capacity = bdrv_getlength(bs) >> BDRV_SECTOR_BITS;
- config->blk_size = blk_size;
- config->size_max = 0;
- config->seg_max = 128 - 2;
- config->min_io_size = 1;
- config->opt_io_size = 1;
- config->num_queues = num_queues;
- config->max_discard_sectors = 32768;
- config->max_discard_seg = 1;
- config->discard_sector_alignment = config->blk_size >> 9;
- config->max_write_zeroes_sectors = 32768;
- config->max_write_zeroes_seg = 1;
+ config->capacity = cpu_to_le64(bdrv_getlength(bs) >> BDRV_SECTOR_BITS);
+ config->blk_size = cpu_to_le32(blk_size);
+ config->size_max = cpu_to_le32(0);
+ config->seg_max = cpu_to_le32(128 - 2);
+ config->min_io_size = cpu_to_le16(1);
+ config->opt_io_size = cpu_to_le32(1);
+ config->num_queues = cpu_to_le16(num_queues);
+ config->max_discard_sectors = cpu_to_le32(32768);
+ config->max_discard_seg = cpu_to_le32(1);
+ config->discard_sector_alignment = cpu_to_le32(config->blk_size >> 9);
+ config->max_write_zeroes_sectors = cpu_to_le32(32768);
+ config->max_write_zeroes_seg = cpu_to_le32(1);
}
static void vu_blk_exp_request_shutdown(BlockExport *exp)
diff --git a/block/file-posix.c b/block/file-posix.c
index c63926d592..d5fd1dbcd2 100644
--- a/block/file-posix.c
+++ b/block/file-posix.c
@@ -1698,6 +1698,7 @@ static int handle_aiocb_write_zeroes_unmap(void *opaque)
switch (ret) {
case -ENOTSUP:
case -EINVAL:
+ case -EBUSY:
break;
default:
return ret;
diff --git a/block/io_uring.c b/block/io_uring.c
index 037af09471..00a3ee9fb8 100644
--- a/block/io_uring.c
+++ b/block/io_uring.c
@@ -425,6 +425,6 @@ LuringState *luring_init(Error **errp)
void luring_cleanup(LuringState *s)
{
io_uring_queue_exit(&s->ring);
- g_free(s);
trace_luring_cleanup_state(s);
+ g_free(s);
}
diff --git a/block/nfs.c b/block/nfs.c
index f86e660374..77905f516d 100644
--- a/block/nfs.c
+++ b/block/nfs.c
@@ -24,7 +24,9 @@
#include "qemu/osdep.h"
+#if !defined(_WIN32)
#include <poll.h>
+#endif
#include "qemu/config-file.h"
#include "qemu/error-report.h"
#include "qapi/error.h"
@@ -58,7 +60,7 @@ typedef struct NFSClient {
bool has_zero_init;
AioContext *aio_context;
QemuMutex mutex;
- blkcnt_t st_blocks;
+ uint64_t st_blocks;
bool cache_used;
NFSServer *server;
char *path;
@@ -545,7 +547,9 @@ static int64_t nfs_client_open(NFSClient *client, BlockdevOptionsNfs *opts,
}
ret = DIV_ROUND_UP(st.st_size, BDRV_SECTOR_SIZE);
+#if !defined(_WIN32)
client->st_blocks = st.st_blocks;
+#endif
client->has_zero_init = S_ISREG(st.st_mode);
*strp = '/';
goto out;
@@ -706,6 +710,7 @@ static int nfs_has_zero_init(BlockDriverState *bs)
return client->has_zero_init;
}
+#if !defined(_WIN32)
/* Called (via nfs_service) with QemuMutex held. */
static void
nfs_get_allocated_file_size_cb(int ret, struct nfs_context *nfs, void *data,
@@ -748,6 +753,7 @@ static int64_t nfs_get_allocated_file_size(BlockDriverState *bs)
return (task.ret < 0 ? task.ret : st.st_blocks * 512);
}
+#endif
static int coroutine_fn
nfs_file_co_truncate(BlockDriverState *bs, int64_t offset, bool exact,
@@ -800,7 +806,9 @@ static int nfs_reopen_prepare(BDRVReopenState *state,
nfs_get_error(client->context));
return ret;
}
+#if !defined(_WIN32)
client->st_blocks = st.st_blocks;
+#endif
}
return 0;
@@ -869,7 +877,10 @@ static BlockDriver bdrv_nfs = {
.create_opts = &nfs_create_opts,
.bdrv_has_zero_init = nfs_has_zero_init,
+/* libnfs does not provide the allocated filesize of a file on win32. */
+#if !defined(_WIN32)
.bdrv_get_allocated_file_size = nfs_get_allocated_file_size,
+#endif
.bdrv_co_truncate = nfs_file_co_truncate,
.bdrv_file_open = nfs_file_open,
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index aa87d3e99b..485b4cb92e 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -1049,6 +1049,8 @@ int qcow2_alloc_cluster_link_l2(BlockDriverState *bs, QCowL2Meta *m)
qcow2_cache_entry_mark_dirty(s->l2_table_cache, l2_slice);
assert(l2_index + m->nb_clusters <= s->l2_slice_size);
+ assert(m->cow_end.offset + m->cow_end.nb_bytes <=
+ m->nb_clusters << s->cluster_bits);
for (i = 0; i < m->nb_clusters; i++) {
uint64_t offset = cluster_offset + ((uint64_t)i << s->cluster_bits);
/* if two concurrent writes happen to the same unallocated cluster
@@ -1070,8 +1072,7 @@ int qcow2_alloc_cluster_link_l2(BlockDriverState *bs, QCowL2Meta *m)
if (has_subclusters(s) && !m->prealloc) {
uint64_t l2_bitmap = get_l2_bitmap(s, l2_slice, l2_index + i);
unsigned written_from = m->cow_start.offset;
- unsigned written_to = m->cow_end.offset + m->cow_end.nb_bytes ?:
- m->nb_clusters << s->cluster_bits;
+ unsigned written_to = m->cow_end.offset + m->cow_end.nb_bytes;
int first_sc, last_sc;
/* Narrow written_from and written_to down to the current cluster */
written_from = MAX(written_from, i << s->cluster_bits);
diff --git a/block/qcow2.c b/block/qcow2.c
index 4274806a2a..3a90ef2786 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -269,7 +269,7 @@ static int qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset,
case QCOW2_EXT_MAGIC_FEATURE_TABLE:
if (p_feature_table != NULL) {
- void* feature_table = g_malloc0(ext.len + 2 * sizeof(Qcow2Feature));
+ void *feature_table = g_malloc0(ext.len + 2 * sizeof(Qcow2Feature));
ret = bdrv_pread(bs->file, offset , feature_table, ext.len);
if (ret < 0) {
error_setg_errno(errp, -ret, "ERROR: ext_feature_table: "
@@ -2361,15 +2361,26 @@ static bool merge_cow(uint64_t offset, unsigned bytes,
continue;
}
- /* The data (middle) region must be immediately after the
- * start region */
+ /*
+ * The write request should start immediately after the first
+ * COW region. This does not always happen because the area
+ * touched by the request can be larger than the one defined
+ * by @m (a single request can span an area consisting of a
+ * mix of previously unallocated and allocated clusters, that
+ * is why @l2meta is a list).
+ */
if (l2meta_cow_start(m) + m->cow_start.nb_bytes != offset) {
+ /* In this case the request starts before this region */
+ assert(offset < l2meta_cow_start(m));
+ assert(m->cow_start.nb_bytes == 0);
continue;
}
- /* The end region must be immediately after the data (middle)
- * region */
+ /* The write request should end immediately before the second
+ * COW region (see above for why it does not always happen) */
if (m->offset + m->cow_end.offset != offset + bytes) {
+ assert(offset + bytes > m->offset + m->cow_end.offset);
+ assert(m->cow_end.nb_bytes == 0);
continue;
}
@@ -3377,7 +3388,7 @@ qcow2_co_create(BlockdevCreateOptions *create_options, Error **errp)
size_t cluster_size;
int version;
int refcount_order;
- uint64_t* refcount_table;
+ uint64_t *refcount_table;
int ret;
uint8_t compression_type = QCOW2_COMPRESSION_TYPE_ZLIB;
diff --git a/block/qcow2.h b/block/qcow2.h
index 125ea9679b..0678073b74 100644
--- a/block/qcow2.h
+++ b/block/qcow2.h
@@ -343,8 +343,8 @@ typedef struct BDRVQcow2State {
uint64_t l1_table_offset;
uint64_t *l1_table;
- Qcow2Cache* l2_table_cache;
- Qcow2Cache* refcount_block_cache;
+ Qcow2Cache *l2_table_cache;
+ Qcow2Cache *refcount_block_cache;
QEMUTimer *cache_clean_timer;
unsigned cache_clean_interval;
@@ -394,7 +394,7 @@ typedef struct BDRVQcow2State {
uint64_t autoclear_features;
size_t unknown_header_fields_size;
- void* unknown_header_fields;
+ void *unknown_header_fields;
QLIST_HEAD(, Qcow2UnknownHeaderExtension) unknown_header_ext;
QTAILQ_HEAD (, Qcow2DiscardRegion) discards;
bool cache_discards;
@@ -435,17 +435,18 @@ typedef struct Qcow2COWRegion {
/**
* Describes an in-flight (part of a) write request that writes to clusters
- * that are not referenced in their L2 table yet.
+ * that need to have their L2 table entries updated (because they are
+ * newly allocated or need changes in their L2 bitmaps)
*/
typedef struct QCowL2Meta
{
- /** Guest offset of the first newly allocated cluster */
+ /** Guest offset of the first updated cluster */
uint64_t offset;
- /** Host offset of the first newly allocated cluster */
+ /** Host offset of the first updated cluster */
uint64_t alloc_offset;
- /** Number of newly allocated clusters */
+ /** Number of updated clusters */
int nb_clusters;
/** Do not free the old clusters */
@@ -458,14 +459,16 @@ typedef struct QCowL2Meta
CoQueue dependent_requests;
/**
- * The COW Region between the start of the first allocated cluster and the
- * area the guest actually writes to.
+ * The COW Region immediately before the area the guest actually
+ * writes to. This (part of the) write request starts at
+ * cow_start.offset + cow_start.nb_bytes.
*/
Qcow2COWRegion cow_start;
/**
- * The COW Region between the area the guest actually writes to and the
- * end of the last allocated cluster.
+ * The COW Region immediately after the area the guest actually
+ * writes to. This (part of the) write request ends at cow_end.offset
+ * (which must always be set even when cow_end.nb_bytes is 0).
*/
Qcow2COWRegion cow_end;
diff --git a/block/quorum.c b/block/quorum.c
index e846a7e892..b10fc2089e 100644
--- a/block/quorum.c
+++ b/block/quorum.c
@@ -1163,7 +1163,12 @@ static void quorum_child_perm(BlockDriverState *bs, BdrvChild *c,
uint64_t perm, uint64_t shared,
uint64_t *nperm, uint64_t *nshared)
{
+ BDRVQuorumState *s = bs->opaque;
+
*nperm = perm & DEFAULT_PERM_PASSTHROUGH;
+ if (s->rewrite_corrupted) {
+ *nperm |= BLK_PERM_WRITE;
+ }
/*
* We cannot share RESIZE or WRITE, as this would make the
diff --git a/block/vpc.c b/block/vpc.c
index 890554277e..1ab55f9287 100644
--- a/block/vpc.c
+++ b/block/vpc.c
@@ -172,7 +172,7 @@ static QemuOptsList vpc_runtime_opts = {
static QemuOptsList vpc_create_opts;
-static uint32_t vpc_checksum(uint8_t* buf, size_t size)
+static uint32_t vpc_checksum(uint8_t *buf, size_t size)
{
uint32_t res = 0;
int i;
@@ -528,7 +528,7 @@ static inline int64_t get_image_offset(BlockDriverState *bs, uint64_t offset,
*
* Returns 0 on success and < 0 on error
*/
-static int rewrite_footer(BlockDriverState* bs)
+static int rewrite_footer(BlockDriverState *bs)
{
int ret;
BDRVVPCState *s = bs->opaque;
@@ -548,7 +548,7 @@ static int rewrite_footer(BlockDriverState* bs)
*
* Returns the sectors' offset in the image file on success and < 0 on error
*/
-static int64_t alloc_block(BlockDriverState* bs, int64_t offset)
+static int64_t alloc_block(BlockDriverState *bs, int64_t offset)
{
BDRVVPCState *s = bs->opaque;
int64_t bat_offset;
@@ -781,8 +781,8 @@ static int coroutine_fn vpc_co_block_status(BlockDriverState *bs,
* the hardware EIDE and ATA-2 limit of 16 heads (max disk size of 127 GB)
* and instead allow up to 255 heads.
*/
-static int calculate_geometry(int64_t total_sectors, uint16_t* cyls,
- uint8_t* heads, uint8_t* secs_per_cyl)
+static int calculate_geometry(int64_t total_sectors, uint16_t *cyls,
+ uint8_t *heads, uint8_t *secs_per_cyl)
{
uint32_t cyls_times_heads;