From 872e82621b1341e8b96bda47f7f43dfffd356249 Mon Sep 17 00:00:00 2001 From: Kevin Wolf Date: Tue, 27 Jul 2021 17:49:23 +0200 Subject: [PATCH 04/13] block: Fix in_flight leak in request padding error path RH-Author: Kevin Wolf RH-MergeRequest: 31: block: Fix in_flight leak in request padding error path RH-Commit: [1/1] a0d1bf38d9a69818cd6cefc3779f2988b484605a (kmwolf/centos-qemu-kvm) RH-Bugzilla: 1972079 RH-Acked-by: Miroslav Rezanina RH-Acked-by: Eric Blake RH-Acked-by: Max Reitz When bdrv_pad_request() fails in bdrv_co_preadv_part(), bs->in_flight has been increased, but is never decreased again. This leads to a hang when trying to drain the block node. This bug was observed with Windows guests which issue a request that fully uses IOV_MAX during installation, so that when padding is necessary (O_DIRECT with a 4k sector size block device on the host), adding another entry causes failure. Call bdrv_dec_in_flight() to fix this. There is a larger problem to solve here because this request shouldn't even fail, but Windows doesn't seem to care and with this minimal fix the installation succeeds. So given that we're already in freeze, let's take this minimal fix for 6.1. Fixes: 98ca45494fcd6bf0336ecd559e440b6de6ea4cd3 Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1972079 Reported-by: Qing Wang Signed-off-by: Kevin Wolf Message-Id: <20210727154923.91067-1-kwolf@redhat.com> Reviewed-by: Max Reitz Signed-off-by: Kevin Wolf (cherry picked from commit 87ab88025247b893aad5071fd38301b67be76d1a) Signed-off-by: Kevin Wolf Signed-off-by: Miroslav Rezanina --- block/io.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/block/io.c b/block/io.c index a4b2e3adf1..5033d51334 100644 --- a/block/io.c +++ b/block/io.c @@ -1811,7 +1811,7 @@ int coroutine_fn bdrv_co_preadv_part(BdrvChild *child, ret = bdrv_pad_request(bs, &qiov, &qiov_offset, &offset, &bytes, &pad, NULL); if (ret < 0) { - return ret; + goto fail; } tracked_request_begin(&req, bs, offset, bytes, BDRV_TRACKED_READ); @@ -1819,10 +1819,11 @@ int coroutine_fn bdrv_co_preadv_part(BdrvChild *child, bs->bl.request_alignment, qiov, qiov_offset, flags); tracked_request_end(&req); - bdrv_dec_in_flight(bs); - bdrv_padding_destroy(&pad); +fail: + bdrv_dec_in_flight(bs); + return ret; } -- 2.27.0