mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Merge tag 'for-upstream' of https://repo.or.cz/qemu/kevin into staging
Block layer patches - Protect BlockBackend.queued_requests with its own lock - Switch to AIO_WAIT_WHILE_UNLOCKED() where possible - AioContext removal: LinuxAioState/LuringState/ThreadPool - Add more coroutine_fn annotations, use bdrv/blk_co_* - Fix crash when execute hmp_commit # -----BEGIN PGP SIGNATURE----- # # iQJFBAABCAAvFiEE3D3rFZqa+V09dFb+fwmycsiPL9YFAmRH0b0RHGt3b2xmQHJl # ZGhhdC5jb20ACgkQfwmycsiPL9Y0yw/6A/vzA4TGgFUP3WIvH/sQri4/V3gyR+PT # u3hOQUCYZ99nioTpKV91TSuUPuU/Mdspy/0NKM+K92yIXqxa9172A2zLOsGOu21l # qKpse+nBf1zqEgB8YzUHyCBdetPz916C/f9RS26SNUCW85GCHYGHA3u7nKvWLMyV # oKIoTlA8QOglOuEKlRoYh7hCFm7ET51NOSEftm8GsYbsW/I2Vzl8a1SHN1lHufjd # We3+898zUrmFqNMp6Rjdhn+yZmmoGzoZqV4YQi83z7xjiv+Ms4VHVVW7X8d20xRX # 5BLFiLHAuZ/1d26HyVhgBUr7KHyf94odocz8BylWKXGl5SXMCZun1Td1vgVKlGK+ # GRxzB2cWGWqzC2UmqSTc0Z0aIWbXukKwvcX76uBKsQZ+kB2A7jFobxHiaoQEDJ8B # WRNEMH2+CqCAu9rsrNRinnJKhT2nXcr9F9YfwRIlagdAePGWin+EUW8huf14dDBm # Z2Y34aKW4RQibF8xirMHeRBbOLmcq2VpKLKwNfBHUDgZB8iuD7bLn4n9nwWXMG1w # zgNsTybkv46vLPamTpEaUoNTHfuRDTAuE7Z7lkcc7jF41Z0V1DC/DCCWcL/0LvhP # GIxFdkYug3hetdF2U/OZhUoEfxvkqcuBnrr55LFzqheKEllQpPwPpt7UF0aH8bg3 # i/YpjHsf3xU= # =mpYX # -----END PGP SIGNATURE----- # gpg: Signature made Tue 25 Apr 2023 02:12:29 PM BST # gpg: using RSA key DC3DEB159A9AF95D3D7456FE7F09B272C88F2FD6 # gpg: issuer "kwolf@redhat.com" # gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>" [full] * tag 'for-upstream' of https://repo.or.cz/qemu/kevin: (25 commits) block/monitor: Fix crash when executing HMP commit vmdk: make vmdk_is_cid_valid a coroutine_fn qcow2: mark various functions as coroutine_fn and GRAPH_RDLOCK tests: mark more coroutine_fns qemu-pr-helper: mark more coroutine_fns 9pfs: mark more coroutine_fns nbd: mark more coroutine_fns, do not use co_wrappers mirror: make mirror_flush a coroutine_fn, do not use co_wrappers blkdebug: add missing coroutine_fn annotation vvfat: mark various functions as coroutine_fn thread-pool: avoid passing the pool parameter every time thread-pool: use ThreadPool from the running thread io_uring: use LuringState from the running thread linux-aio: use LinuxAioState from the running thread block: add missing coroutine_fn to bdrv_sum_allocated_file_size() include/block: fixup typos monitor: convert monitor_cleanup() to AIO_WAIT_WHILE_UNLOCKED() hmp: convert handle_hmp_command() to AIO_WAIT_WHILE_UNLOCKED() block: convert bdrv_drain_all_begin() to AIO_WAIT_WHILE_UNLOCKED() block: convert bdrv_graph_wrlock() to AIO_WAIT_WHILE_UNLOCKED() ... Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
@@ -100,8 +100,6 @@ bool tpm_backend_had_startup_error(TPMBackend *s)
|
||||
|
||||
void tpm_backend_deliver_request(TPMBackend *s, TPMBackendCmd *cmd)
|
||||
{
|
||||
ThreadPool *pool = aio_get_thread_pool(qemu_get_aio_context());
|
||||
|
||||
if (s->cmd != NULL) {
|
||||
error_report("There is a TPM request pending");
|
||||
return;
|
||||
@@ -109,7 +107,7 @@ void tpm_backend_deliver_request(TPMBackend *s, TPMBackendCmd *cmd)
|
||||
|
||||
s->cmd = cmd;
|
||||
object_ref(OBJECT(s));
|
||||
thread_pool_submit_aio(pool, tpm_backend_worker_thread, s,
|
||||
thread_pool_submit_aio(tpm_backend_worker_thread, s,
|
||||
tpm_backend_request_completed, s);
|
||||
}
|
||||
|
||||
|
||||
@@ -5750,7 +5750,7 @@ exit:
|
||||
* sums the size of all data-bearing children. (This excludes backing
|
||||
* children.)
|
||||
*/
|
||||
static int64_t bdrv_sum_allocated_file_size(BlockDriverState *bs)
|
||||
static int64_t coroutine_fn bdrv_sum_allocated_file_size(BlockDriverState *bs)
|
||||
{
|
||||
BdrvChild *child;
|
||||
int64_t child_size, sum = 0;
|
||||
|
||||
+2
-2
@@ -583,8 +583,8 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rule_check(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
|
||||
BlkdebugIOType iotype)
|
||||
static int coroutine_fn rule_check(BlockDriverState *bs, uint64_t offset,
|
||||
uint64_t bytes, BlkdebugIOType iotype)
|
||||
{
|
||||
BDRVBlkdebugState *s = bs->opaque;
|
||||
BlkdebugRule *rule = NULL;
|
||||
|
||||
+27
-18
@@ -80,9 +80,10 @@ struct BlockBackend {
|
||||
NotifierList remove_bs_notifiers, insert_bs_notifiers;
|
||||
QLIST_HEAD(, BlockBackendAioNotifier) aio_notifiers;
|
||||
|
||||
int quiesce_counter;
|
||||
int quiesce_counter; /* atomic: written under BQL, read by other threads */
|
||||
QemuMutex queued_requests_lock; /* protects queued_requests */
|
||||
CoQueue queued_requests;
|
||||
bool disable_request_queuing;
|
||||
bool disable_request_queuing; /* atomic */
|
||||
|
||||
VMChangeStateEntry *vmsh;
|
||||
bool force_allow_inactivate;
|
||||
@@ -368,6 +369,7 @@ BlockBackend *blk_new(AioContext *ctx, uint64_t perm, uint64_t shared_perm)
|
||||
|
||||
block_acct_init(&blk->stats);
|
||||
|
||||
qemu_mutex_init(&blk->queued_requests_lock);
|
||||
qemu_co_queue_init(&blk->queued_requests);
|
||||
notifier_list_init(&blk->remove_bs_notifiers);
|
||||
notifier_list_init(&blk->insert_bs_notifiers);
|
||||
@@ -485,6 +487,8 @@ static void blk_delete(BlockBackend *blk)
|
||||
assert(QLIST_EMPTY(&blk->remove_bs_notifiers.notifiers));
|
||||
assert(QLIST_EMPTY(&blk->insert_bs_notifiers.notifiers));
|
||||
assert(QLIST_EMPTY(&blk->aio_notifiers));
|
||||
assert(qemu_co_queue_empty(&blk->queued_requests));
|
||||
qemu_mutex_destroy(&blk->queued_requests_lock);
|
||||
QTAILQ_REMOVE(&block_backends, blk, link);
|
||||
drive_info_del(blk->legacy_dinfo);
|
||||
block_acct_cleanup(&blk->stats);
|
||||
@@ -1057,7 +1061,7 @@ void blk_set_dev_ops(BlockBackend *blk, const BlockDevOps *ops,
|
||||
blk->dev_opaque = opaque;
|
||||
|
||||
/* Are we currently quiesced? Should we enforce this right now? */
|
||||
if (blk->quiesce_counter && ops && ops->drained_begin) {
|
||||
if (qatomic_read(&blk->quiesce_counter) && ops && ops->drained_begin) {
|
||||
ops->drained_begin(opaque);
|
||||
}
|
||||
}
|
||||
@@ -1232,7 +1236,7 @@ void blk_set_allow_aio_context_change(BlockBackend *blk, bool allow)
|
||||
void blk_set_disable_request_queuing(BlockBackend *blk, bool disable)
|
||||
{
|
||||
IO_CODE();
|
||||
blk->disable_request_queuing = disable;
|
||||
qatomic_set(&blk->disable_request_queuing, disable);
|
||||
}
|
||||
|
||||
static int coroutine_fn GRAPH_RDLOCK
|
||||
@@ -1271,10 +1275,18 @@ static void coroutine_fn blk_wait_while_drained(BlockBackend *blk)
|
||||
{
|
||||
assert(blk->in_flight > 0);
|
||||
|
||||
if (blk->quiesce_counter && !blk->disable_request_queuing) {
|
||||
if (qatomic_read(&blk->quiesce_counter) &&
|
||||
!qatomic_read(&blk->disable_request_queuing)) {
|
||||
/*
|
||||
* Take lock before decrementing in flight counter so main loop thread
|
||||
* waits for us to enqueue ourselves before it can leave the drained
|
||||
* section.
|
||||
*/
|
||||
qemu_mutex_lock(&blk->queued_requests_lock);
|
||||
blk_dec_in_flight(blk);
|
||||
qemu_co_queue_wait(&blk->queued_requests, NULL);
|
||||
qemu_co_queue_wait(&blk->queued_requests, &blk->queued_requests_lock);
|
||||
blk_inc_in_flight(blk);
|
||||
qemu_mutex_unlock(&blk->queued_requests_lock);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1862,14 +1874,8 @@ void blk_drain_all(void)
|
||||
bdrv_drain_all_begin();
|
||||
|
||||
while ((blk = blk_all_next(blk)) != NULL) {
|
||||
AioContext *ctx = blk_get_aio_context(blk);
|
||||
|
||||
aio_context_acquire(ctx);
|
||||
|
||||
/* We may have -ENOMEDIUM completions in flight */
|
||||
AIO_WAIT_WHILE(ctx, qatomic_read(&blk->in_flight) > 0);
|
||||
|
||||
aio_context_release(ctx);
|
||||
AIO_WAIT_WHILE_UNLOCKED(NULL, qatomic_read(&blk->in_flight) > 0);
|
||||
}
|
||||
|
||||
bdrv_drain_all_end();
|
||||
@@ -2595,7 +2601,7 @@ static void blk_root_drained_begin(BdrvChild *child)
|
||||
BlockBackend *blk = child->opaque;
|
||||
ThrottleGroupMember *tgm = &blk->public.throttle_group_member;
|
||||
|
||||
if (++blk->quiesce_counter == 1) {
|
||||
if (qatomic_fetch_inc(&blk->quiesce_counter) == 0) {
|
||||
if (blk->dev_ops && blk->dev_ops->drained_begin) {
|
||||
blk->dev_ops->drained_begin(blk->dev_opaque);
|
||||
}
|
||||
@@ -2613,7 +2619,7 @@ static bool blk_root_drained_poll(BdrvChild *child)
|
||||
{
|
||||
BlockBackend *blk = child->opaque;
|
||||
bool busy = false;
|
||||
assert(blk->quiesce_counter);
|
||||
assert(qatomic_read(&blk->quiesce_counter));
|
||||
|
||||
if (blk->dev_ops && blk->dev_ops->drained_poll) {
|
||||
busy = blk->dev_ops->drained_poll(blk->dev_opaque);
|
||||
@@ -2624,18 +2630,21 @@ static bool blk_root_drained_poll(BdrvChild *child)
|
||||
static void blk_root_drained_end(BdrvChild *child)
|
||||
{
|
||||
BlockBackend *blk = child->opaque;
|
||||
assert(blk->quiesce_counter);
|
||||
assert(qatomic_read(&blk->quiesce_counter));
|
||||
|
||||
assert(blk->public.throttle_group_member.io_limits_disabled);
|
||||
qatomic_dec(&blk->public.throttle_group_member.io_limits_disabled);
|
||||
|
||||
if (--blk->quiesce_counter == 0) {
|
||||
if (qatomic_fetch_dec(&blk->quiesce_counter) == 1) {
|
||||
if (blk->dev_ops && blk->dev_ops->drained_end) {
|
||||
blk->dev_ops->drained_end(blk->dev_opaque);
|
||||
}
|
||||
while (qemu_co_enter_next(&blk->queued_requests, NULL)) {
|
||||
qemu_mutex_lock(&blk->queued_requests_lock);
|
||||
while (qemu_co_enter_next(&blk->queued_requests,
|
||||
&blk->queued_requests_lock)) {
|
||||
/* Resume all queued requests */
|
||||
}
|
||||
qemu_mutex_unlock(&blk->queued_requests_lock);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -306,7 +306,7 @@ void blk_exp_close_all_type(BlockExportType type)
|
||||
blk_exp_request_shutdown(exp);
|
||||
}
|
||||
|
||||
AIO_WAIT_WHILE(NULL, blk_exp_has_type(type));
|
||||
AIO_WAIT_WHILE_UNLOCKED(NULL, blk_exp_has_type(type));
|
||||
}
|
||||
|
||||
void blk_exp_close_all(void)
|
||||
|
||||
+17
-28
@@ -2040,12 +2040,9 @@ out:
|
||||
return result;
|
||||
}
|
||||
|
||||
static int coroutine_fn raw_thread_pool_submit(BlockDriverState *bs,
|
||||
ThreadPoolFunc func, void *arg)
|
||||
static int coroutine_fn raw_thread_pool_submit(ThreadPoolFunc func, void *arg)
|
||||
{
|
||||
/* @bs can be NULL, bdrv_get_aio_context() returns the main context then */
|
||||
ThreadPool *pool = aio_get_thread_pool(bdrv_get_aio_context(bs));
|
||||
return thread_pool_submit_co(pool, func, arg);
|
||||
return thread_pool_submit_co(func, arg);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2089,16 +2086,13 @@ static int coroutine_fn raw_co_prw(BlockDriverState *bs, uint64_t offset,
|
||||
type |= QEMU_AIO_MISALIGNED;
|
||||
#ifdef CONFIG_LINUX_IO_URING
|
||||
} else if (s->use_linux_io_uring) {
|
||||
LuringState *aio = aio_get_linux_io_uring(bdrv_get_aio_context(bs));
|
||||
assert(qiov->size == bytes);
|
||||
return luring_co_submit(bs, aio, s->fd, offset, qiov, type);
|
||||
return luring_co_submit(bs, s->fd, offset, qiov, type);
|
||||
#endif
|
||||
#ifdef CONFIG_LINUX_AIO
|
||||
} else if (s->use_linux_aio) {
|
||||
LinuxAioState *aio = aio_get_linux_aio(bdrv_get_aio_context(bs));
|
||||
assert(qiov->size == bytes);
|
||||
return laio_co_submit(bs, aio, s->fd, offset, qiov, type,
|
||||
s->aio_max_batch);
|
||||
return laio_co_submit(s->fd, offset, qiov, type, s->aio_max_batch);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -2115,7 +2109,7 @@ static int coroutine_fn raw_co_prw(BlockDriverState *bs, uint64_t offset,
|
||||
};
|
||||
|
||||
assert(qiov->size == bytes);
|
||||
return raw_thread_pool_submit(bs, handle_aiocb_rw, &acb);
|
||||
return raw_thread_pool_submit(handle_aiocb_rw, &acb);
|
||||
}
|
||||
|
||||
static int coroutine_fn raw_co_preadv(BlockDriverState *bs, int64_t offset,
|
||||
@@ -2137,14 +2131,12 @@ static void coroutine_fn raw_co_io_plug(BlockDriverState *bs)
|
||||
BDRVRawState __attribute__((unused)) *s = bs->opaque;
|
||||
#ifdef CONFIG_LINUX_AIO
|
||||
if (s->use_linux_aio) {
|
||||
LinuxAioState *aio = aio_get_linux_aio(bdrv_get_aio_context(bs));
|
||||
laio_io_plug(bs, aio);
|
||||
laio_io_plug();
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_LINUX_IO_URING
|
||||
if (s->use_linux_io_uring) {
|
||||
LuringState *aio = aio_get_linux_io_uring(bdrv_get_aio_context(bs));
|
||||
luring_io_plug(bs, aio);
|
||||
luring_io_plug();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -2154,14 +2146,12 @@ static void coroutine_fn raw_co_io_unplug(BlockDriverState *bs)
|
||||
BDRVRawState __attribute__((unused)) *s = bs->opaque;
|
||||
#ifdef CONFIG_LINUX_AIO
|
||||
if (s->use_linux_aio) {
|
||||
LinuxAioState *aio = aio_get_linux_aio(bdrv_get_aio_context(bs));
|
||||
laio_io_unplug(bs, aio, s->aio_max_batch);
|
||||
laio_io_unplug(s->aio_max_batch);
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_LINUX_IO_URING
|
||||
if (s->use_linux_io_uring) {
|
||||
LuringState *aio = aio_get_linux_io_uring(bdrv_get_aio_context(bs));
|
||||
luring_io_unplug(bs, aio);
|
||||
luring_io_unplug();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -2185,11 +2175,10 @@ static int coroutine_fn raw_co_flush_to_disk(BlockDriverState *bs)
|
||||
|
||||
#ifdef CONFIG_LINUX_IO_URING
|
||||
if (s->use_linux_io_uring) {
|
||||
LuringState *aio = aio_get_linux_io_uring(bdrv_get_aio_context(bs));
|
||||
return luring_co_submit(bs, aio, s->fd, 0, NULL, QEMU_AIO_FLUSH);
|
||||
return luring_co_submit(bs, s->fd, 0, NULL, QEMU_AIO_FLUSH);
|
||||
}
|
||||
#endif
|
||||
return raw_thread_pool_submit(bs, handle_aiocb_flush, &acb);
|
||||
return raw_thread_pool_submit(handle_aiocb_flush, &acb);
|
||||
}
|
||||
|
||||
static void raw_aio_attach_aio_context(BlockDriverState *bs,
|
||||
@@ -2251,7 +2240,7 @@ raw_regular_truncate(BlockDriverState *bs, int fd, int64_t offset,
|
||||
},
|
||||
};
|
||||
|
||||
return raw_thread_pool_submit(bs, handle_aiocb_truncate, &acb);
|
||||
return raw_thread_pool_submit(handle_aiocb_truncate, &acb);
|
||||
}
|
||||
|
||||
static int coroutine_fn raw_co_truncate(BlockDriverState *bs, int64_t offset,
|
||||
@@ -3000,7 +2989,7 @@ raw_do_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||
acb.aio_type |= QEMU_AIO_BLKDEV;
|
||||
}
|
||||
|
||||
ret = raw_thread_pool_submit(bs, handle_aiocb_discard, &acb);
|
||||
ret = raw_thread_pool_submit(handle_aiocb_discard, &acb);
|
||||
raw_account_discard(s, bytes, ret);
|
||||
return ret;
|
||||
}
|
||||
@@ -3075,7 +3064,7 @@ raw_do_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||
handler = handle_aiocb_write_zeroes;
|
||||
}
|
||||
|
||||
return raw_thread_pool_submit(bs, handler, &acb);
|
||||
return raw_thread_pool_submit(handler, &acb);
|
||||
}
|
||||
|
||||
static int coroutine_fn raw_co_pwrite_zeroes(
|
||||
@@ -3313,7 +3302,7 @@ raw_co_copy_range_to(BlockDriverState *bs,
|
||||
},
|
||||
};
|
||||
|
||||
return raw_thread_pool_submit(bs, handle_aiocb_copy_range, &acb);
|
||||
return raw_thread_pool_submit(handle_aiocb_copy_range, &acb);
|
||||
}
|
||||
|
||||
BlockDriver bdrv_file = {
|
||||
@@ -3643,7 +3632,7 @@ hdev_co_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
|
||||
struct sg_io_hdr *io_hdr = buf;
|
||||
if (io_hdr->cmdp[0] == PERSISTENT_RESERVE_OUT ||
|
||||
io_hdr->cmdp[0] == PERSISTENT_RESERVE_IN) {
|
||||
return pr_manager_execute(s->pr_mgr, bdrv_get_aio_context(bs),
|
||||
return pr_manager_execute(s->pr_mgr, qemu_get_current_aio_context(),
|
||||
s->fd, io_hdr);
|
||||
}
|
||||
}
|
||||
@@ -3659,7 +3648,7 @@ hdev_co_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
|
||||
},
|
||||
};
|
||||
|
||||
return raw_thread_pool_submit(bs, handle_aiocb_ioctl, &acb);
|
||||
return raw_thread_pool_submit(handle_aiocb_ioctl, &acb);
|
||||
}
|
||||
#endif /* linux */
|
||||
|
||||
|
||||
+1
-3
@@ -153,7 +153,6 @@ static BlockAIOCB *paio_submit(BlockDriverState *bs, HANDLE hfile,
|
||||
BlockCompletionFunc *cb, void *opaque, int type)
|
||||
{
|
||||
RawWin32AIOData *acb = g_new(RawWin32AIOData, 1);
|
||||
ThreadPool *pool;
|
||||
|
||||
acb->bs = bs;
|
||||
acb->hfile = hfile;
|
||||
@@ -168,8 +167,7 @@ static BlockAIOCB *paio_submit(BlockDriverState *bs, HANDLE hfile,
|
||||
acb->aio_offset = offset;
|
||||
|
||||
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);
|
||||
return thread_pool_submit_aio(aio_worker, acb, cb, opaque);
|
||||
}
|
||||
|
||||
int qemu_ftruncate64(int fd, int64_t length)
|
||||
|
||||
+1
-1
@@ -127,7 +127,7 @@ void bdrv_graph_wrlock(void)
|
||||
* reader lock.
|
||||
*/
|
||||
qatomic_set(&has_writer, 0);
|
||||
AIO_WAIT_WHILE(qemu_get_aio_context(), reader_count() >= 1);
|
||||
AIO_WAIT_WHILE_UNLOCKED(NULL, reader_count() >= 1);
|
||||
qatomic_set(&has_writer, 1);
|
||||
|
||||
/*
|
||||
|
||||
+1
-1
@@ -524,7 +524,7 @@ void bdrv_drain_all_begin(void)
|
||||
bdrv_drain_all_begin_nopoll();
|
||||
|
||||
/* Now poll the in-flight requests */
|
||||
AIO_WAIT_WHILE(NULL, bdrv_drain_all_poll());
|
||||
AIO_WAIT_WHILE_UNLOCKED(NULL, bdrv_drain_all_poll());
|
||||
|
||||
while ((bs = bdrv_next_all_states(bs))) {
|
||||
bdrv_drain_assert_idle(bs);
|
||||
|
||||
+15
-8
@@ -18,6 +18,9 @@
|
||||
#include "qapi/error.h"
|
||||
#include "trace.h"
|
||||
|
||||
/* Only used for assertions. */
|
||||
#include "qemu/coroutine_int.h"
|
||||
|
||||
/* io_uring ring size */
|
||||
#define MAX_ENTRIES 128
|
||||
|
||||
@@ -50,10 +53,9 @@ typedef struct LuringState {
|
||||
|
||||
struct io_uring ring;
|
||||
|
||||
/* io queue for submit at batch. Protected by AioContext lock. */
|
||||
/* No locking required, only accessed from AioContext home thread */
|
||||
LuringQueue io_q;
|
||||
|
||||
/* I/O completion processing. Only runs in I/O thread. */
|
||||
QEMUBH *completion_bh;
|
||||
} LuringState;
|
||||
|
||||
@@ -209,6 +211,7 @@ end:
|
||||
* eventually runs later. Coroutines cannot be entered recursively
|
||||
* so avoid doing that!
|
||||
*/
|
||||
assert(luringcb->co->ctx == s->aio_context);
|
||||
if (!qemu_coroutine_entered(luringcb->co)) {
|
||||
aio_co_wake(luringcb->co);
|
||||
}
|
||||
@@ -262,13 +265,11 @@ static int ioq_submit(LuringState *s)
|
||||
|
||||
static void luring_process_completions_and_submit(LuringState *s)
|
||||
{
|
||||
aio_context_acquire(s->aio_context);
|
||||
luring_process_completions(s);
|
||||
|
||||
if (!s->io_q.plugged && s->io_q.in_queue > 0) {
|
||||
ioq_submit(s);
|
||||
}
|
||||
aio_context_release(s->aio_context);
|
||||
}
|
||||
|
||||
static void qemu_luring_completion_bh(void *opaque)
|
||||
@@ -306,14 +307,18 @@ static void ioq_init(LuringQueue *io_q)
|
||||
io_q->blocked = false;
|
||||
}
|
||||
|
||||
void luring_io_plug(BlockDriverState *bs, LuringState *s)
|
||||
void luring_io_plug(void)
|
||||
{
|
||||
AioContext *ctx = qemu_get_current_aio_context();
|
||||
LuringState *s = aio_get_linux_io_uring(ctx);
|
||||
trace_luring_io_plug(s);
|
||||
s->io_q.plugged++;
|
||||
}
|
||||
|
||||
void luring_io_unplug(BlockDriverState *bs, LuringState *s)
|
||||
void luring_io_unplug(void)
|
||||
{
|
||||
AioContext *ctx = qemu_get_current_aio_context();
|
||||
LuringState *s = aio_get_linux_io_uring(ctx);
|
||||
assert(s->io_q.plugged);
|
||||
trace_luring_io_unplug(s, s->io_q.blocked, s->io_q.plugged,
|
||||
s->io_q.in_queue, s->io_q.in_flight);
|
||||
@@ -373,10 +378,12 @@ static int luring_do_submit(int fd, LuringAIOCB *luringcb, LuringState *s,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int coroutine_fn luring_co_submit(BlockDriverState *bs, LuringState *s, int fd,
|
||||
uint64_t offset, QEMUIOVector *qiov, int type)
|
||||
int coroutine_fn luring_co_submit(BlockDriverState *bs, int fd, uint64_t offset,
|
||||
QEMUIOVector *qiov, int type)
|
||||
{
|
||||
int ret;
|
||||
AioContext *ctx = qemu_get_current_aio_context();
|
||||
LuringState *s = aio_get_linux_io_uring(ctx);
|
||||
LuringAIOCB luringcb = {
|
||||
.co = qemu_coroutine_self(),
|
||||
.ret = -EINPROGRESS,
|
||||
|
||||
+17
-12
@@ -16,6 +16,9 @@
|
||||
#include "qemu/coroutine.h"
|
||||
#include "qapi/error.h"
|
||||
|
||||
/* Only used for assertions. */
|
||||
#include "qemu/coroutine_int.h"
|
||||
|
||||
#include <libaio.h>
|
||||
|
||||
/*
|
||||
@@ -56,10 +59,8 @@ struct LinuxAioState {
|
||||
io_context_t ctx;
|
||||
EventNotifier e;
|
||||
|
||||
/* io queue for submit at batch. Protected by AioContext lock. */
|
||||
/* No locking required, only accessed from AioContext home thread */
|
||||
LaioQueue io_q;
|
||||
|
||||
/* I/O completion processing. Only runs in I/O thread. */
|
||||
QEMUBH *completion_bh;
|
||||
int event_idx;
|
||||
int event_max;
|
||||
@@ -102,6 +103,7 @@ static void qemu_laio_process_completion(struct qemu_laiocb *laiocb)
|
||||
* later. Coroutines cannot be entered recursively so avoid doing
|
||||
* that!
|
||||
*/
|
||||
assert(laiocb->co->ctx == laiocb->ctx->aio_context);
|
||||
if (!qemu_coroutine_entered(laiocb->co)) {
|
||||
aio_co_wake(laiocb->co);
|
||||
}
|
||||
@@ -232,13 +234,11 @@ static void qemu_laio_process_completions(LinuxAioState *s)
|
||||
|
||||
static void qemu_laio_process_completions_and_submit(LinuxAioState *s)
|
||||
{
|
||||
aio_context_acquire(s->aio_context);
|
||||
qemu_laio_process_completions(s);
|
||||
|
||||
if (!s->io_q.plugged && !QSIMPLEQ_EMPTY(&s->io_q.pending)) {
|
||||
ioq_submit(s);
|
||||
}
|
||||
aio_context_release(s->aio_context);
|
||||
}
|
||||
|
||||
static void qemu_laio_completion_bh(void *opaque)
|
||||
@@ -354,14 +354,19 @@ static uint64_t laio_max_batch(LinuxAioState *s, uint64_t dev_max_batch)
|
||||
return max_batch;
|
||||
}
|
||||
|
||||
void laio_io_plug(BlockDriverState *bs, LinuxAioState *s)
|
||||
void laio_io_plug(void)
|
||||
{
|
||||
AioContext *ctx = qemu_get_current_aio_context();
|
||||
LinuxAioState *s = aio_get_linux_aio(ctx);
|
||||
|
||||
s->io_q.plugged++;
|
||||
}
|
||||
|
||||
void laio_io_unplug(BlockDriverState *bs, LinuxAioState *s,
|
||||
uint64_t dev_max_batch)
|
||||
void laio_io_unplug(uint64_t dev_max_batch)
|
||||
{
|
||||
AioContext *ctx = qemu_get_current_aio_context();
|
||||
LinuxAioState *s = aio_get_linux_aio(ctx);
|
||||
|
||||
assert(s->io_q.plugged);
|
||||
s->io_q.plugged--;
|
||||
|
||||
@@ -411,15 +416,15 @@ static int laio_do_submit(int fd, struct qemu_laiocb *laiocb, off_t offset,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int coroutine_fn laio_co_submit(BlockDriverState *bs, LinuxAioState *s, int fd,
|
||||
uint64_t offset, QEMUIOVector *qiov, int type,
|
||||
uint64_t dev_max_batch)
|
||||
int coroutine_fn laio_co_submit(int fd, uint64_t offset, QEMUIOVector *qiov,
|
||||
int type, uint64_t dev_max_batch)
|
||||
{
|
||||
int ret;
|
||||
AioContext *ctx = qemu_get_current_aio_context();
|
||||
struct qemu_laiocb laiocb = {
|
||||
.co = qemu_coroutine_self(),
|
||||
.nbytes = qiov->size,
|
||||
.ctx = s,
|
||||
.ctx = aio_get_linux_aio(ctx),
|
||||
.ret = -EINPROGRESS,
|
||||
.is_read = (type == QEMU_AIO_READ),
|
||||
.qiov = qiov,
|
||||
|
||||
+2
-2
@@ -886,9 +886,9 @@ static int coroutine_fn mirror_dirty_init(MirrorBlockJob *s)
|
||||
/* Called when going out of the streaming phase to flush the bulk of the
|
||||
* data to the medium, or just before completing.
|
||||
*/
|
||||
static int mirror_flush(MirrorBlockJob *s)
|
||||
static int coroutine_fn mirror_flush(MirrorBlockJob *s)
|
||||
{
|
||||
int ret = blk_flush(s->target);
|
||||
int ret = blk_co_flush(s->target);
|
||||
if (ret < 0) {
|
||||
if (mirror_error_action(s, false, -ret) == BLOCK_ERROR_ACTION_REPORT) {
|
||||
s->ret = ret;
|
||||
|
||||
@@ -214,15 +214,17 @@ void hmp_commit(Monitor *mon, const QDict *qdict)
|
||||
error_report("Device '%s' not found", device);
|
||||
return;
|
||||
}
|
||||
if (!blk_is_available(blk)) {
|
||||
error_report("Device '%s' has no medium", device);
|
||||
return;
|
||||
}
|
||||
|
||||
bs = bdrv_skip_implicit_filters(blk_bs(blk));
|
||||
aio_context = bdrv_get_aio_context(bs);
|
||||
aio_context_acquire(aio_context);
|
||||
|
||||
if (!blk_is_available(blk)) {
|
||||
error_report("Device '%s' has no medium", device);
|
||||
aio_context_release(aio_context);
|
||||
return;
|
||||
}
|
||||
|
||||
ret = bdrv_commit(bs);
|
||||
|
||||
aio_context_release(aio_context);
|
||||
|
||||
@@ -1221,7 +1221,7 @@ out:
|
||||
}
|
||||
|
||||
/* Checks to see if it's safe to resize bitmaps */
|
||||
int qcow2_truncate_bitmaps_check(BlockDriverState *bs, Error **errp)
|
||||
int coroutine_fn qcow2_truncate_bitmaps_check(BlockDriverState *bs, Error **errp)
|
||||
{
|
||||
BDRVQcow2State *s = bs->opaque;
|
||||
Qcow2BitmapList *bm_list;
|
||||
|
||||
+13
-8
@@ -1126,7 +1126,7 @@ err:
|
||||
* Frees the allocated clusters because the request failed and they won't
|
||||
* actually be linked.
|
||||
*/
|
||||
void qcow2_alloc_cluster_abort(BlockDriverState *bs, QCowL2Meta *m)
|
||||
void coroutine_fn qcow2_alloc_cluster_abort(BlockDriverState *bs, QCowL2Meta *m)
|
||||
{
|
||||
BDRVQcow2State *s = bs->opaque;
|
||||
if (!has_data_file(bs) && !m->keep_old_clusters) {
|
||||
@@ -1156,9 +1156,11 @@ void qcow2_alloc_cluster_abort(BlockDriverState *bs, QCowL2Meta *m)
|
||||
*
|
||||
* Returns 0 on success, -errno on failure.
|
||||
*/
|
||||
static int calculate_l2_meta(BlockDriverState *bs, uint64_t host_cluster_offset,
|
||||
uint64_t guest_offset, unsigned bytes,
|
||||
uint64_t *l2_slice, QCowL2Meta **m, bool keep_old)
|
||||
static int coroutine_fn calculate_l2_meta(BlockDriverState *bs,
|
||||
uint64_t host_cluster_offset,
|
||||
uint64_t guest_offset, unsigned bytes,
|
||||
uint64_t *l2_slice, QCowL2Meta **m,
|
||||
bool keep_old)
|
||||
{
|
||||
BDRVQcow2State *s = bs->opaque;
|
||||
int sc_index, l2_index = offset_to_l2_slice_index(s, guest_offset);
|
||||
@@ -1599,8 +1601,10 @@ out:
|
||||
* function has been waiting for another request and the allocation must be
|
||||
* restarted, but the whole request should not be failed.
|
||||
*/
|
||||
static int do_alloc_cluster_offset(BlockDriverState *bs, uint64_t guest_offset,
|
||||
uint64_t *host_offset, uint64_t *nb_clusters)
|
||||
static int coroutine_fn do_alloc_cluster_offset(BlockDriverState *bs,
|
||||
uint64_t guest_offset,
|
||||
uint64_t *host_offset,
|
||||
uint64_t *nb_clusters)
|
||||
{
|
||||
BDRVQcow2State *s = bs->opaque;
|
||||
|
||||
@@ -2065,8 +2069,9 @@ static int zero_in_l2_slice(BlockDriverState *bs, uint64_t offset,
|
||||
return nb_clusters;
|
||||
}
|
||||
|
||||
static int zero_l2_subclusters(BlockDriverState *bs, uint64_t offset,
|
||||
unsigned nb_subclusters)
|
||||
static int coroutine_fn
|
||||
zero_l2_subclusters(BlockDriverState *bs, uint64_t offset,
|
||||
unsigned nb_subclusters)
|
||||
{
|
||||
BDRVQcow2State *s = bs->opaque;
|
||||
uint64_t *l2_slice;
|
||||
|
||||
@@ -1030,8 +1030,8 @@ int64_t qcow2_alloc_clusters(BlockDriverState *bs, uint64_t size)
|
||||
return offset;
|
||||
}
|
||||
|
||||
int64_t qcow2_alloc_clusters_at(BlockDriverState *bs, uint64_t offset,
|
||||
int64_t nb_clusters)
|
||||
int64_t coroutine_fn qcow2_alloc_clusters_at(BlockDriverState *bs, uint64_t offset,
|
||||
int64_t nb_clusters)
|
||||
{
|
||||
BDRVQcow2State *s = bs->opaque;
|
||||
uint64_t cluster_index, refcount;
|
||||
@@ -1069,7 +1069,7 @@ int64_t qcow2_alloc_clusters_at(BlockDriverState *bs, uint64_t offset,
|
||||
|
||||
/* only used to allocate compressed sectors. We try to allocate
|
||||
contiguous sectors. size must be <= cluster_size */
|
||||
int64_t qcow2_alloc_bytes(BlockDriverState *bs, int size)
|
||||
int64_t coroutine_fn qcow2_alloc_bytes(BlockDriverState *bs, int size)
|
||||
{
|
||||
BDRVQcow2State *s = bs->opaque;
|
||||
int64_t offset;
|
||||
@@ -3685,7 +3685,7 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int64_t qcow2_get_last_cluster(BlockDriverState *bs, int64_t size)
|
||||
int64_t coroutine_fn qcow2_get_last_cluster(BlockDriverState *bs, int64_t size)
|
||||
{
|
||||
BDRVQcow2State *s = bs->opaque;
|
||||
int64_t i;
|
||||
|
||||
+13
-12
@@ -77,10 +77,11 @@ void qcow2_free_snapshots(BlockDriverState *bs)
|
||||
* qcow2_check_refcounts() does not do anything with snapshots'
|
||||
* extra data.)
|
||||
*/
|
||||
static int qcow2_do_read_snapshots(BlockDriverState *bs, bool repair,
|
||||
int *nb_clusters_reduced,
|
||||
int *extra_data_dropped,
|
||||
Error **errp)
|
||||
static coroutine_fn GRAPH_RDLOCK
|
||||
int qcow2_do_read_snapshots(BlockDriverState *bs, bool repair,
|
||||
int *nb_clusters_reduced,
|
||||
int *extra_data_dropped,
|
||||
Error **errp)
|
||||
{
|
||||
BDRVQcow2State *s = bs->opaque;
|
||||
QCowSnapshotHeader h;
|
||||
@@ -108,7 +109,7 @@ static int qcow2_do_read_snapshots(BlockDriverState *bs, bool repair,
|
||||
|
||||
/* Read statically sized part of the snapshot header */
|
||||
offset = ROUND_UP(offset, 8);
|
||||
ret = bdrv_pread(bs->file, offset, sizeof(h), &h, 0);
|
||||
ret = bdrv_co_pread(bs->file, offset, sizeof(h), &h, 0);
|
||||
if (ret < 0) {
|
||||
error_setg_errno(errp, -ret, "Failed to read snapshot table");
|
||||
goto fail;
|
||||
@@ -146,8 +147,8 @@ static int qcow2_do_read_snapshots(BlockDriverState *bs, bool repair,
|
||||
}
|
||||
|
||||
/* Read known extra data */
|
||||
ret = bdrv_pread(bs->file, offset,
|
||||
MIN(sizeof(extra), sn->extra_data_size), &extra, 0);
|
||||
ret = bdrv_co_pread(bs->file, offset,
|
||||
MIN(sizeof(extra), sn->extra_data_size), &extra, 0);
|
||||
if (ret < 0) {
|
||||
error_setg_errno(errp, -ret, "Failed to read snapshot table");
|
||||
goto fail;
|
||||
@@ -184,8 +185,8 @@ static int qcow2_do_read_snapshots(BlockDriverState *bs, bool repair,
|
||||
/* Store unknown extra data */
|
||||
unknown_extra_data_size = sn->extra_data_size - sizeof(extra);
|
||||
sn->unknown_extra_data = g_malloc(unknown_extra_data_size);
|
||||
ret = bdrv_pread(bs->file, offset, unknown_extra_data_size,
|
||||
sn->unknown_extra_data, 0);
|
||||
ret = bdrv_co_pread(bs->file, offset, unknown_extra_data_size,
|
||||
sn->unknown_extra_data, 0);
|
||||
if (ret < 0) {
|
||||
error_setg_errno(errp, -ret,
|
||||
"Failed to read snapshot table");
|
||||
@@ -196,7 +197,7 @@ static int qcow2_do_read_snapshots(BlockDriverState *bs, bool repair,
|
||||
|
||||
/* Read snapshot ID */
|
||||
sn->id_str = g_malloc(id_str_size + 1);
|
||||
ret = bdrv_pread(bs->file, offset, id_str_size, sn->id_str, 0);
|
||||
ret = bdrv_co_pread(bs->file, offset, id_str_size, sn->id_str, 0);
|
||||
if (ret < 0) {
|
||||
error_setg_errno(errp, -ret, "Failed to read snapshot table");
|
||||
goto fail;
|
||||
@@ -206,7 +207,7 @@ static int qcow2_do_read_snapshots(BlockDriverState *bs, bool repair,
|
||||
|
||||
/* Read snapshot name */
|
||||
sn->name = g_malloc(name_size + 1);
|
||||
ret = bdrv_pread(bs->file, offset, name_size, sn->name, 0);
|
||||
ret = bdrv_co_pread(bs->file, offset, name_size, sn->name, 0);
|
||||
if (ret < 0) {
|
||||
error_setg_errno(errp, -ret, "Failed to read snapshot table");
|
||||
goto fail;
|
||||
@@ -261,7 +262,7 @@ fail:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int qcow2_read_snapshots(BlockDriverState *bs, Error **errp)
|
||||
int coroutine_fn qcow2_read_snapshots(BlockDriverState *bs, Error **errp)
|
||||
{
|
||||
return qcow2_do_read_snapshots(bs, false, NULL, NULL, errp);
|
||||
}
|
||||
|
||||
@@ -43,7 +43,6 @@ qcow2_co_process(BlockDriverState *bs, ThreadPoolFunc *func, void *arg)
|
||||
{
|
||||
int ret;
|
||||
BDRVQcow2State *s = bs->opaque;
|
||||
ThreadPool *pool = aio_get_thread_pool(bdrv_get_aio_context(bs));
|
||||
|
||||
qemu_co_mutex_lock(&s->lock);
|
||||
while (s->nb_threads >= QCOW2_MAX_THREADS) {
|
||||
@@ -52,7 +51,7 @@ qcow2_co_process(BlockDriverState *bs, ThreadPoolFunc *func, void *arg)
|
||||
s->nb_threads++;
|
||||
qemu_co_mutex_unlock(&s->lock);
|
||||
|
||||
ret = thread_pool_submit_co(pool, func, arg);
|
||||
ret = thread_pool_submit_co(func, arg);
|
||||
|
||||
qemu_co_mutex_lock(&s->lock);
|
||||
s->nb_threads--;
|
||||
|
||||
+14
-13
@@ -199,10 +199,10 @@ qcow2_extract_crypto_opts(QemuOpts *opts, const char *fmt, Error **errp)
|
||||
* unknown magic is skipped (future extension this version knows nothing about)
|
||||
* return 0 upon success, non-0 otherwise
|
||||
*/
|
||||
static int qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset,
|
||||
uint64_t end_offset, void **p_feature_table,
|
||||
int flags, bool *need_update_header,
|
||||
Error **errp)
|
||||
static int coroutine_fn GRAPH_RDLOCK
|
||||
qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset,
|
||||
uint64_t end_offset, void **p_feature_table,
|
||||
int flags, bool *need_update_header, Error **errp)
|
||||
{
|
||||
BDRVQcow2State *s = bs->opaque;
|
||||
QCowExtension ext;
|
||||
@@ -228,7 +228,7 @@ static int qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset,
|
||||
printf("attempting to read extended header in offset %lu\n", offset);
|
||||
#endif
|
||||
|
||||
ret = bdrv_pread(bs->file, offset, sizeof(ext), &ext, 0);
|
||||
ret = bdrv_co_pread(bs->file, offset, sizeof(ext), &ext, 0);
|
||||
if (ret < 0) {
|
||||
error_setg_errno(errp, -ret, "qcow2_read_extension: ERROR: "
|
||||
"pread fail from offset %" PRIu64, offset);
|
||||
@@ -256,7 +256,7 @@ static int qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset,
|
||||
sizeof(bs->backing_format));
|
||||
return 2;
|
||||
}
|
||||
ret = bdrv_pread(bs->file, offset, ext.len, bs->backing_format, 0);
|
||||
ret = bdrv_co_pread(bs->file, offset, ext.len, bs->backing_format, 0);
|
||||
if (ret < 0) {
|
||||
error_setg_errno(errp, -ret, "ERROR: ext_backing_format: "
|
||||
"Could not read format name");
|
||||
@@ -272,7 +272,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));
|
||||
ret = bdrv_pread(bs->file, offset, ext.len, feature_table, 0);
|
||||
ret = bdrv_co_pread(bs->file, offset, ext.len, feature_table, 0);
|
||||
if (ret < 0) {
|
||||
error_setg_errno(errp, -ret, "ERROR: ext_feature_table: "
|
||||
"Could not read table");
|
||||
@@ -298,7 +298,7 @@ static int qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = bdrv_pread(bs->file, offset, ext.len, &s->crypto_header, 0);
|
||||
ret = bdrv_co_pread(bs->file, offset, ext.len, &s->crypto_header, 0);
|
||||
if (ret < 0) {
|
||||
error_setg_errno(errp, -ret,
|
||||
"Unable to read CRYPTO header extension");
|
||||
@@ -354,7 +354,7 @@ static int qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset,
|
||||
break;
|
||||
}
|
||||
|
||||
ret = bdrv_pread(bs->file, offset, ext.len, &bitmaps_ext, 0);
|
||||
ret = bdrv_co_pread(bs->file, offset, ext.len, &bitmaps_ext, 0);
|
||||
if (ret < 0) {
|
||||
error_setg_errno(errp, -ret, "bitmaps_ext: "
|
||||
"Could not read ext header");
|
||||
@@ -418,7 +418,7 @@ static int qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset,
|
||||
case QCOW2_EXT_MAGIC_DATA_FILE:
|
||||
{
|
||||
s->image_data_file = g_malloc0(ext.len + 1);
|
||||
ret = bdrv_pread(bs->file, offset, ext.len, s->image_data_file, 0);
|
||||
ret = bdrv_co_pread(bs->file, offset, ext.len, s->image_data_file, 0);
|
||||
if (ret < 0) {
|
||||
error_setg_errno(errp, -ret,
|
||||
"ERROR: Could not read data file name");
|
||||
@@ -442,7 +442,7 @@ static int qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset,
|
||||
uext->len = ext.len;
|
||||
QLIST_INSERT_HEAD(&s->unknown_header_ext, uext, next);
|
||||
|
||||
ret = bdrv_pread(bs->file, offset, uext->len, uext->data, 0);
|
||||
ret = bdrv_co_pread(bs->file, offset, uext->len, uext->data, 0);
|
||||
if (ret < 0) {
|
||||
error_setg_errno(errp, -ret, "ERROR: unknown extension: "
|
||||
"Could not read data");
|
||||
@@ -1241,8 +1241,9 @@ static void qcow2_update_options_abort(BlockDriverState *bs,
|
||||
qapi_free_QCryptoBlockOpenOptions(r->crypto_opts);
|
||||
}
|
||||
|
||||
static int qcow2_update_options(BlockDriverState *bs, QDict *options,
|
||||
int flags, Error **errp)
|
||||
static int coroutine_fn
|
||||
qcow2_update_options(BlockDriverState *bs, QDict *options, int flags,
|
||||
Error **errp)
|
||||
{
|
||||
Qcow2ReopenState r = {};
|
||||
int ret;
|
||||
|
||||
+8
-7
@@ -862,9 +862,9 @@ int64_t qcow2_refcount_area(BlockDriverState *bs, uint64_t offset,
|
||||
uint64_t new_refblock_offset);
|
||||
|
||||
int64_t qcow2_alloc_clusters(BlockDriverState *bs, uint64_t size);
|
||||
int64_t qcow2_alloc_clusters_at(BlockDriverState *bs, uint64_t offset,
|
||||
int64_t nb_clusters);
|
||||
int64_t qcow2_alloc_bytes(BlockDriverState *bs, int size);
|
||||
int64_t coroutine_fn qcow2_alloc_clusters_at(BlockDriverState *bs, uint64_t offset,
|
||||
int64_t nb_clusters);
|
||||
int64_t coroutine_fn qcow2_alloc_bytes(BlockDriverState *bs, int size);
|
||||
void qcow2_free_clusters(BlockDriverState *bs,
|
||||
int64_t offset, int64_t size,
|
||||
enum qcow2_discard_type type);
|
||||
@@ -894,7 +894,7 @@ int qcow2_change_refcount_order(BlockDriverState *bs, int refcount_order,
|
||||
BlockDriverAmendStatusCB *status_cb,
|
||||
void *cb_opaque, Error **errp);
|
||||
int coroutine_fn GRAPH_RDLOCK qcow2_shrink_reftable(BlockDriverState *bs);
|
||||
int64_t qcow2_get_last_cluster(BlockDriverState *bs, int64_t size);
|
||||
int64_t coroutine_fn qcow2_get_last_cluster(BlockDriverState *bs, int64_t size);
|
||||
int coroutine_fn qcow2_detect_metadata_preallocation(BlockDriverState *bs);
|
||||
|
||||
/* qcow2-cluster.c functions */
|
||||
@@ -924,7 +924,7 @@ void qcow2_parse_compressed_l2_entry(BlockDriverState *bs, uint64_t l2_entry,
|
||||
int coroutine_fn GRAPH_RDLOCK
|
||||
qcow2_alloc_cluster_link_l2(BlockDriverState *bs, QCowL2Meta *m);
|
||||
|
||||
void qcow2_alloc_cluster_abort(BlockDriverState *bs, QCowL2Meta *m);
|
||||
void coroutine_fn qcow2_alloc_cluster_abort(BlockDriverState *bs, QCowL2Meta *m);
|
||||
int qcow2_cluster_discard(BlockDriverState *bs, uint64_t offset,
|
||||
uint64_t bytes, enum qcow2_discard_type type,
|
||||
bool full_discard);
|
||||
@@ -951,7 +951,8 @@ int qcow2_snapshot_load_tmp(BlockDriverState *bs,
|
||||
Error **errp);
|
||||
|
||||
void qcow2_free_snapshots(BlockDriverState *bs);
|
||||
int qcow2_read_snapshots(BlockDriverState *bs, Error **errp);
|
||||
int coroutine_fn GRAPH_RDLOCK
|
||||
qcow2_read_snapshots(BlockDriverState *bs, Error **errp);
|
||||
int qcow2_write_snapshots(BlockDriverState *bs);
|
||||
|
||||
int coroutine_fn GRAPH_RDLOCK
|
||||
@@ -994,7 +995,7 @@ bool coroutine_fn qcow2_load_dirty_bitmaps(BlockDriverState *bs,
|
||||
bool qcow2_get_bitmap_info_list(BlockDriverState *bs,
|
||||
Qcow2BitmapInfoList **info_list, Error **errp);
|
||||
int qcow2_reopen_bitmaps_rw(BlockDriverState *bs, Error **errp);
|
||||
int qcow2_truncate_bitmaps_check(BlockDriverState *bs, Error **errp);
|
||||
int coroutine_fn qcow2_truncate_bitmaps_check(BlockDriverState *bs, Error **errp);
|
||||
bool qcow2_store_persistent_dirty_bitmaps(BlockDriverState *bs,
|
||||
bool release_stored, Error **errp);
|
||||
int qcow2_reopen_bitmaps_ro(BlockDriverState *bs, Error **errp);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user