]>
Commit | Line | Data |
---|---|---|
39e84ba8 TL |
1 | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
2 | From: Fabian Ebner <f.ebner@proxmox.com> | |
3 | Date: Wed, 22 Jun 2022 10:45:11 +0200 | |
4 | Subject: [PATCH] vma: create: support 64KiB-unaligned input images | |
5 | ||
6 | which fixes backing up templates with such disks in PVE, for example | |
7 | efitype=4m EFI disks on a file-based storage (size = 540672). | |
8 | ||
9 | If there is not enough left to read, blk_co_preadv will return -EIO, | |
10 | so limit the size in the last iteration. | |
11 | ||
12 | For writing, an unaligned end is already handled correctly. | |
13 | ||
14 | The call to memset is not strictly necessary, because writing also | |
15 | checks that it doesn't write data beyond the end of the image. But | |
16 | there are two reasons to do it: | |
17 | 1. It's cleaner that way. | |
18 | 2. It allows detecting when the final piece is all zeroes, which might | |
19 | not happen if the buffer still contains data from the previous | |
20 | iteration. | |
21 | ||
22 | Signed-off-by: Fabian Ebner <f.ebner@proxmox.com> | |
23 | --- | |
24 | vma.c | 12 ++++++++++-- | |
25 | 1 file changed, 10 insertions(+), 2 deletions(-) | |
26 | ||
27 | diff --git a/vma.c b/vma.c | |
5b15e2ec | 28 | index e6e9ffc7fe..304f02bc84 100644 |
39e84ba8 TL |
29 | --- a/vma.c |
30 | +++ b/vma.c | |
5b15e2ec | 31 | @@ -548,7 +548,7 @@ static void coroutine_fn backup_run(void *opaque) |
39e84ba8 TL |
32 | struct iovec iov; |
33 | QEMUIOVector qiov; | |
34 | ||
35 | - int64_t start, end; | |
36 | + int64_t start, end, readlen; | |
37 | int ret = 0; | |
38 | ||
39 | unsigned char *buf = blk_blockalign(job->target, VMA_CLUSTER_SIZE); | |
5b15e2ec | 40 | @@ -562,8 +562,16 @@ static void coroutine_fn backup_run(void *opaque) |
39e84ba8 TL |
41 | iov.iov_len = VMA_CLUSTER_SIZE; |
42 | qemu_iovec_init_external(&qiov, &iov, 1); | |
43 | ||
44 | + if (start + 1 == end) { | |
45 | + memset(buf, 0, VMA_CLUSTER_SIZE); | |
46 | + readlen = job->len - start * VMA_CLUSTER_SIZE; | |
47 | + assert(readlen > 0 && readlen <= VMA_CLUSTER_SIZE); | |
48 | + } else { | |
49 | + readlen = VMA_CLUSTER_SIZE; | |
50 | + } | |
51 | + | |
52 | ret = blk_co_preadv(job->target, start * VMA_CLUSTER_SIZE, | |
53 | - VMA_CLUSTER_SIZE, &qiov, 0); | |
54 | + readlen, &qiov, 0); | |
55 | if (ret < 0) { | |
56 | vma_writer_set_error(job->vmaw, "read error", -1); | |
57 | goto out; |