75 lines
3.0 KiB
Diff
75 lines
3.0 KiB
Diff
From ecdc254dbaa7995a94f67e7dfafb17137d15759e Mon Sep 17 00:00:00 2001
|
|
From: Stefan Hajnoczi <stefanha@redhat.com>
|
|
Date: Thu, 17 Apr 2025 11:05:28 -0400
|
|
Subject: [PATCH 2/3] block/io: skip head/tail requests on EINVAL
|
|
|
|
RH-Author: Stefan Hajnoczi <stefanha@redhat.com>
|
|
RH-MergeRequest: 450: file-posix: probe discard alignment on Linux block devices
|
|
RH-Jira: RHEL-87734
|
|
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
|
|
RH-Acked-by: Eric Blake <eblake@redhat.com>
|
|
RH-Commit: [2/3] 30b17fc1828c45cf958b8254999ce1ef1f100868
|
|
|
|
When guests send misaligned discard requests, the block layer breaks
|
|
them up into a misaligned head, an aligned main body, and a misaligned
|
|
tail.
|
|
|
|
The file-posix block driver on Linux returns -EINVAL on misaligned
|
|
discard requests. This causes bdrv_co_pdiscard() to fail and guests
|
|
configured with werror=stop will pause.
|
|
|
|
Add a special case for misaligned head/tail requests. Simply continue
|
|
when EINVAL is encountered so that the aligned main body of the request
|
|
can be completed and the guest is not paused. This is the best we can do
|
|
when guest discard limits do not match the host discard limits.
|
|
|
|
Fixes: https://issues.redhat.com/browse/RHEL-86032
|
|
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
|
Reviewed-by: Hanna Czenczek <hreitz@redhat.com>
|
|
Message-ID: <20250417150528.76470-3-stefanha@redhat.com>
|
|
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
|
|
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
|
(cherry picked from commit 4733cb0833c4b223f92ec0136980eeb5239ecb87)
|
|
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
|
---
|
|
block/io.c | 15 ++++++++++-----
|
|
1 file changed, 10 insertions(+), 5 deletions(-)
|
|
|
|
diff --git a/block/io.c b/block/io.c
|
|
index 301514c880..3e189837a1 100644
|
|
--- a/block/io.c
|
|
+++ b/block/io.c
|
|
@@ -3105,11 +3105,12 @@ int coroutine_fn bdrv_co_pdiscard(BdrvChild *child, int64_t offset,
|
|
/* Invalidate the cached block-status data range if this discard overlaps */
|
|
bdrv_bsc_invalidate_range(bs, offset, bytes);
|
|
|
|
- /* Discard is advisory, but some devices track and coalesce
|
|
+ /*
|
|
+ * Discard is advisory, but some devices track and coalesce
|
|
* unaligned requests, so we must pass everything down rather than
|
|
- * round here. Still, most devices will just silently ignore
|
|
- * unaligned requests (by returning -ENOTSUP), so we must fragment
|
|
- * the request accordingly. */
|
|
+ * round here. Still, most devices reject unaligned requests with
|
|
+ * -EINVAL or -ENOTSUP, so we must fragment the request accordingly.
|
|
+ */
|
|
align = MAX(bs->bl.pdiscard_alignment, bs->bl.request_alignment);
|
|
assert(align % bs->bl.request_alignment == 0);
|
|
head = offset % align;
|
|
@@ -3176,7 +3177,11 @@ int coroutine_fn bdrv_co_pdiscard(BdrvChild *child, int64_t offset,
|
|
}
|
|
}
|
|
if (ret && ret != -ENOTSUP) {
|
|
- goto out;
|
|
+ if (ret == -EINVAL && (offset % align != 0 || num % align != 0)) {
|
|
+ /* Silently skip rejected unaligned head/tail requests */
|
|
+ } else {
|
|
+ goto out; /* bail out */
|
|
+ }
|
|
}
|
|
|
|
offset += num;
|
|
--
|
|
2.48.1
|
|
|