1
The following changes since commit 20d6c7312f1b812bb9c750f4087f69ac8485cc90:
1
The following changes since commit ca61fa4b803e5d0abaf6f1ceb690f23bb78a4def:
2
2
3
Merge remote-tracking branch 'remotes/palmer/tags/riscv-for-master-3.2-part1' into staging (2019-01-03 13:26:30 +0000)
3
Merge remote-tracking branch 'remotes/quic/tags/pull-hex-20211006' into staging (2021-10-06 12:11:14 -0700)
4
4
5
are available in the Git repository at:
5
are available in the Git repository at:
6
6
7
git://github.com/stefanha/qemu.git tags/block-pull-request
7
https://gitlab.com/stefanha/qemu.git tags/block-pull-request
8
8
9
for you to fetch changes up to 39a0408e768cd00142f5b57d27ab234282bf4df5:
9
for you to fetch changes up to 1cc7eada97914f090125e588497986f6f7900514:
10
10
11
dmg: don't skip zero chunk (2019-01-04 11:15:09 +0000)
11
iothread: use IOThreadParamInfo in iothread_[set|get]_param() (2021-10-07 15:29:50 +0100)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
Pull request
14
Pull request
15
15
16
Bug fixes for the .dmg image file format.
17
18
----------------------------------------------------------------
16
----------------------------------------------------------------
19
17
20
Julio Faracco (1):
18
Stefano Garzarella (2):
21
dmg: Fixing wrong dmg block type value for block terminator.
19
iothread: rename PollParamInfo to IOThreadParamInfo
20
iothread: use IOThreadParamInfo in iothread_[set|get]_param()
22
21
23
yuchenlin (3):
22
iothread.c | 28 +++++++++++++++-------------
24
dmg: fix binary search
23
1 file changed, 15 insertions(+), 13 deletions(-)
25
dmg: use enumeration type instead of hard coding number
26
dmg: don't skip zero chunk
27
28
block/dmg.c | 31 ++++++++++++++++++++-----------
29
1 file changed, 20 insertions(+), 11 deletions(-)
30
24
31
--
25
--
32
2.20.1
26
2.31.1
33
27
34
28
29
diff view generated by jsdifflib
1
From: yuchenlin <npes87184@gmail.com>
1
From: Stefano Garzarella <sgarzare@redhat.com>
2
2
3
There is a possible hang in original binary search implementation. That is
3
Commit 1793ad0247 ("iothread: add aio-max-batch parameter") added
4
if chunk1 = 4, chunk2 = 5, chunk3 = 4, and we go else case.
4
a new parameter (aio-max-batch) to IOThread and used PollParamInfo
5
structure to handle it.
5
6
6
The chunk1 will be still 4, and so on.
7
Since it is not a parameter of the polling mechanism, we rename the
8
structure to a more generic IOThreadParamInfo.
7
9
8
Signed-off-by: yuchenlin <npes87184@gmail.com>
10
Suggested-by: Kevin Wolf <kwolf@redhat.com>
9
Message-id: 20190103114700.9686-2-npes87184@gmail.com
11
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
12
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
13
Message-id: 20210727145936.147032-2-sgarzare@redhat.com
10
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
14
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
11
---
15
---
12
block/dmg.c | 10 +++++++---
16
iothread.c | 14 +++++++-------
13
1 file changed, 7 insertions(+), 3 deletions(-)
17
1 file changed, 7 insertions(+), 7 deletions(-)
14
18
15
diff --git a/block/dmg.c b/block/dmg.c
19
diff --git a/iothread.c b/iothread.c
16
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
17
--- a/block/dmg.c
21
--- a/iothread.c
18
+++ b/block/dmg.c
22
+++ b/iothread.c
19
@@ -XXX,XX +XXX,XX @@ static inline uint32_t search_chunk(BDRVDMGState *s, uint64_t sector_num)
23
@@ -XXX,XX +XXX,XX @@ static void iothread_complete(UserCreatable *obj, Error **errp)
24
typedef struct {
25
const char *name;
26
ptrdiff_t offset; /* field's byte offset in IOThread struct */
27
-} PollParamInfo;
28
+} IOThreadParamInfo;
29
30
-static PollParamInfo poll_max_ns_info = {
31
+static IOThreadParamInfo poll_max_ns_info = {
32
"poll-max-ns", offsetof(IOThread, poll_max_ns),
33
};
34
-static PollParamInfo poll_grow_info = {
35
+static IOThreadParamInfo poll_grow_info = {
36
"poll-grow", offsetof(IOThread, poll_grow),
37
};
38
-static PollParamInfo poll_shrink_info = {
39
+static IOThreadParamInfo poll_shrink_info = {
40
"poll-shrink", offsetof(IOThread, poll_shrink),
41
};
42
-static PollParamInfo aio_max_batch_info = {
43
+static IOThreadParamInfo aio_max_batch_info = {
44
"aio-max-batch", offsetof(IOThread, aio_max_batch),
45
};
46
47
@@ -XXX,XX +XXX,XX @@ static void iothread_get_param(Object *obj, Visitor *v,
48
const char *name, void *opaque, Error **errp)
20
{
49
{
21
/* binary search */
50
IOThread *iothread = IOTHREAD(obj);
22
uint32_t chunk1 = 0, chunk2 = s->n_chunks, chunk3;
51
- PollParamInfo *info = opaque;
23
- while (chunk1 != chunk2) {
52
+ IOThreadParamInfo *info = opaque;
24
+ while (chunk1 <= chunk2) {
53
int64_t *field = (void *)iothread + info->offset;
25
chunk3 = (chunk1 + chunk2) / 2;
54
26
if (s->sectors[chunk3] > sector_num) {
55
visit_type_int64(v, name, field, errp);
27
- chunk2 = chunk3;
56
@@ -XXX,XX +XXX,XX @@ static bool iothread_set_param(Object *obj, Visitor *v,
28
+ if (chunk3 == 0) {
57
const char *name, void *opaque, Error **errp)
29
+ goto err;
58
{
30
+ }
59
IOThread *iothread = IOTHREAD(obj);
31
+ chunk2 = chunk3 - 1;
60
- PollParamInfo *info = opaque;
32
} else if (s->sectors[chunk3] + s->sectorcounts[chunk3] > sector_num) {
61
+ IOThreadParamInfo *info = opaque;
33
return chunk3;
62
int64_t *field = (void *)iothread + info->offset;
34
} else {
63
int64_t value;
35
- chunk1 = chunk3;
36
+ chunk1 = chunk3 + 1;
37
}
38
}
39
+err:
40
return s->n_chunks; /* error */
41
}
42
64
43
--
65
--
44
2.20.1
66
2.31.1
45
67
46
68
diff view generated by jsdifflib
1
From: Julio Faracco <jcfaracco@gmail.com>
1
From: Stefano Garzarella <sgarzare@redhat.com>
2
2
3
This is a trivial patch to fix a wrong value for block terminator.
3
Commit 0445409d74 ("iothread: generalize
4
The old value was 0x7fffffff which is wrong. It was not affecting the
4
iothread_set_param/iothread_get_param") moved common code to set and
5
code because QEMU dmg block is not handling block terminator right now.
5
get IOThread parameters in two new functions.
6
Neverthless, it should be fixed.
7
6
8
Signed-off-by: Julio Faracco <jcfaracco@gmail.com>
7
These functions are called inside callbacks, so we don't need to use an
9
Reviewed-by: yuchenlin <yuchenlin@synology.com>
8
opaque pointer. Let's replace `void *opaque` parameter with
10
Message-id: 20181228145055.18039-1-jcfaracco@gmail.com
9
`IOThreadParamInfo *info`.
10
11
Suggested-by: Kevin Wolf <kwolf@redhat.com>
12
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
13
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
14
Message-id: 20210727145936.147032-3-sgarzare@redhat.com
11
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
15
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
12
---
16
---
13
block/dmg.c | 2 +-
17
iothread.c | 18 ++++++++++--------
14
1 file changed, 1 insertion(+), 1 deletion(-)
18
1 file changed, 10 insertions(+), 8 deletions(-)
15
19
16
diff --git a/block/dmg.c b/block/dmg.c
20
diff --git a/iothread.c b/iothread.c
17
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
18
--- a/block/dmg.c
22
--- a/iothread.c
19
+++ b/block/dmg.c
23
+++ b/iothread.c
20
@@ -XXX,XX +XXX,XX @@ enum {
24
@@ -XXX,XX +XXX,XX @@ static IOThreadParamInfo aio_max_batch_info = {
21
UDBZ,
22
ULFO,
23
UDCM = 0x7ffffffe, /* Comments */
24
- UDLE /* Last Entry */
25
+ UDLE = 0xffffffff /* Last Entry */
26
};
25
};
27
26
28
static int dmg_probe(const uint8_t *buf, int buf_size, const char *filename)
27
static void iothread_get_param(Object *obj, Visitor *v,
28
- const char *name, void *opaque, Error **errp)
29
+ const char *name, IOThreadParamInfo *info, Error **errp)
30
{
31
IOThread *iothread = IOTHREAD(obj);
32
- IOThreadParamInfo *info = opaque;
33
int64_t *field = (void *)iothread + info->offset;
34
35
visit_type_int64(v, name, field, errp);
36
}
37
38
static bool iothread_set_param(Object *obj, Visitor *v,
39
- const char *name, void *opaque, Error **errp)
40
+ const char *name, IOThreadParamInfo *info, Error **errp)
41
{
42
IOThread *iothread = IOTHREAD(obj);
43
- IOThreadParamInfo *info = opaque;
44
int64_t *field = (void *)iothread + info->offset;
45
int64_t value;
46
47
@@ -XXX,XX +XXX,XX @@ static bool iothread_set_param(Object *obj, Visitor *v,
48
static void iothread_get_poll_param(Object *obj, Visitor *v,
49
const char *name, void *opaque, Error **errp)
50
{
51
+ IOThreadParamInfo *info = opaque;
52
53
- iothread_get_param(obj, v, name, opaque, errp);
54
+ iothread_get_param(obj, v, name, info, errp);
55
}
56
57
static void iothread_set_poll_param(Object *obj, Visitor *v,
58
const char *name, void *opaque, Error **errp)
59
{
60
IOThread *iothread = IOTHREAD(obj);
61
+ IOThreadParamInfo *info = opaque;
62
63
- if (!iothread_set_param(obj, v, name, opaque, errp)) {
64
+ if (!iothread_set_param(obj, v, name, info, errp)) {
65
return;
66
}
67
68
@@ -XXX,XX +XXX,XX @@ static void iothread_set_poll_param(Object *obj, Visitor *v,
69
static void iothread_get_aio_param(Object *obj, Visitor *v,
70
const char *name, void *opaque, Error **errp)
71
{
72
+ IOThreadParamInfo *info = opaque;
73
74
- iothread_get_param(obj, v, name, opaque, errp);
75
+ iothread_get_param(obj, v, name, info, errp);
76
}
77
78
static void iothread_set_aio_param(Object *obj, Visitor *v,
79
const char *name, void *opaque, Error **errp)
80
{
81
IOThread *iothread = IOTHREAD(obj);
82
+ IOThreadParamInfo *info = opaque;
83
84
- if (!iothread_set_param(obj, v, name, opaque, errp)) {
85
+ if (!iothread_set_param(obj, v, name, info, errp)) {
86
return;
87
}
88
29
--
89
--
30
2.20.1
90
2.31.1
31
91
32
92
diff view generated by jsdifflib
Deleted patch
1
From: yuchenlin <npes87184@gmail.com>
2
1
3
Signed-off-by: yuchenlin <npes87184@gmail.com>
4
Reviewed-by: Julio Faracco <jcfaracco@gmail.com>
5
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
6
Message-id: 20190103114700.9686-3-npes87184@gmail.com
7
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
8
---
9
block/dmg.c | 4 ++--
10
1 file changed, 2 insertions(+), 2 deletions(-)
11
12
diff --git a/block/dmg.c b/block/dmg.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/block/dmg.c
15
+++ b/block/dmg.c
16
@@ -XXX,XX +XXX,XX @@ static int dmg_read_mish_block(BDRVDMGState *s, DmgHeaderState *ds,
17
18
/* all-zeroes sector (type 2) does not need to be "uncompressed" and can
19
* therefore be unbounded. */
20
- if (s->types[i] != 2 && s->sectorcounts[i] > DMG_SECTORCOUNTS_MAX) {
21
+ if (s->types[i] != UDIG && s->sectorcounts[i] > DMG_SECTORCOUNTS_MAX) {
22
error_report("sector count %" PRIu64 " for chunk %" PRIu32
23
" is larger than max (%u)",
24
s->sectorcounts[i], i, DMG_SECTORCOUNTS_MAX);
25
@@ -XXX,XX +XXX,XX @@ dmg_co_preadv(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
26
/* Special case: current chunk is all zeroes. Do not perform a memcpy as
27
* s->uncompressed_chunk may be too small to cover the large all-zeroes
28
* section. dmg_read_chunk is called to find s->current_chunk */
29
- if (s->types[s->current_chunk] == 2) { /* all zeroes block entry */
30
+ if (s->types[s->current_chunk] == UDIG) { /* all zeroes block entry */
31
qemu_iovec_memset(qiov, i * 512, 0, 512);
32
continue;
33
}
34
--
35
2.20.1
36
37
diff view generated by jsdifflib
Deleted patch
1
From: yuchenlin <npes87184@gmail.com>
2
1
3
The dmg file has many tables which describe: "start from sector XXX to
4
sector XXX, the compression method is XXX and where the compressed data
5
resides on".
6
7
Each sector in the expanded file should be covered by a table. The table
8
will describe the offset of compressed data (or raw depends on the type)
9
in the dmg.
10
11
For example:
12
13
[-----------The expanded file------------]
14
[---bzip table ---]/* zeros */[---zlib---]
15
^
16
| if we want to read this sector.
17
18
we will find bzip table which contains this sector, and get the
19
compressed data offset, read it from dmg, uncompress it, finally write to
20
expanded file.
21
22
If we skip zero chunk (table), some sector cannot find the table which
23
will cause search_chunk() return s->n_chunks, dmg_read_chunk() return -1
24
and finally causing dmg_co_preadv() return EIO.
25
26
See:
27
28
[-----------The expanded file------------]
29
[---bzip table ---]/* zeros */[---zlib---]
30
^
31
| if we want to read this sector.
32
33
Oops, we cannot find the table contains it...
34
35
In the original implementation, we don't have zero table. When we try to
36
read sector inside the zero chunk. We will get EIO, and skip reading.
37
38
After this patch, we treat zero chunk the same as ignore chunk, it will
39
directly write zero and avoid some sector may not find the table.
40
41
After this patch:
42
43
[-----------The expanded file------------]
44
[---bzip table ---][--zeros--][---zlib---]
45
46
Signed-off-by: yuchenlin <npes87184@gmail.com>
47
Reviewed-by: Julio Faracco <jcfaracco@gmail.com>
48
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
49
Message-id: 20190103114700.9686-4-npes87184@gmail.com
50
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
51
---
52
block/dmg.c | 19 ++++++++++++-------
53
1 file changed, 12 insertions(+), 7 deletions(-)
54
55
diff --git a/block/dmg.c b/block/dmg.c
56
index XXXXXXX..XXXXXXX 100644
57
--- a/block/dmg.c
58
+++ b/block/dmg.c
59
@@ -XXX,XX +XXX,XX @@ static void update_max_chunk_size(BDRVDMGState *s, uint32_t chunk,
60
case UDRW: /* copy */
61
uncompressed_sectors = DIV_ROUND_UP(s->lengths[chunk], 512);
62
break;
63
- case UDIG: /* zero */
64
+ case UDZE: /* zero */
65
+ case UDIG: /* ignore */
66
/* as the all-zeroes block may be large, it is treated specially: the
67
* sector is not copied from a large buffer, a simple memset is used
68
* instead. Therefore uncompressed_sectors does not need to be set. */
69
@@ -XXX,XX +XXX,XX @@ typedef struct DmgHeaderState {
70
static bool dmg_is_known_block_type(uint32_t entry_type)
71
{
72
switch (entry_type) {
73
+ case UDZE: /* zeros */
74
case UDRW: /* uncompressed */
75
- case UDIG: /* zeroes */
76
+ case UDIG: /* ignore */
77
case UDZO: /* zlib */
78
return true;
79
case UDBZ: /* bzip2 */
80
@@ -XXX,XX +XXX,XX @@ static int dmg_read_mish_block(BDRVDMGState *s, DmgHeaderState *ds,
81
/* sector count */
82
s->sectorcounts[i] = buff_read_uint64(buffer, offset + 0x10);
83
84
- /* all-zeroes sector (type 2) does not need to be "uncompressed" and can
85
- * therefore be unbounded. */
86
- if (s->types[i] != UDIG && s->sectorcounts[i] > DMG_SECTORCOUNTS_MAX) {
87
+ /* all-zeroes sector (type UDZE and UDIG) does not need to be
88
+ * "uncompressed" and can therefore be unbounded. */
89
+ if (s->types[i] != UDZE && s->types[i] != UDIG
90
+ && s->sectorcounts[i] > DMG_SECTORCOUNTS_MAX) {
91
error_report("sector count %" PRIu64 " for chunk %" PRIu32
92
" is larger than max (%u)",
93
s->sectorcounts[i], i, DMG_SECTORCOUNTS_MAX);
94
@@ -XXX,XX +XXX,XX @@ static inline int dmg_read_chunk(BlockDriverState *bs, uint64_t sector_num)
95
return -1;
96
}
97
break;
98
- case UDIG: /* zero */
99
+ case UDZE: /* zeros */
100
+ case UDIG: /* ignore */
101
/* see dmg_read, it is treated specially. No buffer needs to be
102
* pre-filled, the zeroes can be set directly. */
103
break;
104
@@ -XXX,XX +XXX,XX @@ dmg_co_preadv(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
105
/* Special case: current chunk is all zeroes. Do not perform a memcpy as
106
* s->uncompressed_chunk may be too small to cover the large all-zeroes
107
* section. dmg_read_chunk is called to find s->current_chunk */
108
- if (s->types[s->current_chunk] == UDIG) { /* all zeroes block entry */
109
+ if (s->types[s->current_chunk] == UDZE
110
+ || s->types[s->current_chunk] == UDIG) { /* all zeroes block entry */
111
qemu_iovec_memset(qiov, i * 512, 0, 512);
112
continue;
113
}
114
--
115
2.20.1
116
117
diff view generated by jsdifflib