qemu-kvm/kvm-qemu-io-Add-aio_discard-command.patch
Miroslav Rezanina 6c478a495d * Tue Jun 23 2026 Miroslav Rezanina <mrezanin@redhat.com> - 10.1.0-22
- kvm-blkdebug-Add-delay-ns-option.patch [RHEL-121686]
- kvm-block-Add-blk_co_start-end_request-and-BDRV_REQ_NO_Q.patch [RHEL-121686]
- kvm-block-Add-flags-parameter-to-blk_-_pdiscard.patch [RHEL-121686]
- kvm-ide-Minimal-fix-for-deadlock-between-TRIM-and-drain.patch [RHEL-121686]
- kvm-ide-Clean-up-ide_trim_co_entry-to-be-idiomatic-corou.patch [RHEL-121686]
- kvm-ide-test-Factor-out-wait_dma_completion.patch [RHEL-121686]
- kvm-ide-test-Test-reset-during-TRIM.patch [RHEL-121686]
- kvm-block-graph-lock-fix-missed-wakeup-in-bdrv_graph_co_.patch [RHEL-186384]
- kvm-block-curl-fix-curl-internal-handles-handling.patch [RHEL-186384]
- kvm-block-curl.c-Use-explicit-long-constants-in-curl_eas.patch [RHEL-186384]
- kvm-block-curl.c-Fix-CURLOPT_VERBOSE-parameter-type.patch [RHEL-186384]
- kvm-block-curl-fix-concurrent-completion-handling.patch [RHEL-186384]
- kvm-block-curl-free-s-password-in-cleanup-paths.patch [RHEL-186384]
- kvm-nvme-Kick-and-check-completions-in-BDS-context.patch [RHEL-186384]
- kvm-nvme-Note-in-which-AioContext-some-functions-run.patch [RHEL-186384]
- kvm-block-remove-detached-header-option-from-opts-after-.patch [RHEL-186384]
- kvm-block-fix-luks-amend-when-run-in-coroutine.patch [RHEL-186384]
- kvm-qed-Don-t-try-to-flush-during-incoming-migration.patch [RHEL-186384]
- kvm-block-vmdk-fix-OOB-read-in-vmdk_read_extent.patch [RHEL-186384]
- kvm-block-throttle-groups-fix-deadlock-with-iolimits-and.patch [RHEL-186384]
- kvm-throttle-group-Fix-race-condition-in-throttle_group_.patch [RHEL-186384]
- kvm-qemu-img-Fix-amend-option-parse-error-handling.patch [RHEL-186384]
- kvm-qemu-img-rebase-don-t-exceed-IO_BUF_SIZE-in-one-oper.patch [RHEL-186384]
- kvm-python-backport-drop-Python3.6-workarounds.patch [RHEL-186384]
- kvm-python-backport-Remove-deprecated-get_event_loop-cal.patch [RHEL-186384]
- kvm-python-backport-avoid-creating-additional-event-loop.patch [RHEL-186384]
- kvm-iotests-147-ensure-temporary-sockets-are-closed-befo.patch [RHEL-186384]
- kvm-iotests-151-ensure-subprocesses-are-cleaned-up.patch [RHEL-186384]
- kvm-tests-qemu-iotest-fix-iotest-024-with-qed-images.patch [RHEL-186384]
- kvm-tests-qemu-iotests-Fix-check-for-existing-file-in-_r.patch [RHEL-186384]
- kvm-async-access-bottom-half-flags-with-qatomic_read.patch [RHEL-186384]
- kvm-block-linux-aio-bound-ioq_submit-recursion-depth.patch [RHEL-186384]
- kvm-block-io-fallback-to-bounce-buffer-if-BLKZEROOUT-is-.patch [RHEL-186384]
- kvm-file-posix-populate-pwrite_zeroes_alignment.patch [RHEL-186384]
- kvm-block-use-pwrite_zeroes_alignment-when-writing-first.patch [RHEL-186384]
- kvm-iotests-add-Linux-loop-device-image-creation-test.patch [RHEL-186384]
- kvm-virtio-Fix-crash-when-sriov-pf-is-set-for-non-PCI-Ex.patch [RHEL-186384]
- kvm-virtio-scsi-pass-the-same-cdb_size-to-virtio_scsi_po.patch [RHEL-186384]
- kvm-hw-scsi-avoid-deadlock-upon-TMF-request-cancelling-w.patch [RHEL-186384]
- kvm-virtio-blk-fix-zone-report-buffer-out-of-memory-CVE-.patch [RHEL-186384]
- kvm-ide-Fix-potential-assertion-failure-on-VM-stop-for-P.patch [RHEL-186384]
- kvm-block-Create-DEFAULT_BLOCK_CONF-macro.patch [RHEL-186384]
- kvm-block-Add-more-defaults-to-DEFAULT_BLOCK_CONF.patch [RHEL-186384]
- kvm-block-mirror-check-range-when-setting-zero-bitmap-fo.patch [RHEL-186384]
- kvm-iotests-test-active-mirror-with-unaligned-small-writ.patch [RHEL-186384]
- kvm-block-mirror-fix-assertion-failure-upon-duplicate-co.patch [RHEL-186384]
- kvm-commit-Drain-nodes-across-all-of-bdrv_commit.patch [RHEL-186384]
- kvm-qemu-io-Add-aio_discard-command.patch [RHEL-186384]
- kvm-qcow2-Fix-corruption-on-discard-during-write-with-CO.patch [RHEL-186384]
- kvm-iotests-046-Test-that-discard-write_zeroes-wait-for-.patch [RHEL-186384]
- kvm-qcow2-Fix-data-loss-on-zero-write-with-detect-zeroes.patch [RHEL-186384]
- kvm-block-Fix-crash-after-setting-latency-historygram-wi.patch [RHEL-186384]
- Resolves: RHEL-121686
  (qemu-kvm hung during drain after double pause)
- Resolves: RHEL-186384
  (virt-storage: Backport stable branch fixes)
2026-06-23 09:22:28 +02:00

168 lines
5.0 KiB
Diff

From f598b8e008e2b9179acaa138d75bac390a204508 Mon Sep 17 00:00:00 2001
From: Kevin Wolf <kwolf@redhat.com>
Date: Sat, 13 Jun 2026 23:03:36 +0300
Subject: [PATCH 48/52] qemu-io: Add 'aio_discard' command
RH-Author: Kevin Wolf <kwolf@redhat.com>
RH-MergeRequest: 504: virt-storage: Backport stable branch fixes
RH-Jira: RHEL-186384
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [41/45] f10ea407dd2cb93550396230790802dc8a728774 (kmwolf/centos-qemu-kvm)
Testing interactions between multiple requests that include discard
requests require that qemu-io can do the discard asynchronously, like it
already does for reads and writes. To this effect, add an 'aio_discard'
command.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Message-ID: <20260427170520.101242-3-kwolf@redhat.com>
Reviewed-by: Denis V. Lunev <den@openvz.org>
Tested-by: Denis V. Lunev <den@openvz.org>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 7f8466e2ce620e3c6a6e2f32d616367174d4dbe9)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
Message-ID: <20260613200411.1808021-53-mjt@tls.msk.ru>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
qemu-io-cmds.c | 115 +++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 115 insertions(+)
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
index f6d077908f..de4c1966fe 100644
--- a/qemu-io-cmds.c
+++ b/qemu-io-cmds.c
@@ -2218,6 +2218,120 @@ static int discard_f(BlockBackend *blk, int argc, char **argv)
return 0;
}
+static void aio_discard_help(void)
+{
+ printf(
+"\n"
+" asynchronously discards a range of bytes from the given offset\n"
+"\n"
+" Example:\n"
+" 'aio_discard 512 1k' - discards 1 kilobyte from 512 bytes into the file\n"
+"\n"
+" Discards a segment of the currently open file.\n"
+" -C, -- report statistics in a machine parsable format\n"
+" -q, -- quiet mode, do not show I/O statistics\n"
+" The discard is performed asynchronously and the aio_flush command must be\n"
+" used to ensure all outstanding aio requests have been completed.\n"
+" Note that due to its asynchronous nature, this command will be\n"
+" considered successful once the request is submitted, independently\n"
+" of potential I/O errors.\n"
+"\n");
+}
+
+static int aio_discard_f(BlockBackend *blk, int argc, char **argv);
+
+static const cmdinfo_t aio_discard_cmd = {
+ .name = "aio_discard",
+ .cfunc = aio_discard_f,
+ .perm = BLK_PERM_WRITE,
+ .argmin = 2,
+ .argmax = -1,
+ .args = "[-Cq] off len",
+ .oneline = "asynchronously discards a number of bytes",
+ .help = aio_discard_help,
+};
+
+static void aio_discard_done(void *opaque, int ret)
+{
+ struct aio_ctx *ctx = opaque;
+ struct timespec t2;
+
+ clock_gettime(CLOCK_MONOTONIC, &t2);
+
+ if (ret < 0) {
+ printf("aio_discard failed: %s\n", strerror(-ret));
+ block_acct_failed(blk_get_stats(ctx->blk), &ctx->acct);
+ goto out;
+ }
+
+ block_acct_done(blk_get_stats(ctx->blk), &ctx->acct);
+
+ if (ctx->qflag) {
+ goto out;
+ }
+
+ /* Finally, report back -- -C gives a parsable format */
+ t2 = tsub(t2, ctx->t1);
+ print_report("discarded ", &t2, ctx->offset, ctx->qiov.size,
+ ctx->qiov.size, 1, ctx->Cflag);
+out:
+ g_free(ctx);
+}
+
+static int aio_discard_f(BlockBackend *blk, int argc, char **argv)
+{
+ int c, ret;
+ int64_t count;
+ struct aio_ctx *ctx = g_new0(struct aio_ctx, 1);
+
+ ctx->blk = blk;
+
+ while ((c = getopt(argc, argv, "Cq")) != -1) {
+ switch (c) {
+ case 'C':
+ ctx->Cflag = true;
+ break;
+ case 'q':
+ ctx->qflag = true;
+ break;
+ default:
+ g_free(ctx);
+ qemuio_command_usage(&aio_discard_cmd);
+ return -EINVAL;
+ }
+ }
+
+ if (optind != argc - 2) {
+ g_free(ctx);
+ qemuio_command_usage(&aio_discard_cmd);
+ return -EINVAL;
+ }
+
+ ctx->offset = cvtnum(argv[optind]);
+ if (ctx->offset < 0) {
+ ret = ctx->offset;
+ print_cvtnum_err(ret, argv[optind]);
+ g_free(ctx);
+ return ret;
+ }
+ optind++;
+
+ count = cvtnum(argv[optind]);
+ if (count < 0) {
+ print_cvtnum_err(count, argv[optind]);
+ g_free(ctx);
+ return count;
+ }
+
+ clock_gettime(CLOCK_MONOTONIC, &ctx->t1);
+ ctx->qiov.size = count;
+ block_acct_start(blk_get_stats(blk), &ctx->acct, ctx->qiov.size,
+ BLOCK_ACCT_UNMAP);
+ blk_aio_pdiscard(blk, ctx->offset, count, aio_discard_done, ctx);
+
+ return 0;
+}
+
static int alloc_f(BlockBackend *blk, int argc, char **argv)
{
BlockDriverState *bs = blk_bs(blk);
@@ -2800,6 +2914,7 @@ static void __attribute((constructor)) init_qemuio_commands(void)
qemuio_add_command(&length_cmd);
qemuio_add_command(&info_cmd);
qemuio_add_command(&discard_cmd);
+ qemuio_add_command(&aio_discard_cmd);
qemuio_add_command(&alloc_cmd);
qemuio_add_command(&map_cmd);
qemuio_add_command(&reopen_cmd);
--
2.52.0