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 layer patches: - iotests: Fix output of qemu-io related tests - Don't ignore bdrv_set_aio_context() for nodes with bs->drv = NUL - vmdk: Set vmdk parent backing_format to vmdk - qcow2: Preallocation fixes (especially for external data files) - Add linear-buffer-based APIs (as wrappers around qiov-based ones) - Various code cleanups and small corner case fixes # gpg: Signature made Tue 30 Apr 2019 16:35:09 BST # gpg: using RSA key 7F09B272C88F2FD6 # gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>" [full] # Primary key fingerprint: DC3D EB15 9A9A F95D 3D74 56FE 7F09 B272 C88F 2FD6 * remotes/kevin/tags/for-upstream: (27 commits) block/qed: add missed coroutine_fn markers iotests: Check that images are in read-only mode after block-commit commit: Make base read-only if there is an early failure qemu-img: use buffer-based io block/stream: use buffer-based io block/commit: use buffer-based io block/backup: use buffer-based io block/parallels: use buffer-based io block/qed: use buffer-based io block/qcow: use buffer-based io block/qcow2: use buffer-based io block: introduce byte-based io helpers qcow2: Fix error handling in the compression code qcow2: Fix qcow2_make_empty() with external data file qemu-img: Make create hint at protocol options iotests: Perform the correct test in 082 qcow2: Fix full preallocation with external data file qcow2: Add errp to preallocate_co() qcow2: Avoid COW during metadata preallocation qemu-img: Saner printing of large file sizes ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
@@ -5672,10 +5672,6 @@ void bdrv_detach_aio_context(BlockDriverState *bs)
|
||||
BdrvAioNotifier *baf, *baf_tmp;
|
||||
BdrvChild *child;
|
||||
|
||||
if (!bs->drv) {
|
||||
return;
|
||||
}
|
||||
|
||||
assert(!bs->walking_aio_notifiers);
|
||||
bs->walking_aio_notifiers = true;
|
||||
QLIST_FOREACH_SAFE(baf, &bs->aio_notifiers, list, baf_tmp) {
|
||||
@@ -5690,7 +5686,7 @@ void bdrv_detach_aio_context(BlockDriverState *bs)
|
||||
*/
|
||||
bs->walking_aio_notifiers = false;
|
||||
|
||||
if (bs->drv->bdrv_detach_aio_context) {
|
||||
if (bs->drv && bs->drv->bdrv_detach_aio_context) {
|
||||
bs->drv->bdrv_detach_aio_context(bs);
|
||||
}
|
||||
QLIST_FOREACH(child, &bs->children, next) {
|
||||
@@ -5709,10 +5705,6 @@ void bdrv_attach_aio_context(BlockDriverState *bs,
|
||||
BdrvAioNotifier *ban, *ban_tmp;
|
||||
BdrvChild *child;
|
||||
|
||||
if (!bs->drv) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (bs->quiesce_counter) {
|
||||
aio_disable_external(new_context);
|
||||
}
|
||||
@@ -5722,7 +5714,7 @@ void bdrv_attach_aio_context(BlockDriverState *bs,
|
||||
QLIST_FOREACH(child, &bs->children, next) {
|
||||
bdrv_attach_aio_context(child->bs, new_context);
|
||||
}
|
||||
if (bs->drv->bdrv_attach_aio_context) {
|
||||
if (bs->drv && bs->drv->bdrv_attach_aio_context) {
|
||||
bs->drv->bdrv_attach_aio_context(bs, new_context);
|
||||
}
|
||||
|
||||
|
||||
+6
-8
@@ -107,7 +107,6 @@ static int coroutine_fn backup_cow_with_bounce_buffer(BackupBlockJob *job,
|
||||
void **bounce_buffer)
|
||||
{
|
||||
int ret;
|
||||
QEMUIOVector qiov;
|
||||
BlockBackend *blk = job->common.blk;
|
||||
int nbytes;
|
||||
int read_flags = is_write_notifier ? BDRV_REQ_NO_SERIALISING : 0;
|
||||
@@ -118,9 +117,8 @@ static int coroutine_fn backup_cow_with_bounce_buffer(BackupBlockJob *job,
|
||||
if (!*bounce_buffer) {
|
||||
*bounce_buffer = blk_blockalign(blk, job->cluster_size);
|
||||
}
|
||||
qemu_iovec_init_buf(&qiov, *bounce_buffer, nbytes);
|
||||
|
||||
ret = blk_co_preadv(blk, start, qiov.size, &qiov, read_flags);
|
||||
ret = blk_co_pread(blk, start, nbytes, *bounce_buffer, read_flags);
|
||||
if (ret < 0) {
|
||||
trace_backup_do_cow_read_fail(job, start, ret);
|
||||
if (error_is_read) {
|
||||
@@ -129,13 +127,13 @@ static int coroutine_fn backup_cow_with_bounce_buffer(BackupBlockJob *job,
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (qemu_iovec_is_zero(&qiov)) {
|
||||
if (buffer_is_zero(*bounce_buffer, nbytes)) {
|
||||
ret = blk_co_pwrite_zeroes(job->target, start,
|
||||
qiov.size, write_flags | BDRV_REQ_MAY_UNMAP);
|
||||
nbytes, write_flags | BDRV_REQ_MAY_UNMAP);
|
||||
} else {
|
||||
ret = blk_co_pwritev(job->target, start,
|
||||
qiov.size, &qiov, write_flags |
|
||||
(job->compress ? BDRV_REQ_WRITE_COMPRESSED : 0));
|
||||
ret = blk_co_pwrite(job->target, start,
|
||||
nbytes, *bounce_buffer, write_flags |
|
||||
(job->compress ? BDRV_REQ_WRITE_COMPRESSED : 0));
|
||||
}
|
||||
if (ret < 0) {
|
||||
trace_backup_do_cow_write_fail(job, start, ret);
|
||||
|
||||
+5
-3
@@ -48,16 +48,15 @@ static int coroutine_fn commit_populate(BlockBackend *bs, BlockBackend *base,
|
||||
void *buf)
|
||||
{
|
||||
int ret = 0;
|
||||
QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, bytes);
|
||||
|
||||
assert(bytes < SIZE_MAX);
|
||||
|
||||
ret = blk_co_preadv(bs, offset, qiov.size, &qiov, 0);
|
||||
ret = blk_co_pread(bs, offset, bytes, buf, 0);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = blk_co_pwritev(base, offset, qiov.size, &qiov, 0);
|
||||
ret = blk_co_pwrite(base, offset, bytes, buf, 0);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
@@ -384,6 +383,9 @@ fail:
|
||||
if (s->top) {
|
||||
blk_unref(s->top);
|
||||
}
|
||||
if (s->base_read_only) {
|
||||
bdrv_reopen_set_read_only(base, true, NULL);
|
||||
}
|
||||
job_early_fail(&s->common.job);
|
||||
/* commit_top_bs has to be replaced after deleting the block job,
|
||||
* otherwise this would fail because of lack of permissions. */
|
||||
|
||||
+6
-8
@@ -220,20 +220,18 @@ static int64_t allocate_clusters(BlockDriverState *bs, int64_t sector_num,
|
||||
if (bs->backing) {
|
||||
int64_t nb_cow_sectors = to_allocate * s->tracks;
|
||||
int64_t nb_cow_bytes = nb_cow_sectors << BDRV_SECTOR_BITS;
|
||||
QEMUIOVector qiov =
|
||||
QEMU_IOVEC_INIT_BUF(qiov, qemu_blockalign(bs, nb_cow_bytes),
|
||||
nb_cow_bytes);
|
||||
void *buf = qemu_blockalign(bs, nb_cow_bytes);
|
||||
|
||||
ret = bdrv_co_preadv(bs->backing, idx * s->tracks * BDRV_SECTOR_SIZE,
|
||||
nb_cow_bytes, &qiov, 0);
|
||||
ret = bdrv_co_pread(bs->backing, idx * s->tracks * BDRV_SECTOR_SIZE,
|
||||
nb_cow_bytes, buf, 0);
|
||||
if (ret < 0) {
|
||||
qemu_vfree(qemu_iovec_buf(&qiov));
|
||||
qemu_vfree(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = bdrv_co_pwritev(bs->file, s->data_end * BDRV_SECTOR_SIZE,
|
||||
nb_cow_bytes, &qiov, 0);
|
||||
qemu_vfree(qemu_iovec_buf(&qiov));
|
||||
nb_cow_bytes, buf, 0);
|
||||
qemu_vfree(buf);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
+11
-38
@@ -631,42 +631,13 @@ BlockStatsList *qmp_query_blockstats(bool has_query_nodes,
|
||||
return head;
|
||||
}
|
||||
|
||||
#define NB_SUFFIXES 4
|
||||
|
||||
static char *get_human_readable_size(char *buf, int buf_size, int64_t size)
|
||||
{
|
||||
static const char suffixes[NB_SUFFIXES] = {'K', 'M', 'G', 'T'};
|
||||
int64_t base;
|
||||
int i;
|
||||
|
||||
if (size <= 999) {
|
||||
snprintf(buf, buf_size, "%" PRId64, size);
|
||||
} else {
|
||||
base = 1024;
|
||||
for (i = 0; i < NB_SUFFIXES; i++) {
|
||||
if (size < (10 * base)) {
|
||||
snprintf(buf, buf_size, "%0.1f%c",
|
||||
(double)size / base,
|
||||
suffixes[i]);
|
||||
break;
|
||||
} else if (size < (1000 * base) || i == (NB_SUFFIXES - 1)) {
|
||||
snprintf(buf, buf_size, "%" PRId64 "%c",
|
||||
((size + (base >> 1)) / base),
|
||||
suffixes[i]);
|
||||
break;
|
||||
}
|
||||
base = base * 1024;
|
||||
}
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
void bdrv_snapshot_dump(QEMUSnapshotInfo *sn)
|
||||
{
|
||||
char buf1[128], date_buf[128], clock_buf[128];
|
||||
char date_buf[128], clock_buf[128];
|
||||
struct tm tm;
|
||||
time_t ti;
|
||||
int64_t secs;
|
||||
char *sizing = NULL;
|
||||
|
||||
if (!sn) {
|
||||
qemu_printf("%-10s%-20s%7s%20s%15s",
|
||||
@@ -683,13 +654,14 @@ void bdrv_snapshot_dump(QEMUSnapshotInfo *sn)
|
||||
(int)((secs / 60) % 60),
|
||||
(int)(secs % 60),
|
||||
(int)((sn->vm_clock_nsec / 1000000) % 1000));
|
||||
sizing = size_to_str(sn->vm_state_size);
|
||||
qemu_printf("%-10s%-20s%7s%20s%15s",
|
||||
sn->id_str, sn->name,
|
||||
get_human_readable_size(buf1, sizeof(buf1),
|
||||
sn->vm_state_size),
|
||||
sizing,
|
||||
date_buf,
|
||||
clock_buf);
|
||||
}
|
||||
g_free(sizing);
|
||||
}
|
||||
|
||||
static void dump_qdict(int indentation, QDict *dict);
|
||||
@@ -787,14 +759,13 @@ void bdrv_image_info_specific_dump(ImageInfoSpecific *info_spec)
|
||||
|
||||
void bdrv_image_info_dump(ImageInfo *info)
|
||||
{
|
||||
char size_buf[128], dsize_buf[128];
|
||||
char *size_buf, *dsize_buf;
|
||||
if (!info->has_actual_size) {
|
||||
snprintf(dsize_buf, sizeof(dsize_buf), "unavailable");
|
||||
dsize_buf = g_strdup("unavailable");
|
||||
} else {
|
||||
get_human_readable_size(dsize_buf, sizeof(dsize_buf),
|
||||
info->actual_size);
|
||||
dsize_buf = size_to_str(info->actual_size);
|
||||
}
|
||||
get_human_readable_size(size_buf, sizeof(size_buf), info->virtual_size);
|
||||
size_buf = size_to_str(info->virtual_size);
|
||||
qemu_printf("image: %s\n"
|
||||
"file format: %s\n"
|
||||
"virtual size: %s (%" PRId64 " bytes)\n"
|
||||
@@ -802,6 +773,8 @@ void bdrv_image_info_dump(ImageInfo *info)
|
||||
info->filename, info->format, size_buf,
|
||||
info->virtual_size,
|
||||
dsize_buf);
|
||||
g_free(size_buf);
|
||||
g_free(dsize_buf);
|
||||
|
||||
if (info->has_encrypted && info->encrypted) {
|
||||
qemu_printf("encrypted: yes\n");
|
||||
|
||||
+6
-13
@@ -631,7 +631,6 @@ static coroutine_fn int qcow_co_preadv(BlockDriverState *bs, uint64_t offset,
|
||||
int offset_in_cluster;
|
||||
int ret = 0, n;
|
||||
uint64_t cluster_offset;
|
||||
QEMUIOVector hd_qiov;
|
||||
uint8_t *buf;
|
||||
void *orig_buf;
|
||||
|
||||
@@ -663,11 +662,10 @@ static coroutine_fn int qcow_co_preadv(BlockDriverState *bs, uint64_t offset,
|
||||
if (!cluster_offset) {
|
||||
if (bs->backing) {
|
||||
/* read from the base image */
|
||||
qemu_iovec_init_buf(&hd_qiov, buf, n);
|
||||
qemu_co_mutex_unlock(&s->lock);
|
||||
/* qcow2 emits this on bs->file instead of bs->backing */
|
||||
BLKDBG_EVENT(bs->file, BLKDBG_READ_BACKING_AIO);
|
||||
ret = bdrv_co_preadv(bs->backing, offset, n, &hd_qiov, 0);
|
||||
ret = bdrv_co_pread(bs->backing, offset, n, buf, 0);
|
||||
qemu_co_mutex_lock(&s->lock);
|
||||
if (ret < 0) {
|
||||
break;
|
||||
@@ -688,11 +686,10 @@ static coroutine_fn int qcow_co_preadv(BlockDriverState *bs, uint64_t offset,
|
||||
ret = -EIO;
|
||||
break;
|
||||
}
|
||||
qemu_iovec_init_buf(&hd_qiov, buf, n);
|
||||
qemu_co_mutex_unlock(&s->lock);
|
||||
BLKDBG_EVENT(bs->file, BLKDBG_READ_AIO);
|
||||
ret = bdrv_co_preadv(bs->file, cluster_offset + offset_in_cluster,
|
||||
n, &hd_qiov, 0);
|
||||
ret = bdrv_co_pread(bs->file, cluster_offset + offset_in_cluster,
|
||||
n, buf, 0);
|
||||
qemu_co_mutex_lock(&s->lock);
|
||||
if (ret < 0) {
|
||||
break;
|
||||
@@ -731,7 +728,6 @@ static coroutine_fn int qcow_co_pwritev(BlockDriverState *bs, uint64_t offset,
|
||||
int offset_in_cluster;
|
||||
uint64_t cluster_offset;
|
||||
int ret = 0, n;
|
||||
QEMUIOVector hd_qiov;
|
||||
uint8_t *buf;
|
||||
void *orig_buf;
|
||||
|
||||
@@ -776,11 +772,10 @@ static coroutine_fn int qcow_co_pwritev(BlockDriverState *bs, uint64_t offset,
|
||||
}
|
||||
}
|
||||
|
||||
qemu_iovec_init_buf(&hd_qiov, buf, n);
|
||||
qemu_co_mutex_unlock(&s->lock);
|
||||
BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO);
|
||||
ret = bdrv_co_pwritev(bs->file, cluster_offset + offset_in_cluster,
|
||||
n, &hd_qiov, 0);
|
||||
ret = bdrv_co_pwrite(bs->file, cluster_offset + offset_in_cluster,
|
||||
n, buf, 0);
|
||||
qemu_co_mutex_lock(&s->lock);
|
||||
if (ret < 0) {
|
||||
break;
|
||||
@@ -1056,7 +1051,6 @@ qcow_co_pwritev_compressed(BlockDriverState *bs, uint64_t offset,
|
||||
uint64_t bytes, QEMUIOVector *qiov)
|
||||
{
|
||||
BDRVQcowState *s = bs->opaque;
|
||||
QEMUIOVector hd_qiov;
|
||||
z_stream strm;
|
||||
int ret, out_len;
|
||||
uint8_t *buf, *out_buf;
|
||||
@@ -1122,9 +1116,8 @@ qcow_co_pwritev_compressed(BlockDriverState *bs, uint64_t offset,
|
||||
}
|
||||
cluster_offset &= s->cluster_offset_mask;
|
||||
|
||||
qemu_iovec_init_buf(&hd_qiov, out_buf, out_len);
|
||||
BLKDBG_EVENT(bs->file, BLKDBG_WRITE_COMPRESSED);
|
||||
ret = bdrv_co_pwritev(bs->file, cluster_offset, out_len, &hd_qiov, 0);
|
||||
ret = bdrv_co_pwrite(bs->file, cluster_offset, out_len, out_buf, 0);
|
||||
if (ret < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
+42
-38
@@ -2721,11 +2721,13 @@ static int qcow2_set_up_encryption(BlockDriverState *bs,
|
||||
* Returns: 0 on success, -errno on failure.
|
||||
*/
|
||||
static int coroutine_fn preallocate_co(BlockDriverState *bs, uint64_t offset,
|
||||
uint64_t new_length)
|
||||
uint64_t new_length, PreallocMode mode,
|
||||
Error **errp)
|
||||
{
|
||||
BDRVQcow2State *s = bs->opaque;
|
||||
uint64_t bytes;
|
||||
uint64_t host_offset = 0;
|
||||
int64_t file_length;
|
||||
unsigned int cur_bytes;
|
||||
int ret;
|
||||
QCowL2Meta *meta;
|
||||
@@ -2734,10 +2736,11 @@ static int coroutine_fn preallocate_co(BlockDriverState *bs, uint64_t offset,
|
||||
bytes = new_length - offset;
|
||||
|
||||
while (bytes) {
|
||||
cur_bytes = MIN(bytes, INT_MAX);
|
||||
cur_bytes = MIN(bytes, QEMU_ALIGN_DOWN(INT_MAX, s->cluster_size));
|
||||
ret = qcow2_alloc_cluster_offset(bs, offset, &cur_bytes,
|
||||
&host_offset, &meta);
|
||||
if (ret < 0) {
|
||||
error_setg_errno(errp, -ret, "Allocating clusters failed");
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -2746,6 +2749,7 @@ static int coroutine_fn preallocate_co(BlockDriverState *bs, uint64_t offset,
|
||||
|
||||
ret = qcow2_alloc_cluster_link_l2(bs, meta);
|
||||
if (ret < 0) {
|
||||
error_setg_errno(errp, -ret, "Mapping clusters failed");
|
||||
qcow2_free_any_clusters(bs, meta->alloc_offset,
|
||||
meta->nb_clusters, QCOW2_DISCARD_NEVER);
|
||||
return ret;
|
||||
@@ -2770,10 +2774,18 @@ static int coroutine_fn preallocate_co(BlockDriverState *bs, uint64_t offset,
|
||||
* all of the allocated clusters (otherwise we get failing reads after
|
||||
* EOF). Extend the image to the last allocated sector.
|
||||
*/
|
||||
if (host_offset != 0) {
|
||||
uint8_t data = 0;
|
||||
ret = bdrv_pwrite(s->data_file, (host_offset + cur_bytes) - 1,
|
||||
&data, 1);
|
||||
file_length = bdrv_getlength(s->data_file->bs);
|
||||
if (file_length < 0) {
|
||||
error_setg_errno(errp, -file_length, "Could not get file size");
|
||||
return file_length;
|
||||
}
|
||||
|
||||
if (host_offset + cur_bytes > file_length) {
|
||||
if (mode == PREALLOC_MODE_METADATA) {
|
||||
mode = PREALLOC_MODE_OFF;
|
||||
}
|
||||
ret = bdrv_co_truncate(s->data_file, host_offset + cur_bytes, mode,
|
||||
errp);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
@@ -3745,12 +3757,17 @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
|
||||
|
||||
switch (prealloc) {
|
||||
case PREALLOC_MODE_OFF:
|
||||
if (has_data_file(bs)) {
|
||||
ret = bdrv_co_truncate(s->data_file, offset, prealloc, errp);
|
||||
if (ret < 0) {
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case PREALLOC_MODE_METADATA:
|
||||
ret = preallocate_co(bs, old_length, offset);
|
||||
ret = preallocate_co(bs, old_length, offset, prealloc, errp);
|
||||
if (ret < 0) {
|
||||
error_setg_errno(errp, -ret, "Preallocation failed");
|
||||
goto fail;
|
||||
}
|
||||
break;
|
||||
@@ -3766,9 +3783,8 @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
|
||||
/* With a data file, preallocation means just allocating the metadata
|
||||
* and forwarding the truncate request to the data file */
|
||||
if (has_data_file(bs)) {
|
||||
ret = preallocate_co(bs, old_length, offset);
|
||||
ret = preallocate_co(bs, old_length, offset, prealloc, errp);
|
||||
if (ret < 0) {
|
||||
error_setg_errno(errp, -ret, "Preallocation failed");
|
||||
goto fail;
|
||||
}
|
||||
break;
|
||||
@@ -3882,16 +3898,6 @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
|
||||
|
||||
bs->total_sectors = offset / BDRV_SECTOR_SIZE;
|
||||
|
||||
if (has_data_file(bs)) {
|
||||
if (prealloc == PREALLOC_MODE_METADATA) {
|
||||
prealloc = PREALLOC_MODE_OFF;
|
||||
}
|
||||
ret = bdrv_co_truncate(s->data_file, offset, prealloc, errp);
|
||||
if (ret < 0) {
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
/* write updated header.size */
|
||||
offset = cpu_to_be64(offset);
|
||||
ret = bdrv_pwrite_sync(bs->file, offsetof(QCowHeader, size),
|
||||
@@ -3923,8 +3929,8 @@ fail:
|
||||
* @src - source buffer, @src_size bytes
|
||||
*
|
||||
* Returns: compressed size on success
|
||||
* -1 destination buffer is not enough to store compressed data
|
||||
* -2 on any other error
|
||||
* -ENOMEM destination buffer is not enough to store compressed data
|
||||
* -EIO on any other error
|
||||
*/
|
||||
static ssize_t qcow2_compress(void *dest, size_t dest_size,
|
||||
const void *src, size_t src_size)
|
||||
@@ -3937,7 +3943,7 @@ static ssize_t qcow2_compress(void *dest, size_t dest_size,
|
||||
ret = deflateInit2(&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED,
|
||||
-12, 9, Z_DEFAULT_STRATEGY);
|
||||
if (ret != Z_OK) {
|
||||
return -2;
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
/* strm.next_in is not const in old zlib versions, such as those used on
|
||||
@@ -3951,7 +3957,7 @@ static ssize_t qcow2_compress(void *dest, size_t dest_size,
|
||||
if (ret == Z_STREAM_END) {
|
||||
ret = dest_size - strm.avail_out;
|
||||
} else {
|
||||
ret = (ret == Z_OK ? -1 : -2);
|
||||
ret = (ret == Z_OK ? -ENOMEM : -EIO);
|
||||
}
|
||||
|
||||
deflateEnd(&strm);
|
||||
@@ -4088,9 +4094,8 @@ qcow2_co_pwritev_compressed(BlockDriverState *bs, uint64_t offset,
|
||||
uint64_t bytes, QEMUIOVector *qiov)
|
||||
{
|
||||
BDRVQcow2State *s = bs->opaque;
|
||||
QEMUIOVector hd_qiov;
|
||||
int ret;
|
||||
size_t out_len;
|
||||
ssize_t out_len;
|
||||
uint8_t *buf, *out_buf;
|
||||
uint64_t cluster_offset;
|
||||
|
||||
@@ -4129,16 +4134,16 @@ qcow2_co_pwritev_compressed(BlockDriverState *bs, uint64_t offset,
|
||||
|
||||
out_len = qcow2_co_compress(bs, out_buf, s->cluster_size - 1,
|
||||
buf, s->cluster_size);
|
||||
if (out_len == -2) {
|
||||
ret = -EINVAL;
|
||||
goto fail;
|
||||
} else if (out_len == -1) {
|
||||
if (out_len == -ENOMEM) {
|
||||
/* could not compress: write normal cluster */
|
||||
ret = qcow2_co_pwritev(bs, offset, bytes, qiov, 0);
|
||||
if (ret < 0) {
|
||||
goto fail;
|
||||
}
|
||||
goto success;
|
||||
} else if (out_len < 0) {
|
||||
ret = -EINVAL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
qemu_co_mutex_lock(&s->lock);
|
||||
@@ -4155,10 +4160,8 @@ qcow2_co_pwritev_compressed(BlockDriverState *bs, uint64_t offset,
|
||||
goto fail;
|
||||
}
|
||||
|
||||
qemu_iovec_init_buf(&hd_qiov, out_buf, out_len);
|
||||
|
||||
BLKDBG_EVENT(s->data_file, BLKDBG_WRITE_COMPRESSED);
|
||||
ret = bdrv_co_pwritev(s->data_file, cluster_offset, out_len, &hd_qiov, 0);
|
||||
ret = bdrv_co_pwrite(s->data_file, cluster_offset, out_len, out_buf, 0);
|
||||
if (ret < 0) {
|
||||
goto fail;
|
||||
}
|
||||
@@ -4181,7 +4184,6 @@ qcow2_co_preadv_compressed(BlockDriverState *bs,
|
||||
int ret = 0, csize, nb_csectors;
|
||||
uint64_t coffset;
|
||||
uint8_t *buf, *out_buf;
|
||||
QEMUIOVector local_qiov;
|
||||
int offset_in_cluster = offset_into_cluster(s, offset);
|
||||
|
||||
coffset = file_cluster_offset & s->cluster_offset_mask;
|
||||
@@ -4192,12 +4194,11 @@ qcow2_co_preadv_compressed(BlockDriverState *bs,
|
||||
if (!buf) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
qemu_iovec_init_buf(&local_qiov, buf, csize);
|
||||
|
||||
out_buf = qemu_blockalign(bs, s->cluster_size);
|
||||
|
||||
BLKDBG_EVENT(bs->file, BLKDBG_READ_COMPRESSED);
|
||||
ret = bdrv_co_preadv(bs->file, coffset, csize, &local_qiov, 0);
|
||||
ret = bdrv_co_pread(bs->file, coffset, csize, buf, 0);
|
||||
if (ret < 0) {
|
||||
goto fail;
|
||||
}
|
||||
@@ -4378,14 +4379,17 @@ static int qcow2_make_empty(BlockDriverState *bs)
|
||||
|
||||
if (s->qcow_version >= 3 && !s->snapshots && !s->nb_bitmaps &&
|
||||
3 + l1_clusters <= s->refcount_block_size &&
|
||||
s->crypt_method_header != QCOW_CRYPT_LUKS) {
|
||||
s->crypt_method_header != QCOW_CRYPT_LUKS &&
|
||||
!has_data_file(bs)) {
|
||||
/* The following function only works for qcow2 v3 images (it
|
||||
* requires the dirty flag) and only as long as there are no
|
||||
* features that reserve extra clusters (such as snapshots,
|
||||
* LUKS header, or persistent bitmaps), because it completely
|
||||
* empties the image. Furthermore, the L1 table and three
|
||||
* additional clusters (image header, refcount table, one
|
||||
* refcount block) have to fit inside one refcount block. */
|
||||
* refcount block) have to fit inside one refcount block. It
|
||||
* only resets the image file, i.e. does not work with an
|
||||
* external data file. */
|
||||
return make_completely_empty(bs);
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -106,7 +106,7 @@ static unsigned int qed_check_l2_table(QEDCheck *check, QEDTable *table)
|
||||
/**
|
||||
* Descend tables and check each cluster is referenced once only
|
||||
*/
|
||||
static int qed_check_l1_table(QEDCheck *check, QEDTable *table)
|
||||
static int coroutine_fn qed_check_l1_table(QEDCheck *check, QEDTable *table)
|
||||
{
|
||||
BDRVQEDState *s = check->s;
|
||||
unsigned int i, num_invalid_l1 = 0;
|
||||
@@ -218,7 +218,7 @@ static void qed_check_mark_clean(BDRVQEDState *s, BdrvCheckResult *result)
|
||||
}
|
||||
|
||||
/* Called with table_lock held. */
|
||||
int qed_check(BDRVQEDState *s, BdrvCheckResult *result, bool fix)
|
||||
int coroutine_fn qed_check(BDRVQEDState *s, BdrvCheckResult *result, bool fix)
|
||||
{
|
||||
QEDCheck check = {
|
||||
.s = s,
|
||||
|
||||
+25
-20
@@ -19,24 +19,25 @@
|
||||
#include "qemu/bswap.h"
|
||||
|
||||
/* Called with table_lock held. */
|
||||
static int qed_read_table(BDRVQEDState *s, uint64_t offset, QEDTable *table)
|
||||
static int coroutine_fn qed_read_table(BDRVQEDState *s, uint64_t offset,
|
||||
QEDTable *table)
|
||||
{
|
||||
QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(
|
||||
qiov, table->offsets, s->header.cluster_size * s->header.table_size);
|
||||
unsigned int bytes = s->header.cluster_size * s->header.table_size;
|
||||
|
||||
int noffsets;
|
||||
int i, ret;
|
||||
|
||||
trace_qed_read_table(s, offset, table);
|
||||
|
||||
qemu_co_mutex_unlock(&s->table_lock);
|
||||
ret = bdrv_preadv(s->bs->file, offset, &qiov);
|
||||
ret = bdrv_co_pread(s->bs->file, offset, bytes, table->offsets, 0);
|
||||
qemu_co_mutex_lock(&s->table_lock);
|
||||
if (ret < 0) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Byteswap offsets */
|
||||
noffsets = qiov.size / sizeof(uint64_t);
|
||||
noffsets = bytes / sizeof(uint64_t);
|
||||
for (i = 0; i < noffsets; i++) {
|
||||
table->offsets[i] = le64_to_cpu(table->offsets[i]);
|
||||
}
|
||||
@@ -60,13 +61,13 @@ out:
|
||||
*
|
||||
* Called with table_lock held.
|
||||
*/
|
||||
static int qed_write_table(BDRVQEDState *s, uint64_t offset, QEDTable *table,
|
||||
unsigned int index, unsigned int n, bool flush)
|
||||
static int coroutine_fn qed_write_table(BDRVQEDState *s, uint64_t offset,
|
||||
QEDTable *table, unsigned int index,
|
||||
unsigned int n, bool flush)
|
||||
{
|
||||
unsigned int sector_mask = BDRV_SECTOR_SIZE / sizeof(uint64_t) - 1;
|
||||
unsigned int start, end, i;
|
||||
QEDTable *new_table;
|
||||
QEMUIOVector qiov;
|
||||
size_t len_bytes;
|
||||
int ret;
|
||||
|
||||
@@ -79,7 +80,6 @@ static int qed_write_table(BDRVQEDState *s, uint64_t offset, QEDTable *table,
|
||||
len_bytes = (end - start) * sizeof(uint64_t);
|
||||
|
||||
new_table = qemu_blockalign(s->bs, len_bytes);
|
||||
qemu_iovec_init_buf(&qiov, new_table->offsets, len_bytes);
|
||||
|
||||
/* Byteswap table */
|
||||
for (i = start; i < end; i++) {
|
||||
@@ -91,7 +91,7 @@ static int qed_write_table(BDRVQEDState *s, uint64_t offset, QEDTable *table,
|
||||
offset += start * sizeof(uint64_t);
|
||||
|
||||
qemu_co_mutex_unlock(&s->table_lock);
|
||||
ret = bdrv_pwritev(s->bs->file, offset, &qiov);
|
||||
ret = bdrv_co_pwrite(s->bs->file, offset, len_bytes, new_table->offsets, 0);
|
||||
qemu_co_mutex_lock(&s->table_lock);
|
||||
trace_qed_write_table_cb(s, table, flush, ret);
|
||||
if (ret < 0) {
|
||||
@@ -111,27 +111,29 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int qed_read_l1_table_sync(BDRVQEDState *s)
|
||||
int coroutine_fn qed_read_l1_table_sync(BDRVQEDState *s)
|
||||
{
|
||||
return qed_read_table(s, s->header.l1_table_offset, s->l1_table);
|
||||
}
|
||||
|
||||
/* Called with table_lock held. */
|
||||
int qed_write_l1_table(BDRVQEDState *s, unsigned int index, unsigned int n)
|
||||
int coroutine_fn qed_write_l1_table(BDRVQEDState *s, unsigned int index,
|
||||
unsigned int n)
|
||||
{
|
||||
BLKDBG_EVENT(s->bs->file, BLKDBG_L1_UPDATE);
|
||||
return qed_write_table(s, s->header.l1_table_offset,
|
||||
s->l1_table, index, n, false);
|
||||
}
|
||||
|
||||
int qed_write_l1_table_sync(BDRVQEDState *s, unsigned int index,
|
||||
unsigned int n)
|
||||
int coroutine_fn qed_write_l1_table_sync(BDRVQEDState *s, unsigned int index,
|
||||
unsigned int n)
|
||||
{
|
||||
return qed_write_l1_table(s, index, n);
|
||||
}
|
||||
|
||||
/* Called with table_lock held. */
|
||||
int qed_read_l2_table(BDRVQEDState *s, QEDRequest *request, uint64_t offset)
|
||||
int coroutine_fn qed_read_l2_table(BDRVQEDState *s, QEDRequest *request,
|
||||
uint64_t offset)
|
||||
{
|
||||
int ret;
|
||||
|
||||
@@ -168,22 +170,25 @@ int qed_read_l2_table(BDRVQEDState *s, QEDRequest *request, uint64_t offset)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int qed_read_l2_table_sync(BDRVQEDState *s, QEDRequest *request, uint64_t offset)
|
||||
int coroutine_fn qed_read_l2_table_sync(BDRVQEDState *s, QEDRequest *request,
|
||||
uint64_t offset)
|
||||
{
|
||||
return qed_read_l2_table(s, request, offset);
|
||||
}
|
||||
|
||||
/* Called with table_lock held. */
|
||||
int qed_write_l2_table(BDRVQEDState *s, QEDRequest *request,
|
||||
unsigned int index, unsigned int n, bool flush)
|
||||
int coroutine_fn qed_write_l2_table(BDRVQEDState *s, QEDRequest *request,
|
||||
unsigned int index, unsigned int n,
|
||||
bool flush)
|
||||
{
|
||||
BLKDBG_EVENT(s->bs->file, BLKDBG_L2_UPDATE);
|
||||
return qed_write_table(s, request->l2_table->offset,
|
||||
request->l2_table->table, index, n, flush);
|
||||
}
|
||||
|
||||
int qed_write_l2_table_sync(BDRVQEDState *s, QEDRequest *request,
|
||||
unsigned int index, unsigned int n, bool flush)
|
||||
int coroutine_fn qed_write_l2_table_sync(BDRVQEDState *s, QEDRequest *request,
|
||||
unsigned int index, unsigned int n,
|
||||
bool flush)
|
||||
{
|
||||
return qed_write_l2_table(s, request, index, n, flush);
|
||||
}
|
||||
|
||||
+5
-6
@@ -113,15 +113,13 @@ static int coroutine_fn qed_write_header(BDRVQEDState *s)
|
||||
int nsectors = DIV_ROUND_UP(sizeof(QEDHeader), BDRV_SECTOR_SIZE);
|
||||
size_t len = nsectors * BDRV_SECTOR_SIZE;
|
||||
uint8_t *buf;
|
||||
QEMUIOVector qiov;
|
||||
int ret;
|
||||
|
||||
assert(s->allocating_acb || s->allocating_write_reqs_plugged);
|
||||
|
||||
buf = qemu_blockalign(s->bs, len);
|
||||
qemu_iovec_init_buf(&qiov, buf, len);
|
||||
|
||||
ret = bdrv_co_preadv(s->bs->file, 0, qiov.size, &qiov, 0);
|
||||
ret = bdrv_co_pread(s->bs->file, 0, len, buf, 0);
|
||||
if (ret < 0) {
|
||||
goto out;
|
||||
}
|
||||
@@ -129,7 +127,7 @@ static int coroutine_fn qed_write_header(BDRVQEDState *s)
|
||||
/* Update header */
|
||||
qed_header_cpu_to_le(&s->header, (QEDHeader *) buf);
|
||||
|
||||
ret = bdrv_co_pwritev(s->bs->file, 0, qiov.size, &qiov, 0);
|
||||
ret = bdrv_co_pwrite(s->bs->file, 0, len, buf, 0);
|
||||
if (ret < 0) {
|
||||
goto out;
|
||||
}
|
||||
@@ -1606,8 +1604,9 @@ static void coroutine_fn bdrv_qed_co_invalidate_cache(BlockDriverState *bs,
|
||||
}
|
||||
}
|
||||
|
||||
static int bdrv_qed_co_check(BlockDriverState *bs, BdrvCheckResult *result,
|
||||
BdrvCheckMode fix)
|
||||
static int coroutine_fn bdrv_qed_co_check(BlockDriverState *bs,
|
||||
BdrvCheckResult *result,
|
||||
BdrvCheckMode fix)
|
||||
{
|
||||
BDRVQEDState *s = bs->opaque;
|
||||
int ret;
|
||||
|
||||
+16
-12
@@ -201,17 +201,21 @@ void qed_commit_l2_cache_entry(L2TableCache *l2_cache, CachedL2Table *l2_table);
|
||||
/**
|
||||
* Table I/O functions
|
||||
*/
|
||||
int qed_read_l1_table_sync(BDRVQEDState *s);
|
||||
int qed_write_l1_table(BDRVQEDState *s, unsigned int index, unsigned int n);
|
||||
int qed_write_l1_table_sync(BDRVQEDState *s, unsigned int index,
|
||||
unsigned int n);
|
||||
int qed_read_l2_table_sync(BDRVQEDState *s, QEDRequest *request,
|
||||
uint64_t offset);
|
||||
int qed_read_l2_table(BDRVQEDState *s, QEDRequest *request, uint64_t offset);
|
||||
int qed_write_l2_table(BDRVQEDState *s, QEDRequest *request,
|
||||
unsigned int index, unsigned int n, bool flush);
|
||||
int qed_write_l2_table_sync(BDRVQEDState *s, QEDRequest *request,
|
||||
unsigned int index, unsigned int n, bool flush);
|
||||
int coroutine_fn qed_read_l1_table_sync(BDRVQEDState *s);
|
||||
int coroutine_fn qed_write_l1_table(BDRVQEDState *s, unsigned int index,
|
||||
unsigned int n);
|
||||
int coroutine_fn qed_write_l1_table_sync(BDRVQEDState *s, unsigned int index,
|
||||
unsigned int n);
|
||||
int coroutine_fn qed_read_l2_table_sync(BDRVQEDState *s, QEDRequest *request,
|
||||
uint64_t offset);
|
||||
int coroutine_fn qed_read_l2_table(BDRVQEDState *s, QEDRequest *request,
|
||||
uint64_t offset);
|
||||
int coroutine_fn qed_write_l2_table(BDRVQEDState *s, QEDRequest *request,
|
||||
unsigned int index, unsigned int n,
|
||||
bool flush);
|
||||
int coroutine_fn qed_write_l2_table_sync(BDRVQEDState *s, QEDRequest *request,
|
||||
unsigned int index, unsigned int n,
|
||||
bool flush);
|
||||
|
||||
/**
|
||||
* Cluster functions
|
||||
@@ -223,7 +227,7 @@ int coroutine_fn qed_find_cluster(BDRVQEDState *s, QEDRequest *request,
|
||||
/**
|
||||
* Consistency check
|
||||
*/
|
||||
int qed_check(BDRVQEDState *s, BdrvCheckResult *result, bool fix);
|
||||
int coroutine_fn qed_check(BDRVQEDState *s, BdrvCheckResult *result, bool fix);
|
||||
|
||||
QEDTable *qed_alloc_table(BDRVQEDState *s);
|
||||
|
||||
|
||||
+1
-3
@@ -42,12 +42,10 @@ static int coroutine_fn stream_populate(BlockBackend *blk,
|
||||
int64_t offset, uint64_t bytes,
|
||||
void *buf)
|
||||
{
|
||||
QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, bytes);
|
||||
|
||||
assert(bytes < SIZE_MAX);
|
||||
|
||||
/* Copy-on-read the unallocated clusters */
|
||||
return blk_co_preadv(blk, offset, qiov.size, &qiov, BDRV_REQ_COPY_ON_READ);
|
||||
return blk_co_pread(blk, offset, bytes, buf, BDRV_REQ_COPY_ON_READ);
|
||||
}
|
||||
|
||||
static void stream_abort(Job *job)
|
||||
|
||||
+1
-1
@@ -551,7 +551,7 @@ static int vhdx_log_flush(BlockDriverState *bs, BDRVVHDXState *s,
|
||||
}
|
||||
if (file_length < desc_entries->hdr.last_file_offset) {
|
||||
new_file_size = desc_entries->hdr.last_file_offset;
|
||||
if (new_file_size % (1024*1024)) {
|
||||
if (new_file_size % (1 * MiB)) {
|
||||
/* round up to nearest 1MB boundary */
|
||||
new_file_size = QEMU_ALIGN_UP(new_file_size, MiB);
|
||||
if (new_file_size > INT64_MAX) {
|
||||
|
||||
+4
-3
@@ -1175,7 +1175,7 @@ static int vhdx_allocate_block(BlockDriverState *bs, BDRVVHDXState *s,
|
||||
*new_offset = current_len;
|
||||
|
||||
/* per the spec, the address for a block is in units of 1MB */
|
||||
*new_offset = ROUND_UP(*new_offset, 1024 * 1024);
|
||||
*new_offset = ROUND_UP(*new_offset, 1 * MiB);
|
||||
if (*new_offset > INT64_MAX) {
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -1338,7 +1338,7 @@ static coroutine_fn int vhdx_co_writev(BlockDriverState *bs, int64_t sector_num,
|
||||
case PAYLOAD_BLOCK_FULLY_PRESENT:
|
||||
/* if the file offset address is in the header zone,
|
||||
* there is a problem */
|
||||
if (sinfo.file_offset < (1024 * 1024)) {
|
||||
if (sinfo.file_offset < (1 * MiB)) {
|
||||
ret = -EFAULT;
|
||||
goto error_bat_restore;
|
||||
}
|
||||
@@ -1889,7 +1889,8 @@ static int coroutine_fn vhdx_co_create(BlockdevCreateOptions *opts,
|
||||
return -EINVAL;
|
||||
}
|
||||
if (block_size > VHDX_BLOCK_SIZE_MAX) {
|
||||
error_setg(errp, "Block size must not exceed %d", VHDX_BLOCK_SIZE_MAX);
|
||||
error_setg(errp, "Block size must not exceed %" PRId64,
|
||||
VHDX_BLOCK_SIZE_MAX);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
||||
+7
-9
@@ -17,13 +17,11 @@
|
||||
|
||||
#ifndef BLOCK_VHDX_H
|
||||
#define BLOCK_VHDX_H
|
||||
|
||||
#define KiB (1 * 1024)
|
||||
#define MiB (KiB * 1024)
|
||||
#define GiB (MiB * 1024)
|
||||
#define TiB ((uint64_t) GiB * 1024)
|
||||
#include "qemu/units.h"
|
||||
|
||||
#define DEFAULT_LOG_SIZE 1048576 /* 1MiB */
|
||||
/* Note: can't use 1 * MiB, because it's passed to stringify() */
|
||||
|
||||
/* Structures and fields present in the VHDX file */
|
||||
|
||||
/* The header section has the following blocks,
|
||||
@@ -36,7 +34,7 @@
|
||||
* 0.........64KB...........128KB........192KB..........256KB................1MB
|
||||
*/
|
||||
|
||||
#define VHDX_HEADER_BLOCK_SIZE (64 * 1024)
|
||||
#define VHDX_HEADER_BLOCK_SIZE (64 * KiB)
|
||||
|
||||
#define VHDX_FILE_ID_OFFSET 0
|
||||
#define VHDX_HEADER1_OFFSET (VHDX_HEADER_BLOCK_SIZE * 1)
|
||||
@@ -85,7 +83,7 @@ typedef struct QEMU_PACKED MSGUID {
|
||||
#define guid_eq(a, b) \
|
||||
(memcmp(&(a), &(b), sizeof(MSGUID)) == 0)
|
||||
|
||||
#define VHDX_HEADER_SIZE (4 * 1024) /* although the vhdx_header struct in disk
|
||||
#define VHDX_HEADER_SIZE (4 * KiB) /* although the vhdx_header struct in disk
|
||||
is only 582 bytes, for purposes of crc
|
||||
the header is the first 4KB of the 64KB
|
||||
block */
|
||||
@@ -161,8 +159,8 @@ typedef struct QEMU_PACKED VHDXRegionTableEntry {
|
||||
|
||||
|
||||
/* ---- LOG ENTRY STRUCTURES ---- */
|
||||
#define VHDX_LOG_MIN_SIZE (1024 * 1024)
|
||||
#define VHDX_LOG_SECTOR_SIZE 4096
|
||||
#define VHDX_LOG_MIN_SIZE (1 * MiB)
|
||||
#define VHDX_LOG_SECTOR_SIZE (4 * KiB)
|
||||
#define VHDX_LOG_HDR_SIZE 64
|
||||
#define VHDX_LOG_SIGNATURE 0x65676f6c
|
||||
typedef struct QEMU_PACKED VHDXLogEntryHeader {
|
||||
|
||||
@@ -397,6 +397,8 @@ static int vmdk_parent_open(BlockDriverState *bs)
|
||||
pstrcpy(bs->auto_backing_file, end_name - p_name + 1, p_name);
|
||||
pstrcpy(bs->backing_file, sizeof(bs->backing_file),
|
||||
bs->auto_backing_file);
|
||||
pstrcpy(bs->backing_format, sizeof(bs->backing_format),
|
||||
"vmdk");
|
||||
}
|
||||
|
||||
out:
|
||||
|
||||
@@ -639,8 +639,10 @@ vpc_co_preadv(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
|
||||
qemu_iovec_reset(&local_qiov);
|
||||
qemu_iovec_concat(&local_qiov, qiov, bytes_done, n_bytes);
|
||||
|
||||
qemu_co_mutex_unlock(&s->lock);
|
||||
ret = bdrv_co_preadv(bs->file, image_offset, n_bytes,
|
||||
&local_qiov, 0);
|
||||
qemu_co_mutex_lock(&s->lock);
|
||||
if (ret < 0) {
|
||||
goto fail;
|
||||
}
|
||||
@@ -697,8 +699,10 @@ vpc_co_pwritev(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
|
||||
qemu_iovec_reset(&local_qiov);
|
||||
qemu_iovec_concat(&local_qiov, qiov, bytes_done, n_bytes);
|
||||
|
||||
qemu_co_mutex_unlock(&s->lock);
|
||||
ret = bdrv_co_pwritev(bs->file, image_offset, n_bytes,
|
||||
&local_qiov, 0);
|
||||
qemu_co_mutex_lock(&s->lock);
|
||||
if (ret < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@@ -925,6 +925,22 @@ int coroutine_fn bdrv_co_pwritev(BdrvChild *child,
|
||||
int64_t offset, unsigned int bytes, QEMUIOVector *qiov,
|
||||
BdrvRequestFlags flags);
|
||||
|
||||
static inline int coroutine_fn bdrv_co_pread(BdrvChild *child,
|
||||
int64_t offset, unsigned int bytes, void *buf, BdrvRequestFlags flags)
|
||||
{
|
||||
QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, bytes);
|
||||
|
||||
return bdrv_co_preadv(child, offset, bytes, &qiov, flags);
|
||||
}
|
||||
|
||||
static inline int coroutine_fn bdrv_co_pwrite(BdrvChild *child,
|
||||
int64_t offset, unsigned int bytes, void *buf, BdrvRequestFlags flags)
|
||||
{
|
||||
QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, bytes);
|
||||
|
||||
return bdrv_co_pwritev(child, offset, bytes, &qiov, flags);
|
||||
}
|
||||
|
||||
extern unsigned int bdrv_drain_all_count;
|
||||
void bdrv_apply_subtree_drain(BdrvChild *child, BlockDriverState *new_parent);
|
||||
void bdrv_unapply_subtree_drain(BdrvChild *child, BlockDriverState *old_parent);
|
||||
|
||||
@@ -124,6 +124,25 @@ int coroutine_fn blk_co_preadv(BlockBackend *blk, int64_t offset,
|
||||
int coroutine_fn blk_co_pwritev(BlockBackend *blk, int64_t offset,
|
||||
unsigned int bytes, QEMUIOVector *qiov,
|
||||
BdrvRequestFlags flags);
|
||||
|
||||
static inline int coroutine_fn blk_co_pread(BlockBackend *blk, int64_t offset,
|
||||
unsigned int bytes, void *buf,
|
||||
BdrvRequestFlags flags)
|
||||
{
|
||||
QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, bytes);
|
||||
|
||||
return blk_co_preadv(blk, offset, bytes, &qiov, flags);
|
||||
}
|
||||
|
||||
static inline int coroutine_fn blk_co_pwrite(BlockBackend *blk, int64_t offset,
|
||||
unsigned int bytes, void *buf,
|
||||
BdrvRequestFlags flags)
|
||||
{
|
||||
QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, bytes);
|
||||
|
||||
return blk_co_pwritev(blk, offset, bytes, &qiov, flags);
|
||||
}
|
||||
|
||||
int blk_pwrite_zeroes(BlockBackend *blk, int64_t offset,
|
||||
int bytes, BdrvRequestFlags flags);
|
||||
BlockAIOCB *blk_aio_pwrite_zeroes(BlockBackend *blk, int64_t offset,
|
||||
|
||||
+16
-10
@@ -267,9 +267,20 @@ static int print_block_option_help(const char *filename, const char *fmt)
|
||||
create_opts = qemu_opts_append(create_opts, proto_drv->create_opts);
|
||||
}
|
||||
|
||||
printf("Supported options:\n");
|
||||
if (filename) {
|
||||
printf("Supported options:\n");
|
||||
} else {
|
||||
printf("Supported %s options:\n", fmt);
|
||||
}
|
||||
qemu_opts_print_help(create_opts, false);
|
||||
qemu_opts_free(create_opts);
|
||||
|
||||
if (!filename) {
|
||||
printf("\n"
|
||||
"The protocol level may support further options.\n"
|
||||
"Specify the target filename to include those options.\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1669,7 +1680,6 @@ static int coroutine_fn convert_co_read(ImgConvertState *s, int64_t sector_num,
|
||||
int nb_sectors, uint8_t *buf)
|
||||
{
|
||||
int n, ret;
|
||||
QEMUIOVector qiov;
|
||||
|
||||
assert(nb_sectors <= s->buf_sectors);
|
||||
while (nb_sectors > 0) {
|
||||
@@ -1685,11 +1695,10 @@ static int coroutine_fn convert_co_read(ImgConvertState *s, int64_t sector_num,
|
||||
bs_sectors = s->src_sectors[src_cur];
|
||||
|
||||
n = MIN(nb_sectors, bs_sectors - (sector_num - src_cur_offset));
|
||||
qemu_iovec_init_buf(&qiov, buf, n << BDRV_SECTOR_BITS);
|
||||
|
||||
ret = blk_co_preadv(
|
||||
ret = blk_co_pread(
|
||||
blk, (sector_num - src_cur_offset) << BDRV_SECTOR_BITS,
|
||||
n << BDRV_SECTOR_BITS, &qiov, 0);
|
||||
n << BDRV_SECTOR_BITS, buf, 0);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
@@ -1708,7 +1717,6 @@ static int coroutine_fn convert_co_write(ImgConvertState *s, int64_t sector_num,
|
||||
enum ImgConvertBlockStatus status)
|
||||
{
|
||||
int ret;
|
||||
QEMUIOVector qiov;
|
||||
|
||||
while (nb_sectors > 0) {
|
||||
int n = nb_sectors;
|
||||
@@ -1736,10 +1744,8 @@ static int coroutine_fn convert_co_write(ImgConvertState *s, int64_t sector_num,
|
||||
(s->compressed &&
|
||||
!buffer_is_zero(buf, n * BDRV_SECTOR_SIZE)))
|
||||
{
|
||||
qemu_iovec_init_buf(&qiov, buf, n << BDRV_SECTOR_BITS);
|
||||
|
||||
ret = blk_co_pwritev(s->target, sector_num << BDRV_SECTOR_BITS,
|
||||
n << BDRV_SECTOR_BITS, &qiov, flags);
|
||||
ret = blk_co_pwrite(s->target, sector_num << BDRV_SECTOR_BITS,
|
||||
n << BDRV_SECTOR_BITS, buf, flags);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user