1
The following changes since commit 16aaacb307ed607b9780c12702c44f0fe52edc7e:
1
The following changes since commit c8de6ec63d766ca1998c5af468483ce912fdc0c2:
2
2
3
Merge remote-tracking branch 'remotes/cohuck/tags/s390x-20200430' into staging (2020-04-30 14:00:36 +0100)
3
Merge tag 'pull-request-2022-09-28' of https://gitlab.com/thuth/qemu into staging (2022-09-28 17:04:11 -0400)
4
4
5
are available in the Git repository at:
5
are available in the Git repository at:
6
6
7
git://repo.or.cz/qemu/kevin.git tags/for-upstream
7
git://repo.or.cz/qemu/kevin.git tags/for-upstream
8
8
9
for you to fetch changes up to eaae29ef89d498d0eac553c77b554f310a47f809:
9
for you to fetch changes up to 176e4961bb33d559da1af441fb0ee2e0cb8245ae:
10
10
11
qemu-storage-daemon: Fix non-string --object properties (2020-04-30 17:51:07 +0200)
11
hw/ide/core.c: Implement ATA INITIALIZE_DEVICE_PARAMETERS command (2022-09-30 18:43:44 +0200)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
Block layer patches:
14
Block layer patches
15
15
16
- Fix resize (extending) of short overlays
16
- Fix missing block_acct_setup() with -blockdev
17
- nvme: introduce PMR support from NVMe 1.4 spec
17
- Keep auto_backing_file post-migration
18
- qemu-storage-daemon: Fix non-string --object properties
18
- file-posix: Fixed O_DIRECT memory alignment
19
- ide: Fix state after EXECUTE DEVICE DIAGNOSTIC and implement
20
INITIALIZE DEVICE PARAMETERS
21
- qemu-img: Wean documentation and help output off '?' for help
22
- qcow2: fix memory leak and compiler warning
23
- Code cleanups
19
24
20
----------------------------------------------------------------
25
----------------------------------------------------------------
21
Alberto Garcia (1):
26
Denis V. Lunev (4):
22
qcow2: Add incompatibility note between backing files and raw external data files
27
block: pass OnOffAuto instead of bool to block_acct_setup()
28
block: add missed block_acct_setup with new block device init procedure
29
block: use bdrv_is_sg() helper instead of raw bs->sg reading
30
block: make serializing requests functions 'void'
23
31
24
Andrzej Jakowski (1):
32
Hanna Reitz (3):
25
nvme: introduce PMR support from NVMe 1.4 spec
33
block/qcow2: Keep auto_backing_file if possible
34
block/qed: Keep auto_backing_file if possible
35
iotests/backing-file-invalidation: Add new test
26
36
27
Kevin Wolf (12):
37
Keith Busch (2):
28
block: Add flags to BlockDriver.bdrv_co_truncate()
38
block: move bdrv_qiov_is_aligned to file-posix
29
block: Add flags to bdrv(_co)_truncate()
39
block: use the request length for iov alignment
30
block-backend: Add flags to blk_truncate()
31
qcow2: Support BDRV_REQ_ZERO_WRITE for truncate
32
raw-format: Support BDRV_REQ_ZERO_WRITE for truncate
33
file-posix: Support BDRV_REQ_ZERO_WRITE for truncate
34
block: truncate: Don't make backing file data visible
35
iotests: Filter testfiles out in filter_img_info()
36
iotests: Test committing to short backing file
37
qcow2: Forward ZERO_WRITE flag for full preallocation
38
qom: Factor out user_creatable_add_dict()
39
qemu-storage-daemon: Fix non-string --object properties
40
40
41
Paolo Bonzini (1):
41
Lev Kujawski (5):
42
qemu-iotests: allow qcow2 external discarded clusters to contain stale data
42
piix_ide_reset: Use pci_set_* functions instead of direct access
43
tests/qtest/ide-test.c: Create disk image for use as a secondary
44
hw/ide/core: Clear LBA and drive bits for EXECUTE DEVICE DIAGNOSTIC
45
tests/qtest/ide-test: Verify that DIAGNOSTIC clears DEV to zero
46
hw/ide/core.c: Implement ATA INITIALIZE_DEVICE_PARAMETERS command
43
47
44
docs/interop/qcow2.txt | 3 +
48
Markus Armbruster (1):
45
hw/block/nvme.h | 2 +
49
qemu-img: Wean documentation and help output off '?' for help
46
include/block/block.h | 5 +-
50
47
include/block/block_int.h | 10 +-
51
Philippe Mathieu-Daudé (1):
48
include/block/nvme.h | 172 ++++++++++++++++++++++++++
52
block/qcow2-bitmap: Add missing cast to silent GCC error
49
include/qom/object_interfaces.h | 16 +++
53
50
include/sysemu/block-backend.h | 2 +-
54
Stefan Hajnoczi (1):
51
block.c | 3 +-
55
gluster: stop using .bdrv_needs_filename
52
block/block-backend.c | 4 +-
56
53
block/commit.c | 4 +-
57
lu zhipeng (1):
54
block/crypto.c | 7 +-
58
qcow2: fix memory leak in qcow2_read_extensions
55
block/file-posix.c | 6 +-
59
56
block/file-win32.c | 2 +-
60
docs/tools/qemu-img.rst | 2 +-
57
block/gluster.c | 1 +
61
include/block/accounting.h | 6 +-
58
block/io.c | 43 ++++++-
62
include/block/block-io.h | 1 -
59
block/iscsi.c | 2 +-
63
include/block/block_int-io.h | 2 +-
60
block/mirror.c | 2 +-
64
include/hw/block/block.h | 7 +-
61
block/nfs.c | 3 +-
65
include/hw/ide/internal.h | 3 +
62
block/parallels.c | 6 +-
66
block/accounting.c | 26 +++-
63
block/qcow.c | 4 +-
67
block/file-posix.c | 24 +++-
64
block/qcow2-cluster.c | 2 +-
68
block/gluster.c | 4 -
65
block/qcow2-refcount.c | 2 +-
69
block/io.c | 44 +-----
66
block/qcow2.c | 73 +++++++++--
70
block/iscsi.c | 2 +-
67
block/qed.c | 3 +-
71
block/qcow2-bitmap.c | 2 +-
68
block/raw-format.c | 6 +-
72
block/qcow2.c | 22 ++-
69
block/rbd.c | 1 +
73
block/qed.c | 15 +-
70
block/sheepdog.c | 4 +-
74
block/raw-format.c | 4 +-
71
block/ssh.c | 2 +-
75
blockdev.c | 17 ++-
72
block/vdi.c | 2 +-
76
hw/block/block.c | 2 +
73
block/vhdx-log.c | 2 +-
77
hw/ide/core.c | 35 ++++-
74
block/vhdx.c | 6 +-
78
hw/ide/piix.c | 17 +--
75
block/vmdk.c | 8 +-
79
qemu-img.c | 4 +-
76
block/vpc.c | 2 +-
80
tests/qtest/ide-test.c | 72 +++++++---
77
blockdev.c | 2 +-
81
tests/qemu-iotests/172.out | 76 +++++++++++
78
hw/block/nvme.c | 109 ++++++++++++++++
82
tests/qemu-iotests/227.out | 4 +-
79
qemu-img.c | 2 +-
83
tests/qemu-iotests/tests/backing-file-invalidation | 152 +++++++++++++++++++++
80
qemu-io-cmds.c | 2 +-
84
.../tests/backing-file-invalidation.out | 5 +
81
qemu-storage-daemon.c | 4 +-
85
25 files changed, 447 insertions(+), 101 deletions(-)
82
qom/object_interfaces.c | 31 +++++
86
create mode 100755 tests/qemu-iotests/tests/backing-file-invalidation
83
qom/qom-qmp-cmds.c | 24 +---
87
create mode 100644 tests/qemu-iotests/tests/backing-file-invalidation.out
84
tests/test-block-iothread.c | 9 +-
85
tests/qemu-iotests/iotests.py | 5 +-
86
hw/block/Makefile.objs | 2 +-
87
hw/block/trace-events | 4 +
88
tests/qemu-iotests/244 | 10 +-
89
tests/qemu-iotests/244.out | 9 +-
90
tests/qemu-iotests/274 | 155 +++++++++++++++++++++++
91
tests/qemu-iotests/274.out | 268 ++++++++++++++++++++++++++++++++++++++++
92
tests/qemu-iotests/group | 1 +
93
49 files changed, 951 insertions(+), 96 deletions(-)
94
create mode 100755 tests/qemu-iotests/274
95
create mode 100644 tests/qemu-iotests/274.out
96
88
97
89
diff view generated by jsdifflib
1
The BDRV_REQ_ZERO_WRITE is currently implemented in a way that first the
1
From: lu zhipeng <luzhipeng@cestc.cn>
2
image is possibly preallocated and then the zero flag is added to all
3
clusters. This means that a copy-on-write operation may be needed when
4
writing to these clusters, despite having used preallocation, negating
5
one of the major benefits of preallocation.
6
2
7
Instead, try to forward the BDRV_REQ_ZERO_WRITE to the protocol driver,
3
Free feature_table if it is failed in bdrv_pread.
8
and if the protocol driver can ensure that the new area reads as zeros,
9
we can skip setting the zero flag in the qcow2 layer.
10
4
11
Unfortunately, the same approach doesn't work for metadata
5
Signed-off-by: lu zhipeng <luzhipeng@cestc.cn>
12
preallocation, so we'll still set the zero flag there.
6
Message-Id: <20220921144515.1166-1-luzhipeng@cestc.cn>
13
7
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
14
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
15
Reviewed-by: Max Reitz <mreitz@redhat.com>
16
Message-Id: <20200424142701.67053-1-kwolf@redhat.com>
17
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
18
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
19
---
9
---
20
block/qcow2.c | 22 +++++++++++++++++++---
10
block/qcow2.c | 1 +
21
tests/qemu-iotests/274.out | 4 ++--
11
1 file changed, 1 insertion(+)
22
2 files changed, 21 insertions(+), 5 deletions(-)
23
12
24
diff --git a/block/qcow2.c b/block/qcow2.c
13
diff --git a/block/qcow2.c b/block/qcow2.c
25
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
26
--- a/block/qcow2.c
15
--- a/block/qcow2.c
27
+++ b/block/qcow2.c
16
+++ b/block/qcow2.c
28
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
17
@@ -XXX,XX +XXX,XX @@ static int qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset,
29
/* Allocate the data area */
18
if (ret < 0) {
30
new_file_size = allocation_start +
19
error_setg_errno(errp, -ret, "ERROR: ext_feature_table: "
31
nb_new_data_clusters * s->cluster_size;
20
"Could not read table");
32
- /* Image file grows, so @exact does not matter */
21
+ g_free(feature_table);
33
- ret = bdrv_co_truncate(bs->file, new_file_size, false, prealloc, 0,
22
return ret;
34
- errp);
23
}
35
+ /*
24
36
+ * Image file grows, so @exact does not matter.
37
+ *
38
+ * If we need to zero out the new area, try first whether the protocol
39
+ * driver can already take care of this.
40
+ */
41
+ if (flags & BDRV_REQ_ZERO_WRITE) {
42
+ ret = bdrv_co_truncate(bs->file, new_file_size, false, prealloc,
43
+ BDRV_REQ_ZERO_WRITE, NULL);
44
+ if (ret >= 0) {
45
+ flags &= ~BDRV_REQ_ZERO_WRITE;
46
+ }
47
+ } else {
48
+ ret = -1;
49
+ }
50
+ if (ret < 0) {
51
+ ret = bdrv_co_truncate(bs->file, new_file_size, false, prealloc, 0,
52
+ errp);
53
+ }
54
if (ret < 0) {
55
error_prepend(errp, "Failed to resize underlying file: ");
56
qcow2_free_clusters(bs, allocation_start,
57
diff --git a/tests/qemu-iotests/274.out b/tests/qemu-iotests/274.out
58
index XXXXXXX..XXXXXXX 100644
59
--- a/tests/qemu-iotests/274.out
60
+++ b/tests/qemu-iotests/274.out
61
@@ -XXX,XX +XXX,XX @@ read 65536/65536 bytes at offset 9437184
62
10 MiB (0xa00000) bytes allocated at offset 5 MiB (0x500000)
63
64
[{ "start": 0, "length": 5242880, "depth": 1, "zero": true, "data": false},
65
-{ "start": 5242880, "length": 10485760, "depth": 0, "zero": true, "data": false, "offset": 327680}]
66
+{ "start": 5242880, "length": 10485760, "depth": 0, "zero": false, "data": true, "offset": 327680}]
67
68
=== preallocation=full ===
69
Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=16777216 cluster_size=65536 lazy_refcounts=off refcount_bits=16
70
@@ -XXX,XX +XXX,XX @@ read 65536/65536 bytes at offset 11534336
71
4 MiB (0x400000) bytes allocated at offset 8 MiB (0x800000)
72
73
[{ "start": 0, "length": 8388608, "depth": 1, "zero": true, "data": false},
74
-{ "start": 8388608, "length": 4194304, "depth": 0, "zero": true, "data": false, "offset": 327680}]
75
+{ "start": 8388608, "length": 4194304, "depth": 0, "zero": false, "data": true, "offset": 327680}]
76
77
=== preallocation=off ===
78
Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=393216 cluster_size=65536 lazy_refcounts=off refcount_bits=16
79
--
25
--
80
2.25.3
26
2.37.3
81
82
diff view generated by jsdifflib
1
We want to keep TEST_IMG for the full path of the main test image, but
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
filter_testfiles() must be called for other test images before replacing
3
other things like the image format because the test directory path could
4
contain the format as a substring.
5
2
6
Insert a filter_testfiles() call between both.
3
Commit d1258dd0c8 ("qcow2: autoloading dirty bitmaps") added the
4
set_readonly_helper() GFunc handler, correctly casting the gpointer
5
user_data in both the g_slist_foreach() caller and the handler.
6
Few commits later (commit 1b6b0562db), the handler is reused in
7
qcow2_reopen_bitmaps_rw() but missing the gpointer cast, resulting
8
in the following error when using Homebrew GCC 12.2.0:
7
9
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
[2/658] Compiling C object libblock.fa.p/block_qcow2-bitmap.c.o
9
Reviewed-by: Max Reitz <mreitz@redhat.com>
11
../../block/qcow2-bitmap.c: In function 'qcow2_reopen_bitmaps_rw':
10
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
12
../../block/qcow2-bitmap.c:1211:60: error: incompatible type for argument 3 of 'g_slist_foreach'
11
Message-Id: <20200424125448.63318-9-kwolf@redhat.com>
13
1211 | g_slist_foreach(ro_dirty_bitmaps, set_readonly_helper, false);
14
| ^~~~~
15
| |
16
| _Bool
17
In file included from /opt/homebrew/Cellar/glib/2.72.3_1/include/glib-2.0/glib/gmain.h:26,
18
from /opt/homebrew/Cellar/glib/2.72.3_1/include/glib-2.0/glib/giochannel.h:33,
19
from /opt/homebrew/Cellar/glib/2.72.3_1/include/glib-2.0/glib.h:54,
20
from /Users/philmd/source/qemu/include/glib-compat.h:32,
21
from /Users/philmd/source/qemu/include/qemu/osdep.h:144,
22
from ../../block/qcow2-bitmap.c:28:
23
/opt/homebrew/Cellar/glib/2.72.3_1/include/glib-2.0/glib/gslist.h:127:61: note: expected 'gpointer' {aka 'void *'} but argument is of type '_Bool'
24
127 | gpointer user_data);
25
| ~~~~~~~~~~~~~~~~~~^~~~~~~~~
26
At top level:
27
FAILED: libblock.fa.p/block_qcow2-bitmap.c.o
28
29
Fix by adding the missing gpointer cast.
30
31
Fixes: 1b6b0562db ("qcow2: support .bdrv_reopen_bitmaps_rw")
32
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
33
Message-Id: <20220919182755.51967-1-f4bug@amsat.org>
34
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
35
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
36
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
---
37
---
14
tests/qemu-iotests/iotests.py | 5 +++--
38
block/qcow2-bitmap.c | 2 +-
15
1 file changed, 3 insertions(+), 2 deletions(-)
39
1 file changed, 1 insertion(+), 1 deletion(-)
16
40
17
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
41
diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c
18
index XXXXXXX..XXXXXXX 100644
42
index XXXXXXX..XXXXXXX 100644
19
--- a/tests/qemu-iotests/iotests.py
43
--- a/block/qcow2-bitmap.c
20
+++ b/tests/qemu-iotests/iotests.py
44
+++ b/block/qcow2-bitmap.c
21
@@ -XXX,XX +XXX,XX @@ def filter_img_info(output, filename):
45
@@ -XXX,XX +XXX,XX @@ int qcow2_reopen_bitmaps_rw(BlockDriverState *bs, Error **errp)
22
for line in output.split('\n'):
46
}
23
if 'disk size' in line or 'actual-size' in line:
47
}
24
continue
48
25
- line = line.replace(filename, 'TEST_IMG') \
49
- g_slist_foreach(ro_dirty_bitmaps, set_readonly_helper, false);
26
- .replace(imgfmt, 'IMGFMT')
50
+ g_slist_foreach(ro_dirty_bitmaps, set_readonly_helper, (gpointer)false);
27
+ line = line.replace(filename, 'TEST_IMG')
51
ret = 0;
28
+ line = filter_testfiles(line)
52
29
+ line = line.replace(imgfmt, 'IMGFMT')
53
out:
30
line = re.sub('iters: [0-9]+', 'iters: XXX', line)
31
line = re.sub('uuid: [-a-f0-9]+', 'uuid: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX', line)
32
line = re.sub('cid: [0-9]+', 'cid: XXXXXXXXXX', line)
33
--
54
--
34
2.25.3
55
2.37.3
35
56
36
57
diff view generated by jsdifflib
New patch
1
From: Markus Armbruster <armbru@redhat.com>
1
2
3
'?' for help is deprecated since commit c8057f951d "Support 'help' as
4
a synonym for '?' in command line options", v1.2.0. We neglected to
5
update output of qemu-img --help and the manual. Do that now.
6
7
Signed-off-by: Markus Armbruster <armbru@redhat.com>
8
Message-Id: <20220908130842.641410-1-armbru@redhat.com>
9
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
---
12
docs/tools/qemu-img.rst | 2 +-
13
qemu-img.c | 4 ++--
14
2 files changed, 3 insertions(+), 3 deletions(-)
15
16
diff --git a/docs/tools/qemu-img.rst b/docs/tools/qemu-img.rst
17
index XXXXXXX..XXXXXXX 100644
18
--- a/docs/tools/qemu-img.rst
19
+++ b/docs/tools/qemu-img.rst
20
@@ -XXX,XX +XXX,XX @@ cases. See below for a description of the supported disk formats.
21
*OUTPUT_FMT* is the destination format.
22
23
*OPTIONS* is a comma separated list of format specific options in a
24
-name=value format. Use ``-o ?`` for an overview of the options supported
25
+name=value format. Use ``-o help`` for an overview of the options supported
26
by the used format or see the format descriptions below for details.
27
28
*SNAPSHOT_PARAM* is param used for internal snapshot, format is
29
diff --git a/qemu-img.c b/qemu-img.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/qemu-img.c
32
+++ b/qemu-img.c
33
@@ -XXX,XX +XXX,XX @@ void help(void)
34
" 'output_filename' is the destination disk image filename\n"
35
" 'output_fmt' is the destination format\n"
36
" 'options' is a comma separated list of format specific options in a\n"
37
- " name=value format. Use -o ? for an overview of the options supported by the\n"
38
- " used format\n"
39
+ " name=value format. Use -o help for an overview of the options supported by\n"
40
+ " the used format\n"
41
" 'snapshot_param' is param used for internal snapshot, format\n"
42
" is 'snapshot.id=[ID],snapshot.name=[NAME]', or\n"
43
" '[ID_OR_NAME]'\n"
44
--
45
2.37.3
diff view generated by jsdifflib
1
Now that node level interface bdrv_truncate() supports passing request
1
From: "Denis V. Lunev" <den@openvz.org>
2
flags to the block driver, expose this on the BlockBackend level, too.
3
2
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
3
We would have one more place for block_acct_setup() calling, which should
5
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
4
not corrupt original value.
6
Reviewed-by: Alberto Garcia <berto@igalia.com>
5
7
Reviewed-by: Max Reitz <mreitz@redhat.com>
6
Signed-off-by: Denis V. Lunev <den@openvz.org>
8
Message-Id: <20200424125448.63318-4-kwolf@redhat.com>
7
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
8
CC: Peter Krempa <pkrempa@redhat.com>
9
CC: Markus Armbruster <armbru@redhat.com>
10
CC: John Snow <jsnow@redhat.com>
11
CC: Kevin Wolf <kwolf@redhat.com>
12
CC: Hanna Reitz <hreitz@redhat.com>
13
Message-Id: <20220824095044.166009-2-den@openvz.org>
14
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
15
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
16
---
11
include/sysemu/block-backend.h | 2 +-
17
include/block/accounting.h | 6 +++---
12
block.c | 3 ++-
18
block/accounting.c | 22 ++++++++++++++++++----
13
block/block-backend.c | 4 ++--
19
blockdev.c | 17 ++++++++++++++---
14
block/commit.c | 4 ++--
20
3 files changed, 35 insertions(+), 10 deletions(-)
15
block/crypto.c | 2 +-
16
block/mirror.c | 2 +-
17
block/qcow2.c | 4 ++--
18
block/qed.c | 2 +-
19
block/vdi.c | 2 +-
20
block/vhdx.c | 4 ++--
21
block/vmdk.c | 6 +++---
22
block/vpc.c | 2 +-
23
blockdev.c | 2 +-
24
qemu-img.c | 2 +-
25
qemu-io-cmds.c | 2 +-
26
15 files changed, 22 insertions(+), 21 deletions(-)
27
21
28
diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h
22
diff --git a/include/block/accounting.h b/include/block/accounting.h
29
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
30
--- a/include/sysemu/block-backend.h
24
--- a/include/block/accounting.h
31
+++ b/include/sysemu/block-backend.h
25
+++ b/include/block/accounting.h
32
@@ -XXX,XX +XXX,XX @@ int coroutine_fn blk_co_pwrite_zeroes(BlockBackend *blk, int64_t offset,
26
@@ -XXX,XX +XXX,XX @@
33
int blk_pwrite_compressed(BlockBackend *blk, int64_t offset, const void *buf,
27
34
int bytes);
28
#include "qemu/timed-average.h"
35
int blk_truncate(BlockBackend *blk, int64_t offset, bool exact,
29
#include "qemu/thread.h"
36
- PreallocMode prealloc, Error **errp);
30
-#include "qapi/qapi-builtin-types.h"
37
+ PreallocMode prealloc, BdrvRequestFlags flags, Error **errp);
31
+#include "qapi/qapi-types-common.h"
38
int blk_pdiscard(BlockBackend *blk, int64_t offset, int bytes);
32
39
int blk_save_vmstate(BlockBackend *blk, const uint8_t *buf,
33
typedef struct BlockAcctTimedStats BlockAcctTimedStats;
40
int64_t pos, int size);
34
typedef struct BlockAcctStats BlockAcctStats;
41
diff --git a/block.c b/block.c
35
@@ -XXX,XX +XXX,XX @@ typedef struct BlockAcctCookie {
36
} BlockAcctCookie;
37
38
void block_acct_init(BlockAcctStats *stats);
39
-void block_acct_setup(BlockAcctStats *stats, bool account_invalid,
40
- bool account_failed);
41
+void block_acct_setup(BlockAcctStats *stats, enum OnOffAuto account_invalid,
42
+ enum OnOffAuto account_failed);
43
void block_acct_cleanup(BlockAcctStats *stats);
44
void block_acct_add_interval(BlockAcctStats *stats, unsigned interval_length);
45
BlockAcctTimedStats *block_acct_interval_next(BlockAcctStats *stats,
46
diff --git a/block/accounting.c b/block/accounting.c
42
index XXXXXXX..XXXXXXX 100644
47
index XXXXXXX..XXXXXXX 100644
43
--- a/block.c
48
--- a/block/accounting.c
44
+++ b/block.c
49
+++ b/block/accounting.c
45
@@ -XXX,XX +XXX,XX @@ static int64_t create_file_fallback_truncate(BlockBackend *blk,
50
@@ -XXX,XX +XXX,XX @@ void block_acct_init(BlockAcctStats *stats)
46
int64_t size;
51
}
47
int ret;
48
49
- ret = blk_truncate(blk, minimum_size, false, PREALLOC_MODE_OFF, &local_err);
50
+ ret = blk_truncate(blk, minimum_size, false, PREALLOC_MODE_OFF, 0,
51
+ &local_err);
52
if (ret < 0 && ret != -ENOTSUP) {
53
error_propagate(errp, local_err);
54
return ret;
55
diff --git a/block/block-backend.c b/block/block-backend.c
56
index XXXXXXX..XXXXXXX 100644
57
--- a/block/block-backend.c
58
+++ b/block/block-backend.c
59
@@ -XXX,XX +XXX,XX @@ int blk_pwrite_compressed(BlockBackend *blk, int64_t offset, const void *buf,
60
}
52
}
61
53
62
int blk_truncate(BlockBackend *blk, int64_t offset, bool exact,
54
-void block_acct_setup(BlockAcctStats *stats, bool account_invalid,
63
- PreallocMode prealloc, Error **errp)
55
- bool account_failed)
64
+ PreallocMode prealloc, BdrvRequestFlags flags, Error **errp)
56
+static bool bool_from_onoffauto(OnOffAuto val, bool def)
65
{
57
{
66
if (!blk_is_available(blk)) {
58
- stats->account_invalid = account_invalid;
67
error_setg(errp, "No medium inserted");
59
- stats->account_failed = account_failed;
68
return -ENOMEDIUM;
60
+ switch (val) {
69
}
61
+ case ON_OFF_AUTO_AUTO:
70
62
+ return def;
71
- return bdrv_truncate(blk->root, offset, exact, prealloc, 0, errp);
63
+ case ON_OFF_AUTO_ON:
72
+ return bdrv_truncate(blk->root, offset, exact, prealloc, flags, errp);
64
+ return true;
65
+ case ON_OFF_AUTO_OFF:
66
+ return false;
67
+ default:
68
+ abort();
69
+ }
70
+}
71
+
72
+void block_acct_setup(BlockAcctStats *stats, enum OnOffAuto account_invalid,
73
+ enum OnOffAuto account_failed)
74
+{
75
+ stats->account_invalid = bool_from_onoffauto(account_invalid, true);
76
+ stats->account_failed = bool_from_onoffauto(account_failed, true);
73
}
77
}
74
78
75
int blk_save_vmstate(BlockBackend *blk, const uint8_t *buf,
79
void block_acct_cleanup(BlockAcctStats *stats)
76
diff --git a/block/commit.c b/block/commit.c
77
index XXXXXXX..XXXXXXX 100644
78
--- a/block/commit.c
79
+++ b/block/commit.c
80
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn commit_run(Job *job, Error **errp)
81
}
82
83
if (base_len < len) {
84
- ret = blk_truncate(s->base, len, false, PREALLOC_MODE_OFF, NULL);
85
+ ret = blk_truncate(s->base, len, false, PREALLOC_MODE_OFF, 0, NULL);
86
if (ret) {
87
goto out;
88
}
89
@@ -XXX,XX +XXX,XX @@ int bdrv_commit(BlockDriverState *bs)
90
* grow the backing file image if possible. If not possible,
91
* we must return an error */
92
if (length > backing_length) {
93
- ret = blk_truncate(backing, length, false, PREALLOC_MODE_OFF,
94
+ ret = blk_truncate(backing, length, false, PREALLOC_MODE_OFF, 0,
95
&local_err);
96
if (ret < 0) {
97
error_report_err(local_err);
98
diff --git a/block/crypto.c b/block/crypto.c
99
index XXXXXXX..XXXXXXX 100644
100
--- a/block/crypto.c
101
+++ b/block/crypto.c
102
@@ -XXX,XX +XXX,XX @@ static ssize_t block_crypto_init_func(QCryptoBlock *block,
103
* which will be used by the crypto header
104
*/
105
return blk_truncate(data->blk, data->size + headerlen, false,
106
- data->prealloc, errp);
107
+ data->prealloc, 0, errp);
108
}
109
110
111
diff --git a/block/mirror.c b/block/mirror.c
112
index XXXXXXX..XXXXXXX 100644
113
--- a/block/mirror.c
114
+++ b/block/mirror.c
115
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn mirror_run(Job *job, Error **errp)
116
117
if (s->bdev_length > base_length) {
118
ret = blk_truncate(s->target, s->bdev_length, false,
119
- PREALLOC_MODE_OFF, NULL);
120
+ PREALLOC_MODE_OFF, 0, NULL);
121
if (ret < 0) {
122
goto immediate_exit;
123
}
124
diff --git a/block/qcow2.c b/block/qcow2.c
125
index XXXXXXX..XXXXXXX 100644
126
--- a/block/qcow2.c
127
+++ b/block/qcow2.c
128
@@ -XXX,XX +XXX,XX @@ qcow2_co_create(BlockdevCreateOptions *create_options, Error **errp)
129
130
/* Okay, now that we have a valid image, let's give it the right size */
131
ret = blk_truncate(blk, qcow2_opts->size, false, qcow2_opts->preallocation,
132
- errp);
133
+ 0, errp);
134
if (ret < 0) {
135
error_prepend(errp, "Could not resize image: ");
136
goto out;
137
@@ -XXX,XX +XXX,XX @@ static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts,
138
* Amending image options should ensure that the image has
139
* exactly the given new values, so pass exact=true here.
140
*/
141
- ret = blk_truncate(blk, new_size, true, PREALLOC_MODE_OFF, errp);
142
+ ret = blk_truncate(blk, new_size, true, PREALLOC_MODE_OFF, 0, errp);
143
blk_unref(blk);
144
if (ret < 0) {
145
return ret;
146
diff --git a/block/qed.c b/block/qed.c
147
index XXXXXXX..XXXXXXX 100644
148
--- a/block/qed.c
149
+++ b/block/qed.c
150
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_qed_co_create(BlockdevCreateOptions *opts,
151
* The QED format associates file length with allocation status,
152
* so a new file (which is empty) must have a length of 0.
153
*/
154
- ret = blk_truncate(blk, 0, true, PREALLOC_MODE_OFF, errp);
155
+ ret = blk_truncate(blk, 0, true, PREALLOC_MODE_OFF, 0, errp);
156
if (ret < 0) {
157
goto out;
158
}
159
diff --git a/block/vdi.c b/block/vdi.c
160
index XXXXXXX..XXXXXXX 100644
161
--- a/block/vdi.c
162
+++ b/block/vdi.c
163
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn vdi_co_do_create(BlockdevCreateOptions *create_options,
164
165
if (image_type == VDI_TYPE_STATIC) {
166
ret = blk_truncate(blk, offset + blocks * block_size, false,
167
- PREALLOC_MODE_OFF, errp);
168
+ PREALLOC_MODE_OFF, 0, errp);
169
if (ret < 0) {
170
error_prepend(errp, "Failed to statically allocate file");
171
goto exit;
172
diff --git a/block/vhdx.c b/block/vhdx.c
173
index XXXXXXX..XXXXXXX 100644
174
--- a/block/vhdx.c
175
+++ b/block/vhdx.c
176
@@ -XXX,XX +XXX,XX @@ static int vhdx_create_bat(BlockBackend *blk, BDRVVHDXState *s,
177
/* All zeroes, so we can just extend the file - the end of the BAT
178
* is the furthest thing we have written yet */
179
ret = blk_truncate(blk, data_file_offset, false, PREALLOC_MODE_OFF,
180
- errp);
181
+ 0, errp);
182
if (ret < 0) {
183
goto exit;
184
}
185
} else if (type == VHDX_TYPE_FIXED) {
186
ret = blk_truncate(blk, data_file_offset + image_size, false,
187
- PREALLOC_MODE_OFF, errp);
188
+ PREALLOC_MODE_OFF, 0, errp);
189
if (ret < 0) {
190
goto exit;
191
}
192
diff --git a/block/vmdk.c b/block/vmdk.c
193
index XXXXXXX..XXXXXXX 100644
194
--- a/block/vmdk.c
195
+++ b/block/vmdk.c
196
@@ -XXX,XX +XXX,XX @@ static int vmdk_init_extent(BlockBackend *blk,
197
int gd_buf_size;
198
199
if (flat) {
200
- ret = blk_truncate(blk, filesize, false, PREALLOC_MODE_OFF, errp);
201
+ ret = blk_truncate(blk, filesize, false, PREALLOC_MODE_OFF, 0, errp);
202
goto exit;
203
}
204
magic = cpu_to_be32(VMDK4_MAGIC);
205
@@ -XXX,XX +XXX,XX @@ static int vmdk_init_extent(BlockBackend *blk,
206
}
207
208
ret = blk_truncate(blk, le64_to_cpu(header.grain_offset) << 9, false,
209
- PREALLOC_MODE_OFF, errp);
210
+ PREALLOC_MODE_OFF, 0, errp);
211
if (ret < 0) {
212
goto exit;
213
}
214
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn vmdk_co_do_create(int64_t size,
215
/* bdrv_pwrite write padding zeros to align to sector, we don't need that
216
* for description file */
217
if (desc_offset == 0) {
218
- ret = blk_truncate(blk, desc_len, false, PREALLOC_MODE_OFF, errp);
219
+ ret = blk_truncate(blk, desc_len, false, PREALLOC_MODE_OFF, 0, errp);
220
if (ret < 0) {
221
goto exit;
222
}
223
diff --git a/block/vpc.c b/block/vpc.c
224
index XXXXXXX..XXXXXXX 100644
225
--- a/block/vpc.c
226
+++ b/block/vpc.c
227
@@ -XXX,XX +XXX,XX @@ static int create_fixed_disk(BlockBackend *blk, uint8_t *buf,
228
/* Add footer to total size */
229
total_size += HEADER_SIZE;
230
231
- ret = blk_truncate(blk, total_size, false, PREALLOC_MODE_OFF, errp);
232
+ ret = blk_truncate(blk, total_size, false, PREALLOC_MODE_OFF, 0, errp);
233
if (ret < 0) {
234
return ret;
235
}
236
diff --git a/blockdev.c b/blockdev.c
80
diff --git a/blockdev.c b/blockdev.c
237
index XXXXXXX..XXXXXXX 100644
81
index XXXXXXX..XXXXXXX 100644
238
--- a/blockdev.c
82
--- a/blockdev.c
239
+++ b/blockdev.c
83
+++ b/blockdev.c
240
@@ -XXX,XX +XXX,XX @@ void qmp_block_resize(bool has_device, const char *device,
84
@@ -XXX,XX +XXX,XX @@ static void extract_common_blockdev_options(QemuOpts *opts, int *bdrv_flags,
241
}
85
}
242
86
}
243
bdrv_drained_begin(bs);
87
244
- ret = blk_truncate(blk, size, false, PREALLOC_MODE_OFF, errp);
88
+static OnOffAuto account_get_opt(QemuOpts *opts, const char *name)
245
+ ret = blk_truncate(blk, size, false, PREALLOC_MODE_OFF, 0, errp);
89
+{
246
bdrv_drained_end(bs);
90
+ if (!qemu_opt_find(opts, name)) {
247
91
+ return ON_OFF_AUTO_AUTO;
248
out:
92
+ }
249
diff --git a/qemu-img.c b/qemu-img.c
93
+ if (qemu_opt_get_bool(opts, name, true)) {
250
index XXXXXXX..XXXXXXX 100644
94
+ return ON_OFF_AUTO_ON;
251
--- a/qemu-img.c
95
+ }
252
+++ b/qemu-img.c
96
+ return ON_OFF_AUTO_OFF;
253
@@ -XXX,XX +XXX,XX @@ static int img_resize(int argc, char **argv)
97
+}
254
* resizing, so pass @exact=true. It is of no use to report
98
+
255
* success when the image has not actually been resized.
99
/* Takes the ownership of bs_opts */
256
*/
100
static BlockBackend *blockdev_init(const char *file, QDict *bs_opts,
257
- ret = blk_truncate(blk, total_size, true, prealloc, &err);
101
Error **errp)
258
+ ret = blk_truncate(blk, total_size, true, prealloc, 0, &err);
102
@@ -XXX,XX +XXX,XX @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts,
259
if (!ret) {
103
const char *buf;
260
qprintf(quiet, "Image resized.\n");
104
int bdrv_flags = 0;
261
} else {
105
int on_read_error, on_write_error;
262
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
106
- bool account_invalid, account_failed;
263
index XXXXXXX..XXXXXXX 100644
107
+ OnOffAuto account_invalid, account_failed;
264
--- a/qemu-io-cmds.c
108
bool writethrough, read_only;
265
+++ b/qemu-io-cmds.c
109
BlockBackend *blk;
266
@@ -XXX,XX +XXX,XX @@ static int truncate_f(BlockBackend *blk, int argc, char **argv)
110
BlockDriverState *bs;
267
* exact=true. It is better to err on the "emit more errors" side
111
@@ -XXX,XX +XXX,XX @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts,
268
* than to be overly permissive.
112
/* extract parameters */
269
*/
113
snapshot = qemu_opt_get_bool(opts, "snapshot", 0);
270
- ret = blk_truncate(blk, offset, true, PREALLOC_MODE_OFF, &local_err);
114
271
+ ret = blk_truncate(blk, offset, true, PREALLOC_MODE_OFF, 0, &local_err);
115
- account_invalid = qemu_opt_get_bool(opts, "stats-account-invalid", true);
272
if (ret < 0) {
116
- account_failed = qemu_opt_get_bool(opts, "stats-account-failed", true);
273
error_report_err(local_err);
117
+ account_invalid = account_get_opt(opts, "stats-account-invalid");
274
return ret;
118
+ account_failed = account_get_opt(opts, "stats-account-failed");
119
120
writethrough = !qemu_opt_get_bool(opts, BDRV_OPT_CACHE_WB, true);
121
275
--
122
--
276
2.25.3
123
2.37.3
277
278
diff view generated by jsdifflib
1
The QMP handler qmp_object_add() and the implementation of --object in
1
From: "Denis V. Lunev" <den@openvz.org>
2
qemu-storage-daemon can share most of the code. Currently,
3
qemu-storage-daemon calls qmp_object_add(), but this is not correct
4
because different visitors need to be used.
5
2
6
As a first step towards a fix, make qmp_object_add() a wrapper around a
3
Commit 5f76a7aac156ca75680dad5df4a385fd0b58f6b1 is looking harmless from
7
new function user_creatable_add_dict() that can get an additional
4
the first glance, but it has changed things a lot. 'libvirt' uses it to
8
parameter. The handling of "props" is only required for compatibility
5
detect that it should follow new initialization way and this changes
9
and not required for the qemu-storage-daemon command line, so it stays
6
things considerably. With this procedure followed, blockdev_init() is
10
in qmp_object_add().
7
not called anymore and thus block_acct_setup() helper is not called.
11
8
9
This means in particular that defaults for block accounting statistics
10
are changed and account_invalid/account_failed are actually initialized
11
as false instead of true originally.
12
13
This commit changes things to match original world. There are the following
14
constraints:
15
* new default value in block_acct_init() is set to true
16
* block_acct_setup() inside blockdev_init() is called before
17
blkconf_apply_backend_options()
18
* thus newly created option in block device properties has precedence if
19
specified
20
21
Signed-off-by: Denis V. Lunev <den@openvz.org>
22
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
23
CC: Peter Krempa <pkrempa@redhat.com>
24
CC: Markus Armbruster <armbru@redhat.com>
25
CC: John Snow <jsnow@redhat.com>
26
CC: Kevin Wolf <kwolf@redhat.com>
27
CC: Hanna Reitz <hreitz@redhat.com>
28
Message-Id: <20220824095044.166009-3-den@openvz.org>
29
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
30
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
---
31
---
14
include/qom/object_interfaces.h | 12 ++++++++++++
32
include/hw/block/block.h | 7 +++-
15
qom/object_interfaces.c | 27 +++++++++++++++++++++++++++
33
block/accounting.c | 8 +++-
16
qom/qom-qmp-cmds.c | 24 +-----------------------
34
hw/block/block.c | 2 +
17
3 files changed, 40 insertions(+), 23 deletions(-)
35
tests/qemu-iotests/172.out | 76 ++++++++++++++++++++++++++++++++++++++
36
tests/qemu-iotests/227.out | 4 +-
37
5 files changed, 92 insertions(+), 5 deletions(-)
18
38
19
diff --git a/include/qom/object_interfaces.h b/include/qom/object_interfaces.h
39
diff --git a/include/hw/block/block.h b/include/hw/block/block.h
20
index XXXXXXX..XXXXXXX 100644
40
index XXXXXXX..XXXXXXX 100644
21
--- a/include/qom/object_interfaces.h
41
--- a/include/hw/block/block.h
22
+++ b/include/qom/object_interfaces.h
42
+++ b/include/hw/block/block.h
23
@@ -XXX,XX +XXX,XX @@ Object *user_creatable_add_type(const char *type, const char *id,
43
@@ -XXX,XX +XXX,XX @@ typedef struct BlockConf {
24
const QDict *qdict,
44
uint32_t lcyls, lheads, lsecs;
25
Visitor *v, Error **errp);
45
OnOffAuto wce;
26
46
bool share_rw;
27
+/**
47
+ OnOffAuto account_invalid, account_failed;
28
+ * user_creatable_add_dict:
48
BlockdevOnError rerror;
29
+ * @qdict: the object definition
49
BlockdevOnError werror;
30
+ * @errp: if an error occurs, a pointer to an area to store the error
50
} BlockConf;
31
+ *
51
@@ -XXX,XX +XXX,XX @@ static inline unsigned int get_physical_block_exp(BlockConf *conf)
32
+ * Create an instance of the user creatable object that is defined by
52
_conf.discard_granularity, -1), \
33
+ * @qdict. The object type is taken from the QDict key 'qom-type', its
53
DEFINE_PROP_ON_OFF_AUTO("write-cache", _state, _conf.wce, \
34
+ * ID from the key 'id'. The remaining entries in @qdict are used to
54
ON_OFF_AUTO_AUTO), \
35
+ * initialize the object properties.
55
- DEFINE_PROP_BOOL("share-rw", _state, _conf.share_rw, false)
36
+ */
56
+ DEFINE_PROP_BOOL("share-rw", _state, _conf.share_rw, false), \
37
+void user_creatable_add_dict(QDict *qdict, Error **errp);
57
+ DEFINE_PROP_ON_OFF_AUTO("account-invalid", _state, \
38
+
58
+ _conf.account_invalid, ON_OFF_AUTO_AUTO), \
39
/**
59
+ DEFINE_PROP_ON_OFF_AUTO("account-failed", _state, \
40
* user_creatable_add_opts:
60
+ _conf.account_failed, ON_OFF_AUTO_AUTO)
41
* @opts: the object definition
61
42
diff --git a/qom/object_interfaces.c b/qom/object_interfaces.c
62
#define DEFINE_BLOCK_PROPERTIES(_state, _conf) \
63
DEFINE_PROP_DRIVE("drive", _state, _conf.blk), \
64
diff --git a/block/accounting.c b/block/accounting.c
43
index XXXXXXX..XXXXXXX 100644
65
index XXXXXXX..XXXXXXX 100644
44
--- a/qom/object_interfaces.c
66
--- a/block/accounting.c
45
+++ b/qom/object_interfaces.c
67
+++ b/block/accounting.c
46
@@ -XXX,XX +XXX,XX @@
68
@@ -XXX,XX +XXX,XX @@ void block_acct_init(BlockAcctStats *stats)
47
#include "qapi/qmp/qerror.h"
69
if (qtest_enabled()) {
48
#include "qapi/qmp/qjson.h"
70
clock_type = QEMU_CLOCK_VIRTUAL;
49
#include "qapi/qmp/qstring.h"
71
}
50
+#include "qapi/qobject-input-visitor.h"
72
+ stats->account_invalid = true;
51
#include "qom/object_interfaces.h"
73
+ stats->account_failed = true;
52
#include "qemu/help_option.h"
53
#include "qemu/module.h"
54
@@ -XXX,XX +XXX,XX @@ out:
55
return obj;
56
}
74
}
57
75
58
+void user_creatable_add_dict(QDict *qdict, Error **errp)
76
static bool bool_from_onoffauto(OnOffAuto val, bool def)
59
+{
77
@@ -XXX,XX +XXX,XX @@ static bool bool_from_onoffauto(OnOffAuto val, bool def)
60
+ Visitor *v;
78
void block_acct_setup(BlockAcctStats *stats, enum OnOffAuto account_invalid,
61
+ Object *obj;
79
enum OnOffAuto account_failed)
62
+ g_autofree char *type = NULL;
63
+ g_autofree char *id = NULL;
64
+
65
+ type = g_strdup(qdict_get_try_str(qdict, "qom-type"));
66
+ if (!type) {
67
+ error_setg(errp, QERR_MISSING_PARAMETER, "qom-type");
68
+ return;
69
+ }
70
+ qdict_del(qdict, "qom-type");
71
+
72
+ id = g_strdup(qdict_get_try_str(qdict, "id"));
73
+ if (!id) {
74
+ error_setg(errp, QERR_MISSING_PARAMETER, "id");
75
+ return;
76
+ }
77
+ qdict_del(qdict, "id");
78
+
79
+ v = qobject_input_visitor_new(QOBJECT(qdict));
80
+ obj = user_creatable_add_type(type, id, qdict, v, errp);
81
+ visit_free(v);
82
+ object_unref(obj);
83
+}
84
85
Object *user_creatable_add_opts(QemuOpts *opts, Error **errp)
86
{
80
{
87
diff --git a/qom/qom-qmp-cmds.c b/qom/qom-qmp-cmds.c
81
- stats->account_invalid = bool_from_onoffauto(account_invalid, true);
82
- stats->account_failed = bool_from_onoffauto(account_failed, true);
83
+ stats->account_invalid = bool_from_onoffauto(account_invalid,
84
+ stats->account_invalid);
85
+ stats->account_failed = bool_from_onoffauto(account_failed,
86
+ stats->account_failed);
87
}
88
89
void block_acct_cleanup(BlockAcctStats *stats)
90
diff --git a/hw/block/block.c b/hw/block/block.c
88
index XXXXXXX..XXXXXXX 100644
91
index XXXXXXX..XXXXXXX 100644
89
--- a/qom/qom-qmp-cmds.c
92
--- a/hw/block/block.c
90
+++ b/qom/qom-qmp-cmds.c
93
+++ b/hw/block/block.c
91
@@ -XXX,XX +XXX,XX @@
94
@@ -XXX,XX +XXX,XX @@ bool blkconf_apply_backend_options(BlockConf *conf, bool readonly,
92
#include "qapi/qapi-commands-qom.h"
95
blk_set_enable_write_cache(blk, wce);
93
#include "qapi/qmp/qdict.h"
96
blk_set_on_error(blk, rerror, werror);
94
#include "qapi/qmp/qerror.h"
97
95
-#include "qapi/qobject-input-visitor.h"
98
+ block_acct_setup(blk_get_stats(blk), conf->account_invalid,
96
#include "qemu/cutils.h"
99
+ conf->account_failed);
97
#include "qom/object_interfaces.h"
100
return true;
98
#include "qom/qom-qobject.h"
99
@@ -XXX,XX +XXX,XX @@ void qmp_object_add(QDict *qdict, QObject **ret_data, Error **errp)
100
{
101
QObject *props;
102
QDict *pdict;
103
- Visitor *v;
104
- Object *obj;
105
- g_autofree char *type = NULL;
106
- g_autofree char *id = NULL;
107
-
108
- type = g_strdup(qdict_get_try_str(qdict, "qom-type"));
109
- if (!type) {
110
- error_setg(errp, QERR_MISSING_PARAMETER, "qom-type");
111
- return;
112
- }
113
- qdict_del(qdict, "qom-type");
114
-
115
- id = g_strdup(qdict_get_try_str(qdict, "id"));
116
- if (!id) {
117
- error_setg(errp, QERR_MISSING_PARAMETER, "id");
118
- return;
119
- }
120
- qdict_del(qdict, "id");
121
122
props = qdict_get(qdict, "props");
123
if (props) {
124
@@ -XXX,XX +XXX,XX @@ void qmp_object_add(QDict *qdict, QObject **ret_data, Error **errp)
125
qobject_unref(pdict);
126
}
127
128
- v = qobject_input_visitor_new(QOBJECT(qdict));
129
- obj = user_creatable_add_type(type, id, qdict, v, errp);
130
- visit_free(v);
131
- object_unref(obj);
132
+ user_creatable_add_dict(qdict, errp);
133
}
101
}
134
102
135
void qmp_object_del(const char *id, Error **errp)
103
diff --git a/tests/qemu-iotests/172.out b/tests/qemu-iotests/172.out
104
index XXXXXXX..XXXXXXX 100644
105
--- a/tests/qemu-iotests/172.out
106
+++ b/tests/qemu-iotests/172.out
107
@@ -XXX,XX +XXX,XX @@ Testing:
108
discard_granularity = 4294967295 (4 GiB)
109
write-cache = "auto"
110
share-rw = false
111
+ account-invalid = "auto"
112
+ account-failed = "auto"
113
drive-type = "288"
114
115
116
@@ -XXX,XX +XXX,XX @@ Testing: -fda TEST_DIR/t.qcow2
117
discard_granularity = 4294967295 (4 GiB)
118
write-cache = "auto"
119
share-rw = false
120
+ account-invalid = "auto"
121
+ account-failed = "auto"
122
drive-type = "144"
123
floppy0 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2)
124
Attached to: /machine/unattached/device[N]
125
@@ -XXX,XX +XXX,XX @@ Testing: -fdb TEST_DIR/t.qcow2
126
discard_granularity = 4294967295 (4 GiB)
127
write-cache = "auto"
128
share-rw = false
129
+ account-invalid = "auto"
130
+ account-failed = "auto"
131
drive-type = "144"
132
dev: floppy, id ""
133
unit = 0 (0x0)
134
@@ -XXX,XX +XXX,XX @@ Testing: -fdb TEST_DIR/t.qcow2
135
discard_granularity = 4294967295 (4 GiB)
136
write-cache = "auto"
137
share-rw = false
138
+ account-invalid = "auto"
139
+ account-failed = "auto"
140
drive-type = "288"
141
floppy1 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2)
142
Attached to: /machine/unattached/device[N]
143
@@ -XXX,XX +XXX,XX @@ Testing: -fda TEST_DIR/t.qcow2 -fdb TEST_DIR/t.qcow2.2
144
discard_granularity = 4294967295 (4 GiB)
145
write-cache = "auto"
146
share-rw = false
147
+ account-invalid = "auto"
148
+ account-failed = "auto"
149
drive-type = "144"
150
dev: floppy, id ""
151
unit = 0 (0x0)
152
@@ -XXX,XX +XXX,XX @@ Testing: -fda TEST_DIR/t.qcow2 -fdb TEST_DIR/t.qcow2.2
153
discard_granularity = 4294967295 (4 GiB)
154
write-cache = "auto"
155
share-rw = false
156
+ account-invalid = "auto"
157
+ account-failed = "auto"
158
drive-type = "144"
159
floppy0 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2)
160
Attached to: /machine/unattached/device[N]
161
@@ -XXX,XX +XXX,XX @@ Testing: -fdb
162
discard_granularity = 4294967295 (4 GiB)
163
write-cache = "auto"
164
share-rw = false
165
+ account-invalid = "auto"
166
+ account-failed = "auto"
167
drive-type = "288"
168
dev: floppy, id ""
169
unit = 0 (0x0)
170
@@ -XXX,XX +XXX,XX @@ Testing: -fdb
171
discard_granularity = 4294967295 (4 GiB)
172
write-cache = "auto"
173
share-rw = false
174
+ account-invalid = "auto"
175
+ account-failed = "auto"
176
drive-type = "288"
177
178
179
@@ -XXX,XX +XXX,XX @@ Testing: -drive if=floppy,file=TEST_DIR/t.qcow2
180
discard_granularity = 4294967295 (4 GiB)
181
write-cache = "auto"
182
share-rw = false
183
+ account-invalid = "auto"
184
+ account-failed = "auto"
185
drive-type = "144"
186
floppy0 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2)
187
Attached to: /machine/unattached/device[N]
188
@@ -XXX,XX +XXX,XX @@ Testing: -drive if=floppy,file=TEST_DIR/t.qcow2,index=1
189
discard_granularity = 4294967295 (4 GiB)
190
write-cache = "auto"
191
share-rw = false
192
+ account-invalid = "auto"
193
+ account-failed = "auto"
194
drive-type = "144"
195
dev: floppy, id ""
196
unit = 0 (0x0)
197
@@ -XXX,XX +XXX,XX @@ Testing: -drive if=floppy,file=TEST_DIR/t.qcow2,index=1
198
discard_granularity = 4294967295 (4 GiB)
199
write-cache = "auto"
200
share-rw = false
201
+ account-invalid = "auto"
202
+ account-failed = "auto"
203
drive-type = "288"
204
floppy1 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2)
205
Attached to: /machine/unattached/device[N]
206
@@ -XXX,XX +XXX,XX @@ Testing: -drive if=floppy,file=TEST_DIR/t.qcow2 -drive if=floppy,file=TEST_DIR/t
207
discard_granularity = 4294967295 (4 GiB)
208
write-cache = "auto"
209
share-rw = false
210
+ account-invalid = "auto"
211
+ account-failed = "auto"
212
drive-type = "144"
213
dev: floppy, id ""
214
unit = 0 (0x0)
215
@@ -XXX,XX +XXX,XX @@ Testing: -drive if=floppy,file=TEST_DIR/t.qcow2 -drive if=floppy,file=TEST_DIR/t
216
discard_granularity = 4294967295 (4 GiB)
217
write-cache = "auto"
218
share-rw = false
219
+ account-invalid = "auto"
220
+ account-failed = "auto"
221
drive-type = "144"
222
floppy0 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2)
223
Attached to: /machine/unattached/device[N]
224
@@ -XXX,XX +XXX,XX @@ Testing: -drive if=none,file=TEST_DIR/t.qcow2 -device floppy,drive=none0
225
discard_granularity = 4294967295 (4 GiB)
226
write-cache = "auto"
227
share-rw = false
228
+ account-invalid = "auto"
229
+ account-failed = "auto"
230
drive-type = "144"
231
none0 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2)
232
Attached to: /machine/peripheral-anon/device[N]
233
@@ -XXX,XX +XXX,XX @@ Testing: -drive if=none,file=TEST_DIR/t.qcow2 -device floppy,drive=none0,unit=1
234
discard_granularity = 4294967295 (4 GiB)
235
write-cache = "auto"
236
share-rw = false
237
+ account-invalid = "auto"
238
+ account-failed = "auto"
239
drive-type = "144"
240
none0 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2)
241
Attached to: /machine/peripheral-anon/device[N]
242
@@ -XXX,XX +XXX,XX @@ Testing: -drive if=none,file=TEST_DIR/t.qcow2 -drive if=none,file=TEST_DIR/t.qco
243
discard_granularity = 4294967295 (4 GiB)
244
write-cache = "auto"
245
share-rw = false
246
+ account-invalid = "auto"
247
+ account-failed = "auto"
248
drive-type = "144"
249
dev: floppy, id ""
250
unit = 0 (0x0)
251
@@ -XXX,XX +XXX,XX @@ Testing: -drive if=none,file=TEST_DIR/t.qcow2 -drive if=none,file=TEST_DIR/t.qco
252
discard_granularity = 4294967295 (4 GiB)
253
write-cache = "auto"
254
share-rw = false
255
+ account-invalid = "auto"
256
+ account-failed = "auto"
257
drive-type = "144"
258
none0 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2)
259
Attached to: /machine/peripheral-anon/device[N]
260
@@ -XXX,XX +XXX,XX @@ Testing: -fda TEST_DIR/t.qcow2 -drive if=none,file=TEST_DIR/t.qcow2.2 -device fl
261
discard_granularity = 4294967295 (4 GiB)
262
write-cache = "auto"
263
share-rw = false
264
+ account-invalid = "auto"
265
+ account-failed = "auto"
266
drive-type = "144"
267
dev: floppy, id ""
268
unit = 0 (0x0)
269
@@ -XXX,XX +XXX,XX @@ Testing: -fda TEST_DIR/t.qcow2 -drive if=none,file=TEST_DIR/t.qcow2.2 -device fl
270
discard_granularity = 4294967295 (4 GiB)
271
write-cache = "auto"
272
share-rw = false
273
+ account-invalid = "auto"
274
+ account-failed = "auto"
275
drive-type = "144"
276
floppy0 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2)
277
Attached to: /machine/unattached/device[N]
278
@@ -XXX,XX +XXX,XX @@ Testing: -fda TEST_DIR/t.qcow2 -drive if=none,file=TEST_DIR/t.qcow2.2 -device fl
279
discard_granularity = 4294967295 (4 GiB)
280
write-cache = "auto"
281
share-rw = false
282
+ account-invalid = "auto"
283
+ account-failed = "auto"
284
drive-type = "144"
285
dev: floppy, id ""
286
unit = 0 (0x0)
287
@@ -XXX,XX +XXX,XX @@ Testing: -fda TEST_DIR/t.qcow2 -drive if=none,file=TEST_DIR/t.qcow2.2 -device fl
288
discard_granularity = 4294967295 (4 GiB)
289
write-cache = "auto"
290
share-rw = false
291
+ account-invalid = "auto"
292
+ account-failed = "auto"
293
drive-type = "144"
294
floppy0 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2)
295
Attached to: /machine/unattached/device[N]
296
@@ -XXX,XX +XXX,XX @@ Testing: -fdb TEST_DIR/t.qcow2 -drive if=none,file=TEST_DIR/t.qcow2.2 -device fl
297
discard_granularity = 4294967295 (4 GiB)
298
write-cache = "auto"
299
share-rw = false
300
+ account-invalid = "auto"
301
+ account-failed = "auto"
302
drive-type = "144"
303
dev: floppy, id ""
304
unit = 1 (0x1)
305
@@ -XXX,XX +XXX,XX @@ Testing: -fdb TEST_DIR/t.qcow2 -drive if=none,file=TEST_DIR/t.qcow2.2 -device fl
306
discard_granularity = 4294967295 (4 GiB)
307
write-cache = "auto"
308
share-rw = false
309
+ account-invalid = "auto"
310
+ account-failed = "auto"
311
drive-type = "144"
312
floppy1 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2)
313
Attached to: /machine/unattached/device[N]
314
@@ -XXX,XX +XXX,XX @@ Testing: -fdb TEST_DIR/t.qcow2 -drive if=none,file=TEST_DIR/t.qcow2.2 -device fl
315
discard_granularity = 4294967295 (4 GiB)
316
write-cache = "auto"
317
share-rw = false
318
+ account-invalid = "auto"
319
+ account-failed = "auto"
320
drive-type = "144"
321
dev: floppy, id ""
322
unit = 1 (0x1)
323
@@ -XXX,XX +XXX,XX @@ Testing: -fdb TEST_DIR/t.qcow2 -drive if=none,file=TEST_DIR/t.qcow2.2 -device fl
324
discard_granularity = 4294967295 (4 GiB)
325
write-cache = "auto"
326
share-rw = false
327
+ account-invalid = "auto"
328
+ account-failed = "auto"
329
drive-type = "144"
330
floppy1 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2)
331
Attached to: /machine/unattached/device[N]
332
@@ -XXX,XX +XXX,XX @@ Testing: -drive if=floppy,file=TEST_DIR/t.qcow2 -drive if=none,file=TEST_DIR/t.q
333
discard_granularity = 4294967295 (4 GiB)
334
write-cache = "auto"
335
share-rw = false
336
+ account-invalid = "auto"
337
+ account-failed = "auto"
338
drive-type = "144"
339
dev: floppy, id ""
340
unit = 0 (0x0)
341
@@ -XXX,XX +XXX,XX @@ Testing: -drive if=floppy,file=TEST_DIR/t.qcow2 -drive if=none,file=TEST_DIR/t.q
342
discard_granularity = 4294967295 (4 GiB)
343
write-cache = "auto"
344
share-rw = false
345
+ account-invalid = "auto"
346
+ account-failed = "auto"
347
drive-type = "144"
348
floppy0 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2)
349
Attached to: /machine/unattached/device[N]
350
@@ -XXX,XX +XXX,XX @@ Testing: -drive if=floppy,file=TEST_DIR/t.qcow2 -drive if=none,file=TEST_DIR/t.q
351
discard_granularity = 4294967295 (4 GiB)
352
write-cache = "auto"
353
share-rw = false
354
+ account-invalid = "auto"
355
+ account-failed = "auto"
356
drive-type = "144"
357
dev: floppy, id ""
358
unit = 0 (0x0)
359
@@ -XXX,XX +XXX,XX @@ Testing: -drive if=floppy,file=TEST_DIR/t.qcow2 -drive if=none,file=TEST_DIR/t.q
360
discard_granularity = 4294967295 (4 GiB)
361
write-cache = "auto"
362
share-rw = false
363
+ account-invalid = "auto"
364
+ account-failed = "auto"
365
drive-type = "144"
366
floppy0 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2)
367
Attached to: /machine/unattached/device[N]
368
@@ -XXX,XX +XXX,XX @@ Testing: -drive if=none,file=TEST_DIR/t.qcow2 -global floppy.drive=none0 -device
369
discard_granularity = 4294967295 (4 GiB)
370
write-cache = "auto"
371
share-rw = false
372
+ account-invalid = "auto"
373
+ account-failed = "auto"
374
drive-type = "144"
375
none0 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2)
376
Attached to: /machine/peripheral-anon/device[N]
377
@@ -XXX,XX +XXX,XX @@ Testing: -device floppy
378
discard_granularity = 4294967295 (4 GiB)
379
write-cache = "auto"
380
share-rw = false
381
+ account-invalid = "auto"
382
+ account-failed = "auto"
383
drive-type = "288"
384
385
Testing: -device floppy,drive-type=120
386
@@ -XXX,XX +XXX,XX @@ Testing: -device floppy,drive-type=120
387
discard_granularity = 4294967295 (4 GiB)
388
write-cache = "auto"
389
share-rw = false
390
+ account-invalid = "auto"
391
+ account-failed = "auto"
392
drive-type = "120"
393
394
Testing: -device floppy,drive-type=144
395
@@ -XXX,XX +XXX,XX @@ Testing: -device floppy,drive-type=144
396
discard_granularity = 4294967295 (4 GiB)
397
write-cache = "auto"
398
share-rw = false
399
+ account-invalid = "auto"
400
+ account-failed = "auto"
401
drive-type = "144"
402
403
Testing: -device floppy,drive-type=288
404
@@ -XXX,XX +XXX,XX @@ Testing: -device floppy,drive-type=288
405
discard_granularity = 4294967295 (4 GiB)
406
write-cache = "auto"
407
share-rw = false
408
+ account-invalid = "auto"
409
+ account-failed = "auto"
410
drive-type = "288"
411
412
413
@@ -XXX,XX +XXX,XX @@ Testing: -drive if=none,file=TEST_DIR/t.qcow2 -device floppy,drive=none0,drive-t
414
discard_granularity = 4294967295 (4 GiB)
415
write-cache = "auto"
416
share-rw = false
417
+ account-invalid = "auto"
418
+ account-failed = "auto"
419
drive-type = "120"
420
none0 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2)
421
Attached to: /machine/peripheral-anon/device[N]
422
@@ -XXX,XX +XXX,XX @@ Testing: -drive if=none,file=TEST_DIR/t.qcow2 -device floppy,drive=none0,drive-t
423
discard_granularity = 4294967295 (4 GiB)
424
write-cache = "auto"
425
share-rw = false
426
+ account-invalid = "auto"
427
+ account-failed = "auto"
428
drive-type = "288"
429
none0 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2)
430
Attached to: /machine/peripheral-anon/device[N]
431
@@ -XXX,XX +XXX,XX @@ Testing: -drive if=none,file=TEST_DIR/t.qcow2 -device floppy,drive=none0,logical
432
discard_granularity = 4294967295 (4 GiB)
433
write-cache = "auto"
434
share-rw = false
435
+ account-invalid = "auto"
436
+ account-failed = "auto"
437
drive-type = "144"
438
none0 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2)
439
Attached to: /machine/peripheral-anon/device[N]
440
@@ -XXX,XX +XXX,XX @@ Testing: -drive if=none,file=TEST_DIR/t.qcow2 -device floppy,drive=none0,physica
441
discard_granularity = 4294967295 (4 GiB)
442
write-cache = "auto"
443
share-rw = false
444
+ account-invalid = "auto"
445
+ account-failed = "auto"
446
drive-type = "144"
447
none0 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2)
448
Attached to: /machine/peripheral-anon/device[N]
449
diff --git a/tests/qemu-iotests/227.out b/tests/qemu-iotests/227.out
450
index XXXXXXX..XXXXXXX 100644
451
--- a/tests/qemu-iotests/227.out
452
+++ b/tests/qemu-iotests/227.out
453
@@ -XXX,XX +XXX,XX @@ Testing: -blockdev driver=null-co,read-zeroes=on,node-name=null -device virtio-b
454
],
455
"failed_unmap_operations": 0,
456
"failed_flush_operations": 0,
457
- "account_invalid": false,
458
+ "account_invalid": true,
459
"rd_total_time_ns": 0,
460
"invalid_unmap_operations": 0,
461
"flush_operations": 0,
462
@@ -XXX,XX +XXX,XX @@ Testing: -blockdev driver=null-co,read-zeroes=on,node-name=null -device virtio-b
463
"rd_bytes": 0,
464
"unmap_total_time_ns": 0,
465
"invalid_flush_operations": 0,
466
- "account_failed": false,
467
+ "account_failed": true,
468
"rd_operations": 0,
469
"invalid_wr_operations": 0,
470
"invalid_rd_operations": 0
136
--
471
--
137
2.25.3
472
2.37.3
138
139
diff view generated by jsdifflib
1
This adds a new BdrvRequestFlags parameter to the .bdrv_co_truncate()
1
From: "Denis V. Lunev" <den@openvz.org>
2
driver callbacks, and a supported_truncate_flags field in
3
BlockDriverState that allows drivers to advertise support for request
4
flags in the context of truncate.
5
2
6
For now, we always pass 0 and no drivers declare support for any flag.
3
I believe that if the helper exists, it must be used always for reading
4
of the value. It breaks expectations in the other case.
7
5
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
Signed-off-by: Denis V. Lunev <den@openvz.org>
9
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
7
CC: Kevin Wolf <kwolf@redhat.com>
10
Reviewed-by: Alberto Garcia <berto@igalia.com>
8
CC: Hanna Reitz <hreitz@redhat.com>
11
Reviewed-by: Max Reitz <mreitz@redhat.com>
9
CC: Stefan Hajnoczi <stefanha@redhat.com>
12
Message-Id: <20200424125448.63318-2-kwolf@redhat.com>
10
CC: Fam Zheng <fam@euphon.net>
11
CC: Ronnie Sahlberg <ronniesahlberg@gmail.com>
12
CC: Paolo Bonzini <pbonzini@redhat.com>
13
CC: Peter Lieven <pl@kamp.de>
14
CC: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
15
Message-Id: <20220817083736.40981-2-den@openvz.org>
16
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
17
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
13
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
18
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
---
19
---
15
include/block/block_int.h | 10 +++++++++-
20
block/file-posix.c | 2 +-
16
block/crypto.c | 3 ++-
21
block/iscsi.c | 2 +-
17
block/file-posix.c | 2 +-
22
block/raw-format.c | 4 ++--
18
block/file-win32.c | 2 +-
23
3 files changed, 4 insertions(+), 4 deletions(-)
19
block/gluster.c | 1 +
20
block/io.c | 8 +++++++-
21
block/iscsi.c | 2 +-
22
block/nfs.c | 3 ++-
23
block/qcow2.c | 2 +-
24
block/qed.c | 1 +
25
block/raw-format.c | 2 +-
26
block/rbd.c | 1 +
27
block/sheepdog.c | 4 ++--
28
block/ssh.c | 2 +-
29
tests/test-block-iothread.c | 3 ++-
30
15 files changed, 33 insertions(+), 13 deletions(-)
31
24
32
diff --git a/include/block/block_int.h b/include/block/block_int.h
33
index XXXXXXX..XXXXXXX 100644
34
--- a/include/block/block_int.h
35
+++ b/include/block/block_int.h
36
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
37
*/
38
int coroutine_fn (*bdrv_co_truncate)(BlockDriverState *bs, int64_t offset,
39
bool exact, PreallocMode prealloc,
40
- Error **errp);
41
+ BdrvRequestFlags flags, Error **errp);
42
43
int64_t (*bdrv_getlength)(BlockDriverState *bs);
44
bool has_variable_length;
45
@@ -XXX,XX +XXX,XX @@ struct BlockDriverState {
46
/* Flags honored during pwrite_zeroes (so far: BDRV_REQ_FUA,
47
* BDRV_REQ_MAY_UNMAP, BDRV_REQ_WRITE_UNCHANGED) */
48
unsigned int supported_zero_flags;
49
+ /*
50
+ * Flags honoured during truncate (so far: BDRV_REQ_ZERO_WRITE).
51
+ *
52
+ * If BDRV_REQ_ZERO_WRITE is given, the truncate operation must make sure
53
+ * that any added space reads as all zeros. If this can't be guaranteed,
54
+ * the operation must fail.
55
+ */
56
+ unsigned int supported_truncate_flags;
57
58
/* the following member gives a name to every node on the bs graph. */
59
char node_name[32];
60
diff --git a/block/crypto.c b/block/crypto.c
61
index XXXXXXX..XXXXXXX 100644
62
--- a/block/crypto.c
63
+++ b/block/crypto.c
64
@@ -XXX,XX +XXX,XX @@ static int block_crypto_co_create_generic(BlockDriverState *bs,
65
66
static int coroutine_fn
67
block_crypto_co_truncate(BlockDriverState *bs, int64_t offset, bool exact,
68
- PreallocMode prealloc, Error **errp)
69
+ PreallocMode prealloc, BdrvRequestFlags flags,
70
+ Error **errp)
71
{
72
BlockCrypto *crypto = bs->opaque;
73
uint64_t payload_offset =
74
diff --git a/block/file-posix.c b/block/file-posix.c
25
diff --git a/block/file-posix.c b/block/file-posix.c
75
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
76
--- a/block/file-posix.c
27
--- a/block/file-posix.c
77
+++ b/block/file-posix.c
28
+++ b/block/file-posix.c
78
@@ -XXX,XX +XXX,XX @@ raw_regular_truncate(BlockDriverState *bs, int fd, int64_t offset,
29
@@ -XXX,XX +XXX,XX @@ static void raw_refresh_limits(BlockDriverState *bs, Error **errp)
79
80
static int coroutine_fn raw_co_truncate(BlockDriverState *bs, int64_t offset,
81
bool exact, PreallocMode prealloc,
82
- Error **errp)
83
+ BdrvRequestFlags flags, Error **errp)
84
{
85
BDRVRawState *s = bs->opaque;
86
struct stat st;
87
diff --git a/block/file-win32.c b/block/file-win32.c
88
index XXXXXXX..XXXXXXX 100644
89
--- a/block/file-win32.c
90
+++ b/block/file-win32.c
91
@@ -XXX,XX +XXX,XX @@ static void raw_close(BlockDriverState *bs)
92
93
static int coroutine_fn raw_co_truncate(BlockDriverState *bs, int64_t offset,
94
bool exact, PreallocMode prealloc,
95
- Error **errp)
96
+ BdrvRequestFlags flags, Error **errp)
97
{
98
BDRVRawState *s = bs->opaque;
99
LONG low, high;
100
diff --git a/block/gluster.c b/block/gluster.c
101
index XXXXXXX..XXXXXXX 100644
102
--- a/block/gluster.c
103
+++ b/block/gluster.c
104
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int qemu_gluster_co_truncate(BlockDriverState *bs,
105
int64_t offset,
106
bool exact,
107
PreallocMode prealloc,
108
+ BdrvRequestFlags flags,
109
Error **errp)
110
{
111
BDRVGlusterState *s = bs->opaque;
112
diff --git a/block/io.c b/block/io.c
113
index XXXXXXX..XXXXXXX 100644
114
--- a/block/io.c
115
+++ b/block/io.c
116
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact,
117
BlockDriverState *bs = child->bs;
118
BlockDriver *drv = bs->drv;
119
BdrvTrackedRequest req;
120
+ BdrvRequestFlags flags = 0;
121
int64_t old_size, new_bytes;
122
int ret;
123
124
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact,
125
}
30
}
126
31
#endif
127
if (drv->bdrv_co_truncate) {
32
128
- ret = drv->bdrv_co_truncate(bs, offset, exact, prealloc, errp);
33
- if (bs->sg || S_ISBLK(st.st_mode)) {
129
+ if (flags & ~bs->supported_truncate_flags) {
34
+ if (bdrv_is_sg(bs) || S_ISBLK(st.st_mode)) {
130
+ error_setg(errp, "Block driver does not support requested flags");
35
int ret = hdev_get_max_hw_transfer(s->fd, &st);
131
+ ret = -ENOTSUP;
36
132
+ goto out;
37
if (ret > 0 && ret <= BDRV_REQUEST_MAX_BYTES) {
133
+ }
134
+ ret = drv->bdrv_co_truncate(bs, offset, exact, prealloc, flags, errp);
135
} else if (bs->file && drv->is_filter) {
136
ret = bdrv_co_truncate(bs->file, offset, exact, prealloc, errp);
137
} else {
138
diff --git a/block/iscsi.c b/block/iscsi.c
38
diff --git a/block/iscsi.c b/block/iscsi.c
139
index XXXXXXX..XXXXXXX 100644
39
index XXXXXXX..XXXXXXX 100644
140
--- a/block/iscsi.c
40
--- a/block/iscsi.c
141
+++ b/block/iscsi.c
41
+++ b/block/iscsi.c
142
@@ -XXX,XX +XXX,XX @@ static void iscsi_reopen_commit(BDRVReopenState *reopen_state)
42
@@ -XXX,XX +XXX,XX @@ static void iscsi_refresh_limits(BlockDriverState *bs, Error **errp)
143
43
uint64_t max_xfer_len = iscsilun->use_16_for_rw ? 0xffffffff : 0xffff;
144
static int coroutine_fn iscsi_co_truncate(BlockDriverState *bs, int64_t offset,
44
unsigned int block_size = MAX(BDRV_SECTOR_SIZE, iscsilun->block_size);
145
bool exact, PreallocMode prealloc,
45
146
- Error **errp)
46
- assert(iscsilun->block_size >= BDRV_SECTOR_SIZE || bs->sg);
147
+ BdrvRequestFlags flags, Error **errp)
47
+ assert(iscsilun->block_size >= BDRV_SECTOR_SIZE || bdrv_is_sg(bs));
148
{
48
149
IscsiLun *iscsilun = bs->opaque;
49
bs->bl.request_alignment = block_size;
150
int64_t cur_length;
50
151
diff --git a/block/nfs.c b/block/nfs.c
152
index XXXXXXX..XXXXXXX 100644
153
--- a/block/nfs.c
154
+++ b/block/nfs.c
155
@@ -XXX,XX +XXX,XX @@ static int64_t nfs_get_allocated_file_size(BlockDriverState *bs)
156
157
static int coroutine_fn
158
nfs_file_co_truncate(BlockDriverState *bs, int64_t offset, bool exact,
159
- PreallocMode prealloc, Error **errp)
160
+ PreallocMode prealloc, BdrvRequestFlags flags,
161
+ Error **errp)
162
{
163
NFSClient *client = bs->opaque;
164
int ret;
165
diff --git a/block/qcow2.c b/block/qcow2.c
166
index XXXXXXX..XXXXXXX 100644
167
--- a/block/qcow2.c
168
+++ b/block/qcow2.c
169
@@ -XXX,XX +XXX,XX @@ fail:
170
171
static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
172
bool exact, PreallocMode prealloc,
173
- Error **errp)
174
+ BdrvRequestFlags flags, Error **errp)
175
{
176
BDRVQcow2State *s = bs->opaque;
177
uint64_t old_length;
178
diff --git a/block/qed.c b/block/qed.c
179
index XXXXXXX..XXXXXXX 100644
180
--- a/block/qed.c
181
+++ b/block/qed.c
182
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_qed_co_truncate(BlockDriverState *bs,
183
int64_t offset,
184
bool exact,
185
PreallocMode prealloc,
186
+ BdrvRequestFlags flags,
187
Error **errp)
188
{
189
BDRVQEDState *s = bs->opaque;
190
diff --git a/block/raw-format.c b/block/raw-format.c
51
diff --git a/block/raw-format.c b/block/raw-format.c
191
index XXXXXXX..XXXXXXX 100644
52
index XXXXXXX..XXXXXXX 100644
192
--- a/block/raw-format.c
53
--- a/block/raw-format.c
193
+++ b/block/raw-format.c
54
+++ b/block/raw-format.c
194
@@ -XXX,XX +XXX,XX @@ static void raw_refresh_limits(BlockDriverState *bs, Error **errp)
55
@@ -XXX,XX +XXX,XX @@ static int raw_open(BlockDriverState *bs, QDict *options, int flags,
195
56
return -EINVAL;
196
static int coroutine_fn raw_co_truncate(BlockDriverState *bs, int64_t offset,
57
}
197
bool exact, PreallocMode prealloc,
58
198
- Error **errp)
59
- bs->sg = bs->file->bs->sg;
199
+ BdrvRequestFlags flags, Error **errp)
60
+ bs->sg = bdrv_is_sg(bs->file->bs);
200
{
61
bs->supported_write_flags = BDRV_REQ_WRITE_UNCHANGED |
201
BDRVRawState *s = bs->opaque;
62
(BDRV_REQ_FUA & bs->file->bs->supported_write_flags);
202
63
bs->supported_zero_flags = BDRV_REQ_WRITE_UNCHANGED |
203
diff --git a/block/rbd.c b/block/rbd.c
64
@@ -XXX,XX +XXX,XX @@ static int raw_open(BlockDriverState *bs, QDict *options, int flags,
204
index XXXXXXX..XXXXXXX 100644
65
return ret;
205
--- a/block/rbd.c
66
}
206
+++ b/block/rbd.c
67
207
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qemu_rbd_co_truncate(BlockDriverState *bs,
68
- if (bs->sg && (s->offset || s->has_size)) {
208
int64_t offset,
69
+ if (bdrv_is_sg(bs) && (s->offset || s->has_size)) {
209
bool exact,
70
error_setg(errp, "Cannot use offset/size with SCSI generic devices");
210
PreallocMode prealloc,
71
return -EINVAL;
211
+ BdrvRequestFlags flags,
72
}
212
Error **errp)
213
{
214
int r;
215
diff --git a/block/sheepdog.c b/block/sheepdog.c
216
index XXXXXXX..XXXXXXX 100644
217
--- a/block/sheepdog.c
218
+++ b/block/sheepdog.c
219
@@ -XXX,XX +XXX,XX @@ static int64_t sd_getlength(BlockDriverState *bs)
220
221
static int coroutine_fn sd_co_truncate(BlockDriverState *bs, int64_t offset,
222
bool exact, PreallocMode prealloc,
223
- Error **errp)
224
+ BdrvRequestFlags flags, Error **errp)
225
{
226
BDRVSheepdogState *s = bs->opaque;
227
int ret, fd;
228
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int sd_co_writev(BlockDriverState *bs, int64_t sector_num,
229
230
assert(!flags);
231
if (offset > s->inode.vdi_size) {
232
- ret = sd_co_truncate(bs, offset, false, PREALLOC_MODE_OFF, NULL);
233
+ ret = sd_co_truncate(bs, offset, false, PREALLOC_MODE_OFF, 0, NULL);
234
if (ret < 0) {
235
return ret;
236
}
237
diff --git a/block/ssh.c b/block/ssh.c
238
index XXXXXXX..XXXXXXX 100644
239
--- a/block/ssh.c
240
+++ b/block/ssh.c
241
@@ -XXX,XX +XXX,XX @@ static int64_t ssh_getlength(BlockDriverState *bs)
242
243
static int coroutine_fn ssh_co_truncate(BlockDriverState *bs, int64_t offset,
244
bool exact, PreallocMode prealloc,
245
- Error **errp)
246
+ BdrvRequestFlags flags, Error **errp)
247
{
248
BDRVSSHState *s = bs->opaque;
249
250
diff --git a/tests/test-block-iothread.c b/tests/test-block-iothread.c
251
index XXXXXXX..XXXXXXX 100644
252
--- a/tests/test-block-iothread.c
253
+++ b/tests/test-block-iothread.c
254
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_test_co_pdiscard(BlockDriverState *bs,
255
256
static int coroutine_fn
257
bdrv_test_co_truncate(BlockDriverState *bs, int64_t offset, bool exact,
258
- PreallocMode prealloc, Error **errp)
259
+ PreallocMode prealloc, BdrvRequestFlags flags,
260
+ Error **errp)
261
{
262
return 0;
263
}
264
--
73
--
265
2.25.3
74
2.37.3
266
267
diff view generated by jsdifflib
1
Now that block drivers can support flags for .bdrv_co_truncate, expose
1
From: "Denis V. Lunev" <den@openvz.org>
2
the parameter in the node level interfaces bdrv_co_truncate() and
3
bdrv_truncate().
4
2
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
3
Return codes of the following functions are never used in the code:
6
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
4
* bdrv_wait_serialising_requests_locked
7
Reviewed-by: Alberto Garcia <berto@igalia.com>
5
* bdrv_wait_serialising_requests
8
Reviewed-by: Max Reitz <mreitz@redhat.com>
6
* bdrv_make_request_serialising
9
Message-Id: <20200424125448.63318-3-kwolf@redhat.com>
7
8
Signed-off-by: Denis V. Lunev <den@openvz.org>
9
CC: Kevin Wolf <kwolf@redhat.com>
10
CC: Hanna Reitz <hreitz@redhat.com>
11
CC: Stefan Hajnoczi <stefanha@redhat.com>
12
CC: Fam Zheng <fam@euphon.net>
13
CC: Ronnie Sahlberg <ronniesahlberg@gmail.com>
14
CC: Paolo Bonzini <pbonzini@redhat.com>
15
CC: Peter Lieven <pl@kamp.de>
16
CC: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
17
Message-Id: <20220817083736.40981-3-den@openvz.org>
18
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
19
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
20
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
---
21
---
12
include/block/block.h | 5 +++--
22
include/block/block_int-io.h | 2 +-
13
block/block-backend.c | 2 +-
23
block/io.c | 23 +++++++----------------
14
block/crypto.c | 2 +-
24
2 files changed, 8 insertions(+), 17 deletions(-)
15
block/io.c | 12 +++++++-----
16
block/parallels.c | 6 +++---
17
block/qcow.c | 4 ++--
18
block/qcow2-refcount.c | 2 +-
19
block/qcow2.c | 15 +++++++++------
20
block/raw-format.c | 2 +-
21
block/vhdx-log.c | 2 +-
22
block/vhdx.c | 2 +-
23
block/vmdk.c | 2 +-
24
tests/test-block-iothread.c | 6 +++---
25
13 files changed, 34 insertions(+), 28 deletions(-)
26
25
27
diff --git a/include/block/block.h b/include/block/block.h
26
diff --git a/include/block/block_int-io.h b/include/block/block_int-io.h
28
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
29
--- a/include/block/block.h
28
--- a/include/block/block_int-io.h
30
+++ b/include/block/block.h
29
+++ b/include/block/block_int-io.h
31
@@ -XXX,XX +XXX,XX @@ BlockDriverState *bdrv_find_backing_image(BlockDriverState *bs,
30
@@ -XXX,XX +XXX,XX @@ static inline int coroutine_fn bdrv_co_pwrite(BdrvChild *child,
32
void bdrv_refresh_filename(BlockDriverState *bs);
31
return bdrv_co_pwritev(child, offset, bytes, &qiov, flags);
33
34
int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact,
35
- PreallocMode prealloc, Error **errp);
36
+ PreallocMode prealloc, BdrvRequestFlags flags,
37
+ Error **errp);
38
int bdrv_truncate(BdrvChild *child, int64_t offset, bool exact,
39
- PreallocMode prealloc, Error **errp);
40
+ PreallocMode prealloc, BdrvRequestFlags flags, Error **errp);
41
42
int64_t bdrv_nb_sectors(BlockDriverState *bs);
43
int64_t bdrv_getlength(BlockDriverState *bs);
44
diff --git a/block/block-backend.c b/block/block-backend.c
45
index XXXXXXX..XXXXXXX 100644
46
--- a/block/block-backend.c
47
+++ b/block/block-backend.c
48
@@ -XXX,XX +XXX,XX @@ int blk_truncate(BlockBackend *blk, int64_t offset, bool exact,
49
return -ENOMEDIUM;
50
}
51
52
- return bdrv_truncate(blk->root, offset, exact, prealloc, errp);
53
+ return bdrv_truncate(blk->root, offset, exact, prealloc, 0, errp);
54
}
32
}
55
33
56
int blk_save_vmstate(BlockBackend *blk, const uint8_t *buf,
34
-bool coroutine_fn bdrv_make_request_serialising(BdrvTrackedRequest *req,
57
diff --git a/block/crypto.c b/block/crypto.c
35
+void coroutine_fn bdrv_make_request_serialising(BdrvTrackedRequest *req,
58
index XXXXXXX..XXXXXXX 100644
36
uint64_t align);
59
--- a/block/crypto.c
37
BdrvTrackedRequest *coroutine_fn bdrv_co_get_self_request(BlockDriverState *bs);
60
+++ b/block/crypto.c
38
61
@@ -XXX,XX +XXX,XX @@ block_crypto_co_truncate(BlockDriverState *bs, int64_t offset, bool exact,
62
63
offset += payload_offset;
64
65
- return bdrv_co_truncate(bs->file, offset, exact, prealloc, errp);
66
+ return bdrv_co_truncate(bs->file, offset, exact, prealloc, 0, errp);
67
}
68
69
static void block_crypto_close(BlockDriverState *bs)
70
diff --git a/block/io.c b/block/io.c
39
diff --git a/block/io.c b/block/io.c
71
index XXXXXXX..XXXXXXX 100644
40
index XXXXXXX..XXXXXXX 100644
72
--- a/block/io.c
41
--- a/block/io.c
73
+++ b/block/io.c
42
+++ b/block/io.c
74
@@ -XXX,XX +XXX,XX @@ static void bdrv_parent_cb_resize(BlockDriverState *bs)
43
@@ -XXX,XX +XXX,XX @@ bdrv_find_conflicting_request(BdrvTrackedRequest *self)
75
* 'offset' bytes in length.
44
}
76
*/
45
77
int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact,
46
/* Called with self->bs->reqs_lock held */
78
- PreallocMode prealloc, Error **errp)
47
-static bool coroutine_fn
79
+ PreallocMode prealloc, BdrvRequestFlags flags,
48
+static void coroutine_fn
80
+ Error **errp)
49
bdrv_wait_serialising_requests_locked(BdrvTrackedRequest *self)
81
{
50
{
82
BlockDriverState *bs = child->bs;
51
BdrvTrackedRequest *req;
83
BlockDriver *drv = bs->drv;
52
- bool waited = false;
84
BdrvTrackedRequest req;
53
85
- BdrvRequestFlags flags = 0;
54
while ((req = bdrv_find_conflicting_request(self))) {
86
int64_t old_size, new_bytes;
55
self->waiting_for = req;
87
int ret;
56
qemu_co_queue_wait(&req->wait_queue, &self->bs->reqs_lock);
88
57
self->waiting_for = NULL;
89
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact,
58
- waited = true;
90
}
59
}
91
ret = drv->bdrv_co_truncate(bs, offset, exact, prealloc, flags, errp);
60
-
92
} else if (bs->file && drv->is_filter) {
61
- return waited;
93
- ret = bdrv_co_truncate(bs->file, offset, exact, prealloc, errp);
62
}
94
+ ret = bdrv_co_truncate(bs->file, offset, exact, prealloc, flags, errp);
63
95
} else {
64
/* Called with req->bs->reqs_lock held */
96
error_setg(errp, "Image format driver does not support resize");
65
@@ -XXX,XX +XXX,XX @@ void bdrv_dec_in_flight(BlockDriverState *bs)
97
ret = -ENOTSUP;
66
bdrv_wakeup(bs);
98
@@ -XXX,XX +XXX,XX @@ typedef struct TruncateCo {
67
}
99
int64_t offset;
68
100
bool exact;
69
-static bool coroutine_fn bdrv_wait_serialising_requests(BdrvTrackedRequest *self)
101
PreallocMode prealloc;
70
+static void coroutine_fn
102
+ BdrvRequestFlags flags;
71
+bdrv_wait_serialising_requests(BdrvTrackedRequest *self)
103
Error **errp;
104
int ret;
105
} TruncateCo;
106
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn bdrv_truncate_co_entry(void *opaque)
107
{
72
{
108
TruncateCo *tco = opaque;
73
BlockDriverState *bs = self->bs;
109
tco->ret = bdrv_co_truncate(tco->child, tco->offset, tco->exact,
74
- bool waited = false;
110
- tco->prealloc, tco->errp);
75
111
+ tco->prealloc, tco->flags, tco->errp);
76
if (!qatomic_read(&bs->serialising_in_flight)) {
112
aio_wait_kick();
77
- return false;
78
+ return;
79
}
80
81
qemu_co_mutex_lock(&bs->reqs_lock);
82
- waited = bdrv_wait_serialising_requests_locked(self);
83
+ bdrv_wait_serialising_requests_locked(self);
84
qemu_co_mutex_unlock(&bs->reqs_lock);
85
-
86
- return waited;
113
}
87
}
114
88
115
int bdrv_truncate(BdrvChild *child, int64_t offset, bool exact,
89
-bool coroutine_fn bdrv_make_request_serialising(BdrvTrackedRequest *req,
116
- PreallocMode prealloc, Error **errp)
90
+void coroutine_fn bdrv_make_request_serialising(BdrvTrackedRequest *req,
117
+ PreallocMode prealloc, BdrvRequestFlags flags, Error **errp)
91
uint64_t align)
118
{
92
{
119
Coroutine *co;
93
- bool waited;
120
TruncateCo tco = {
94
IO_CODE();
121
@@ -XXX,XX +XXX,XX @@ int bdrv_truncate(BdrvChild *child, int64_t offset, bool exact,
95
122
.offset = offset,
96
qemu_co_mutex_lock(&req->bs->reqs_lock);
123
.exact = exact,
97
124
.prealloc = prealloc,
98
tracked_request_set_serialising(req, align);
125
+ .flags = flags,
99
- waited = bdrv_wait_serialising_requests_locked(req);
126
.errp = errp,
100
+ bdrv_wait_serialising_requests_locked(req);
127
.ret = NOT_DONE,
101
128
};
102
qemu_co_mutex_unlock(&req->bs->reqs_lock);
129
diff --git a/block/parallels.c b/block/parallels.c
103
-
130
index XXXXXXX..XXXXXXX 100644
104
- return waited;
131
--- a/block/parallels.c
132
+++ b/block/parallels.c
133
@@ -XXX,XX +XXX,XX @@ static int64_t allocate_clusters(BlockDriverState *bs, int64_t sector_num,
134
} else {
135
ret = bdrv_truncate(bs->file,
136
(s->data_end + space) << BDRV_SECTOR_BITS,
137
- false, PREALLOC_MODE_OFF, NULL);
138
+ false, PREALLOC_MODE_OFF, 0, NULL);
139
}
140
if (ret < 0) {
141
return ret;
142
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn parallels_co_check(BlockDriverState *bs,
143
* That means we have to pass exact=true.
144
*/
145
ret = bdrv_truncate(bs->file, res->image_end_offset, true,
146
- PREALLOC_MODE_OFF, &local_err);
147
+ PREALLOC_MODE_OFF, 0, &local_err);
148
if (ret < 0) {
149
error_report_err(local_err);
150
res->check_errors++;
151
@@ -XXX,XX +XXX,XX @@ static void parallels_close(BlockDriverState *bs)
152
153
/* errors are ignored, so we might as well pass exact=true */
154
bdrv_truncate(bs->file, s->data_end << BDRV_SECTOR_BITS, true,
155
- PREALLOC_MODE_OFF, NULL);
156
+ PREALLOC_MODE_OFF, 0, NULL);
157
}
158
159
g_free(s->bat_dirty_bmap);
160
diff --git a/block/qcow.c b/block/qcow.c
161
index XXXXXXX..XXXXXXX 100644
162
--- a/block/qcow.c
163
+++ b/block/qcow.c
164
@@ -XXX,XX +XXX,XX @@ static int get_cluster_offset(BlockDriverState *bs,
165
return -E2BIG;
166
}
167
ret = bdrv_truncate(bs->file, cluster_offset + s->cluster_size,
168
- false, PREALLOC_MODE_OFF, NULL);
169
+ false, PREALLOC_MODE_OFF, 0, NULL);
170
if (ret < 0) {
171
return ret;
172
}
173
@@ -XXX,XX +XXX,XX @@ static int qcow_make_empty(BlockDriverState *bs)
174
l1_length) < 0)
175
return -1;
176
ret = bdrv_truncate(bs->file, s->l1_table_offset + l1_length, false,
177
- PREALLOC_MODE_OFF, NULL);
178
+ PREALLOC_MODE_OFF, 0, NULL);
179
if (ret < 0)
180
return ret;
181
182
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
183
index XXXXXXX..XXXXXXX 100644
184
--- a/block/qcow2-refcount.c
185
+++ b/block/qcow2-refcount.c
186
@@ -XXX,XX +XXX,XX @@ static int check_refblocks(BlockDriverState *bs, BdrvCheckResult *res,
187
}
188
189
ret = bdrv_truncate(bs->file, offset + s->cluster_size, false,
190
- PREALLOC_MODE_OFF, &local_err);
191
+ PREALLOC_MODE_OFF, 0, &local_err);
192
if (ret < 0) {
193
error_report_err(local_err);
194
goto resize_fail;
195
diff --git a/block/qcow2.c b/block/qcow2.c
196
index XXXXXXX..XXXXXXX 100644
197
--- a/block/qcow2.c
198
+++ b/block/qcow2.c
199
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn preallocate_co(BlockDriverState *bs, uint64_t offset,
200
mode = PREALLOC_MODE_OFF;
201
}
202
ret = bdrv_co_truncate(s->data_file, host_offset + cur_bytes, false,
203
- mode, errp);
204
+ mode, 0, errp);
205
if (ret < 0) {
206
return ret;
207
}
208
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
209
* always fulfilled, so there is no need to pass it on.)
210
*/
211
bdrv_co_truncate(bs->file, (last_cluster + 1) * s->cluster_size,
212
- false, PREALLOC_MODE_OFF, &local_err);
213
+ false, PREALLOC_MODE_OFF, 0, &local_err);
214
if (local_err) {
215
warn_reportf_err(local_err,
216
"Failed to truncate the tail of the image: ");
217
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
218
* file should be resized to the exact target size, too,
219
* so we pass @exact here.
220
*/
221
- ret = bdrv_co_truncate(s->data_file, offset, exact, prealloc, errp);
222
+ ret = bdrv_co_truncate(s->data_file, offset, exact, prealloc, 0,
223
+ errp);
224
if (ret < 0) {
225
goto fail;
226
}
227
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
228
new_file_size = allocation_start +
229
nb_new_data_clusters * s->cluster_size;
230
/* Image file grows, so @exact does not matter */
231
- ret = bdrv_co_truncate(bs->file, new_file_size, false, prealloc, errp);
232
+ ret = bdrv_co_truncate(bs->file, new_file_size, false, prealloc, 0,
233
+ errp);
234
if (ret < 0) {
235
error_prepend(errp, "Failed to resize underlying file: ");
236
qcow2_free_clusters(bs, allocation_start,
237
@@ -XXX,XX +XXX,XX @@ qcow2_co_pwritev_compressed_part(BlockDriverState *bs,
238
if (len < 0) {
239
return len;
240
}
241
- return bdrv_co_truncate(bs->file, len, false, PREALLOC_MODE_OFF, NULL);
242
+ return bdrv_co_truncate(bs->file, len, false, PREALLOC_MODE_OFF, 0,
243
+ NULL);
244
}
245
246
if (offset_into_cluster(s, offset)) {
247
@@ -XXX,XX +XXX,XX @@ static int make_completely_empty(BlockDriverState *bs)
248
}
249
250
ret = bdrv_truncate(bs->file, (3 + l1_clusters) * s->cluster_size, false,
251
- PREALLOC_MODE_OFF, &local_err);
252
+ PREALLOC_MODE_OFF, 0, &local_err);
253
if (ret < 0) {
254
error_report_err(local_err);
255
goto fail;
256
diff --git a/block/raw-format.c b/block/raw-format.c
257
index XXXXXXX..XXXXXXX 100644
258
--- a/block/raw-format.c
259
+++ b/block/raw-format.c
260
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn raw_co_truncate(BlockDriverState *bs, int64_t offset,
261
262
s->size = offset;
263
offset += s->offset;
264
- return bdrv_co_truncate(bs->file, offset, exact, prealloc, errp);
265
+ return bdrv_co_truncate(bs->file, offset, exact, prealloc, 0, errp);
266
}
105
}
267
106
268
static void raw_eject(BlockDriverState *bs, bool eject_flag)
107
int bdrv_check_qiov_request(int64_t offset, int64_t bytes,
269
diff --git a/block/vhdx-log.c b/block/vhdx-log.c
270
index XXXXXXX..XXXXXXX 100644
271
--- a/block/vhdx-log.c
272
+++ b/block/vhdx-log.c
273
@@ -XXX,XX +XXX,XX @@ static int vhdx_log_flush(BlockDriverState *bs, BDRVVHDXState *s,
274
goto exit;
275
}
276
ret = bdrv_truncate(bs->file, new_file_size, false,
277
- PREALLOC_MODE_OFF, NULL);
278
+ PREALLOC_MODE_OFF, 0, NULL);
279
if (ret < 0) {
280
goto exit;
281
}
282
diff --git a/block/vhdx.c b/block/vhdx.c
283
index XXXXXXX..XXXXXXX 100644
284
--- a/block/vhdx.c
285
+++ b/block/vhdx.c
286
@@ -XXX,XX +XXX,XX @@ static int vhdx_allocate_block(BlockDriverState *bs, BDRVVHDXState *s,
287
}
288
289
return bdrv_truncate(bs->file, *new_offset + s->block_size, false,
290
- PREALLOC_MODE_OFF, NULL);
291
+ PREALLOC_MODE_OFF, 0, NULL);
292
}
293
294
/*
295
diff --git a/block/vmdk.c b/block/vmdk.c
296
index XXXXXXX..XXXXXXX 100644
297
--- a/block/vmdk.c
298
+++ b/block/vmdk.c
299
@@ -XXX,XX +XXX,XX @@ vmdk_co_pwritev_compressed(BlockDriverState *bs, uint64_t offset,
300
}
301
length = QEMU_ALIGN_UP(length, BDRV_SECTOR_SIZE);
302
ret = bdrv_truncate(s->extents[i].file, length, false,
303
- PREALLOC_MODE_OFF, NULL);
304
+ PREALLOC_MODE_OFF, 0, NULL);
305
if (ret < 0) {
306
return ret;
307
}
308
diff --git a/tests/test-block-iothread.c b/tests/test-block-iothread.c
309
index XXXXXXX..XXXXXXX 100644
310
--- a/tests/test-block-iothread.c
311
+++ b/tests/test-block-iothread.c
312
@@ -XXX,XX +XXX,XX @@ static void test_sync_op_truncate(BdrvChild *c)
313
int ret;
314
315
/* Normal success path */
316
- ret = bdrv_truncate(c, 65536, false, PREALLOC_MODE_OFF, NULL);
317
+ ret = bdrv_truncate(c, 65536, false, PREALLOC_MODE_OFF, 0, NULL);
318
g_assert_cmpint(ret, ==, 0);
319
320
/* Early error: Negative offset */
321
- ret = bdrv_truncate(c, -2, false, PREALLOC_MODE_OFF, NULL);
322
+ ret = bdrv_truncate(c, -2, false, PREALLOC_MODE_OFF, 0, NULL);
323
g_assert_cmpint(ret, ==, -EINVAL);
324
325
/* Error: Read-only image */
326
c->bs->read_only = true;
327
c->bs->open_flags &= ~BDRV_O_RDWR;
328
329
- ret = bdrv_truncate(c, 65536, false, PREALLOC_MODE_OFF, NULL);
330
+ ret = bdrv_truncate(c, 65536, false, PREALLOC_MODE_OFF, 0, NULL);
331
g_assert_cmpint(ret, ==, -EACCES);
332
333
c->bs->read_only = false;
334
--
108
--
335
2.25.3
109
2.37.3
336
337
diff view generated by jsdifflib
New patch
1
From: Stefan Hajnoczi <stefanha@redhat.com>
1
2
3
The gluster protocol driver used to parse URIs (filenames) but was
4
extended with a richer JSON syntax in commit 6c7189bb29de
5
("block/gluster: add support for multiple gluster servers"). The gluster
6
drivers that have JSON parsing set .bdrv_needs_filename to false.
7
8
The gluster+unix and gluster+rdma drivers still to require a filename
9
even though the JSON parser is equipped to parse the same
10
volume/path/sockaddr details as the URI parser. Let's allow JSON parsing
11
for these drivers too.
12
13
Note that the gluster+rdma driver actually uses TCP because RDMA support
14
is not available, so the JSON server.type field must be "inet".
15
16
Drop .bdrv_needs_filename since both the filename and the JSON parsers
17
can handle gluster+unix and gluster+rdma. This change is in preparation
18
for eventually removing .bdrv_needs_filename across the entire codebase.
19
20
Cc: Prasanna Kumar Kalever <prasanna.kalever@redhat.com>
21
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
22
Message-Id: <20220811164905.430834-1-stefanha@redhat.com>
23
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
24
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
25
---
26
block/gluster.c | 4 ----
27
1 file changed, 4 deletions(-)
28
29
diff --git a/block/gluster.c b/block/gluster.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/block/gluster.c
32
+++ b/block/gluster.c
33
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_gluster = {
34
.format_name = "gluster",
35
.protocol_name = "gluster",
36
.instance_size = sizeof(BDRVGlusterState),
37
- .bdrv_needs_filename = false,
38
.bdrv_file_open = qemu_gluster_open,
39
.bdrv_reopen_prepare = qemu_gluster_reopen_prepare,
40
.bdrv_reopen_commit = qemu_gluster_reopen_commit,
41
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_gluster_tcp = {
42
.format_name = "gluster",
43
.protocol_name = "gluster+tcp",
44
.instance_size = sizeof(BDRVGlusterState),
45
- .bdrv_needs_filename = false,
46
.bdrv_file_open = qemu_gluster_open,
47
.bdrv_reopen_prepare = qemu_gluster_reopen_prepare,
48
.bdrv_reopen_commit = qemu_gluster_reopen_commit,
49
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_gluster_unix = {
50
.format_name = "gluster",
51
.protocol_name = "gluster+unix",
52
.instance_size = sizeof(BDRVGlusterState),
53
- .bdrv_needs_filename = true,
54
.bdrv_file_open = qemu_gluster_open,
55
.bdrv_reopen_prepare = qemu_gluster_reopen_prepare,
56
.bdrv_reopen_commit = qemu_gluster_reopen_commit,
57
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_gluster_rdma = {
58
.format_name = "gluster",
59
.protocol_name = "gluster+rdma",
60
.instance_size = sizeof(BDRVGlusterState),
61
- .bdrv_needs_filename = true,
62
.bdrv_file_open = qemu_gluster_open,
63
.bdrv_reopen_prepare = qemu_gluster_reopen_prepare,
64
.bdrv_reopen_commit = qemu_gluster_reopen_commit,
65
--
66
2.37.3
diff view generated by jsdifflib
1
If BDRV_REQ_ZERO_WRITE is set and we're extending the image, calling
1
From: Hanna Reitz <hreitz@redhat.com>
2
qcow2_cluster_zeroize() with flags=0 does the right thing: It doesn't
3
undo any previous preallocation, but just adds the zero flag to all
4
relevant L2 entries. If an external data file is in use, a write_zeroes
5
request to the data file is made instead.
6
2
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
3
qcow2_do_open() is used by qcow2_co_invalidate_cache(), i.e. may be run
8
Message-Id: <20200424125448.63318-5-kwolf@redhat.com>
4
on an image that has been opened before. When reading the backing file
9
Reviewed-by: Eric Blake <eblake@redhat.com>
5
string from the image header, compare it against the existing
10
Reviewed-by: Max Reitz <mreitz@redhat.com>
6
bs->backing_file, and update bs->auto_backing_file only if they differ.
7
8
auto_backing_file should ideally contain the filename the backing BDS
9
will actually have after opening, i.e. a post-bdrv_refresh_filename()
10
version of what is in the image header. So for example, if the image
11
header reports the following backing file string:
12
13
json:{"driver": "qcow2", "file": {
14
"driver": "file", "filename": "/tmp/backing.qcow2"
15
}}
16
17
Then auto_backing_file should contain simply "/tmp/backing.qcow2".
18
19
Because bdrv_refresh_filename() only works on existing BDSs, though, the
20
way how we get this auto_backing_file value is to have the format driver
21
set it to whatever is in the image header, and when the backing BDS is
22
opened based on that, we update it with the filename the backing BDS
23
actually got.
24
25
However, qcow2's qcow2_co_invalidate_cache() implementation breaks this
26
because it just resets auto_backing_file to whatever is in the image
27
file without opening a BDS based on it, so we never get
28
auto_backing_file back to the "refreshed" version, and in the example
29
above, it would stay "json:{...}".
30
31
Then, bs->backing->bs->filename will differ from bs->auto_backing_file,
32
making bdrv_backing_overridden(bs) return true, which will lead
33
bdrv_refresh_filename(bs) to generate a json:{} filename for bs, even
34
though that may not have been necessary. This is reported in the issue
35
linked below.
36
37
Therefore, skip updating auto_backing_file if nothing has changed in the
38
image header since we last read it.
39
40
Fixes: https://gitlab.com/qemu-project/qemu/-/issues/1117
41
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
42
Message-Id: <20220803144446.20723-2-hreitz@redhat.com>
43
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
44
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
---
45
---
13
block/qcow2-cluster.c | 2 +-
46
block/qcow2.c | 21 ++++++++++++++++-----
14
block/qcow2.c | 34 ++++++++++++++++++++++++++++++++++
47
1 file changed, 16 insertions(+), 5 deletions(-)
15
2 files changed, 35 insertions(+), 1 deletion(-)
16
48
17
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/block/qcow2-cluster.c
20
+++ b/block/qcow2-cluster.c
21
@@ -XXX,XX +XXX,XX @@ int qcow2_cluster_zeroize(BlockDriverState *bs, uint64_t offset,
22
/* Caller must pass aligned values, except at image end */
23
assert(QEMU_IS_ALIGNED(offset, s->cluster_size));
24
assert(QEMU_IS_ALIGNED(end_offset, s->cluster_size) ||
25
- end_offset == bs->total_sectors << BDRV_SECTOR_BITS);
26
+ end_offset >= bs->total_sectors << BDRV_SECTOR_BITS);
27
28
/* The zero flag is only supported by version 3 and newer */
29
if (s->qcow_version < 3) {
30
diff --git a/block/qcow2.c b/block/qcow2.c
49
diff --git a/block/qcow2.c b/block/qcow2.c
31
index XXXXXXX..XXXXXXX 100644
50
index XXXXXXX..XXXXXXX 100644
32
--- a/block/qcow2.c
51
--- a/block/qcow2.c
33
+++ b/block/qcow2.c
52
+++ b/block/qcow2.c
34
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options,
53
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options,
35
54
ret = -EINVAL;
36
bs->supported_zero_flags = header.version >= 3 ?
55
goto fail;
37
BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK : 0;
56
}
38
+ bs->supported_truncate_flags = BDRV_REQ_ZERO_WRITE;
57
+
39
58
+ s->image_backing_file = g_malloc(len + 1);
40
/* Repair image if dirty */
59
ret = bdrv_pread(bs->file, header.backing_file_offset, len,
41
if (!(flags & (BDRV_O_CHECK | BDRV_O_INACTIVE)) && !bs->read_only &&
60
- bs->auto_backing_file, 0);
42
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
61
+ s->image_backing_file, 0);
43
g_assert_not_reached();
62
if (ret < 0) {
44
}
63
error_setg_errno(errp, -ret, "Could not read backing file name");
45
64
goto fail;
46
+ if ((flags & BDRV_REQ_ZERO_WRITE) && offset > old_length) {
65
}
47
+ uint64_t zero_start = QEMU_ALIGN_UP(old_length, s->cluster_size);
66
- bs->auto_backing_file[len] = '\0';
67
- pstrcpy(bs->backing_file, sizeof(bs->backing_file),
68
- bs->auto_backing_file);
69
- s->image_backing_file = g_strdup(bs->auto_backing_file);
70
+ s->image_backing_file[len] = '\0';
48
+
71
+
49
+ /*
72
+ /*
50
+ * Use zero clusters as much as we can. qcow2_cluster_zeroize()
73
+ * Update only when something has changed. This function is called by
51
+ * requires a cluster-aligned start. The end may be unaligned if it is
74
+ * qcow2_co_invalidate_cache(), and we do not want to reset
52
+ * at the end of the image (which it is here).
75
+ * auto_backing_file unless necessary.
53
+ */
76
+ */
54
+ ret = qcow2_cluster_zeroize(bs, zero_start, offset - zero_start, 0);
77
+ if (!g_str_equal(s->image_backing_file, bs->backing_file)) {
55
+ if (ret < 0) {
78
+ pstrcpy(bs->backing_file, sizeof(bs->backing_file),
56
+ error_setg_errno(errp, -ret, "Failed to zero out new clusters");
79
+ s->image_backing_file);
57
+ goto fail;
80
+ pstrcpy(bs->auto_backing_file, sizeof(bs->auto_backing_file),
81
+ s->image_backing_file);
58
+ }
82
+ }
59
+
83
}
60
+ /* Write explicit zeros for the unaligned head */
84
61
+ if (zero_start > old_length) {
85
/*
62
+ uint64_t len = zero_start - old_length;
63
+ uint8_t *buf = qemu_blockalign0(bs, len);
64
+ QEMUIOVector qiov;
65
+ qemu_iovec_init_buf(&qiov, buf, len);
66
+
67
+ qemu_co_mutex_unlock(&s->lock);
68
+ ret = qcow2_co_pwritev_part(bs, old_length, len, &qiov, 0, 0);
69
+ qemu_co_mutex_lock(&s->lock);
70
+
71
+ qemu_vfree(buf);
72
+ if (ret < 0) {
73
+ error_setg_errno(errp, -ret, "Failed to zero out the new area");
74
+ goto fail;
75
+ }
76
+ }
77
+ }
78
+
79
if (prealloc != PREALLOC_MODE_OFF) {
80
/* Flush metadata before actually changing the image size */
81
ret = qcow2_write_caches(bs);
82
--
86
--
83
2.25.3
87
2.37.3
84
85
diff view generated by jsdifflib
New patch
1
From: Hanna Reitz <hreitz@redhat.com>
1
2
3
Just like qcow2, qed invokes its open function in its
4
.bdrv_co_invalidate_cache() implementation. Therefore, just like done
5
for qcow2 in HEAD^, update auto_backing_file only if the backing file
6
string in the image header differs from the one we have read before.
7
8
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
9
Message-Id: <20220803144446.20723-3-hreitz@redhat.com>
10
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
---
13
block/qed.c | 15 +++++++++++----
14
1 file changed, 11 insertions(+), 4 deletions(-)
15
16
diff --git a/block/qed.c b/block/qed.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/block/qed.c
19
+++ b/block/qed.c
20
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_qed_do_open(BlockDriverState *bs, QDict *options,
21
}
22
23
if ((s->header.features & QED_F_BACKING_FILE)) {
24
+ g_autofree char *backing_file_str = NULL;
25
+
26
if ((uint64_t)s->header.backing_filename_offset +
27
s->header.backing_filename_size >
28
s->header.cluster_size * s->header.header_size) {
29
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_qed_do_open(BlockDriverState *bs, QDict *options,
30
return -EINVAL;
31
}
32
33
+ backing_file_str = g_malloc(sizeof(bs->backing_file));
34
ret = qed_read_string(bs->file, s->header.backing_filename_offset,
35
s->header.backing_filename_size,
36
- bs->auto_backing_file,
37
- sizeof(bs->auto_backing_file));
38
+ backing_file_str, sizeof(bs->backing_file));
39
if (ret < 0) {
40
error_setg(errp, "Failed to read backing filename");
41
return ret;
42
}
43
- pstrcpy(bs->backing_file, sizeof(bs->backing_file),
44
- bs->auto_backing_file);
45
+
46
+ if (!g_str_equal(backing_file_str, bs->backing_file)) {
47
+ pstrcpy(bs->backing_file, sizeof(bs->backing_file),
48
+ backing_file_str);
49
+ pstrcpy(bs->auto_backing_file, sizeof(bs->auto_backing_file),
50
+ backing_file_str);
51
+ }
52
53
if (s->header.features & QED_F_BACKING_FORMAT_NO_PROBE) {
54
pstrcpy(bs->backing_format, sizeof(bs->backing_format), "raw");
55
--
56
2.37.3
diff view generated by jsdifflib
1
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
1
From: Hanna Reitz <hreitz@redhat.com>
2
Message-Id: <20200424125448.63318-10-kwolf@redhat.com>
2
3
Reviewed-by: Max Reitz <mreitz@redhat.com>
3
Add a new test to see what happens when you migrate a VM with a backing
4
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
4
chain that has json:{} backing file strings, which, when opened, will be
5
resolved to plain filenames.
6
7
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
8
Message-Id: <20220803144446.20723-4-hreitz@redhat.com>
9
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
---
11
---
7
tests/qemu-iotests/274 | 155 +++++++++++++++++++++
12
.../tests/backing-file-invalidation | 152 ++++++++++++++++++
8
tests/qemu-iotests/274.out | 268 +++++++++++++++++++++++++++++++++++++
13
.../tests/backing-file-invalidation.out | 5 +
9
tests/qemu-iotests/group | 1 +
14
2 files changed, 157 insertions(+)
10
3 files changed, 424 insertions(+)
15
create mode 100755 tests/qemu-iotests/tests/backing-file-invalidation
11
create mode 100755 tests/qemu-iotests/274
16
create mode 100644 tests/qemu-iotests/tests/backing-file-invalidation.out
12
create mode 100644 tests/qemu-iotests/274.out
13
17
14
diff --git a/tests/qemu-iotests/274 b/tests/qemu-iotests/274
18
diff --git a/tests/qemu-iotests/tests/backing-file-invalidation b/tests/qemu-iotests/tests/backing-file-invalidation
15
new file mode 100755
19
new file mode 100755
16
index XXXXXXX..XXXXXXX
20
index XXXXXXX..XXXXXXX
17
--- /dev/null
21
--- /dev/null
18
+++ b/tests/qemu-iotests/274
22
+++ b/tests/qemu-iotests/tests/backing-file-invalidation
19
@@ -XXX,XX +XXX,XX @@
23
@@ -XXX,XX +XXX,XX @@
20
+#!/usr/bin/env python3
24
+#!/usr/bin/env python3
25
+# group: rw migration
21
+#
26
+#
22
+# Copyright (C) 2019 Red Hat, Inc.
27
+# Migrate a VM with a BDS with backing nodes, which runs
28
+# bdrv_invalidate_cache(), which for qcow2 and qed triggers reading the
29
+# backing file string from the image header. Check whether this
30
+# interferes with bdrv_backing_overridden().
31
+#
32
+# Copyright (C) 2022 Red Hat, Inc.
23
+#
33
+#
24
+# This program is free software; you can redistribute it and/or modify
34
+# This program is free software; you can redistribute it and/or modify
25
+# it under the terms of the GNU General Public License as published by
35
+# it under the terms of the GNU General Public License as published by
26
+# the Free Software Foundation; either version 2 of the License, or
36
+# the Free Software Foundation; either version 2 of the License, or
27
+# (at your option) any later version.
37
+# (at your option) any later version.
...
...
32
+# GNU General Public License for more details.
42
+# GNU General Public License for more details.
33
+#
43
+#
34
+# You should have received a copy of the GNU General Public License
44
+# You should have received a copy of the GNU General Public License
35
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
45
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
36
+#
46
+#
37
+# Creator/Owner: Kevin Wolf <kwolf@redhat.com>
47
+
38
+#
48
+import json
39
+# Some tests for short backing files and short overlays
49
+import os
50
+from typing import Optional
40
+
51
+
41
+import iotests
52
+import iotests
42
+
53
+from iotests import qemu_img_create, qemu_img_info
43
+iotests.verify_image_format(supported_fmts=['qcow2'])
44
+iotests.verify_platform(['linux'])
45
+
46
+size_short = 1 * 1024 * 1024
47
+size_long = 2 * 1024 * 1024
48
+size_diff = size_long - size_short
49
+
50
+def create_chain() -> None:
51
+ iotests.qemu_img_log('create', '-f', iotests.imgfmt, base,
52
+ str(size_long))
53
+ iotests.qemu_img_log('create', '-f', iotests.imgfmt, '-b', base, mid,
54
+ str(size_short))
55
+ iotests.qemu_img_log('create', '-f', iotests.imgfmt, '-b', mid, top,
56
+ str(size_long))
57
+
58
+ iotests.qemu_io_log('-c', 'write -P 1 0 %d' % size_long, base)
59
+
60
+def create_vm() -> iotests.VM:
61
+ vm = iotests.VM()
62
+ vm.add_blockdev('file,filename=%s,node-name=base-file' % base)
63
+ vm.add_blockdev('%s,file=base-file,node-name=base' % iotests.imgfmt)
64
+ vm.add_blockdev('file,filename=%s,node-name=mid-file' % mid)
65
+ vm.add_blockdev('%s,file=mid-file,node-name=mid,backing=base'
66
+ % iotests.imgfmt)
67
+ vm.add_drive(top, 'backing=mid,node-name=top')
68
+ return vm
69
+
70
+with iotests.FilePath('base') as base, \
71
+ iotests.FilePath('mid') as mid, \
72
+ iotests.FilePath('top') as top:
73
+
74
+ iotests.log('== Commit tests ==')
75
+
76
+ create_chain()
77
+
78
+ iotests.log('=== Check visible data ===')
79
+
80
+ iotests.qemu_io_log('-c', 'read -P 1 0 %d' % size_short, top)
81
+ iotests.qemu_io_log('-c', 'read -P 0 %d %d' % (size_short, size_diff), top)
82
+
83
+ iotests.log('=== Checking allocation status ===')
84
+
85
+ iotests.qemu_io_log('-c', 'alloc 0 %d' % size_short,
86
+ '-c', 'alloc %d %d' % (size_short, size_diff),
87
+ base)
88
+
89
+ iotests.qemu_io_log('-c', 'alloc 0 %d' % size_short,
90
+ '-c', 'alloc %d %d' % (size_short, size_diff),
91
+ mid)
92
+
93
+ iotests.qemu_io_log('-c', 'alloc 0 %d' % size_short,
94
+ '-c', 'alloc %d %d' % (size_short, size_diff),
95
+ top)
96
+
97
+ iotests.log('=== Checking map ===')
98
+
99
+ iotests.qemu_img_log('map', '--output=json', base)
100
+ iotests.qemu_img_log('map', '--output=human', base)
101
+ iotests.qemu_img_log('map', '--output=json', mid)
102
+ iotests.qemu_img_log('map', '--output=human', mid)
103
+ iotests.qemu_img_log('map', '--output=json', top)
104
+ iotests.qemu_img_log('map', '--output=human', top)
105
+
106
+ iotests.log('=== Testing qemu-img commit (top -> mid) ===')
107
+
108
+ iotests.qemu_img_log('commit', top)
109
+ iotests.img_info_log(mid)
110
+ iotests.qemu_io_log('-c', 'read -P 1 0 %d' % size_short, mid)
111
+ iotests.qemu_io_log('-c', 'read -P 0 %d %d' % (size_short, size_diff), mid)
112
+
113
+ iotests.log('=== Testing HMP commit (top -> mid) ===')
114
+
115
+ create_chain()
116
+ with create_vm() as vm:
117
+ vm.launch()
118
+ vm.qmp_log('human-monitor-command', command_line='commit drive0')
119
+
120
+ iotests.img_info_log(mid)
121
+ iotests.qemu_io_log('-c', 'read -P 1 0 %d' % size_short, mid)
122
+ iotests.qemu_io_log('-c', 'read -P 0 %d %d' % (size_short, size_diff), mid)
123
+
124
+ iotests.log('=== Testing QMP active commit (top -> mid) ===')
125
+
126
+ create_chain()
127
+ with create_vm() as vm:
128
+ vm.launch()
129
+ vm.qmp_log('block-commit', device='top', base_node='mid',
130
+ job_id='job0', auto_dismiss=False)
131
+ vm.run_job('job0', wait=5)
132
+
133
+ iotests.img_info_log(mid)
134
+ iotests.qemu_io_log('-c', 'read -P 1 0 %d' % size_short, mid)
135
+ iotests.qemu_io_log('-c', 'read -P 0 %d %d' % (size_short, size_diff), mid)
136
+
54
+
137
+
55
+
138
+ iotests.log('== Resize tests ==')
56
+image_size = 1 * 1024 * 1024
57
+imgs = [os.path.join(iotests.test_dir, f'{i}.img') for i in range(0, 4)]
139
+
58
+
140
+ # Use different sizes for different allocation modes:
59
+mig_sock = os.path.join(iotests.sock_dir, 'mig.sock')
141
+ #
142
+ # We want to have at least one test where 32 bit truncation in the size of
143
+ # the overlapping area becomes visible. This is covered by the
144
+ # prealloc='off' case (1G to 6G is an overlap of 5G).
145
+ #
146
+ # However, we can only do this for modes that don't preallocate data
147
+ # because otherwise we might run out of space on the test host.
148
+ #
149
+ # We also want to test some unaligned combinations.
150
+ for (prealloc, base_size, top_size_old, top_size_new, off) in [
151
+ ('off', '6G', '1G', '8G', '5G'),
152
+ ('metadata', '32G', '30G', '33G', '31G'),
153
+ ('falloc', '10M', '5M', '15M', '9M'),
154
+ ('full', '16M', '8M', '12M', '11M'),
155
+ ('off', '384k', '253k', '512k', '253k'),
156
+ ('off', '400k', '256k', '512k', '336k'),
157
+ ('off', '512k', '256k', '500k', '436k')]:
158
+
60
+
159
+ iotests.log('=== preallocation=%s ===' % prealloc)
160
+ iotests.qemu_img_log('create', '-f', iotests.imgfmt, base, base_size)
161
+ iotests.qemu_img_log('create', '-f', iotests.imgfmt, '-b', base, top,
162
+ top_size_old)
163
+ iotests.qemu_io_log('-c', 'write -P 1 %s 64k' % off, base)
164
+
61
+
165
+ # After this, top_size_old to base_size should be allocated/zeroed.
62
+class TestPostMigrateFilename(iotests.QMPTestCase):
166
+ #
63
+ vm_s: Optional[iotests.VM] = None
167
+ # In theory, leaving base_size to top_size_new unallocated would be
64
+ vm_d: Optional[iotests.VM] = None
168
+ # correct, but in practice, if we zero out anything, we zero out
65
+
169
+ # everything up to top_size_new.
66
+ def setUp(self) -> None:
170
+ iotests.qemu_img_log('resize', '-f', iotests.imgfmt,
67
+ # Create backing chain of three images, where the backing file strings
171
+ '--preallocation', prealloc, top, top_size_new)
68
+ # are json:{} filenames
172
+ iotests.qemu_io_log('-c', 'read -P 0 %s 64k' % off, top)
69
+ qemu_img_create('-f', iotests.imgfmt, imgs[0], str(image_size))
173
+ iotests.qemu_io_log('-c', 'map', top)
70
+ for i in range(1, 3):
174
+ iotests.qemu_img_log('map', '--output=json', top)
71
+ backing = {
175
diff --git a/tests/qemu-iotests/274.out b/tests/qemu-iotests/274.out
72
+ 'driver': iotests.imgfmt,
73
+ 'file': {
74
+ 'driver': 'file',
75
+ 'filename': imgs[i - 1]
76
+ }
77
+ }
78
+ qemu_img_create('-f', iotests.imgfmt, '-F', iotests.imgfmt,
79
+ '-b', 'json:' + json.dumps(backing),
80
+ imgs[i], str(image_size))
81
+
82
+ def tearDown(self) -> None:
83
+ if self.vm_s is not None:
84
+ self.vm_s.shutdown()
85
+ if self.vm_d is not None:
86
+ self.vm_d.shutdown()
87
+
88
+ for img in imgs:
89
+ try:
90
+ os.remove(img)
91
+ except OSError:
92
+ pass
93
+ try:
94
+ os.remove(mig_sock)
95
+ except OSError:
96
+ pass
97
+
98
+ def test_migration(self) -> None:
99
+ """
100
+ Migrate a VM with the backing chain created in setUp() attached. At
101
+ the end of the migration process, the destination will run
102
+ bdrv_invalidate_cache(), which for some image formats (qcow2 and qed)
103
+ means the backing file string is re-read from the image header. If
104
+ this overwrites bs->auto_backing_file, doing so may cause
105
+ bdrv_backing_overridden() to become true: The image header reports a
106
+ json:{} filename, but when opening it, bdrv_refresh_filename() will
107
+ simplify it to a plain simple filename; and when bs->auto_backing_file
108
+ and bs->backing->bs->filename differ, bdrv_backing_overridden() becomes
109
+ true.
110
+ If bdrv_backing_overridden() is true, the BDS will be forced to get a
111
+ json:{} filename, which in general is not the end of the world, but not
112
+ great. Check whether that happens, i.e. whether migration changes the
113
+ node's filename.
114
+ """
115
+
116
+ blockdev = {
117
+ 'node-name': 'node0',
118
+ 'driver': iotests.imgfmt,
119
+ 'file': {
120
+ 'driver': 'file',
121
+ 'filename': imgs[2]
122
+ }
123
+ }
124
+
125
+ self.vm_s = iotests.VM(path_suffix='a') \
126
+ .add_blockdev(json.dumps(blockdev))
127
+ self.vm_d = iotests.VM(path_suffix='b') \
128
+ .add_blockdev(json.dumps(blockdev)) \
129
+ .add_incoming(f'unix:{mig_sock}')
130
+
131
+ assert self.vm_s is not None
132
+ assert self.vm_d is not None
133
+
134
+ self.vm_s.launch()
135
+ self.vm_d.launch()
136
+
137
+ pre_mig_filename = self.vm_s.node_info('node0')['file']
138
+
139
+ self.vm_s.qmp('migrate', uri=f'unix:{mig_sock}')
140
+
141
+ # Wait for migration to be done
142
+ self.vm_s.event_wait('STOP')
143
+ self.vm_d.event_wait('RESUME')
144
+
145
+ post_mig_filename = self.vm_d.node_info('node0')['file']
146
+
147
+ # Verify that the filename hasn't changed from before the migration
148
+ self.assertEqual(pre_mig_filename, post_mig_filename)
149
+
150
+ self.vm_s.shutdown()
151
+ self.vm_s = None
152
+
153
+ # For good measure, try creating an overlay and check its backing
154
+ # chain below. This is how the issue was originally found.
155
+ result = self.vm_d.qmp('blockdev-snapshot-sync',
156
+ format=iotests.imgfmt,
157
+ snapshot_file=imgs[3],
158
+ node_name='node0',
159
+ snapshot_node_name='node0-overlay')
160
+ self.assert_qmp(result, 'return', {})
161
+
162
+ self.vm_d.shutdown()
163
+ self.vm_d = None
164
+
165
+ # Check the newly created overlay's backing chain
166
+ chain = qemu_img_info('--backing-chain', imgs[3])
167
+ for index, image in enumerate(chain):
168
+ self.assertEqual(image['filename'], imgs[3 - index])
169
+
170
+
171
+if __name__ == '__main__':
172
+ # These are the image formats that run their open() function from their
173
+ # .bdrv_co_invaliate_cache() implementations, so test them
174
+ iotests.main(supported_fmts=['qcow2', 'qed'],
175
+ supported_protocols=['file'])
176
diff --git a/tests/qemu-iotests/tests/backing-file-invalidation.out b/tests/qemu-iotests/tests/backing-file-invalidation.out
176
new file mode 100644
177
new file mode 100644
177
index XXXXXXX..XXXXXXX
178
index XXXXXXX..XXXXXXX
178
--- /dev/null
179
--- /dev/null
179
+++ b/tests/qemu-iotests/274.out
180
+++ b/tests/qemu-iotests/tests/backing-file-invalidation.out
180
@@ -XXX,XX +XXX,XX @@
181
@@ -XXX,XX +XXX,XX @@
181
+== Commit tests ==
182
+.
182
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=2097152 cluster_size=65536 lazy_refcounts=off refcount_bits=16
183
+----------------------------------------------------------------------
184
+Ran 1 tests
183
+
185
+
184
+Formatting 'TEST_DIR/PID-mid', fmt=qcow2 size=1048576 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
186
+OK
185
+
186
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=2097152 backing_file=TEST_DIR/PID-mid cluster_size=65536 lazy_refcounts=off refcount_bits=16
187
+
188
+wrote 2097152/2097152 bytes at offset 0
189
+2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
190
+
191
+=== Check visible data ===
192
+read 1048576/1048576 bytes at offset 0
193
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
194
+
195
+read 1048576/1048576 bytes at offset 1048576
196
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
197
+
198
+=== Checking allocation status ===
199
+1048576/1048576 bytes allocated at offset 0 bytes
200
+1048576/1048576 bytes allocated at offset 1 MiB
201
+
202
+0/1048576 bytes allocated at offset 0 bytes
203
+0/0 bytes allocated at offset 1 MiB
204
+
205
+0/1048576 bytes allocated at offset 0 bytes
206
+0/1048576 bytes allocated at offset 1 MiB
207
+
208
+=== Checking map ===
209
+[{ "start": 0, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": 327680}]
210
+
211
+Offset Length Mapped to File
212
+0 0x200000 0x50000 TEST_DIR/PID-base
213
+
214
+[{ "start": 0, "length": 1048576, "depth": 1, "zero": false, "data": true, "offset": 327680}]
215
+
216
+Offset Length Mapped to File
217
+0 0x100000 0x50000 TEST_DIR/PID-base
218
+
219
+[{ "start": 0, "length": 1048576, "depth": 2, "zero": false, "data": true, "offset": 327680},
220
+{ "start": 1048576, "length": 1048576, "depth": 0, "zero": true, "data": false}]
221
+
222
+Offset Length Mapped to File
223
+0 0x100000 0x50000 TEST_DIR/PID-base
224
+
225
+=== Testing qemu-img commit (top -> mid) ===
226
+Image committed.
227
+
228
+image: TEST_IMG
229
+file format: IMGFMT
230
+virtual size: 2 MiB (2097152 bytes)
231
+cluster_size: 65536
232
+backing file: TEST_DIR/PID-base
233
+Format specific information:
234
+ compat: 1.1
235
+ lazy refcounts: false
236
+ refcount bits: 16
237
+ corrupt: false
238
+
239
+read 1048576/1048576 bytes at offset 0
240
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
241
+
242
+read 1048576/1048576 bytes at offset 1048576
243
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
244
+
245
+=== Testing HMP commit (top -> mid) ===
246
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=2097152 cluster_size=65536 lazy_refcounts=off refcount_bits=16
247
+
248
+Formatting 'TEST_DIR/PID-mid', fmt=qcow2 size=1048576 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
249
+
250
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=2097152 backing_file=TEST_DIR/PID-mid cluster_size=65536 lazy_refcounts=off refcount_bits=16
251
+
252
+wrote 2097152/2097152 bytes at offset 0
253
+2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
254
+
255
+{"execute": "human-monitor-command", "arguments": {"command-line": "commit drive0"}}
256
+{"return": ""}
257
+image: TEST_IMG
258
+file format: IMGFMT
259
+virtual size: 2 MiB (2097152 bytes)
260
+cluster_size: 65536
261
+backing file: TEST_DIR/PID-base
262
+Format specific information:
263
+ compat: 1.1
264
+ lazy refcounts: false
265
+ refcount bits: 16
266
+ corrupt: false
267
+
268
+read 1048576/1048576 bytes at offset 0
269
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
270
+
271
+read 1048576/1048576 bytes at offset 1048576
272
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
273
+
274
+=== Testing QMP active commit (top -> mid) ===
275
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=2097152 cluster_size=65536 lazy_refcounts=off refcount_bits=16
276
+
277
+Formatting 'TEST_DIR/PID-mid', fmt=qcow2 size=1048576 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
278
+
279
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=2097152 backing_file=TEST_DIR/PID-mid cluster_size=65536 lazy_refcounts=off refcount_bits=16
280
+
281
+wrote 2097152/2097152 bytes at offset 0
282
+2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
283
+
284
+{"execute": "block-commit", "arguments": {"auto-dismiss": false, "base-node": "mid", "device": "top", "job-id": "job0"}}
285
+{"return": {}}
286
+{"execute": "job-complete", "arguments": {"id": "job0"}}
287
+{"return": {}}
288
+{"data": {"device": "job0", "len": 0, "offset": 0, "speed": 0, "type": "commit"}, "event": "BLOCK_JOB_READY", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
289
+{"data": {"device": "job0", "len": 0, "offset": 0, "speed": 0, "type": "commit"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
290
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
291
+{"return": {}}
292
+image: TEST_IMG
293
+file format: IMGFMT
294
+virtual size: 2 MiB (2097152 bytes)
295
+cluster_size: 65536
296
+backing file: TEST_DIR/PID-base
297
+Format specific information:
298
+ compat: 1.1
299
+ lazy refcounts: false
300
+ refcount bits: 16
301
+ corrupt: false
302
+
303
+read 1048576/1048576 bytes at offset 0
304
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
305
+
306
+read 1048576/1048576 bytes at offset 1048576
307
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
308
+
309
+== Resize tests ==
310
+=== preallocation=off ===
311
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=6442450944 cluster_size=65536 lazy_refcounts=off refcount_bits=16
312
+
313
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=1073741824 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
314
+
315
+wrote 65536/65536 bytes at offset 5368709120
316
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
317
+
318
+Image resized.
319
+
320
+read 65536/65536 bytes at offset 5368709120
321
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
322
+
323
+1 GiB (0x40000000) bytes not allocated at offset 0 bytes (0x0)
324
+7 GiB (0x1c0000000) bytes allocated at offset 1 GiB (0x40000000)
325
+
326
+[{ "start": 0, "length": 1073741824, "depth": 1, "zero": true, "data": false},
327
+{ "start": 1073741824, "length": 7516192768, "depth": 0, "zero": true, "data": false}]
328
+
329
+=== preallocation=metadata ===
330
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=34359738368 cluster_size=65536 lazy_refcounts=off refcount_bits=16
331
+
332
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=32212254720 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
333
+
334
+wrote 65536/65536 bytes at offset 33285996544
335
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
336
+
337
+Image resized.
338
+
339
+read 65536/65536 bytes at offset 33285996544
340
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
341
+
342
+30 GiB (0x780000000) bytes not allocated at offset 0 bytes (0x0)
343
+3 GiB (0xc0000000) bytes allocated at offset 30 GiB (0x780000000)
344
+
345
+[{ "start": 0, "length": 32212254720, "depth": 1, "zero": true, "data": false},
346
+{ "start": 32212254720, "length": 536870912, "depth": 0, "zero": true, "data": false, "offset": 327680},
347
+{ "start": 32749125632, "length": 536870912, "depth": 0, "zero": true, "data": false, "offset": 537264128},
348
+{ "start": 33285996544, "length": 536870912, "depth": 0, "zero": true, "data": false, "offset": 1074200576},
349
+{ "start": 33822867456, "length": 536870912, "depth": 0, "zero": true, "data": false, "offset": 1611137024},
350
+{ "start": 34359738368, "length": 536870912, "depth": 0, "zero": true, "data": false, "offset": 2148139008},
351
+{ "start": 34896609280, "length": 536870912, "depth": 0, "zero": true, "data": false, "offset": 2685075456}]
352
+
353
+=== preallocation=falloc ===
354
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=10485760 cluster_size=65536 lazy_refcounts=off refcount_bits=16
355
+
356
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=5242880 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
357
+
358
+wrote 65536/65536 bytes at offset 9437184
359
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
360
+
361
+Image resized.
362
+
363
+read 65536/65536 bytes at offset 9437184
364
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
365
+
366
+5 MiB (0x500000) bytes not allocated at offset 0 bytes (0x0)
367
+10 MiB (0xa00000) bytes allocated at offset 5 MiB (0x500000)
368
+
369
+[{ "start": 0, "length": 5242880, "depth": 1, "zero": true, "data": false},
370
+{ "start": 5242880, "length": 10485760, "depth": 0, "zero": true, "data": false, "offset": 327680}]
371
+
372
+=== preallocation=full ===
373
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=16777216 cluster_size=65536 lazy_refcounts=off refcount_bits=16
374
+
375
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=8388608 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
376
+
377
+wrote 65536/65536 bytes at offset 11534336
378
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
379
+
380
+Image resized.
381
+
382
+read 65536/65536 bytes at offset 11534336
383
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
384
+
385
+8 MiB (0x800000) bytes not allocated at offset 0 bytes (0x0)
386
+4 MiB (0x400000) bytes allocated at offset 8 MiB (0x800000)
387
+
388
+[{ "start": 0, "length": 8388608, "depth": 1, "zero": true, "data": false},
389
+{ "start": 8388608, "length": 4194304, "depth": 0, "zero": true, "data": false, "offset": 327680}]
390
+
391
+=== preallocation=off ===
392
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=393216 cluster_size=65536 lazy_refcounts=off refcount_bits=16
393
+
394
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=259072 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
395
+
396
+wrote 65536/65536 bytes at offset 259072
397
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
398
+
399
+Image resized.
400
+
401
+read 65536/65536 bytes at offset 259072
402
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
403
+
404
+192 KiB (0x30000) bytes not allocated at offset 0 bytes (0x0)
405
+320 KiB (0x50000) bytes allocated at offset 192 KiB (0x30000)
406
+
407
+[{ "start": 0, "length": 196608, "depth": 1, "zero": true, "data": false},
408
+{ "start": 196608, "length": 65536, "depth": 0, "zero": false, "data": true, "offset": 327680},
409
+{ "start": 262144, "length": 262144, "depth": 0, "zero": true, "data": false}]
410
+
411
+=== preallocation=off ===
412
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=409600 cluster_size=65536 lazy_refcounts=off refcount_bits=16
413
+
414
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=262144 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
415
+
416
+wrote 65536/65536 bytes at offset 344064
417
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
418
+
419
+Image resized.
420
+
421
+read 65536/65536 bytes at offset 344064
422
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
423
+
424
+256 KiB (0x40000) bytes not allocated at offset 0 bytes (0x0)
425
+256 KiB (0x40000) bytes allocated at offset 256 KiB (0x40000)
426
+
427
+[{ "start": 0, "length": 262144, "depth": 1, "zero": true, "data": false},
428
+{ "start": 262144, "length": 262144, "depth": 0, "zero": true, "data": false}]
429
+
430
+=== preallocation=off ===
431
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=524288 cluster_size=65536 lazy_refcounts=off refcount_bits=16
432
+
433
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=262144 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
434
+
435
+wrote 65536/65536 bytes at offset 446464
436
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
437
+
438
+Image resized.
439
+
440
+read 65536/65536 bytes at offset 446464
441
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
442
+
443
+256 KiB (0x40000) bytes not allocated at offset 0 bytes (0x0)
444
+244 KiB (0x3d000) bytes allocated at offset 256 KiB (0x40000)
445
+
446
+[{ "start": 0, "length": 262144, "depth": 1, "zero": true, "data": false},
447
+{ "start": 262144, "length": 249856, "depth": 0, "zero": true, "data": false}]
448
+
449
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
450
index XXXXXXX..XXXXXXX 100644
451
--- a/tests/qemu-iotests/group
452
+++ b/tests/qemu-iotests/group
453
@@ -XXX,XX +XXX,XX @@
454
270 rw backing quick
455
272 rw
456
273 backing quick
457
+274 rw backing
458
277 rw quick
459
279 rw backing quick
460
280 rw migration quick
461
--
187
--
462
2.25.3
188
2.37.3
463
464
diff view generated by jsdifflib
1
When extending the size of an image that has a backing file larger than
1
From: Keith Busch <kbusch@kernel.org>
2
its old size, make sure that the backing file data doesn't become
3
visible in the guest, but the added area is properly zeroed out.
4
2
5
Consider the following scenario where the overlay is shorter than its
3
There is only user of bdrv_qiov_is_aligned(), so move the alignment
6
backing file:
4
function to there and make it static.
7
5
8
base.qcow2: AAAAAAAA
6
Signed-off-by: Keith Busch <kbusch@kernel.org>
9
overlay.qcow2: BBBB
7
Message-Id: <20220929200523.3218710-2-kbusch@meta.com>
10
8
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
11
When resizing (extending) overlay.qcow2, the new blocks should not stay
12
unallocated and make the additional As from base.qcow2 visible like
13
before this patch, but zeros should be read.
14
15
A similar case happens with the various variants of a commit job when an
16
intermediate file is short (- for unallocated):
17
18
base.qcow2: A-A-AAAA
19
mid.qcow2: BB-B
20
top.qcow2: C--C--C-
21
22
After commit top.qcow2 to mid.qcow2, the following happens:
23
24
mid.qcow2: CB-C00C0 (correct result)
25
mid.qcow2: CB-C--C- (before this fix)
26
27
Without the fix, blocks that previously read as zeros on top.qcow2
28
suddenly turn into A.
29
30
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
31
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
32
Message-Id: <20200424125448.63318-8-kwolf@redhat.com>
33
Reviewed-by: Max Reitz <mreitz@redhat.com>
34
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
35
---
10
---
36
block/io.c | 25 +++++++++++++++++++++++++
11
include/block/block-io.h | 1 -
37
1 file changed, 25 insertions(+)
12
block/file-posix.c | 21 +++++++++++++++++++++
13
block/io.c | 21 ---------------------
14
3 files changed, 21 insertions(+), 22 deletions(-)
38
15
16
diff --git a/include/block/block-io.h b/include/block/block-io.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/include/block/block-io.h
19
+++ b/include/block/block-io.h
20
@@ -XXX,XX +XXX,XX @@ void *qemu_blockalign(BlockDriverState *bs, size_t size);
21
void *qemu_blockalign0(BlockDriverState *bs, size_t size);
22
void *qemu_try_blockalign(BlockDriverState *bs, size_t size);
23
void *qemu_try_blockalign0(BlockDriverState *bs, size_t size);
24
-bool bdrv_qiov_is_aligned(BlockDriverState *bs, QEMUIOVector *qiov);
25
26
void bdrv_enable_copy_on_read(BlockDriverState *bs);
27
void bdrv_disable_copy_on_read(BlockDriverState *bs);
28
diff --git a/block/file-posix.c b/block/file-posix.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/block/file-posix.c
31
+++ b/block/file-posix.c
32
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn raw_thread_pool_submit(BlockDriverState *bs,
33
return thread_pool_submit_co(pool, func, arg);
34
}
35
36
+/*
37
+ * Check if all memory in this vector is sector aligned.
38
+ */
39
+static bool bdrv_qiov_is_aligned(BlockDriverState *bs, QEMUIOVector *qiov)
40
+{
41
+ int i;
42
+ size_t alignment = bdrv_min_mem_align(bs);
43
+ IO_CODE();
44
+
45
+ for (i = 0; i < qiov->niov; i++) {
46
+ if ((uintptr_t) qiov->iov[i].iov_base % alignment) {
47
+ return false;
48
+ }
49
+ if (qiov->iov[i].iov_len % alignment) {
50
+ return false;
51
+ }
52
+ }
53
+
54
+ return true;
55
+}
56
+
57
static int coroutine_fn raw_co_prw(BlockDriverState *bs, uint64_t offset,
58
uint64_t bytes, QEMUIOVector *qiov, int type)
59
{
39
diff --git a/block/io.c b/block/io.c
60
diff --git a/block/io.c b/block/io.c
40
index XXXXXXX..XXXXXXX 100644
61
index XXXXXXX..XXXXXXX 100644
41
--- a/block/io.c
62
--- a/block/io.c
42
+++ b/block/io.c
63
+++ b/block/io.c
43
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact,
64
@@ -XXX,XX +XXX,XX @@ void *qemu_try_blockalign0(BlockDriverState *bs, size_t size)
44
goto out;
65
return mem;
45
}
66
}
46
67
47
+ /*
68
-/*
48
+ * If the image has a backing file that is large enough that it would
69
- * Check if all memory in this vector is sector aligned.
49
+ * provide data for the new area, we cannot leave it unallocated because
70
- */
50
+ * then the backing file content would become visible. Instead, zero-fill
71
-bool bdrv_qiov_is_aligned(BlockDriverState *bs, QEMUIOVector *qiov)
51
+ * the new area.
72
-{
52
+ *
73
- int i;
53
+ * Note that if the image has a backing file, but was opened without the
74
- size_t alignment = bdrv_min_mem_align(bs);
54
+ * backing file, taking care of keeping things consistent with that backing
75
- IO_CODE();
55
+ * file is the user's responsibility.
76
-
56
+ */
77
- for (i = 0; i < qiov->niov; i++) {
57
+ if (new_bytes && bs->backing) {
78
- if ((uintptr_t) qiov->iov[i].iov_base % alignment) {
58
+ int64_t backing_len;
79
- return false;
59
+
80
- }
60
+ backing_len = bdrv_getlength(backing_bs(bs));
81
- if (qiov->iov[i].iov_len % alignment) {
61
+ if (backing_len < 0) {
82
- return false;
62
+ ret = backing_len;
83
- }
63
+ error_setg_errno(errp, -ret, "Could not get backing file size");
84
- }
64
+ goto out;
85
-
65
+ }
86
- return true;
66
+
87
-}
67
+ if (backing_len > old_size) {
88
-
68
+ flags |= BDRV_REQ_ZERO_WRITE;
89
void bdrv_io_plug(BlockDriverState *bs)
69
+ }
90
{
70
+ }
91
BdrvChild *child;
71
+
72
if (drv->bdrv_co_truncate) {
73
if (flags & ~bs->supported_truncate_flags) {
74
error_setg(errp, "Block driver does not support requested flags");
75
--
92
--
76
2.25.3
93
2.37.3
77
78
diff view generated by jsdifflib
1
For regular files, we always get BDRV_REQ_ZERO_WRITE behaviour from the
1
From: Keith Busch <kbusch@kernel.org>
2
OS, so we can advertise the flag and just ignore it.
3
2
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
3
An iov length needs to be aligned to the logical block size, which may
5
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
4
be larger than the memory alignment.
6
Reviewed-by: Alberto Garcia <berto@igalia.com>
5
7
Reviewed-by: Max Reitz <mreitz@redhat.com>
6
Tested-by: Jens Axboe <axboe@kernel.dk>
8
Message-Id: <20200424125448.63318-7-kwolf@redhat.com>
7
Signed-off-by: Keith Busch <kbusch@kernel.org>
8
Message-Id: <20220929200523.3218710-3-kbusch@meta.com>
9
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
11
---
11
block/file-posix.c | 4 ++++
12
block/file-posix.c | 3 ++-
12
1 file changed, 4 insertions(+)
13
1 file changed, 2 insertions(+), 1 deletion(-)
13
14
14
diff --git a/block/file-posix.c b/block/file-posix.c
15
diff --git a/block/file-posix.c b/block/file-posix.c
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/block/file-posix.c
17
--- a/block/file-posix.c
17
+++ b/block/file-posix.c
18
+++ b/block/file-posix.c
18
@@ -XXX,XX +XXX,XX @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
19
@@ -XXX,XX +XXX,XX @@ static bool bdrv_qiov_is_aligned(BlockDriverState *bs, QEMUIOVector *qiov)
19
#endif
20
{
20
21
int i;
21
bs->supported_zero_flags = BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK;
22
size_t alignment = bdrv_min_mem_align(bs);
22
+ if (S_ISREG(st.st_mode)) {
23
+ size_t len = bs->bl.request_alignment;
23
+ /* When extending regular files, we get zeros from the OS */
24
IO_CODE();
24
+ bs->supported_truncate_flags = BDRV_REQ_ZERO_WRITE;
25
25
+ }
26
for (i = 0; i < qiov->niov; i++) {
26
ret = 0;
27
if ((uintptr_t) qiov->iov[i].iov_base % alignment) {
27
fail:
28
return false;
28
if (filename && (bdrv_flags & BDRV_O_TEMPORARY)) {
29
}
30
- if (qiov->iov[i].iov_len % alignment) {
31
+ if (qiov->iov[i].iov_len % len) {
32
return false;
33
}
34
}
29
--
35
--
30
2.25.3
36
2.37.3
31
32
diff view generated by jsdifflib
1
From: Andrzej Jakowski <andrzej.jakowski@linux.intel.com>
1
From: Lev Kujawski <lkujaw@member.fsf.org>
2
2
3
This patch introduces support for PMR that has been defined as part of NVMe 1.4
3
Eliminate the remaining TODOs in hw/ide/piix.c by:
4
spec. User can now specify a pmrdev option that should point to HostMemoryBackend.
4
* Using pci_set_{size} functions to write the PIIX PCI configuration
5
pmrdev memory region will subsequently be exposed as PCI BAR 2 in emulated NVMe
5
space instead of manipulating it directly as an array; and
6
device. Guest OS can perform mmio read and writes to the PMR region that will stay
6
* Documenting the default register values by reference to the
7
persistent across system reboot.
7
controlling specification.
8
8
9
Signed-off-by: Andrzej Jakowski <andrzej.jakowski@linux.intel.com>
9
Signed-off-by: Lev Kujawski <lkujaw@member.fsf.org>
10
Reviewed-by: Klaus Jensen <k.jensen@samsung.com>
10
Message-Id: <20220707031140.158958-1-lkujaw@member.fsf.org>
11
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
12
Message-Id: <20200330164656.9348-1-andrzej.jakowski@linux.intel.com>
13
Reviewed-by: Keith Busch <kbusch@kernel.org>
14
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
15
---
12
---
16
hw/block/nvme.h | 2 +
13
hw/ide/piix.c | 17 +++++++++--------
17
include/block/nvme.h | 172 +++++++++++++++++++++++++++++++++++++++++
14
1 file changed, 9 insertions(+), 8 deletions(-)
18
hw/block/nvme.c | 109 ++++++++++++++++++++++++++
19
hw/block/Makefile.objs | 2 +-
20
hw/block/trace-events | 4 +
21
5 files changed, 288 insertions(+), 1 deletion(-)
22
15
23
diff --git a/hw/block/nvme.h b/hw/block/nvme.h
16
diff --git a/hw/ide/piix.c b/hw/ide/piix.c
24
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
25
--- a/hw/block/nvme.h
18
--- a/hw/ide/piix.c
26
+++ b/hw/block/nvme.h
19
+++ b/hw/ide/piix.c
27
@@ -XXX,XX +XXX,XX @@ typedef struct NvmeCtrl {
28
uint64_t timestamp_set_qemu_clock_ms; /* QEMU clock time */
29
30
char *serial;
31
+ HostMemoryBackend *pmrdev;
32
+
33
NvmeNamespace *namespaces;
34
NvmeSQueue **sq;
35
NvmeCQueue **cq;
36
diff --git a/include/block/nvme.h b/include/block/nvme.h
37
index XXXXXXX..XXXXXXX 100644
38
--- a/include/block/nvme.h
39
+++ b/include/block/nvme.h
40
@@ -XXX,XX +XXX,XX @@ typedef struct NvmeBar {
41
uint64_t acq;
42
uint32_t cmbloc;
43
uint32_t cmbsz;
44
+ uint8_t padding[3520]; /* not used by QEMU */
45
+ uint32_t pmrcap;
46
+ uint32_t pmrctl;
47
+ uint32_t pmrsts;
48
+ uint32_t pmrebs;
49
+ uint32_t pmrswtp;
50
+ uint32_t pmrmsc;
51
} NvmeBar;
52
53
enum NvmeCapShift {
54
@@ -XXX,XX +XXX,XX @@ enum NvmeCapShift {
55
CAP_CSS_SHIFT = 37,
56
CAP_MPSMIN_SHIFT = 48,
57
CAP_MPSMAX_SHIFT = 52,
58
+ CAP_PMR_SHIFT = 56,
59
};
60
61
enum NvmeCapMask {
62
@@ -XXX,XX +XXX,XX @@ enum NvmeCapMask {
63
CAP_CSS_MASK = 0xff,
64
CAP_MPSMIN_MASK = 0xf,
65
CAP_MPSMAX_MASK = 0xf,
66
+ CAP_PMR_MASK = 0x1,
67
};
68
69
#define NVME_CAP_MQES(cap) (((cap) >> CAP_MQES_SHIFT) & CAP_MQES_MASK)
70
@@ -XXX,XX +XXX,XX @@ enum NvmeCapMask {
71
<< CAP_MPSMIN_SHIFT)
72
#define NVME_CAP_SET_MPSMAX(cap, val) (cap |= (uint64_t)(val & CAP_MPSMAX_MASK)\
73
<< CAP_MPSMAX_SHIFT)
74
+#define NVME_CAP_SET_PMRS(cap, val) (cap |= (uint64_t)(val & CAP_PMR_MASK)\
75
+ << CAP_PMR_SHIFT)
76
77
enum NvmeCcShift {
78
CC_EN_SHIFT = 0,
79
@@ -XXX,XX +XXX,XX @@ enum NvmeCmbszMask {
80
#define NVME_CMBSZ_GETSIZE(cmbsz) \
81
(NVME_CMBSZ_SZ(cmbsz) * (1 << (12 + 4 * NVME_CMBSZ_SZU(cmbsz))))
82
83
+enum NvmePmrcapShift {
84
+ PMRCAP_RDS_SHIFT = 3,
85
+ PMRCAP_WDS_SHIFT = 4,
86
+ PMRCAP_BIR_SHIFT = 5,
87
+ PMRCAP_PMRTU_SHIFT = 8,
88
+ PMRCAP_PMRWBM_SHIFT = 10,
89
+ PMRCAP_PMRTO_SHIFT = 16,
90
+ PMRCAP_CMSS_SHIFT = 24,
91
+};
92
+
93
+enum NvmePmrcapMask {
94
+ PMRCAP_RDS_MASK = 0x1,
95
+ PMRCAP_WDS_MASK = 0x1,
96
+ PMRCAP_BIR_MASK = 0x7,
97
+ PMRCAP_PMRTU_MASK = 0x3,
98
+ PMRCAP_PMRWBM_MASK = 0xf,
99
+ PMRCAP_PMRTO_MASK = 0xff,
100
+ PMRCAP_CMSS_MASK = 0x1,
101
+};
102
+
103
+#define NVME_PMRCAP_RDS(pmrcap) \
104
+ ((pmrcap >> PMRCAP_RDS_SHIFT) & PMRCAP_RDS_MASK)
105
+#define NVME_PMRCAP_WDS(pmrcap) \
106
+ ((pmrcap >> PMRCAP_WDS_SHIFT) & PMRCAP_WDS_MASK)
107
+#define NVME_PMRCAP_BIR(pmrcap) \
108
+ ((pmrcap >> PMRCAP_BIR_SHIFT) & PMRCAP_BIR_MASK)
109
+#define NVME_PMRCAP_PMRTU(pmrcap) \
110
+ ((pmrcap >> PMRCAP_PMRTU_SHIFT) & PMRCAP_PMRTU_MASK)
111
+#define NVME_PMRCAP_PMRWBM(pmrcap) \
112
+ ((pmrcap >> PMRCAP_PMRWBM_SHIFT) & PMRCAP_PMRWBM_MASK)
113
+#define NVME_PMRCAP_PMRTO(pmrcap) \
114
+ ((pmrcap >> PMRCAP_PMRTO_SHIFT) & PMRCAP_PMRTO_MASK)
115
+#define NVME_PMRCAP_CMSS(pmrcap) \
116
+ ((pmrcap >> PMRCAP_CMSS_SHIFT) & PMRCAP_CMSS_MASK)
117
+
118
+#define NVME_PMRCAP_SET_RDS(pmrcap, val) \
119
+ (pmrcap |= (uint64_t)(val & PMRCAP_RDS_MASK) << PMRCAP_RDS_SHIFT)
120
+#define NVME_PMRCAP_SET_WDS(pmrcap, val) \
121
+ (pmrcap |= (uint64_t)(val & PMRCAP_WDS_MASK) << PMRCAP_WDS_SHIFT)
122
+#define NVME_PMRCAP_SET_BIR(pmrcap, val) \
123
+ (pmrcap |= (uint64_t)(val & PMRCAP_BIR_MASK) << PMRCAP_BIR_SHIFT)
124
+#define NVME_PMRCAP_SET_PMRTU(pmrcap, val) \
125
+ (pmrcap |= (uint64_t)(val & PMRCAP_PMRTU_MASK) << PMRCAP_PMRTU_SHIFT)
126
+#define NVME_PMRCAP_SET_PMRWBM(pmrcap, val) \
127
+ (pmrcap |= (uint64_t)(val & PMRCAP_PMRWBM_MASK) << PMRCAP_PMRWBM_SHIFT)
128
+#define NVME_PMRCAP_SET_PMRTO(pmrcap, val) \
129
+ (pmrcap |= (uint64_t)(val & PMRCAP_PMRTO_MASK) << PMRCAP_PMRTO_SHIFT)
130
+#define NVME_PMRCAP_SET_CMSS(pmrcap, val) \
131
+ (pmrcap |= (uint64_t)(val & PMRCAP_CMSS_MASK) << PMRCAP_CMSS_SHIFT)
132
+
133
+enum NvmePmrctlShift {
134
+ PMRCTL_EN_SHIFT = 0,
135
+};
136
+
137
+enum NvmePmrctlMask {
138
+ PMRCTL_EN_MASK = 0x1,
139
+};
140
+
141
+#define NVME_PMRCTL_EN(pmrctl) ((pmrctl >> PMRCTL_EN_SHIFT) & PMRCTL_EN_MASK)
142
+
143
+#define NVME_PMRCTL_SET_EN(pmrctl, val) \
144
+ (pmrctl |= (uint64_t)(val & PMRCTL_EN_MASK) << PMRCTL_EN_SHIFT)
145
+
146
+enum NvmePmrstsShift {
147
+ PMRSTS_ERR_SHIFT = 0,
148
+ PMRSTS_NRDY_SHIFT = 8,
149
+ PMRSTS_HSTS_SHIFT = 9,
150
+ PMRSTS_CBAI_SHIFT = 12,
151
+};
152
+
153
+enum NvmePmrstsMask {
154
+ PMRSTS_ERR_MASK = 0xff,
155
+ PMRSTS_NRDY_MASK = 0x1,
156
+ PMRSTS_HSTS_MASK = 0x7,
157
+ PMRSTS_CBAI_MASK = 0x1,
158
+};
159
+
160
+#define NVME_PMRSTS_ERR(pmrsts) \
161
+ ((pmrsts >> PMRSTS_ERR_SHIFT) & PMRSTS_ERR_MASK)
162
+#define NVME_PMRSTS_NRDY(pmrsts) \
163
+ ((pmrsts >> PMRSTS_NRDY_SHIFT) & PMRSTS_NRDY_MASK)
164
+#define NVME_PMRSTS_HSTS(pmrsts) \
165
+ ((pmrsts >> PMRSTS_HSTS_SHIFT) & PMRSTS_HSTS_MASK)
166
+#define NVME_PMRSTS_CBAI(pmrsts) \
167
+ ((pmrsts >> PMRSTS_CBAI_SHIFT) & PMRSTS_CBAI_MASK)
168
+
169
+#define NVME_PMRSTS_SET_ERR(pmrsts, val) \
170
+ (pmrsts |= (uint64_t)(val & PMRSTS_ERR_MASK) << PMRSTS_ERR_SHIFT)
171
+#define NVME_PMRSTS_SET_NRDY(pmrsts, val) \
172
+ (pmrsts |= (uint64_t)(val & PMRSTS_NRDY_MASK) << PMRSTS_NRDY_SHIFT)
173
+#define NVME_PMRSTS_SET_HSTS(pmrsts, val) \
174
+ (pmrsts |= (uint64_t)(val & PMRSTS_HSTS_MASK) << PMRSTS_HSTS_SHIFT)
175
+#define NVME_PMRSTS_SET_CBAI(pmrsts, val) \
176
+ (pmrsts |= (uint64_t)(val & PMRSTS_CBAI_MASK) << PMRSTS_CBAI_SHIFT)
177
+
178
+enum NvmePmrebsShift {
179
+ PMREBS_PMRSZU_SHIFT = 0,
180
+ PMREBS_RBB_SHIFT = 4,
181
+ PMREBS_PMRWBZ_SHIFT = 8,
182
+};
183
+
184
+enum NvmePmrebsMask {
185
+ PMREBS_PMRSZU_MASK = 0xf,
186
+ PMREBS_RBB_MASK = 0x1,
187
+ PMREBS_PMRWBZ_MASK = 0xffffff,
188
+};
189
+
190
+#define NVME_PMREBS_PMRSZU(pmrebs) \
191
+ ((pmrebs >> PMREBS_PMRSZU_SHIFT) & PMREBS_PMRSZU_MASK)
192
+#define NVME_PMREBS_RBB(pmrebs) \
193
+ ((pmrebs >> PMREBS_RBB_SHIFT) & PMREBS_RBB_MASK)
194
+#define NVME_PMREBS_PMRWBZ(pmrebs) \
195
+ ((pmrebs >> PMREBS_PMRWBZ_SHIFT) & PMREBS_PMRWBZ_MASK)
196
+
197
+#define NVME_PMREBS_SET_PMRSZU(pmrebs, val) \
198
+ (pmrebs |= (uint64_t)(val & PMREBS_PMRSZU_MASK) << PMREBS_PMRSZU_SHIFT)
199
+#define NVME_PMREBS_SET_RBB(pmrebs, val) \
200
+ (pmrebs |= (uint64_t)(val & PMREBS_RBB_MASK) << PMREBS_RBB_SHIFT)
201
+#define NVME_PMREBS_SET_PMRWBZ(pmrebs, val) \
202
+ (pmrebs |= (uint64_t)(val & PMREBS_PMRWBZ_MASK) << PMREBS_PMRWBZ_SHIFT)
203
+
204
+enum NvmePmrswtpShift {
205
+ PMRSWTP_PMRSWTU_SHIFT = 0,
206
+ PMRSWTP_PMRSWTV_SHIFT = 8,
207
+};
208
+
209
+enum NvmePmrswtpMask {
210
+ PMRSWTP_PMRSWTU_MASK = 0xf,
211
+ PMRSWTP_PMRSWTV_MASK = 0xffffff,
212
+};
213
+
214
+#define NVME_PMRSWTP_PMRSWTU(pmrswtp) \
215
+ ((pmrswtp >> PMRSWTP_PMRSWTU_SHIFT) & PMRSWTP_PMRSWTU_MASK)
216
+#define NVME_PMRSWTP_PMRSWTV(pmrswtp) \
217
+ ((pmrswtp >> PMRSWTP_PMRSWTV_SHIFT) & PMRSWTP_PMRSWTV_MASK)
218
+
219
+#define NVME_PMRSWTP_SET_PMRSWTU(pmrswtp, val) \
220
+ (pmrswtp |= (uint64_t)(val & PMRSWTP_PMRSWTU_MASK) << PMRSWTP_PMRSWTU_SHIFT)
221
+#define NVME_PMRSWTP_SET_PMRSWTV(pmrswtp, val) \
222
+ (pmrswtp |= (uint64_t)(val & PMRSWTP_PMRSWTV_MASK) << PMRSWTP_PMRSWTV_SHIFT)
223
+
224
+enum NvmePmrmscShift {
225
+ PMRMSC_CMSE_SHIFT = 1,
226
+ PMRMSC_CBA_SHIFT = 12,
227
+};
228
+
229
+enum NvmePmrmscMask {
230
+ PMRMSC_CMSE_MASK = 0x1,
231
+ PMRMSC_CBA_MASK = 0xfffffffffffff,
232
+};
233
+
234
+#define NVME_PMRMSC_CMSE(pmrmsc) \
235
+ ((pmrmsc >> PMRMSC_CMSE_SHIFT) & PMRMSC_CMSE_MASK)
236
+#define NVME_PMRMSC_CBA(pmrmsc) \
237
+ ((pmrmsc >> PMRMSC_CBA_SHIFT) & PMRMSC_CBA_MASK)
238
+
239
+#define NVME_PMRMSC_SET_CMSE(pmrmsc, val) \
240
+ (pmrmsc |= (uint64_t)(val & PMRMSC_CMSE_MASK) << PMRMSC_CMSE_SHIFT)
241
+#define NVME_PMRMSC_SET_CBA(pmrmsc, val) \
242
+ (pmrmsc |= (uint64_t)(val & PMRMSC_CBA_MASK) << PMRMSC_CBA_SHIFT)
243
+
244
typedef struct NvmeCmd {
245
uint8_t opcode;
246
uint8_t fuse;
247
diff --git a/hw/block/nvme.c b/hw/block/nvme.c
248
index XXXXXXX..XXXXXXX 100644
249
--- a/hw/block/nvme.c
250
+++ b/hw/block/nvme.c
251
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@
252
* -drive file=<file>,if=none,id=<drive_id>
21
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
253
* -device nvme,drive=<drive_id>,serial=<serial>,id=<id[optional]>, \
22
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
254
* cmb_size_mb=<cmb_size_mb[optional]>, \
23
* THE SOFTWARE.
255
+ * [pmrdev=<mem_backend_file_id>,] \
256
* num_queues=<N[optional]>
257
*
258
* Note cmb_size_mb denotes size of CMB in MB. CMB is assumed to be at
259
* offset 0 in BAR2 and supports only WDS, RDS and SQS for now.
260
+ *
24
+ *
261
+ * cmb_size_mb= and pmrdev= options are mutually exclusive due to limitation
25
+ * References:
262
+ * in available BAR's. cmb_size_mb= will take precedence over pmrdev= when
26
+ * [1] 82371FB (PIIX) AND 82371SB (PIIX3) PCI ISA IDE XCELERATOR,
263
+ * both provided.
27
+ * 290550-002, Intel Corporation, April 1997.
264
+ * Enabling pmr emulation can be achieved by pointing to memory-backend-file.
265
+ * For example:
266
+ * -object memory-backend-file,id=<mem_id>,share=on,mem-path=<file_path>, \
267
+ * size=<size> .... -device nvme,...,pmrdev=<mem_id>
268
*/
28
*/
269
29
270
#include "qemu/osdep.h"
30
#include "qemu/osdep.h"
271
@@ -XXX,XX +XXX,XX @@
31
@@ -XXX,XX +XXX,XX @@ static void piix_ide_reset(DeviceState *dev)
272
#include "sysemu/sysemu.h"
32
ide_bus_reset(&d->bus[i]);
273
#include "qapi/error.h"
274
#include "qapi/visitor.h"
275
+#include "sysemu/hostmem.h"
276
#include "sysemu/block-backend.h"
277
+#include "exec/ram_addr.h"
278
279
#include "qemu/log.h"
280
#include "qemu/module.h"
281
@@ -XXX,XX +XXX,XX @@ static void nvme_write_bar(NvmeCtrl *n, hwaddr offset, uint64_t data,
282
NVME_GUEST_ERR(nvme_ub_mmiowr_cmbsz_readonly,
283
"invalid write to read only CMBSZ, ignored");
284
return;
285
+ case 0xE00: /* PMRCAP */
286
+ NVME_GUEST_ERR(nvme_ub_mmiowr_pmrcap_readonly,
287
+ "invalid write to PMRCAP register, ignored");
288
+ return;
289
+ case 0xE04: /* TODO PMRCTL */
290
+ break;
291
+ case 0xE08: /* PMRSTS */
292
+ NVME_GUEST_ERR(nvme_ub_mmiowr_pmrsts_readonly,
293
+ "invalid write to PMRSTS register, ignored");
294
+ return;
295
+ case 0xE0C: /* PMREBS */
296
+ NVME_GUEST_ERR(nvme_ub_mmiowr_pmrebs_readonly,
297
+ "invalid write to PMREBS register, ignored");
298
+ return;
299
+ case 0xE10: /* PMRSWTP */
300
+ NVME_GUEST_ERR(nvme_ub_mmiowr_pmrswtp_readonly,
301
+ "invalid write to PMRSWTP register, ignored");
302
+ return;
303
+ case 0xE14: /* TODO PMRMSC */
304
+ break;
305
default:
306
NVME_GUEST_ERR(nvme_ub_mmiowr_invalid,
307
"invalid MMIO write,"
308
@@ -XXX,XX +XXX,XX @@ static uint64_t nvme_mmio_read(void *opaque, hwaddr addr, unsigned size)
309
}
33
}
310
34
311
if (addr < sizeof(n->bar)) {
35
- /* TODO: this is the default. do not override. */
312
+ /*
36
- pci_conf[PCI_COMMAND] = 0x00;
313
+ * When PMRWBM bit 1 is set then read from
37
- /* TODO: this is the default. do not override. */
314
+ * from PMRSTS should ensure prior writes
38
- pci_conf[PCI_COMMAND + 1] = 0x00;
315
+ * made it to persistent media
39
- /* TODO: use pci_set_word */
316
+ */
40
- pci_conf[PCI_STATUS] = PCI_STATUS_FAST_BACK;
317
+ if (addr == 0xE08 &&
41
- pci_conf[PCI_STATUS + 1] = PCI_STATUS_DEVSEL_MEDIUM >> 8;
318
+ (NVME_PMRCAP_PMRWBM(n->bar.pmrcap) & 0x02)) {
42
- pci_conf[0x20] = 0x01; /* BMIBA: 20-23h */
319
+ qemu_ram_writeback(n->pmrdev->mr.ram_block,
43
+ /* PCI command register default value (0000h) per [1, p.48]. */
320
+ 0, n->pmrdev->size);
44
+ pci_set_word(pci_conf + PCI_COMMAND, 0x0000);
321
+ }
45
+ pci_set_word(pci_conf + PCI_STATUS,
322
memcpy(&val, ptr + addr, size);
46
+ PCI_STATUS_DEVSEL_MEDIUM | PCI_STATUS_FAST_BACK);
323
} else {
47
+ pci_set_byte(pci_conf + 0x20, 0x01); /* BMIBA: 20-23h */
324
NVME_GUEST_ERR(nvme_ub_mmiord_invalid_ofs,
325
@@ -XXX,XX +XXX,XX @@ static void nvme_realize(PCIDevice *pci_dev, Error **errp)
326
error_setg(errp, "serial property not set");
327
return;
328
}
329
+
330
+ if (!n->cmb_size_mb && n->pmrdev) {
331
+ if (host_memory_backend_is_mapped(n->pmrdev)) {
332
+ char *path = object_get_canonical_path_component(OBJECT(n->pmrdev));
333
+ error_setg(errp, "can't use already busy memdev: %s", path);
334
+ g_free(path);
335
+ return;
336
+ }
337
+
338
+ if (!is_power_of_2(n->pmrdev->size)) {
339
+ error_setg(errp, "pmr backend size needs to be power of 2 in size");
340
+ return;
341
+ }
342
+
343
+ host_memory_backend_set_mapped(n->pmrdev, true);
344
+ }
345
+
346
blkconf_blocksizes(&n->conf);
347
if (!blkconf_apply_backend_options(&n->conf, blk_is_read_only(n->conf.blk),
348
false, errp)) {
349
@@ -XXX,XX +XXX,XX @@ static void nvme_realize(PCIDevice *pci_dev, Error **errp)
350
PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_TYPE_64 |
351
PCI_BASE_ADDRESS_MEM_PREFETCH, &n->ctrl_mem);
352
353
+ } else if (n->pmrdev) {
354
+ /* Controller Capabilities register */
355
+ NVME_CAP_SET_PMRS(n->bar.cap, 1);
356
+
357
+ /* PMR Capabities register */
358
+ n->bar.pmrcap = 0;
359
+ NVME_PMRCAP_SET_RDS(n->bar.pmrcap, 0);
360
+ NVME_PMRCAP_SET_WDS(n->bar.pmrcap, 0);
361
+ NVME_PMRCAP_SET_BIR(n->bar.pmrcap, 2);
362
+ NVME_PMRCAP_SET_PMRTU(n->bar.pmrcap, 0);
363
+ /* Turn on bit 1 support */
364
+ NVME_PMRCAP_SET_PMRWBM(n->bar.pmrcap, 0x02);
365
+ NVME_PMRCAP_SET_PMRTO(n->bar.pmrcap, 0);
366
+ NVME_PMRCAP_SET_CMSS(n->bar.pmrcap, 0);
367
+
368
+ /* PMR Control register */
369
+ n->bar.pmrctl = 0;
370
+ NVME_PMRCTL_SET_EN(n->bar.pmrctl, 0);
371
+
372
+ /* PMR Status register */
373
+ n->bar.pmrsts = 0;
374
+ NVME_PMRSTS_SET_ERR(n->bar.pmrsts, 0);
375
+ NVME_PMRSTS_SET_NRDY(n->bar.pmrsts, 0);
376
+ NVME_PMRSTS_SET_HSTS(n->bar.pmrsts, 0);
377
+ NVME_PMRSTS_SET_CBAI(n->bar.pmrsts, 0);
378
+
379
+ /* PMR Elasticity Buffer Size register */
380
+ n->bar.pmrebs = 0;
381
+ NVME_PMREBS_SET_PMRSZU(n->bar.pmrebs, 0);
382
+ NVME_PMREBS_SET_RBB(n->bar.pmrebs, 0);
383
+ NVME_PMREBS_SET_PMRWBZ(n->bar.pmrebs, 0);
384
+
385
+ /* PMR Sustained Write Throughput register */
386
+ n->bar.pmrswtp = 0;
387
+ NVME_PMRSWTP_SET_PMRSWTU(n->bar.pmrswtp, 0);
388
+ NVME_PMRSWTP_SET_PMRSWTV(n->bar.pmrswtp, 0);
389
+
390
+ /* PMR Memory Space Control register */
391
+ n->bar.pmrmsc = 0;
392
+ NVME_PMRMSC_SET_CMSE(n->bar.pmrmsc, 0);
393
+ NVME_PMRMSC_SET_CBA(n->bar.pmrmsc, 0);
394
+
395
+ pci_register_bar(pci_dev, NVME_PMRCAP_BIR(n->bar.pmrcap),
396
+ PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_TYPE_64 |
397
+ PCI_BASE_ADDRESS_MEM_PREFETCH, &n->pmrdev->mr);
398
}
399
400
for (i = 0; i < n->num_namespaces; i++) {
401
@@ -XXX,XX +XXX,XX @@ static void nvme_exit(PCIDevice *pci_dev)
402
if (n->cmb_size_mb) {
403
g_free(n->cmbuf);
404
}
405
+
406
+ if (n->pmrdev) {
407
+ host_memory_backend_set_mapped(n->pmrdev, false);
408
+ }
409
msix_uninit_exclusive_bar(pci_dev);
410
}
48
}
411
49
412
static Property nvme_props[] = {
50
static int pci_piix_init_ports(PCIIDEState *d)
413
DEFINE_BLOCK_PROPERTIES(NvmeCtrl, conf),
414
+ DEFINE_PROP_LINK("pmrdev", NvmeCtrl, pmrdev, TYPE_MEMORY_BACKEND,
415
+ HostMemoryBackend *),
416
DEFINE_PROP_STRING("serial", NvmeCtrl, serial),
417
DEFINE_PROP_UINT32("cmb_size_mb", NvmeCtrl, cmb_size_mb, 0),
418
DEFINE_PROP_UINT32("num_queues", NvmeCtrl, num_queues, 64),
419
diff --git a/hw/block/Makefile.objs b/hw/block/Makefile.objs
420
index XXXXXXX..XXXXXXX 100644
421
--- a/hw/block/Makefile.objs
422
+++ b/hw/block/Makefile.objs
423
@@ -XXX,XX +XXX,XX @@ common-obj-$(CONFIG_PFLASH_CFI02) += pflash_cfi02.o
424
common-obj-$(CONFIG_XEN) += xen-block.o
425
common-obj-$(CONFIG_ECC) += ecc.o
426
common-obj-$(CONFIG_ONENAND) += onenand.o
427
-common-obj-$(CONFIG_NVME_PCI) += nvme.o
428
common-obj-$(CONFIG_SWIM) += swim.o
429
430
common-obj-$(CONFIG_SH4) += tc58128.o
431
432
obj-$(CONFIG_VIRTIO_BLK) += virtio-blk.o
433
obj-$(CONFIG_VHOST_USER_BLK) += vhost-user-blk.o
434
+obj-$(CONFIG_NVME_PCI) += nvme.o
435
436
obj-y += dataplane/
437
diff --git a/hw/block/trace-events b/hw/block/trace-events
438
index XXXXXXX..XXXXXXX 100644
439
--- a/hw/block/trace-events
440
+++ b/hw/block/trace-events
441
@@ -XXX,XX +XXX,XX @@ nvme_ub_mmiowr_ssreset_w1c_unsupported(void) "attempted to W1C CSTS.NSSRO but CA
442
nvme_ub_mmiowr_ssreset_unsupported(void) "attempted NVM subsystem reset but CAP.NSSRS is zero (not supported)"
443
nvme_ub_mmiowr_cmbloc_reserved(void) "invalid write to reserved CMBLOC when CMBSZ is zero, ignored"
444
nvme_ub_mmiowr_cmbsz_readonly(void) "invalid write to read only CMBSZ, ignored"
445
+nvme_ub_mmiowr_pmrcap_readonly(void) "invalid write to read only PMRCAP, ignored"
446
+nvme_ub_mmiowr_pmrsts_readonly(void) "invalid write to read only PMRSTS, ignored"
447
+nvme_ub_mmiowr_pmrebs_readonly(void) "invalid write to read only PMREBS, ignored"
448
+nvme_ub_mmiowr_pmrswtp_readonly(void) "invalid write to read only PMRSWTP, ignored"
449
nvme_ub_mmiowr_invalid(uint64_t offset, uint64_t data) "invalid MMIO write, offset=0x%"PRIx64", data=0x%"PRIx64""
450
nvme_ub_mmiord_misaligned32(uint64_t offset) "MMIO read not 32-bit aligned, offset=0x%"PRIx64""
451
nvme_ub_mmiord_toosmall(uint64_t offset) "MMIO read smaller than 32-bits, offset=0x%"PRIx64""
452
--
51
--
453
2.25.3
52
2.37.3
454
455
diff view generated by jsdifflib
1
From: Paolo Bonzini <pbonzini@redhat.com>
1
From: Lev Kujawski <lkujaw@member.fsf.org>
2
2
3
Test 244 checks the expected behavior of qcow2 external data files
3
Change 'tmp_path' into an array of two members to accommodate another
4
with respect to zero and discarded clusters. Filesystems however
4
disk image of size TEST_IMAGE_SIZE. This facilitates testing ATA
5
are free to ignore discard requests, and this seems to be the
5
protocol aspects peculiar to secondary devices on the same controller.
6
case for overlayfs. Relax the tests to skip checks on the
7
external data file for discarded areas, which implies not using
8
qemu-img compare in the data_file_raw=on case.
9
6
10
This fixes docker tests on RHEL8.
7
Signed-off-by: Lev Kujawski <lkujaw@member.fsf.org>
11
8
Message-Id: <20220707031140.158958-2-lkujaw@member.fsf.org>
12
Cc: Kevin Wolf <kwolf@redhat.com>
13
Cc: qemu-block@nongnu.org
14
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
15
Message-Id: <20200409191006.24429-1-pbonzini@redhat.com>
16
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
17
---
10
---
18
tests/qemu-iotests/244 | 10 ++++++++--
11
tests/qtest/ide-test.c | 39 ++++++++++++++++++++++-----------------
19
tests/qemu-iotests/244.out | 9 ++++++---
12
1 file changed, 22 insertions(+), 17 deletions(-)
20
2 files changed, 14 insertions(+), 5 deletions(-)
21
13
22
diff --git a/tests/qemu-iotests/244 b/tests/qemu-iotests/244
14
diff --git a/tests/qtest/ide-test.c b/tests/qtest/ide-test.c
23
index XXXXXXX..XXXXXXX 100755
24
--- a/tests/qemu-iotests/244
25
+++ b/tests/qemu-iotests/244
26
@@ -XXX,XX +XXX,XX @@ $QEMU_IO -c 'read -P 0 0 1M' \
27
echo
28
$QEMU_IO -c 'read -P 0 0 1M' \
29
-c 'read -P 0x11 1M 1M' \
30
- -c 'read -P 0 2M 2M' \
31
-c 'read -P 0x11 4M 1M' \
32
-c 'read -P 0 5M 1M' \
33
-f raw "$TEST_IMG.data" |
34
@@ -XXX,XX +XXX,XX @@ $QEMU_IO -c 'read -P 0 0 1M' \
35
-f $IMGFMT "$TEST_IMG" |
36
_filter_qemu_io
37
38
+# Discarded clusters are only marked as such in the qcow2 metadata, but
39
+# they can contain stale data in the external data file. Instead, zero
40
+# clusters must be zeroed in the external data file too.
41
echo
42
-$QEMU_IMG compare "$TEST_IMG" "$TEST_IMG.data"
43
+$QEMU_IO -c 'read -P 0 0 1M' \
44
+ -c 'read -P 0x11 1M 1M' \
45
+ -c 'read -P 0 3M 3M' \
46
+ -f raw "$TEST_IMG".data |
47
+ _filter_qemu_io
48
49
echo -n "qcow2 file size after I/O: "
50
du -b $TEST_IMG | cut -f1
51
diff --git a/tests/qemu-iotests/244.out b/tests/qemu-iotests/244.out
52
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
53
--- a/tests/qemu-iotests/244.out
16
--- a/tests/qtest/ide-test.c
54
+++ b/tests/qemu-iotests/244.out
17
+++ b/tests/qtest/ide-test.c
55
@@ -XXX,XX +XXX,XX @@ read 1048576/1048576 bytes at offset 0
18
@@ -XXX,XX +XXX,XX @@ enum {
56
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
19
static QPCIBus *pcibus = NULL;
57
read 1048576/1048576 bytes at offset 1048576
20
static QGuestAllocator guest_malloc;
58
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
21
59
-read 2097152/2097152 bytes at offset 2097152
22
-static char *tmp_path;
60
-2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
23
+static char *tmp_path[2];
61
read 1048576/1048576 bytes at offset 4194304
24
static char *debug_path;
62
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
25
63
read 1048576/1048576 bytes at offset 5242880
26
static QTestState *ide_test_start(const char *cmdline_fmt, ...)
64
@@ -XXX,XX +XXX,XX @@ read 1048576/1048576 bytes at offset 1048576
27
@@ -XXX,XX +XXX,XX @@ static QTestState *test_bmdma_setup(void)
65
read 4194304/4194304 bytes at offset 2097152
28
qts = ide_test_start(
66
4 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
29
"-drive file=%s,if=ide,cache=writeback,format=raw "
67
30
"-global ide-hd.serial=%s -global ide-hd.ver=%s",
68
-Images are identical.
31
- tmp_path, "testdisk", "version");
69
+read 1048576/1048576 bytes at offset 0
32
+ tmp_path[0], "testdisk", "version");
70
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
33
qtest_irq_intercept_in(qts, "ioapic");
71
+read 1048576/1048576 bytes at offset 1048576
34
72
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
35
return qts;
73
+read 3145728/3145728 bytes at offset 3145728
36
@@ -XXX,XX +XXX,XX @@ static void test_identify(void)
74
+3 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
37
qts = ide_test_start(
75
qcow2 file size after I/O: 327680
38
"-drive file=%s,if=ide,cache=writeback,format=raw "
76
39
"-global ide-hd.serial=%s -global ide-hd.ver=%s",
77
=== bdrv_co_block_status test for file and offset=0 ===
40
- tmp_path, "testdisk", "version");
41
+ tmp_path[0], "testdisk", "version");
42
43
dev = get_pci_device(qts, &bmdma_bar, &ide_bar);
44
45
@@ -XXX,XX +XXX,XX @@ static void test_flush(void)
46
47
qts = ide_test_start(
48
"-drive file=blkdebug::%s,if=ide,cache=writeback,format=raw",
49
- tmp_path);
50
+ tmp_path[0]);
51
52
dev = get_pci_device(qts, &bmdma_bar, &ide_bar);
53
54
@@ -XXX,XX +XXX,XX @@ static void test_pci_retry_flush(void)
55
qts = ide_test_start(
56
"-drive file=blkdebug:%s:%s,if=ide,cache=writeback,format=raw,"
57
"rerror=stop,werror=stop",
58
- debug_path, tmp_path);
59
+ debug_path, tmp_path[0]);
60
61
dev = get_pci_device(qts, &bmdma_bar, &ide_bar);
62
63
@@ -XXX,XX +XXX,XX @@ static void cdrom_pio_impl(int nblocks)
64
65
/* Prepopulate the CDROM with an interesting pattern */
66
generate_pattern(pattern, patt_len, ATAPI_BLOCK_SIZE);
67
- fh = fopen(tmp_path, "wb+");
68
+ fh = fopen(tmp_path[0], "wb+");
69
ret = fwrite(pattern, ATAPI_BLOCK_SIZE, patt_blocks, fh);
70
g_assert_cmpint(ret, ==, patt_blocks);
71
fclose(fh);
72
73
qts = ide_test_start(
74
"-drive if=none,file=%s,media=cdrom,format=raw,id=sr0,index=0 "
75
- "-device ide-cd,drive=sr0,bus=ide.0", tmp_path);
76
+ "-device ide-cd,drive=sr0,bus=ide.0", tmp_path[0]);
77
dev = get_pci_device(qts, &bmdma_bar, &ide_bar);
78
qtest_irq_intercept_in(qts, "ioapic");
79
80
@@ -XXX,XX +XXX,XX @@ static void test_cdrom_dma(void)
81
82
qts = ide_test_start(
83
"-drive if=none,file=%s,media=cdrom,format=raw,id=sr0,index=0 "
84
- "-device ide-cd,drive=sr0,bus=ide.0", tmp_path);
85
+ "-device ide-cd,drive=sr0,bus=ide.0", tmp_path[0]);
86
qtest_irq_intercept_in(qts, "ioapic");
87
88
guest_buf = guest_alloc(&guest_malloc, len);
89
@@ -XXX,XX +XXX,XX @@ static void test_cdrom_dma(void)
90
prdt[0].size = cpu_to_le32(len | PRDT_EOT);
91
92
generate_pattern(pattern, ATAPI_BLOCK_SIZE * 16, ATAPI_BLOCK_SIZE);
93
- fh = fopen(tmp_path, "wb+");
94
+ fh = fopen(tmp_path[0], "wb+");
95
ret = fwrite(pattern, ATAPI_BLOCK_SIZE, 16, fh);
96
g_assert_cmpint(ret, ==, 16);
97
fclose(fh);
98
@@ -XXX,XX +XXX,XX @@ static void test_cdrom_dma(void)
99
int main(int argc, char **argv)
100
{
101
const char *base;
102
+ int i;
103
int fd;
104
int ret;
105
106
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv)
107
close(fd);
108
109
/* Create a temporary raw image */
110
- tmp_path = g_strdup_printf("%s/qtest.XXXXXX", base);
111
- fd = g_mkstemp(tmp_path);
112
- g_assert(fd >= 0);
113
- ret = ftruncate(fd, TEST_IMAGE_SIZE);
114
- g_assert(ret == 0);
115
- close(fd);
116
+ for (i = 0; i < 2; ++i) {
117
+ tmp_path[i] = g_strdup_printf("%s/qtest.XXXXXX", base);
118
+ fd = g_mkstemp(tmp_path[i]);
119
+ g_assert(fd >= 0);
120
+ ret = ftruncate(fd, TEST_IMAGE_SIZE);
121
+ g_assert(ret == 0);
122
+ close(fd);
123
+ }
124
125
/* Run the tests */
126
g_test_init(&argc, &argv, NULL);
127
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv)
128
ret = g_test_run();
129
130
/* Cleanup */
131
- unlink(tmp_path);
132
- g_free(tmp_path);
133
+ for (i = 0; i < 2; ++i) {
134
+ unlink(tmp_path[i]);
135
+ g_free(tmp_path[i]);
136
+ }
137
unlink(debug_path);
138
g_free(debug_path);
139
78
--
140
--
79
2.25.3
141
2.37.3
80
81
diff view generated by jsdifflib
1
After processing the option string with the keyval parser, we get a
1
From: Lev Kujawski <lkujaw@member.fsf.org>
2
QDict that contains only strings. This QDict must be fed to a keyval
3
visitor which converts the strings into the right data types.
4
2
5
qmp_object_add(), however, uses the normal QObject input visitor, which
3
Prior to this patch, cmd_exec_dev_diagnostic relied upon
6
expects a QDict where all properties already have the QType that matches
4
ide_set_signature to clear the device register. While the
7
the data type required by the QOM object type.
5
preservation of the drive bit by ide_set_signature is necessary for
6
the DEVICE RESET, IDENTIFY DEVICE, and READ SECTOR commands,
7
ATA/ATAPI-6 specifies that "DEV shall be cleared to zero" for EXECUTE
8
DEVICE DIAGNOSTIC.
8
9
9
Change the --object implementation in qemu-storage-daemon so that it
10
This deviation was uncovered by the ATACT Device Testing Program
10
doesn't call qmp_object_add(), but calls user_creatable_add_dict()
11
written by Hale Landis.
11
directly instead and pass it a new keyval boolean that decides which
12
visitor must be used.
13
12
14
Reported-by: Coiby Xu <coiby.xu@gmail.com>
13
Signed-off-by: Lev Kujawski <lkujaw@member.fsf.org>
14
Message-Id: <20220707031140.158958-3-lkujaw@member.fsf.org>
15
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
15
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
16
---
16
---
17
include/qom/object_interfaces.h | 6 +++++-
17
hw/ide/core.c | 6 ++++++
18
qemu-storage-daemon.c | 4 +---
18
1 file changed, 6 insertions(+)
19
qom/object_interfaces.c | 8 ++++++--
20
qom/qom-qmp-cmds.c | 2 +-
21
4 files changed, 13 insertions(+), 7 deletions(-)
22
19
23
diff --git a/include/qom/object_interfaces.h b/include/qom/object_interfaces.h
20
diff --git a/hw/ide/core.c b/hw/ide/core.c
24
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
25
--- a/include/qom/object_interfaces.h
22
--- a/hw/ide/core.c
26
+++ b/include/qom/object_interfaces.h
23
+++ b/hw/ide/core.c
27
@@ -XXX,XX +XXX,XX @@ Object *user_creatable_add_type(const char *type, const char *id,
24
@@ -XXX,XX +XXX,XX @@ static bool cmd_identify_packet(IDEState *s, uint8_t cmd)
28
/**
25
return false;
29
* user_creatable_add_dict:
30
* @qdict: the object definition
31
+ * @keyval: if true, use a keyval visitor for processing @qdict (i.e.
32
+ * assume that all @qdict values are strings); otherwise, use
33
+ * the normal QObject visitor (i.e. assume all @qdict values
34
+ * have the QType expected by the QOM object type)
35
* @errp: if an error occurs, a pointer to an area to store the error
36
*
37
* Create an instance of the user creatable object that is defined by
38
@@ -XXX,XX +XXX,XX @@ Object *user_creatable_add_type(const char *type, const char *id,
39
* ID from the key 'id'. The remaining entries in @qdict are used to
40
* initialize the object properties.
41
*/
42
-void user_creatable_add_dict(QDict *qdict, Error **errp);
43
+void user_creatable_add_dict(QDict *qdict, bool keyval, Error **errp);
44
45
/**
46
* user_creatable_add_opts:
47
diff --git a/qemu-storage-daemon.c b/qemu-storage-daemon.c
48
index XXXXXXX..XXXXXXX 100644
49
--- a/qemu-storage-daemon.c
50
+++ b/qemu-storage-daemon.c
51
@@ -XXX,XX +XXX,XX @@ static void process_options(int argc, char *argv[])
52
QemuOpts *opts;
53
const char *type;
54
QDict *args;
55
- QObject *ret_data = NULL;
56
57
/* FIXME The keyval parser rejects 'help' arguments, so we must
58
* unconditionall try QemuOpts first. */
59
@@ -XXX,XX +XXX,XX @@ static void process_options(int argc, char *argv[])
60
qemu_opts_del(opts);
61
62
args = keyval_parse(optarg, "qom-type", &error_fatal);
63
- qmp_object_add(args, &ret_data, &error_fatal);
64
+ user_creatable_add_dict(args, true, &error_fatal);
65
qobject_unref(args);
66
- qobject_unref(ret_data);
67
break;
68
}
69
default:
70
diff --git a/qom/object_interfaces.c b/qom/object_interfaces.c
71
index XXXXXXX..XXXXXXX 100644
72
--- a/qom/object_interfaces.c
73
+++ b/qom/object_interfaces.c
74
@@ -XXX,XX +XXX,XX @@ out:
75
return obj;
76
}
26
}
77
27
78
-void user_creatable_add_dict(QDict *qdict, Error **errp)
28
+/* EXECUTE DEVICE DIAGNOSTIC */
79
+void user_creatable_add_dict(QDict *qdict, bool keyval, Error **errp)
29
static bool cmd_exec_dev_diagnostic(IDEState *s, uint8_t cmd)
80
{
30
{
81
Visitor *v;
31
+ /*
82
Object *obj;
32
+ * Clear the device register per the ATA (v6) specification,
83
@@ -XXX,XX +XXX,XX @@ void user_creatable_add_dict(QDict *qdict, Error **errp)
33
+ * because ide_set_signature does not clear LBA or drive bits.
84
}
34
+ */
85
qdict_del(qdict, "id");
35
+ s->select = (ATA_DEV_ALWAYS_ON);
86
36
ide_set_signature(s);
87
- v = qobject_input_visitor_new(QOBJECT(qdict));
37
88
+ if (keyval) {
38
if (s->drive_kind == IDE_CD) {
89
+ v = qobject_input_visitor_new_keyval(QOBJECT(qdict));
90
+ } else {
91
+ v = qobject_input_visitor_new(QOBJECT(qdict));
92
+ }
93
obj = user_creatable_add_type(type, id, qdict, v, errp);
94
visit_free(v);
95
object_unref(obj);
96
diff --git a/qom/qom-qmp-cmds.c b/qom/qom-qmp-cmds.c
97
index XXXXXXX..XXXXXXX 100644
98
--- a/qom/qom-qmp-cmds.c
99
+++ b/qom/qom-qmp-cmds.c
100
@@ -XXX,XX +XXX,XX @@ void qmp_object_add(QDict *qdict, QObject **ret_data, Error **errp)
101
qobject_unref(pdict);
102
}
103
104
- user_creatable_add_dict(qdict, errp);
105
+ user_creatable_add_dict(qdict, false, errp);
106
}
107
108
void qmp_object_del(const char *id, Error **errp)
109
--
39
--
110
2.25.3
40
2.37.3
111
112
diff view generated by jsdifflib
1
The raw format driver can simply forward the flag and let its bs->file
1
From: Lev Kujawski <lkujaw@member.fsf.org>
2
child take care of actually providing the zeros.
3
2
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
3
Verify correction of EXECUTE DEVICE DIAGNOSTIC introduced in commit
5
Reviewed-by: Max Reitz <mreitz@redhat.com>
4
72423831c3 (hw/ide/core: Clear LBA and drive bits for EXECUTE DEVICE
6
Reviewed-by: Eric Blake <eblake@redhat.com>
5
DIAGNOSTIC, 2022-05-28).
7
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
6
8
Message-Id: <20200424125448.63318-6-kwolf@redhat.com>
7
Signed-off-by: Lev Kujawski <lkujaw@member.fsf.org>
8
Message-Id: <20220707031140.158958-4-lkujaw@member.fsf.org>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
10
---
11
block/raw-format.c | 4 +++-
11
tests/qtest/ide-test.c | 33 +++++++++++++++++++++++++++++++++
12
1 file changed, 3 insertions(+), 1 deletion(-)
12
1 file changed, 33 insertions(+)
13
13
14
diff --git a/block/raw-format.c b/block/raw-format.c
14
diff --git a/tests/qtest/ide-test.c b/tests/qtest/ide-test.c
15
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
16
--- a/block/raw-format.c
16
--- a/tests/qtest/ide-test.c
17
+++ b/block/raw-format.c
17
+++ b/tests/qtest/ide-test.c
18
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn raw_co_truncate(BlockDriverState *bs, int64_t offset,
18
@@ -XXX,XX +XXX,XX @@ enum {
19
19
20
s->size = offset;
20
enum {
21
offset += s->offset;
21
CMD_DSM = 0x06,
22
- return bdrv_co_truncate(bs->file, offset, exact, prealloc, 0, errp);
22
+ CMD_DIAGNOSE = 0x90,
23
+ return bdrv_co_truncate(bs->file, offset, exact, prealloc, flags, errp);
23
CMD_READ_DMA = 0xc8,
24
CMD_WRITE_DMA = 0xca,
25
CMD_FLUSH_CACHE = 0xe7,
26
@@ -XXX,XX +XXX,XX @@ static void test_identify(void)
27
free_pci_device(dev);
24
}
28
}
25
29
26
static void raw_eject(BlockDriverState *bs, bool eject_flag)
30
+static void test_diagnostic(void)
27
@@ -XXX,XX +XXX,XX @@ static int raw_open(BlockDriverState *bs, QDict *options, int flags,
31
+{
28
bs->supported_zero_flags = BDRV_REQ_WRITE_UNCHANGED |
32
+ QTestState *qts;
29
((BDRV_REQ_FUA | BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK) &
33
+ QPCIDevice *dev;
30
bs->file->bs->supported_zero_flags);
34
+ QPCIBar bmdma_bar, ide_bar;
31
+ bs->supported_truncate_flags = bs->file->bs->supported_truncate_flags &
35
+ uint8_t data;
32
+ BDRV_REQ_ZERO_WRITE;
36
+
33
37
+ qts = ide_test_start(
34
if (bs->probed && !bdrv_is_read_only(bs)) {
38
+ "-blockdev driver=file,node-name=hda,filename=%s "
35
bdrv_refresh_filename(bs->file->bs);
39
+ "-blockdev driver=file,node-name=hdb,filename=%s "
40
+ "-device ide-hd,drive=hda,bus=ide.0,unit=0 "
41
+ "-device ide-hd,drive=hdb,bus=ide.0,unit=1 ",
42
+ tmp_path[0], tmp_path[1]);
43
+
44
+ dev = get_pci_device(qts, &bmdma_bar, &ide_bar);
45
+
46
+ /* DIAGNOSE command on device 1 */
47
+ qpci_io_writeb(dev, ide_bar, reg_device, DEV);
48
+ data = qpci_io_readb(dev, ide_bar, reg_device);
49
+ g_assert_cmphex(data & DEV, ==, DEV);
50
+ qpci_io_writeb(dev, ide_bar, reg_command, CMD_DIAGNOSE);
51
+
52
+ /* Verify that DEVICE is now 0 */
53
+ data = qpci_io_readb(dev, ide_bar, reg_device);
54
+ g_assert_cmphex(data & DEV, ==, 0);
55
+
56
+ ide_test_quit(qts);
57
+ free_pci_device(dev);
58
+}
59
+
60
/*
61
* Write sector 1 with random data to make IDE storage dirty
62
* Needed for flush tests so that flushes actually go though the block layer
63
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv)
64
65
qtest_add_func("/ide/identify", test_identify);
66
67
+ qtest_add_func("/ide/diagnostic", test_diagnostic);
68
+
69
qtest_add_func("/ide/bmdma/simple_rw", test_bmdma_simple_rw);
70
qtest_add_func("/ide/bmdma/trim", test_bmdma_trim);
71
qtest_add_func("/ide/bmdma/various_prdts", test_bmdma_various_prdts);
36
--
72
--
37
2.25.3
73
2.37.3
38
39
diff view generated by jsdifflib
1
From: Alberto Garcia <berto@igalia.com>
1
From: Lev Kujawski <lkujaw@member.fsf.org>
2
2
3
Backing files and raw external data files are mutually exclusive.
3
CHS-based disk utilities and operating systems may adjust the logical
4
The documentation of the raw external data bit (in autoclear_features)
4
geometry of a hard drive to cope with the expectations or limitations
5
already indicates that, but we should also mention it on the other
5
of software using the ATA INITIALIZE_DEVICE_PARAMETERS command.
6
side.
7
6
8
Suggested-by: Eric Blake <eblake@redhat.com>
7
Prior to this patch, INITIALIZE_DEVICE_PARAMETERS was a nop that
9
Signed-off-by: Alberto Garcia <berto@igalia.com>
8
always returned success, raising the possibility of data loss or
10
Message-Id: <20200410121816.8334-1-berto@igalia.com>
9
corruption if the CHS<->LBA translation redirected a write to the
11
Reviewed-by: Eric Blake <eblake@redhat.com>
10
wrong sector.
11
12
* hw/ide/core.c
13
ide_reset():
14
Reset the logical CHS geometry of the hard disk when the power-on
15
defaults feature is enabled.
16
cmd_specify():
17
a) New function implementing INITIALIZE_DEVICE_PARAMETERS.
18
b) Ignore calls for empty or ATAPI devices.
19
cmd_set_features():
20
Implement the power-on defaults enable and disable features.
21
struct ide_cmd_table:
22
Switch WIN_SPECIFY from cmd_nop() to cmd_specify().
23
ide_init_drive():
24
Set new fields 'drive_heads' and 'drive_sectors' based upon the
25
actual disk geometry.
26
27
* include/hw/ide/internal.h
28
struct IDEState:
29
a) Store the actual drive CHS values within the new fields
30
'drive_heads' and 'drive_sectors.'
31
b) Track whether a soft IDE reset should also reset the logical CHS
32
geometry of the hard disk within the new field 'reset_reverts'.
33
34
Signed-off-by: Lev Kujawski <lkujaw@member.fsf.org>
35
Message-Id: <20220707031140.158958-7-lkujaw@member.fsf.org>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
36
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
---
37
---
14
docs/interop/qcow2.txt | 3 +++
38
include/hw/ide/internal.h | 3 +++
15
1 file changed, 3 insertions(+)
39
hw/ide/core.c | 29 ++++++++++++++++++++++++++---
40
2 files changed, 29 insertions(+), 3 deletions(-)
16
41
17
diff --git a/docs/interop/qcow2.txt b/docs/interop/qcow2.txt
42
diff --git a/include/hw/ide/internal.h b/include/hw/ide/internal.h
18
index XXXXXXX..XXXXXXX 100644
43
index XXXXXXX..XXXXXXX 100644
19
--- a/docs/interop/qcow2.txt
44
--- a/include/hw/ide/internal.h
20
+++ b/docs/interop/qcow2.txt
45
+++ b/include/hw/ide/internal.h
21
@@ -XXX,XX +XXX,XX @@ The first cluster of a qcow2 image contains the file header:
46
@@ -XXX,XX +XXX,XX @@ struct IDEState {
22
is stored (NB: The string is not null terminated). 0 if the
47
uint8_t unit;
23
image doesn't have a backing file.
48
/* ide config */
24
49
IDEDriveKind drive_kind;
25
+ Note: backing files are incompatible with raw external data
50
+ int drive_heads, drive_sectors;
26
+ files (auto-clear feature bit 1).
51
int cylinders, heads, sectors, chs_trans;
52
int64_t nb_sectors;
53
int mult_sectors;
54
@@ -XXX,XX +XXX,XX @@ struct IDEState {
55
uint8_t select;
56
uint8_t status;
57
58
+ bool reset_reverts;
27
+
59
+
28
16 - 19: backing_file_size
60
/* set for lba48 access */
29
Length of the backing file name in bytes. Must not be
61
uint8_t lba48;
30
longer than 1023 bytes. Undefined if the image doesn't have
62
BlockBackend *blk;
63
diff --git a/hw/ide/core.c b/hw/ide/core.c
64
index XXXXXXX..XXXXXXX 100644
65
--- a/hw/ide/core.c
66
+++ b/hw/ide/core.c
67
@@ -XXX,XX +XXX,XX @@ static void ide_reset(IDEState *s)
68
s->pio_aiocb = NULL;
69
}
70
71
+ if (s->reset_reverts) {
72
+ s->reset_reverts = false;
73
+ s->heads = s->drive_heads;
74
+ s->sectors = s->drive_sectors;
75
+ }
76
if (s->drive_kind == IDE_CFATA)
77
s->mult_sectors = 0;
78
else
79
@@ -XXX,XX +XXX,XX @@ static bool cmd_check_power_mode(IDEState *s, uint8_t cmd)
80
return true;
81
}
82
83
+/* INITIALIZE DEVICE PARAMETERS */
84
+static bool cmd_specify(IDEState *s, uint8_t cmd)
85
+{
86
+ if (s->blk && s->drive_kind != IDE_CD) {
87
+ s->heads = (s->select & (ATA_DEV_HS)) + 1;
88
+ s->sectors = s->nsector;
89
+ ide_set_irq(s->bus);
90
+ } else {
91
+ ide_abort_command(s);
92
+ }
93
+
94
+ return true;
95
+}
96
+
97
static bool cmd_set_features(IDEState *s, uint8_t cmd)
98
{
99
uint16_t *identify_data;
100
@@ -XXX,XX +XXX,XX @@ static bool cmd_set_features(IDEState *s, uint8_t cmd)
101
ide_flush_cache(s);
102
return false;
103
case 0xcc: /* reverting to power-on defaults enable */
104
+ s->reset_reverts = true;
105
+ return true;
106
case 0x66: /* reverting to power-on defaults disable */
107
+ s->reset_reverts = false;
108
+ return true;
109
case 0xaa: /* read look-ahead enable */
110
case 0x55: /* read look-ahead disable */
111
case 0x05: /* set advanced power management mode */
112
@@ -XXX,XX +XXX,XX @@ static const struct {
113
[WIN_SEEK] = { cmd_seek, HD_CFA_OK | SET_DSC },
114
[CFA_TRANSLATE_SECTOR] = { cmd_cfa_translate_sector, CFA_OK },
115
[WIN_DIAGNOSE] = { cmd_exec_dev_diagnostic, ALL_OK },
116
- [WIN_SPECIFY] = { cmd_nop, HD_CFA_OK | SET_DSC },
117
+ [WIN_SPECIFY] = { cmd_specify, HD_CFA_OK | SET_DSC },
118
[WIN_STANDBYNOW2] = { cmd_nop, HD_CFA_OK },
119
[WIN_IDLEIMMEDIATE2] = { cmd_nop, HD_CFA_OK },
120
[WIN_STANDBY2] = { cmd_nop, HD_CFA_OK },
121
@@ -XXX,XX +XXX,XX @@ int ide_init_drive(IDEState *s, BlockBackend *blk, IDEDriveKind kind,
122
123
blk_get_geometry(blk, &nb_sectors);
124
s->cylinders = cylinders;
125
- s->heads = heads;
126
- s->sectors = secs;
127
+ s->heads = s->drive_heads = heads;
128
+ s->sectors = s->drive_sectors = secs;
129
s->chs_trans = chs_trans;
130
s->nb_sectors = nb_sectors;
131
s->wwn = wwn;
31
--
132
--
32
2.25.3
133
2.37.3
33
34
diff view generated by jsdifflib