*/
#include "qemu/osdep.h"
+#include "block/block-io.h"
+#include "block/block_int.h"
#include "block/throttle-groups.h"
#include "qemu/module.h"
#include "qemu/option.h"
{
int ret;
const char *group_name;
- Error *local_err = NULL;
QemuOpts *opts = qemu_opts_create(&throttle_opts, NULL, 0, &error_abort);
- qemu_opts_absorb_qdict(opts, options, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
+ if (!qemu_opts_absorb_qdict(opts, options, errp)) {
ret = -EINVAL;
goto fin;
}
char *group;
int ret;
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
- BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY,
- false, errp);
- if (!bs->file) {
- return -EINVAL;
+ ret = bdrv_open_file_child(NULL, options, "file", bs, errp);
+ if (ret < 0) {
+ return ret;
}
+
+ GRAPH_RDLOCK_GUARD_MAINLOOP();
+
bs->supported_write_flags = bs->file->bs->supported_write_flags |
BDRV_REQ_WRITE_UNCHANGED;
bs->supported_zero_flags = bs->file->bs->supported_zero_flags |
}
-static int64_t throttle_getlength(BlockDriverState *bs)
+static int64_t coroutine_fn GRAPH_RDLOCK
+throttle_co_getlength(BlockDriverState *bs)
{
- return bdrv_getlength(bs->file->bs);
+ return bdrv_co_getlength(bs->file->bs);
}
-static int coroutine_fn throttle_co_preadv(BlockDriverState *bs,
- uint64_t offset, uint64_t bytes,
- QEMUIOVector *qiov, int flags)
+static int coroutine_fn GRAPH_RDLOCK
+throttle_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
+ QEMUIOVector *qiov, BdrvRequestFlags flags)
{
ThrottleGroupMember *tgm = bs->opaque;
- throttle_group_co_io_limits_intercept(tgm, bytes, false);
+ throttle_group_co_io_limits_intercept(tgm, bytes, THROTTLE_READ);
return bdrv_co_preadv(bs->file, offset, bytes, qiov, flags);
}
-static int coroutine_fn throttle_co_pwritev(BlockDriverState *bs,
- uint64_t offset, uint64_t bytes,
- QEMUIOVector *qiov, int flags)
+static int coroutine_fn GRAPH_RDLOCK
+throttle_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
+ QEMUIOVector *qiov, BdrvRequestFlags flags)
{
ThrottleGroupMember *tgm = bs->opaque;
- throttle_group_co_io_limits_intercept(tgm, bytes, true);
+ throttle_group_co_io_limits_intercept(tgm, bytes, THROTTLE_WRITE);
return bdrv_co_pwritev(bs->file, offset, bytes, qiov, flags);
}
-static int coroutine_fn throttle_co_pwrite_zeroes(BlockDriverState *bs,
- int64_t offset, int bytes,
- BdrvRequestFlags flags)
+static int coroutine_fn GRAPH_RDLOCK
+throttle_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes,
+ BdrvRequestFlags flags)
{
ThrottleGroupMember *tgm = bs->opaque;
- throttle_group_co_io_limits_intercept(tgm, bytes, true);
+ throttle_group_co_io_limits_intercept(tgm, bytes, THROTTLE_WRITE);
return bdrv_co_pwrite_zeroes(bs->file, offset, bytes, flags);
}
-static int coroutine_fn throttle_co_pdiscard(BlockDriverState *bs,
- int64_t offset, int bytes)
+static int coroutine_fn GRAPH_RDLOCK
+throttle_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes)
{
ThrottleGroupMember *tgm = bs->opaque;
- throttle_group_co_io_limits_intercept(tgm, bytes, true);
+ throttle_group_co_io_limits_intercept(tgm, bytes, THROTTLE_WRITE);
return bdrv_co_pdiscard(bs->file, offset, bytes);
}
-static int throttle_co_flush(BlockDriverState *bs)
+static int coroutine_fn GRAPH_RDLOCK
+throttle_co_pwritev_compressed(BlockDriverState *bs, int64_t offset,
+ int64_t bytes, QEMUIOVector *qiov)
+{
+ return throttle_co_pwritev(bs, offset, bytes, qiov,
+ BDRV_REQ_WRITE_COMPRESSED);
+}
+
+static int coroutine_fn GRAPH_RDLOCK throttle_co_flush(BlockDriverState *bs)
{
return bdrv_co_flush(bs->file->bs);
}
reopen_state->opaque = NULL;
}
-static void coroutine_fn throttle_co_drain_begin(BlockDriverState *bs)
+static void throttle_drain_begin(BlockDriverState *bs)
{
ThrottleGroupMember *tgm = bs->opaque;
- if (atomic_fetch_inc(&tgm->io_limits_disabled) == 0) {
+ if (qatomic_fetch_inc(&tgm->io_limits_disabled) == 0) {
throttle_group_restart_tgm(tgm);
}
}
-static void coroutine_fn throttle_co_drain_end(BlockDriverState *bs)
+static void throttle_drain_end(BlockDriverState *bs)
{
ThrottleGroupMember *tgm = bs->opaque;
assert(tgm->io_limits_disabled);
- atomic_dec(&tgm->io_limits_disabled);
+ qatomic_dec(&tgm->io_limits_disabled);
}
static const char *const throttle_strong_runtime_opts[] = {
.bdrv_child_perm = bdrv_default_perms,
- .bdrv_getlength = throttle_getlength,
+ .bdrv_co_getlength = throttle_co_getlength,
.bdrv_co_preadv = throttle_co_preadv,
.bdrv_co_pwritev = throttle_co_pwritev,
.bdrv_co_pwrite_zeroes = throttle_co_pwrite_zeroes,
.bdrv_co_pdiscard = throttle_co_pdiscard,
+ .bdrv_co_pwritev_compressed = throttle_co_pwritev_compressed,
.bdrv_attach_aio_context = throttle_attach_aio_context,
.bdrv_detach_aio_context = throttle_detach_aio_context,
.bdrv_reopen_prepare = throttle_reopen_prepare,
.bdrv_reopen_commit = throttle_reopen_commit,
.bdrv_reopen_abort = throttle_reopen_abort,
- .bdrv_co_block_status = bdrv_co_block_status_from_file,
- .bdrv_co_drain_begin = throttle_co_drain_begin,
- .bdrv_co_drain_end = throttle_co_drain_end,
+ .bdrv_drain_begin = throttle_drain_begin,
+ .bdrv_drain_end = throttle_drain_end,
.is_filter = true,
.strong_runtime_opts = throttle_strong_runtime_opts,