]>
Commit | Line | Data |
---|---|---|
20209d8d TL |
1 | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
2 | From: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru> | |
3 | Date: Thu, 11 Apr 2024 11:29:23 +0200 | |
4 | Subject: [PATCH] block/copy-before-write: support unligned snapshot-discard | |
5 | ||
6 | First thing that crashes on unligned access here is | |
7 | bdrv_reset_dirty_bitmap(). Correct way is to align-down the | |
8 | snapshot-discard request. | |
9 | ||
10 | Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru> | |
11 | Signed-off-by: Fiona Ebner <f.ebner@proxmox.com> | |
12 | Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com> | |
13 | --- | |
14 | block/copy-before-write.c | 16 +++++++++++++--- | |
15 | 1 file changed, 13 insertions(+), 3 deletions(-) | |
16 | ||
17 | diff --git a/block/copy-before-write.c b/block/copy-before-write.c | |
18 | index a2dddf6f57..0a219c2b75 100644 | |
19 | --- a/block/copy-before-write.c | |
20 | +++ b/block/copy-before-write.c | |
21 | @@ -325,14 +325,24 @@ static int coroutine_fn GRAPH_RDLOCK | |
22 | cbw_co_pdiscard_snapshot(BlockDriverState *bs, int64_t offset, int64_t bytes) | |
23 | { | |
24 | BDRVCopyBeforeWriteState *s = bs->opaque; | |
25 | + uint32_t cluster_size = block_copy_cluster_size(s->bcs); | |
26 | + int64_t aligned_offset = QEMU_ALIGN_UP(offset, cluster_size); | |
27 | + int64_t aligned_end = QEMU_ALIGN_DOWN(offset + bytes, cluster_size); | |
28 | + int64_t aligned_bytes; | |
29 | + | |
30 | + if (aligned_end <= aligned_offset) { | |
31 | + return 0; | |
32 | + } | |
33 | + aligned_bytes = aligned_end - aligned_offset; | |
34 | ||
35 | WITH_QEMU_LOCK_GUARD(&s->lock) { | |
36 | - bdrv_reset_dirty_bitmap(s->access_bitmap, offset, bytes); | |
37 | + bdrv_reset_dirty_bitmap(s->access_bitmap, aligned_offset, | |
38 | + aligned_bytes); | |
39 | } | |
40 | ||
41 | - block_copy_reset(s->bcs, offset, bytes); | |
42 | + block_copy_reset(s->bcs, aligned_offset, aligned_bytes); | |
43 | ||
44 | - return bdrv_co_pdiscard(s->target, offset, bytes); | |
45 | + return bdrv_co_pdiscard(s->target, aligned_offset, aligned_bytes); | |
46 | } | |
47 | ||
48 | static void cbw_refresh_filename(BlockDriverState *bs) |