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: - Copy offloading fixes for when the copy increases the image size - Temporary revert of the removal of deprecated -drive options - Fix request serialisation in the image fleecing scenario - Fix copy-on-read crash with unaligned image size - Fix another drain crash # gpg: Signature made Tue 10 Jul 2018 16:37:52 BST # gpg: using RSA key 7F09B272C88F2FD6 # gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>" # Primary key fingerprint: DC3D EB15 9A9A F95D 3D74 56FE 7F09 B272 C88F 2FD6 * remotes/kevin/tags/for-upstream: (24 commits) block: Use common write req handling in truncate block: Fix bdrv_co_truncate overlap check block: Use common req handling in copy offloading block: Use common req handling for discard block: Fix handling of image enlarging write block: Extract common write req handling block: Use uint64_t for BdrvTrackedRequest byte fields block: Use BdrvChild to discard block: Add copy offloading trace points block: Prefix file driver trace points with "file_" Revert "block: Remove deprecated -drive geometry options" Revert "block: Remove deprecated -drive option addr" Revert "block: Remove deprecated -drive option serial" Revert "block: Remove dead deprecation warning code" block/blklogwrites: Make sure the log sector size is not too small qapi/block-core.json: Add missing documentation for blklogwrites log-append option block/backup: fix fleecing scheme: use serialized writes block: add BDRV_REQ_SERIALISING flag block: split flags in copy_range block/io: fix copy_range ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
@@ -2066,7 +2066,7 @@ static void bdrv_replace_child_noperm(BdrvChild *child,
|
||||
}
|
||||
assert(num >= 0);
|
||||
for (i = 0; i < num; i++) {
|
||||
child->role->drained_begin(child);
|
||||
bdrv_parent_drained_begin_single(child, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+14
-6
@@ -47,6 +47,8 @@ typedef struct BackupBlockJob {
|
||||
HBitmap *copy_bitmap;
|
||||
bool use_copy_range;
|
||||
int64_t copy_range_size;
|
||||
|
||||
bool serialize_target_writes;
|
||||
} BackupBlockJob;
|
||||
|
||||
static const BlockJobDriver backup_job_driver;
|
||||
@@ -102,6 +104,8 @@ static int coroutine_fn backup_cow_with_bounce_buffer(BackupBlockJob *job,
|
||||
QEMUIOVector qiov;
|
||||
BlockBackend *blk = job->common.blk;
|
||||
int nbytes;
|
||||
int read_flags = is_write_notifier ? BDRV_REQ_NO_SERIALISING : 0;
|
||||
int write_flags = job->serialize_target_writes ? BDRV_REQ_SERIALISING : 0;
|
||||
|
||||
hbitmap_reset(job->copy_bitmap, start / job->cluster_size, 1);
|
||||
nbytes = MIN(job->cluster_size, job->len - start);
|
||||
@@ -112,8 +116,7 @@ static int coroutine_fn backup_cow_with_bounce_buffer(BackupBlockJob *job,
|
||||
iov.iov_len = nbytes;
|
||||
qemu_iovec_init_external(&qiov, &iov, 1);
|
||||
|
||||
ret = blk_co_preadv(blk, start, qiov.size, &qiov,
|
||||
is_write_notifier ? BDRV_REQ_NO_SERIALISING : 0);
|
||||
ret = blk_co_preadv(blk, start, qiov.size, &qiov, read_flags);
|
||||
if (ret < 0) {
|
||||
trace_backup_do_cow_read_fail(job, start, ret);
|
||||
if (error_is_read) {
|
||||
@@ -124,11 +127,11 @@ static int coroutine_fn backup_cow_with_bounce_buffer(BackupBlockJob *job,
|
||||
|
||||
if (qemu_iovec_is_zero(&qiov)) {
|
||||
ret = blk_co_pwrite_zeroes(job->target, start,
|
||||
qiov.size, BDRV_REQ_MAY_UNMAP);
|
||||
qiov.size, write_flags | BDRV_REQ_MAY_UNMAP);
|
||||
} else {
|
||||
ret = blk_co_pwritev(job->target, start,
|
||||
qiov.size, &qiov,
|
||||
job->compress ? BDRV_REQ_WRITE_COMPRESSED : 0);
|
||||
qiov.size, &qiov, write_flags |
|
||||
(job->compress ? BDRV_REQ_WRITE_COMPRESSED : 0));
|
||||
}
|
||||
if (ret < 0) {
|
||||
trace_backup_do_cow_write_fail(job, start, ret);
|
||||
@@ -156,6 +159,8 @@ static int coroutine_fn backup_cow_with_offload(BackupBlockJob *job,
|
||||
int nr_clusters;
|
||||
BlockBackend *blk = job->common.blk;
|
||||
int nbytes;
|
||||
int read_flags = is_write_notifier ? BDRV_REQ_NO_SERIALISING : 0;
|
||||
int write_flags = job->serialize_target_writes ? BDRV_REQ_SERIALISING : 0;
|
||||
|
||||
assert(QEMU_IS_ALIGNED(job->copy_range_size, job->cluster_size));
|
||||
nbytes = MIN(job->copy_range_size, end - start);
|
||||
@@ -163,7 +168,7 @@ static int coroutine_fn backup_cow_with_offload(BackupBlockJob *job,
|
||||
hbitmap_reset(job->copy_bitmap, start / job->cluster_size,
|
||||
nr_clusters);
|
||||
ret = blk_co_copy_range(blk, start, job->target, start, nbytes,
|
||||
is_write_notifier ? BDRV_REQ_NO_SERIALISING : 0);
|
||||
read_flags, write_flags);
|
||||
if (ret < 0) {
|
||||
trace_backup_do_cow_copy_range_fail(job, start, ret);
|
||||
hbitmap_set(job->copy_bitmap, start / job->cluster_size,
|
||||
@@ -701,6 +706,9 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
|
||||
sync_bitmap : NULL;
|
||||
job->compress = compress;
|
||||
|
||||
/* Detect image-fleecing (and similar) schemes */
|
||||
job->serialize_target_writes = bdrv_chain_contains(target, bs);
|
||||
|
||||
/* If there is no backing file on the target, we cannot rely on COW if our
|
||||
* backup cluster size is smaller than the target cluster size. Even for
|
||||
* targets with a backing file, try to avoid COW if possible. */
|
||||
|
||||
+1
-1
@@ -625,7 +625,7 @@ static int coroutine_fn blkdebug_co_pdiscard(BlockDriverState *bs,
|
||||
return err;
|
||||
}
|
||||
|
||||
return bdrv_co_pdiscard(bs->file->bs, offset, bytes);
|
||||
return bdrv_co_pdiscard(bs->file, offset, bytes);
|
||||
}
|
||||
|
||||
static int coroutine_fn blkdebug_co_block_status(BlockDriverState *bs,
|
||||
|
||||
@@ -89,7 +89,10 @@ static inline uint32_t blk_log_writes_log2(uint32_t value)
|
||||
|
||||
static inline bool blk_log_writes_sector_size_valid(uint32_t sector_size)
|
||||
{
|
||||
return sector_size < (1ull << 24) && is_power_of_2(sector_size);
|
||||
return is_power_of_2(sector_size) &&
|
||||
sector_size >= sizeof(struct log_write_super) &&
|
||||
sector_size >= sizeof(struct log_write_entry) &&
|
||||
sector_size < (1ull << 24);
|
||||
}
|
||||
|
||||
static uint64_t blk_log_writes_find_cur_log_sector(BdrvChild *log,
|
||||
@@ -483,7 +486,7 @@ static int coroutine_fn blk_log_writes_co_do_file_flush(BlkLogWritesFileReq *fr)
|
||||
static int coroutine_fn
|
||||
blk_log_writes_co_do_file_pdiscard(BlkLogWritesFileReq *fr)
|
||||
{
|
||||
return bdrv_co_pdiscard(fr->bs->file->bs, fr->offset, fr->bytes);
|
||||
return bdrv_co_pdiscard(fr->bs->file, fr->offset, fr->bytes);
|
||||
}
|
||||
|
||||
static int coroutine_fn
|
||||
|
||||
+1
-1
@@ -113,7 +113,7 @@ static int coroutine_fn blkreplay_co_pdiscard(BlockDriverState *bs,
|
||||
int64_t offset, int bytes)
|
||||
{
|
||||
uint64_t reqid = blkreplay_next_id();
|
||||
int ret = bdrv_co_pdiscard(bs->file->bs, offset, bytes);
|
||||
int ret = bdrv_co_pdiscard(bs->file, offset, bytes);
|
||||
block_request_create(reqid, bs, qemu_coroutine_self());
|
||||
qemu_coroutine_yield();
|
||||
|
||||
|
||||
@@ -419,6 +419,7 @@ static void drive_info_del(DriveInfo *dinfo)
|
||||
return;
|
||||
}
|
||||
qemu_opts_del(dinfo->opts);
|
||||
g_free(dinfo->serial);
|
||||
g_free(dinfo);
|
||||
}
|
||||
|
||||
@@ -1559,7 +1560,7 @@ int blk_co_pdiscard(BlockBackend *blk, int64_t offset, int bytes)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return bdrv_co_pdiscard(blk_bs(blk), offset, bytes);
|
||||
return bdrv_co_pdiscard(blk->root, offset, bytes);
|
||||
}
|
||||
|
||||
int blk_co_flush(BlockBackend *blk)
|
||||
@@ -2218,7 +2219,8 @@ void blk_unregister_buf(BlockBackend *blk, void *host)
|
||||
|
||||
int coroutine_fn blk_co_copy_range(BlockBackend *blk_in, int64_t off_in,
|
||||
BlockBackend *blk_out, int64_t off_out,
|
||||
int bytes, BdrvRequestFlags flags)
|
||||
int bytes, BdrvRequestFlags read_flags,
|
||||
BdrvRequestFlags write_flags)
|
||||
{
|
||||
int r;
|
||||
r = blk_check_byte_request(blk_in, off_in, bytes);
|
||||
@@ -2231,5 +2233,5 @@ int coroutine_fn blk_co_copy_range(BlockBackend *blk_in, int64_t off_in,
|
||||
}
|
||||
return bdrv_co_copy_range(blk_in->root, off_in,
|
||||
blk_out->root, off_out,
|
||||
bytes, flags);
|
||||
bytes, read_flags, write_flags);
|
||||
}
|
||||
|
||||
@@ -116,7 +116,7 @@ static int coroutine_fn cor_co_pwrite_zeroes(BlockDriverState *bs,
|
||||
static int coroutine_fn cor_co_pdiscard(BlockDriverState *bs,
|
||||
int64_t offset, int bytes)
|
||||
{
|
||||
return bdrv_co_pdiscard(bs->file->bs, offset, bytes);
|
||||
return bdrv_co_pdiscard(bs->file, offset, bytes);
|
||||
}
|
||||
|
||||
|
||||
|
||||
+16
-9
@@ -1488,6 +1488,8 @@ static ssize_t handle_aiocb_copy_range(RawPosixAIOData *aiocb)
|
||||
ssize_t ret = copy_file_range(aiocb->aio_fildes, &in_off,
|
||||
aiocb->aio_fd2, &out_off,
|
||||
bytes, 0);
|
||||
trace_file_copy_file_range(aiocb->bs, aiocb->aio_fildes, in_off,
|
||||
aiocb->aio_fd2, out_off, bytes, 0, ret);
|
||||
if (ret == 0) {
|
||||
/* No progress (e.g. when beyond EOF), let the caller fall back to
|
||||
* buffer I/O. */
|
||||
@@ -1743,7 +1745,7 @@ static int paio_submit_co_full(BlockDriverState *bs, int fd,
|
||||
assert(qiov->size == bytes);
|
||||
}
|
||||
|
||||
trace_paio_submit_co(offset, bytes, type);
|
||||
trace_file_paio_submit_co(offset, bytes, type);
|
||||
pool = aio_get_thread_pool(bdrv_get_aio_context(bs));
|
||||
return thread_pool_submit_co(pool, aio_worker, acb);
|
||||
}
|
||||
@@ -2589,18 +2591,23 @@ static void raw_abort_perm_update(BlockDriverState *bs)
|
||||
raw_handle_perm_lock(bs, RAW_PL_ABORT, 0, 0, NULL);
|
||||
}
|
||||
|
||||
static int coroutine_fn raw_co_copy_range_from(BlockDriverState *bs,
|
||||
BdrvChild *src, uint64_t src_offset,
|
||||
BdrvChild *dst, uint64_t dst_offset,
|
||||
uint64_t bytes, BdrvRequestFlags flags)
|
||||
static int coroutine_fn raw_co_copy_range_from(
|
||||
BlockDriverState *bs, BdrvChild *src, uint64_t src_offset,
|
||||
BdrvChild *dst, uint64_t dst_offset, uint64_t bytes,
|
||||
BdrvRequestFlags read_flags, BdrvRequestFlags write_flags)
|
||||
{
|
||||
return bdrv_co_copy_range_to(src, src_offset, dst, dst_offset, bytes, flags);
|
||||
return bdrv_co_copy_range_to(src, src_offset, dst, dst_offset, bytes,
|
||||
read_flags, write_flags);
|
||||
}
|
||||
|
||||
static int coroutine_fn raw_co_copy_range_to(BlockDriverState *bs,
|
||||
BdrvChild *src, uint64_t src_offset,
|
||||
BdrvChild *dst, uint64_t dst_offset,
|
||||
uint64_t bytes, BdrvRequestFlags flags)
|
||||
BdrvChild *src,
|
||||
uint64_t src_offset,
|
||||
BdrvChild *dst,
|
||||
uint64_t dst_offset,
|
||||
uint64_t bytes,
|
||||
BdrvRequestFlags read_flags,
|
||||
BdrvRequestFlags write_flags)
|
||||
{
|
||||
BDRVRawState *s = bs->opaque;
|
||||
BDRVRawState *src_s;
|
||||
|
||||
+1
-1
@@ -162,7 +162,7 @@ static BlockAIOCB *paio_submit(BlockDriverState *bs, HANDLE hfile,
|
||||
acb->aio_nbytes = count;
|
||||
acb->aio_offset = offset;
|
||||
|
||||
trace_paio_submit(acb, opaque, offset, count, type);
|
||||
trace_file_paio_submit(acb, opaque, offset, count, type);
|
||||
pool = aio_get_thread_pool(bdrv_get_aio_context(bs));
|
||||
return thread_pool_submit_aio(pool, aio_worker, acb, cb, opaque);
|
||||
}
|
||||
|
||||
+218
-98
File diff suppressed because it is too large
Load Diff
+9
-3
@@ -44,6 +44,7 @@
|
||||
#include "qapi/qmp/qstring.h"
|
||||
#include "crypto/secret.h"
|
||||
#include "scsi/utils.h"
|
||||
#include "trace.h"
|
||||
|
||||
/* Conflict between scsi/utils.h and libiscsi! :( */
|
||||
#define SCSI_XFER_NONE ISCSI_XFER_NONE
|
||||
@@ -2193,9 +2194,11 @@ static int coroutine_fn iscsi_co_copy_range_from(BlockDriverState *bs,
|
||||
BdrvChild *dst,
|
||||
uint64_t dst_offset,
|
||||
uint64_t bytes,
|
||||
BdrvRequestFlags flags)
|
||||
BdrvRequestFlags read_flags,
|
||||
BdrvRequestFlags write_flags)
|
||||
{
|
||||
return bdrv_co_copy_range_to(src, src_offset, dst, dst_offset, bytes, flags);
|
||||
return bdrv_co_copy_range_to(src, src_offset, dst, dst_offset, bytes,
|
||||
read_flags, write_flags);
|
||||
}
|
||||
|
||||
static struct scsi_task *iscsi_xcopy_task(int param_len)
|
||||
@@ -2332,7 +2335,8 @@ static int coroutine_fn iscsi_co_copy_range_to(BlockDriverState *bs,
|
||||
BdrvChild *dst,
|
||||
uint64_t dst_offset,
|
||||
uint64_t bytes,
|
||||
BdrvRequestFlags flags)
|
||||
BdrvRequestFlags read_flags,
|
||||
BdrvRequestFlags write_flags)
|
||||
{
|
||||
IscsiLun *dst_lun = dst->bs->opaque;
|
||||
IscsiLun *src_lun;
|
||||
@@ -2396,6 +2400,8 @@ retry:
|
||||
}
|
||||
|
||||
out_unlock:
|
||||
|
||||
trace_iscsi_xcopy(src_lun, src_offset, dst_lun, dst_offset, bytes, r);
|
||||
g_free(iscsi_task.task);
|
||||
qemu_mutex_unlock(&dst_lun->mutex);
|
||||
g_free(iscsi_task.err_str);
|
||||
|
||||
+1
-1
@@ -1333,7 +1333,7 @@ static int coroutine_fn bdrv_mirror_top_do_write(BlockDriverState *bs,
|
||||
break;
|
||||
|
||||
case MIRROR_METHOD_DISCARD:
|
||||
ret = bdrv_co_pdiscard(bs->backing->bs, offset, bytes);
|
||||
ret = bdrv_co_pdiscard(bs->backing, offset, bytes);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
@@ -734,7 +734,7 @@ void qcow2_process_discards(BlockDriverState *bs, int ret)
|
||||
|
||||
/* Discard is optional, ignore the return value */
|
||||
if (ret >= 0) {
|
||||
bdrv_pdiscard(bs->file->bs, d->offset, d->bytes);
|
||||
bdrv_pdiscard(bs->file, d->offset, d->bytes);
|
||||
}
|
||||
|
||||
g_free(d);
|
||||
|
||||
+11
-9
@@ -3259,13 +3259,14 @@ static int coroutine_fn
|
||||
qcow2_co_copy_range_from(BlockDriverState *bs,
|
||||
BdrvChild *src, uint64_t src_offset,
|
||||
BdrvChild *dst, uint64_t dst_offset,
|
||||
uint64_t bytes, BdrvRequestFlags flags)
|
||||
uint64_t bytes, BdrvRequestFlags read_flags,
|
||||
BdrvRequestFlags write_flags)
|
||||
{
|
||||
BDRVQcow2State *s = bs->opaque;
|
||||
int ret;
|
||||
unsigned int cur_bytes; /* number of bytes in current iteration */
|
||||
BdrvChild *child = NULL;
|
||||
BdrvRequestFlags cur_flags;
|
||||
BdrvRequestFlags cur_write_flags;
|
||||
|
||||
assert(!bs->encrypted);
|
||||
qemu_co_mutex_lock(&s->lock);
|
||||
@@ -3274,7 +3275,7 @@ qcow2_co_copy_range_from(BlockDriverState *bs,
|
||||
uint64_t copy_offset = 0;
|
||||
/* prepare next request */
|
||||
cur_bytes = MIN(bytes, INT_MAX);
|
||||
cur_flags = flags;
|
||||
cur_write_flags = write_flags;
|
||||
|
||||
ret = qcow2_get_cluster_offset(bs, src_offset, &cur_bytes, ©_offset);
|
||||
if (ret < 0) {
|
||||
@@ -3286,20 +3287,20 @@ qcow2_co_copy_range_from(BlockDriverState *bs,
|
||||
if (bs->backing && bs->backing->bs) {
|
||||
int64_t backing_length = bdrv_getlength(bs->backing->bs);
|
||||
if (src_offset >= backing_length) {
|
||||
cur_flags |= BDRV_REQ_ZERO_WRITE;
|
||||
cur_write_flags |= BDRV_REQ_ZERO_WRITE;
|
||||
} else {
|
||||
child = bs->backing;
|
||||
cur_bytes = MIN(cur_bytes, backing_length - src_offset);
|
||||
copy_offset = src_offset;
|
||||
}
|
||||
} else {
|
||||
cur_flags |= BDRV_REQ_ZERO_WRITE;
|
||||
cur_write_flags |= BDRV_REQ_ZERO_WRITE;
|
||||
}
|
||||
break;
|
||||
|
||||
case QCOW2_CLUSTER_ZERO_PLAIN:
|
||||
case QCOW2_CLUSTER_ZERO_ALLOC:
|
||||
cur_flags |= BDRV_REQ_ZERO_WRITE;
|
||||
cur_write_flags |= BDRV_REQ_ZERO_WRITE;
|
||||
break;
|
||||
|
||||
case QCOW2_CLUSTER_COMPRESSED:
|
||||
@@ -3322,7 +3323,7 @@ qcow2_co_copy_range_from(BlockDriverState *bs,
|
||||
ret = bdrv_co_copy_range_from(child,
|
||||
copy_offset,
|
||||
dst, dst_offset,
|
||||
cur_bytes, cur_flags);
|
||||
cur_bytes, read_flags, cur_write_flags);
|
||||
qemu_co_mutex_lock(&s->lock);
|
||||
if (ret < 0) {
|
||||
goto out;
|
||||
@@ -3343,7 +3344,8 @@ static int coroutine_fn
|
||||
qcow2_co_copy_range_to(BlockDriverState *bs,
|
||||
BdrvChild *src, uint64_t src_offset,
|
||||
BdrvChild *dst, uint64_t dst_offset,
|
||||
uint64_t bytes, BdrvRequestFlags flags)
|
||||
uint64_t bytes, BdrvRequestFlags read_flags,
|
||||
BdrvRequestFlags write_flags)
|
||||
{
|
||||
BDRVQcow2State *s = bs->opaque;
|
||||
int offset_in_cluster;
|
||||
@@ -3386,7 +3388,7 @@ qcow2_co_copy_range_to(BlockDriverState *bs,
|
||||
ret = bdrv_co_copy_range_to(src, src_offset,
|
||||
bs->file,
|
||||
cluster_offset + offset_in_cluster,
|
||||
cur_bytes, flags);
|
||||
cur_bytes, read_flags, write_flags);
|
||||
qemu_co_mutex_lock(&s->lock);
|
||||
if (ret < 0) {
|
||||
goto fail;
|
||||
|
||||
+17
-9
@@ -297,7 +297,7 @@ static int coroutine_fn raw_co_pdiscard(BlockDriverState *bs,
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
return bdrv_co_pdiscard(bs->file->bs, offset, bytes);
|
||||
return bdrv_co_pdiscard(bs->file, offset, bytes);
|
||||
}
|
||||
|
||||
static int64_t raw_getlength(BlockDriverState *bs)
|
||||
@@ -498,9 +498,13 @@ static int raw_probe_geometry(BlockDriverState *bs, HDGeometry *geo)
|
||||
}
|
||||
|
||||
static int coroutine_fn raw_co_copy_range_from(BlockDriverState *bs,
|
||||
BdrvChild *src, uint64_t src_offset,
|
||||
BdrvChild *dst, uint64_t dst_offset,
|
||||
uint64_t bytes, BdrvRequestFlags flags)
|
||||
BdrvChild *src,
|
||||
uint64_t src_offset,
|
||||
BdrvChild *dst,
|
||||
uint64_t dst_offset,
|
||||
uint64_t bytes,
|
||||
BdrvRequestFlags read_flags,
|
||||
BdrvRequestFlags write_flags)
|
||||
{
|
||||
int ret;
|
||||
|
||||
@@ -509,13 +513,17 @@ static int coroutine_fn raw_co_copy_range_from(BlockDriverState *bs,
|
||||
return ret;
|
||||
}
|
||||
return bdrv_co_copy_range_from(bs->file, src_offset, dst, dst_offset,
|
||||
bytes, flags);
|
||||
bytes, read_flags, write_flags);
|
||||
}
|
||||
|
||||
static int coroutine_fn raw_co_copy_range_to(BlockDriverState *bs,
|
||||
BdrvChild *src, uint64_t src_offset,
|
||||
BdrvChild *dst, uint64_t dst_offset,
|
||||
uint64_t bytes, BdrvRequestFlags flags)
|
||||
BdrvChild *src,
|
||||
uint64_t src_offset,
|
||||
BdrvChild *dst,
|
||||
uint64_t dst_offset,
|
||||
uint64_t bytes,
|
||||
BdrvRequestFlags read_flags,
|
||||
BdrvRequestFlags write_flags)
|
||||
{
|
||||
int ret;
|
||||
|
||||
@@ -524,7 +532,7 @@ static int coroutine_fn raw_co_copy_range_to(BlockDriverState *bs,
|
||||
return ret;
|
||||
}
|
||||
return bdrv_co_copy_range_to(src, src_offset, bs->file, dst_offset, bytes,
|
||||
flags);
|
||||
read_flags, write_flags);
|
||||
}
|
||||
|
||||
BlockDriver bdrv_raw = {
|
||||
|
||||
+1
-1
@@ -149,7 +149,7 @@ static int coroutine_fn throttle_co_pdiscard(BlockDriverState *bs,
|
||||
ThrottleGroupMember *tgm = bs->opaque;
|
||||
throttle_group_co_io_limits_intercept(tgm, bytes, true);
|
||||
|
||||
return bdrv_co_pdiscard(bs->file->bs, offset, bytes);
|
||||
return bdrv_co_pdiscard(bs->file, offset, bytes);
|
||||
}
|
||||
|
||||
static int throttle_co_flush(BlockDriverState *bs)
|
||||
|
||||
+8
-2
@@ -15,6 +15,8 @@ bdrv_co_preadv(void *bs, int64_t offset, int64_t nbytes, unsigned int flags) "bs
|
||||
bdrv_co_pwritev(void *bs, int64_t offset, int64_t nbytes, unsigned int flags) "bs %p offset %"PRId64" nbytes %"PRId64" flags 0x%x"
|
||||
bdrv_co_pwrite_zeroes(void *bs, int64_t offset, int count, int flags) "bs %p offset %"PRId64" count %d flags 0x%x"
|
||||
bdrv_co_do_copy_on_readv(void *bs, int64_t offset, unsigned int bytes, int64_t cluster_offset, int64_t cluster_bytes) "bs %p offset %"PRId64" bytes %u cluster_offset %"PRId64" cluster_bytes %"PRId64
|
||||
bdrv_co_copy_range_from(void *src, uint64_t src_offset, void *dst, uint64_t dst_offset, uint64_t bytes, int read_flags, int write_flags) "src %p offset %"PRIu64" dst %p offset %"PRIu64" bytes %"PRIu64" rw flags 0x%x 0x%x"
|
||||
bdrv_co_copy_range_to(void *src, uint64_t src_offset, void *dst, uint64_t dst_offset, uint64_t bytes, int read_flags, int write_flags) "src %p offset %"PRIu64" dst %p offset %"PRIu64" bytes %"PRIu64" rw flags 0x%x 0x%x"
|
||||
|
||||
# block/stream.c
|
||||
stream_one_iteration(void *s, int64_t offset, uint64_t bytes, int is_allocated) "s %p offset %" PRId64 " bytes %" PRIu64 " is_allocated %d"
|
||||
@@ -55,8 +57,9 @@ qmp_block_stream(void *bs, void *job) "bs %p job %p"
|
||||
|
||||
# block/file-win32.c
|
||||
# block/file-posix.c
|
||||
paio_submit_co(int64_t offset, int count, int type) "offset %"PRId64" count %d type %d"
|
||||
paio_submit(void *acb, void *opaque, int64_t offset, int count, int type) "acb %p opaque %p offset %"PRId64" count %d type %d"
|
||||
file_paio_submit_co(int64_t offset, int count, int type) "offset %"PRId64" count %d type %d"
|
||||
file_paio_submit(void *acb, void *opaque, int64_t offset, int count, int type) "acb %p opaque %p offset %"PRId64" count %d type %d"
|
||||
file_copy_file_range(void *bs, int src, int64_t src_off, int dst, int64_t dst_off, int64_t bytes, int flags, int64_t ret) "bs %p src_fd %d offset %"PRIu64" dst_fd %d offset %"PRIu64" bytes %"PRIu64" flags %d ret %"PRId64
|
||||
|
||||
# block/qcow2.c
|
||||
qcow2_writev_start_req(void *co, int64_t offset, int bytes) "co %p offset 0x%" PRIx64 " bytes %d"
|
||||
@@ -150,3 +153,6 @@ nvme_free_req_queue_wait(void *q) "q %p"
|
||||
nvme_cmd_map_qiov(void *s, void *cmd, void *req, void *qiov, int entries) "s %p cmd %p req %p qiov %p entries %d"
|
||||
nvme_cmd_map_qiov_pages(void *s, int i, uint64_t page) "s %p page[%d] 0x%"PRIx64
|
||||
nvme_cmd_map_qiov_iov(void *s, int i, void *page, int pages) "s %p iov[%d] %p pages %d"
|
||||
|
||||
# block/iscsi.c
|
||||
iscsi_xcopy(void *src_lun, uint64_t src_off, void *dst_lun, uint64_t dst_off, uint64_t bytes, int ret) "src_lun %p offset %"PRIu64" dst_lun %p offset %"PRIu64" bytes %"PRIu64" ret %d"
|
||||
|
||||
+110
@@ -730,6 +730,30 @@ QemuOptsList qemu_legacy_drive_opts = {
|
||||
.name = "if",
|
||||
.type = QEMU_OPT_STRING,
|
||||
.help = "interface (ide, scsi, sd, mtd, floppy, pflash, virtio)",
|
||||
},{
|
||||
.name = "cyls",
|
||||
.type = QEMU_OPT_NUMBER,
|
||||
.help = "number of cylinders (ide disk geometry)",
|
||||
},{
|
||||
.name = "heads",
|
||||
.type = QEMU_OPT_NUMBER,
|
||||
.help = "number of heads (ide disk geometry)",
|
||||
},{
|
||||
.name = "secs",
|
||||
.type = QEMU_OPT_NUMBER,
|
||||
.help = "number of sectors (ide disk geometry)",
|
||||
},{
|
||||
.name = "trans",
|
||||
.type = QEMU_OPT_STRING,
|
||||
.help = "chs translation (auto, lba, none)",
|
||||
},{
|
||||
.name = "addr",
|
||||
.type = QEMU_OPT_STRING,
|
||||
.help = "pci address (virtio only)",
|
||||
},{
|
||||
.name = "serial",
|
||||
.type = QEMU_OPT_STRING,
|
||||
.help = "disk serial number",
|
||||
},{
|
||||
.name = "file",
|
||||
.type = QEMU_OPT_STRING,
|
||||
@@ -768,13 +792,19 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
|
||||
QemuOpts *legacy_opts;
|
||||
DriveMediaType media = MEDIA_DISK;
|
||||
BlockInterfaceType type;
|
||||
int cyls, heads, secs, translation;
|
||||
int max_devs, bus_id, unit_id, index;
|
||||
const char *devaddr;
|
||||
const char *werror, *rerror;
|
||||
bool read_only = false;
|
||||
bool copy_on_read;
|
||||
const char *serial;
|
||||
const char *filename;
|
||||
Error *local_err = NULL;
|
||||
int i;
|
||||
const char *deprecated[] = {
|
||||
"serial", "trans", "secs", "heads", "cyls", "addr"
|
||||
};
|
||||
|
||||
/* Change legacy command line options into QMP ones */
|
||||
static const struct {
|
||||
@@ -851,6 +881,16 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Other deprecated options */
|
||||
if (!qtest_enabled()) {
|
||||
for (i = 0; i < ARRAY_SIZE(deprecated); i++) {
|
||||
if (qemu_opt_get(legacy_opts, deprecated[i]) != NULL) {
|
||||
error_report("'%s' is deprecated, please use the corresponding "
|
||||
"option of '-device' instead", deprecated[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Media type */
|
||||
value = qemu_opt_get(legacy_opts, "media");
|
||||
if (value) {
|
||||
@@ -892,6 +932,57 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
|
||||
type = block_default_type;
|
||||
}
|
||||
|
||||
/* Geometry */
|
||||
cyls = qemu_opt_get_number(legacy_opts, "cyls", 0);
|
||||
heads = qemu_opt_get_number(legacy_opts, "heads", 0);
|
||||
secs = qemu_opt_get_number(legacy_opts, "secs", 0);
|
||||
|
||||
if (cyls || heads || secs) {
|
||||
if (cyls < 1) {
|
||||
error_report("invalid physical cyls number");
|
||||
goto fail;
|
||||
}
|
||||
if (heads < 1) {
|
||||
error_report("invalid physical heads number");
|
||||
goto fail;
|
||||
}
|
||||
if (secs < 1) {
|
||||
error_report("invalid physical secs number");
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
translation = BIOS_ATA_TRANSLATION_AUTO;
|
||||
value = qemu_opt_get(legacy_opts, "trans");
|
||||
if (value != NULL) {
|
||||
if (!cyls) {
|
||||
error_report("'%s' trans must be used with cyls, heads and secs",
|
||||
value);
|
||||
goto fail;
|
||||
}
|
||||
if (!strcmp(value, "none")) {
|
||||
translation = BIOS_ATA_TRANSLATION_NONE;
|
||||
} else if (!strcmp(value, "lba")) {
|
||||
translation = BIOS_ATA_TRANSLATION_LBA;
|
||||
} else if (!strcmp(value, "large")) {
|
||||
translation = BIOS_ATA_TRANSLATION_LARGE;
|
||||
} else if (!strcmp(value, "rechs")) {
|
||||
translation = BIOS_ATA_TRANSLATION_RECHS;
|
||||
} else if (!strcmp(value, "auto")) {
|
||||
translation = BIOS_ATA_TRANSLATION_AUTO;
|
||||
} else {
|
||||
error_report("'%s' invalid translation type", value);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
if (media == MEDIA_CDROM) {
|
||||
if (cyls || secs || heads) {
|
||||
error_report("CHS can't be set with media=cdrom");
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
/* Device address specified by bus/unit or index.
|
||||
* If none was specified, try to find the first free one. */
|
||||
bus_id = qemu_opt_get_number(legacy_opts, "bus", 0);
|
||||
@@ -931,6 +1022,9 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Serial number */
|
||||
serial = qemu_opt_get(legacy_opts, "serial");
|
||||
|
||||
/* no id supplied -> create one */
|
||||
if (qemu_opts_id(all_opts) == NULL) {
|
||||
char *new_id;
|
||||
@@ -950,6 +1044,12 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
|
||||
}
|
||||
|
||||
/* Add virtio block device */
|
||||
devaddr = qemu_opt_get(legacy_opts, "addr");
|
||||
if (devaddr && type != IF_VIRTIO) {
|
||||
error_report("addr is not supported by this bus type");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (type == IF_VIRTIO) {
|
||||
QemuOpts *devopts;
|
||||
devopts = qemu_opts_create(qemu_find_opts("device"), NULL, 0,
|
||||
@@ -961,6 +1061,9 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
|
||||
}
|
||||
qemu_opt_set(devopts, "drive", qdict_get_str(bs_opts, "id"),
|
||||
&error_abort);
|
||||
if (devaddr) {
|
||||
qemu_opt_set(devopts, "addr", devaddr, &error_abort);
|
||||
}
|
||||
}
|
||||
|
||||
filename = qemu_opt_get(legacy_opts, "file");
|
||||
@@ -1002,9 +1105,16 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
|
||||
dinfo = g_malloc0(sizeof(*dinfo));
|
||||
dinfo->opts = all_opts;
|
||||
|
||||
dinfo->cyls = cyls;
|
||||
dinfo->heads = heads;
|
||||
dinfo->secs = secs;
|
||||
dinfo->trans = translation;
|
||||
|
||||
dinfo->type = type;
|
||||
dinfo->bus = bus_id;
|
||||
dinfo->unit = unit_id;
|
||||
dinfo->devaddr = devaddr;
|
||||
dinfo->serial = g_strdup(serial);
|
||||
|
||||
blk_set_legacy_dinfo(blk, dinfo);
|
||||
|
||||
|
||||
@@ -69,6 +69,10 @@ void hmp_drive_add(Monitor *mon, const QDict *qdict)
|
||||
if (!dinfo) {
|
||||
goto err;
|
||||
}
|
||||
if (dinfo->devaddr) {
|
||||
monitor_printf(mon, "Parameter addr not supported\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
switch (dinfo->type) {
|
||||
case IF_NONE:
|
||||
|
||||
@@ -1306,6 +1306,7 @@ ETEXI
|
||||
.params = "[-n] [[<domain>:]<bus>:]<slot>\n"
|
||||
"[file=file][,if=type][,bus=n]\n"
|
||||
"[,unit=m][,media=d][,index=i]\n"
|
||||
"[,cyls=c,heads=h,secs=s[,trans=t]]\n"
|
||||
"[,snapshot=on|off][,cache=on|off]\n"
|
||||
"[,readonly=on|off][,copy-on-read=on|off]",
|
||||
.help = "add drive to PCI storage controller",
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user