Skip to content

Commit

Permalink
Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into s…
Browse files Browse the repository at this point in the history
…taging

Block layer patches:

- block: Fix crash with qcow2 partial cluster COW with small cluster
  sizes (misaligned write requests with BDRV_REQ_NO_FALLBACK)
- qcow2: Fix integer overflow potentially causing corruption with huge
  requests
- vhdx: Detect truncated image files
- tools: Support help options for --object
- Various block-related replay improvements
- iotests/028: Fix for long $TEST_DIRs

# gpg: Signature made Mon 14 Oct 2019 17:02:54 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:
  iotests: Test large write request to qcow2 file
  qcow2: Limit total allocation range to INT_MAX
  qemu-nbd: Support help options for --object
  qemu-img: Support help options for --object
  qemu-io: Support help options for --object
  vl: Split off user_creatable_print_help()
  iotests/028: Fix for long $TEST_DIRs
  block: Reject misaligned write requests with BDRV_REQ_NO_FALLBACK
  replay: add BH oneshot event for block layer
  replay: finish record/replay before closing the disks
  replay: don't drain/flush bdrv queue while RR is working
  replay: update docs for record/replay with block devices
  replay: disable default snapshot for record/replay
  block: implement bdrv_snapshot_goto for blkreplay
  block/vhdx: add check for truncated image files

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
  • Loading branch information
pm215 committed Oct 15, 2019
2 parents 9020e95 + a1406a9 commit 3af78db
Show file tree
Hide file tree
Showing 32 changed files with 504 additions and 111 deletions.
8 changes: 8 additions & 0 deletions block/blkreplay.c
Expand Up @@ -126,6 +126,12 @@ static int coroutine_fn blkreplay_co_flush(BlockDriverState *bs)
return ret;
}

static int blkreplay_snapshot_goto(BlockDriverState *bs,
const char *snapshot_id)
{
return bdrv_snapshot_goto(bs->file->bs, snapshot_id, NULL);
}

static BlockDriver bdrv_blkreplay = {
.format_name = "blkreplay",
.instance_size = 0,
Expand All @@ -140,6 +146,8 @@ static BlockDriver bdrv_blkreplay = {
.bdrv_co_pwrite_zeroes = blkreplay_co_pwrite_zeroes,
.bdrv_co_pdiscard = blkreplay_co_pdiscard,
.bdrv_co_flush = blkreplay_co_flush,

.bdrv_snapshot_goto = blkreplay_snapshot_goto,
};

static void bdrv_blkreplay_init(void)
Expand Down
9 changes: 6 additions & 3 deletions block/block-backend.c
Expand Up @@ -18,6 +18,8 @@
#include "hw/qdev-core.h"
#include "sysemu/blockdev.h"
#include "sysemu/runstate.h"
#include "sysemu/sysemu.h"
#include "sysemu/replay.h"
#include "qapi/error.h"
#include "qapi/qapi-events-block.h"
#include "qemu/id.h"
Expand Down Expand Up @@ -1306,7 +1308,8 @@ BlockAIOCB *blk_abort_aio_request(BlockBackend *blk,
acb->blk = blk;
acb->ret = ret;

aio_bh_schedule_oneshot(blk_get_aio_context(blk), error_callback_bh, acb);
replay_bh_schedule_oneshot_event(blk_get_aio_context(blk),
error_callback_bh, acb);
return &acb->common;
}

Expand Down Expand Up @@ -1362,8 +1365,8 @@ static BlockAIOCB *blk_aio_prwv(BlockBackend *blk, int64_t offset, int bytes,

acb->has_returned = true;
if (acb->rwco.ret != NOT_DONE) {
aio_bh_schedule_oneshot(blk_get_aio_context(blk),
blk_aio_complete_bh, acb);
replay_bh_schedule_oneshot_event(blk_get_aio_context(blk),
blk_aio_complete_bh, acb);
}

return &acb->common;
Expand Down
39 changes: 37 additions & 2 deletions block/io.c
Expand Up @@ -33,6 +33,7 @@
#include "qapi/error.h"
#include "qemu/error-report.h"
#include "qemu/main-loop.h"
#include "sysemu/replay.h"

#define NOT_DONE 0x7fffffff /* used while emulated sync operation in progress */

Expand Down Expand Up @@ -368,8 +369,8 @@ static void coroutine_fn bdrv_co_yield_to_drain(BlockDriverState *bs,
if (bs) {
bdrv_inc_in_flight(bs);
}
aio_bh_schedule_oneshot(bdrv_get_aio_context(bs),
bdrv_co_drain_bh_cb, &data);
replay_bh_schedule_oneshot_event(bdrv_get_aio_context(bs),
bdrv_co_drain_bh_cb, &data);

qemu_coroutine_yield();
/* If we are resumed from some other event (such as an aio completion or a
Expand Down Expand Up @@ -600,6 +601,15 @@ void bdrv_drain_all_begin(void)
return;
}

/*
* bdrv queue is managed by record/replay,
* waiting for finishing the I/O requests may
* be infinite
*/
if (replay_events_enabled()) {
return;
}

/* AIO_WAIT_WHILE() with a NULL context can only be called from the main
* loop AioContext, so make sure we're in the main context. */
assert(qemu_get_current_aio_context() == qemu_get_aio_context());
Expand Down Expand Up @@ -629,6 +639,15 @@ void bdrv_drain_all_end(void)
BlockDriverState *bs = NULL;
int drained_end_counter = 0;

/*
* bdrv queue is managed by record/replay,
* waiting for finishing the I/O requests may
* be endless
*/
if (replay_events_enabled()) {
return;
}

while ((bs = bdrv_next_all_states(bs))) {
AioContext *aio_context = bdrv_get_aio_context(bs);

Expand Down Expand Up @@ -2071,6 +2090,13 @@ int coroutine_fn bdrv_co_pwritev_part(BdrvChild *child,
return ret;
}

/* If the request is misaligned then we can't make it efficient */
if ((flags & BDRV_REQ_NO_FALLBACK) &&
!QEMU_IS_ALIGNED(offset | bytes, align))
{
return -ENOTSUP;
}

bdrv_inc_in_flight(bs);
/*
* Align write if necessary by performing a read-modify-write cycle.
Expand Down Expand Up @@ -2124,6 +2150,15 @@ int bdrv_flush_all(void)
BlockDriverState *bs = NULL;
int result = 0;

/*
* bdrv queue is managed by record/replay,
* creating new flush request for stopping
* the VM may break the determinism
*/
if (replay_events_enabled()) {
return result;
}

for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
AioContext *aio_context = bdrv_get_aio_context(bs);
int ret;
Expand Down
5 changes: 3 additions & 2 deletions block/iscsi.c
Expand Up @@ -40,6 +40,7 @@
#include "qemu/module.h"
#include "qemu/option.h"
#include "qemu/uuid.h"
#include "sysemu/replay.h"
#include "qapi/error.h"
#include "qapi/qapi-commands-misc.h"
#include "qapi/qmp/qdict.h"
Expand Down Expand Up @@ -280,8 +281,8 @@ iscsi_co_generic_cb(struct iscsi_context *iscsi, int status,
}

if (iTask->co) {
aio_bh_schedule_oneshot(iTask->iscsilun->aio_context,
iscsi_co_generic_bh_cb, iTask);
replay_bh_schedule_oneshot_event(iTask->iscsilun->aio_context,
iscsi_co_generic_bh_cb, iTask);
} else {
iTask->complete = 1;
}
Expand Down
6 changes: 4 additions & 2 deletions block/nfs.c
Expand Up @@ -37,6 +37,8 @@
#include "qemu/option.h"
#include "qemu/uri.h"
#include "qemu/cutils.h"
#include "sysemu/sysemu.h"
#include "sysemu/replay.h"
#include "qapi/qapi-visit-block-core.h"
#include "qapi/qmp/qdict.h"
#include "qapi/qmp/qstring.h"
Expand Down Expand Up @@ -257,8 +259,8 @@ nfs_co_generic_cb(int ret, struct nfs_context *nfs, void *data,
if (task->ret < 0) {
error_report("NFS Error: %s", nfs_get_error(nfs));
}
aio_bh_schedule_oneshot(task->client->aio_context,
nfs_co_generic_bh_cb, task);
replay_bh_schedule_oneshot_event(task->client->aio_context,
nfs_co_generic_bh_cb, task);
}

static int coroutine_fn nfs_co_preadv(BlockDriverState *bs, uint64_t offset,
Expand Down
4 changes: 3 additions & 1 deletion block/null.c
Expand Up @@ -17,6 +17,7 @@
#include "qemu/module.h"
#include "qemu/option.h"
#include "block/block_int.h"
#include "sysemu/replay.h"

#define NULL_OPT_LATENCY "latency-ns"
#define NULL_OPT_ZEROES "read-zeroes"
Expand Down Expand Up @@ -179,7 +180,8 @@ static inline BlockAIOCB *null_aio_common(BlockDriverState *bs,
timer_mod_ns(&acb->timer,
qemu_clock_get_ns(QEMU_CLOCK_REALTIME) + s->latency_ns);
} else {
aio_bh_schedule_oneshot(bdrv_get_aio_context(bs), null_bh_cb, acb);
replay_bh_schedule_oneshot_event(bdrv_get_aio_context(bs),
null_bh_cb, acb);
}
return &acb->common;
}
Expand Down
6 changes: 4 additions & 2 deletions block/nvme.c
Expand Up @@ -23,6 +23,7 @@
#include "qemu/option.h"
#include "qemu/vfio-helpers.h"
#include "block/block_int.h"
#include "sysemu/replay.h"
#include "trace.h"

#include "block/nvme.h"
Expand Down Expand Up @@ -351,7 +352,8 @@ static bool nvme_process_completion(BDRVNVMeState *s, NVMeQueuePair *q)
smp_mb_release();
*q->cq.doorbell = cpu_to_le32(q->cq.head);
if (!qemu_co_queue_empty(&q->free_req_queue)) {
aio_bh_schedule_oneshot(s->aio_context, nvme_free_req_queue_cb, q);
replay_bh_schedule_oneshot_event(s->aio_context,
nvme_free_req_queue_cb, q);
}
}
q->busy = false;
Expand Down Expand Up @@ -935,7 +937,7 @@ static void nvme_rw_cb(void *opaque, int ret)
/* The rw coroutine hasn't yielded, don't try to enter. */
return;
}
aio_bh_schedule_oneshot(data->ctx, nvme_rw_cb_bh, data);
replay_bh_schedule_oneshot_event(data->ctx, nvme_rw_cb_bh, data);
}

static coroutine_fn int nvme_co_prw_aligned(BlockDriverState *bs,
Expand Down
5 changes: 4 additions & 1 deletion block/qcow2-cluster.c
Expand Up @@ -1330,6 +1330,9 @@ static int handle_alloc(BlockDriverState *bs, uint64_t guest_offset,
nb_clusters = MIN(nb_clusters, s->l2_slice_size - l2_index);
assert(nb_clusters <= INT_MAX);

/* Limit total allocation byte count to INT_MAX */
nb_clusters = MIN(nb_clusters, INT_MAX >> s->cluster_bits);

/* Find L2 entry for the first involved cluster */
ret = get_cluster_table(bs, guest_offset, &l2_slice, &l2_index);
if (ret < 0) {
Expand Down Expand Up @@ -1412,7 +1415,7 @@ static int handle_alloc(BlockDriverState *bs, uint64_t guest_offset,
* request actually writes to (excluding COW at the end)
*/
uint64_t requested_bytes = *bytes + offset_into_cluster(s, guest_offset);
int avail_bytes = MIN(INT_MAX, nb_clusters << s->cluster_bits);
int avail_bytes = nb_clusters << s->cluster_bits;
int nb_bytes = MIN(requested_bytes, avail_bytes);
QCowL2Meta *old_m = *m;

Expand Down
5 changes: 3 additions & 2 deletions block/rbd.c
Expand Up @@ -22,6 +22,7 @@
#include "block/qdict.h"
#include "crypto/secret.h"
#include "qemu/cutils.h"
#include "sysemu/replay.h"
#include "qapi/qmp/qstring.h"
#include "qapi/qmp/qdict.h"
#include "qapi/qmp/qjson.h"
Expand Down Expand Up @@ -884,8 +885,8 @@ static void rbd_finish_aiocb(rbd_completion_t c, RADOSCB *rcb)
rcb->ret = rbd_aio_get_return_value(c);
rbd_aio_release(c);

aio_bh_schedule_oneshot(bdrv_get_aio_context(acb->common.bs),
rbd_finish_bh, rcb);
replay_bh_schedule_oneshot_event(bdrv_get_aio_context(acb->common.bs),
rbd_finish_bh, rcb);
}

static int rbd_aio_discard_wrapper(rbd_image_t image,
Expand Down

0 comments on commit 3af78db

Please sign in to comment.