1
The following changes since commit 6d8e75d41c58892ccc5d4ad61c4da476684c1c83:
1
The following changes since commit 013a18edbbc59cdad019100c7d03c0494642b74c:
2
2
3
Merge remote-tracking branch 'remotes/rth/tags/pull-axp-20190519' into staging (2019-05-20 11:38:36 +0100)
3
Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20200514' into staging (2020-05-14 16:17:55 +0100)
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 c423a6af592cf36b4f149c54e2966dd0016b7e96:
9
for you to fetch changes up to 7d8f21a650e562270f5ed5341134c9c2c39dc5e8:
10
10
11
iotests: Make 245 faster and more reliable (2019-05-20 17:08:57 +0200)
11
iotests/030: Reduce run time by unthrottling job earlier (2020-05-15 14:12:34 +0200)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
Block layer patches:
14
Block layer patches:
15
15
16
- block: AioContext management, part 1
16
- Introduce real BdrvChildRole
17
- qmp: forbid qmp_cont in RUN_STATE_FINISH_MIGRATE
17
- blk/bdrv_make_empty() functions instead of calling callbacks directly
18
- nvme: fix copy direction in DMA reads going to CMB
18
- mirror: Make sure that source and target size match
19
- file-posix: Fix block status for unaligned raw images with O_DIRECT
19
- block-copy: Fix uninitialized variable
20
- file-posix: Fix xfs_write_zeroes() after EOF
20
- block/replication: Avoid cancelling the job twice
21
- Documentation and iotests improvements
21
- ahci: Log lost IRQs
22
- iotests: Run pylint and mypy in a testcase
23
- iotests: log messages from notrun()
22
24
23
----------------------------------------------------------------
25
----------------------------------------------------------------
24
Alberto Garcia (2):
26
John Snow (1):
25
qcow2: Define and use QCOW2_COMPRESSED_SECTOR_SIZE
27
iotests: log messages from notrun()
26
block: Use BDRV_REQUEST_MAX_BYTES instead of BDRV_REQUEST_MAX_SECTORS
27
28
28
Kevin Wolf (10):
29
Kevin Wolf (8):
29
block: Add bdrv_try_set_aio_context()
30
iotests/109: Don't mirror with mismatched size
30
block: Make bdrv_attach/detach_aio_context() static
31
iotests/229: Use blkdebug to inject an error
31
block: Move recursion to bdrv_set_aio_context()
32
mirror: Make sure that source and target size match
32
block: Propagate AioContext change to parents
33
iotests: Mirror with different source/target size
33
test-block-iothread: Test AioContext propagation through the tree
34
iotests: Fix incomplete type declarations
34
block: Implement .(can_)set_aio_ctx for BlockBackend
35
iotests: Run pylint and mypy in a testcase
35
block: Add blk_set_allow_aio_context_change()
36
replication: Avoid blk_make_empty() on read-only child
36
blockjob: Propagate AioContext change to all job nodes
37
iotests/030: Reduce run time by unthrottling job earlier
37
blockjob: Remove AioContext notifiers
38
test-block-iothread: Test AioContext propagation for block jobs
39
38
40
Klaus Birkelund Jensen (1):
39
Lukas Straub (1):
41
nvme: fix copy direction in DMA reads going to CMB
40
block/replication.c: Avoid cancelling the job twice
42
41
43
Max Reitz (9):
42
Max Reitz (38):
44
block/file-posix: Truncate in xfs_write_zeroes()
43
block: Add bdrv_make_empty()
45
block/file-posix: Unaligned O_DIRECT block-status
44
block: Add blk_make_empty()
46
iotests: Test unaligned raw images with O_DIRECT
45
block: Use blk_make_empty() after commits
47
qemu-img.texi: Be specific about JSON object types
46
block: Use bdrv_make_empty() where possible
48
qemu-img.texi: Describe human-readable info output
47
block: Mark commit, mirror, blkreplay as filters
49
block: Improve "Block node is read-only" message
48
block: Add BlockDriver.is_format
50
iotests.py: Let assert_qmp() accept an array
49
block: Rename BdrvChildRole to BdrvChildClass
51
iotests.py: Fix VM.run_job
50
block: Add BdrvChildRole and BdrvChildRoleBits
52
iotests: Make 245 faster and more reliable
51
block: Add BdrvChildRole to BdrvChild
52
block: Pass BdrvChildRole to bdrv_child_perm()
53
block: Pass BdrvChildRole to .inherit_options()
54
block: Pass parent_is_format to .inherit_options()
55
block: Rename bdrv_inherited_options()
56
block: Add generic bdrv_inherited_options()
57
block: Use bdrv_inherited_options()
58
block: Unify bdrv_child_cb_attach()
59
block: Unify bdrv_child_cb_detach()
60
block: Add child_of_bds
61
block: Distinguish paths in *_format_default_perms
62
block: Pull out bdrv_default_perms_for_cow()
63
block: Pull out bdrv_default_perms_for_storage()
64
block: Relax *perms_for_storage for data children
65
block: Add bdrv_default_perms()
66
raw-format: Split raw_read_options()
67
block: Switch child_format users to child_of_bds
68
block: Drop child_format
69
block: Make backing files child_of_bds children
70
block: Drop child_backing
71
block: Make format drivers use child_of_bds
72
block: Make filter drivers use child_of_bds
73
block: Use child_of_bds in remaining places
74
tests: Use child_of_bds instead of child_file
75
block: Use bdrv_default_perms()
76
block: Make bdrv_filter_default_perms() static
77
block: Drop bdrv_format_default_perms()
78
block: Drop child_file
79
block: Pass BdrvChildRole in remaining cases
80
block: Drop @child_class from bdrv_child_perm()
53
81
54
Vladimir Sementsov-Ogievskiy (2):
82
Philippe Mathieu-Daudé (3):
55
qmp: forbid qmp_cont in RUN_STATE_FINISH_MIGRATE
83
block/block-copy: Fix uninitialized variable in block_copy_task_entry
56
iotest: fix 169: do not run qmp_cont in RUN_STATE_FINISH_MIGRATE
84
block/block-copy: Simplify block_copy_do_copy()
85
hw/ide/ahci: Log lost IRQs
57
86
58
block/qcow2.h | 4 +
87
include/block/block.h | 65 ++++-
59
include/block/block.h | 10 ++
88
include/block/block_int.h | 57 ++--
60
include/block/block_int.h | 25 +----
89
include/sysemu/block-backend.h | 2 +
61
include/sysemu/block-backend.h | 1 +
90
block.c | 601 ++++++++++++++++++++++++---------------
62
block.c | 174 +++++++++++++++++++++++++++++++----
91
block/backup-top.c | 11 +-
63
block/backup.c | 8 --
92
block/blkdebug.c | 10 +-
64
block/block-backend.c | 55 ++++++++++-
93
block/blklogwrites.c | 16 +-
65
block/file-posix.c | 29 ++++++
94
block/blkreplay.c | 8 +-
66
block/io.c | 6 +-
95
block/blkverify.c | 10 +-
67
block/mirror.c | 10 +-
96
block/block-backend.c | 30 +-
68
block/qcow2-cluster.c | 5 +-
97
block/block-copy.c | 14 +-
69
block/qcow2-refcount.c | 25 ++---
98
block/bochs.c | 7 +-
70
block/qcow2.c | 3 +-
99
block/cloop.c | 7 +-
71
blockjob.c | 77 ++++++++--------
100
block/commit.c | 20 +-
72
hw/block/nvme.c | 2 +-
101
block/copy-on-read.c | 7 +-
73
qemu-io-cmds.c | 7 +-
102
block/crypto.c | 8 +-
74
qmp.c | 3 +
103
block/dmg.c | 7 +-
75
tests/test-block-iothread.c | 202 +++++++++++++++++++++++++++++++++++++++++
104
block/filter-compress.c | 7 +-
76
qemu-img.texi | 52 ++++++++++-
105
block/io.c | 22 +-
77
tests/qemu-iotests/169 | 7 +-
106
block/mirror.c | 25 +-
78
tests/qemu-iotests/221 | 4 +
107
block/parallels.c | 7 +-
79
tests/qemu-iotests/245 | 22 +++--
108
block/qcow.c | 7 +-
80
tests/qemu-iotests/245.out | 12 +++
109
block/qcow2.c | 20 +-
81
tests/qemu-iotests/253 | 84 +++++++++++++++++
110
block/qed.c | 7 +-
82
tests/qemu-iotests/253.out | 14 +++
111
block/quorum.c | 8 +-
83
tests/qemu-iotests/group | 1 +
112
block/raw-format.c | 128 +++++----
84
tests/qemu-iotests/iotests.py | 20 +++-
113
block/replication.c | 23 +-
85
27 files changed, 728 insertions(+), 134 deletions(-)
114
block/throttle.c | 7 +-
86
create mode 100755 tests/qemu-iotests/253
115
block/vdi.c | 7 +-
87
create mode 100644 tests/qemu-iotests/253.out
116
block/vhdx.c | 7 +-
117
block/vmdk.c | 23 +-
118
block/vpc.c | 7 +-
119
block/vvfat.c | 17 +-
120
blockjob.c | 7 +-
121
hw/ide/ahci.c | 1 +
122
qemu-img.c | 19 +-
123
tests/test-bdrv-drain.c | 72 +++--
124
tests/test-bdrv-graph-mod.c | 10 +-
125
tests/test-block-iothread.c | 17 +-
126
tests/qemu-iotests/iotests.py | 19 +-
127
tests/qemu-iotests/030 | 6 +-
128
tests/qemu-iotests/041 | 45 +++
129
tests/qemu-iotests/041.out | 4 +-
130
tests/qemu-iotests/098.out | 8 +-
131
tests/qemu-iotests/109 | 10 +-
132
tests/qemu-iotests/109.out | 74 ++---
133
tests/qemu-iotests/229 | 15 +-
134
tests/qemu-iotests/229.out | 6 +-
135
tests/qemu-iotests/297 | 44 +++
136
tests/qemu-iotests/297.out | 3 +
137
tests/qemu-iotests/common.filter | 5 +
138
tests/qemu-iotests/group | 1 +
139
52 files changed, 995 insertions(+), 573 deletions(-)
140
create mode 100755 tests/qemu-iotests/297
141
create mode 100644 tests/qemu-iotests/297.out
88
142
143
diff view generated by jsdifflib
New patch
1
1
This patch makes the raw image the same size as the file in a different
2
format that is mirrored as raw to it to avoid errors when mirror starts
3
to enforce that source and target are the same size.
4
5
We check only that the first 512 bytes are zeroed (instead of 64k)
6
because some image formats create image files that are smaller than 64k,
7
so trying to read 64k would result in I/O errors. Apart from this, 512
8
is more appropriate anyway because the raw format driver protects
9
specifically the first 512 bytes.
10
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
Message-Id: <20200511135825.219437-2-kwolf@redhat.com>
13
Reviewed-by: Max Reitz <mreitz@redhat.com>
14
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
15
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
16
---
17
tests/qemu-iotests/109 | 10 ++---
18
tests/qemu-iotests/109.out | 74 +++++++++++++-------------------
19
tests/qemu-iotests/common.filter | 5 +++
20
3 files changed, 41 insertions(+), 48 deletions(-)
21
22
diff --git a/tests/qemu-iotests/109 b/tests/qemu-iotests/109
23
index XXXXXXX..XXXXXXX 100755
24
--- a/tests/qemu-iotests/109
25
+++ b/tests/qemu-iotests/109
26
@@ -XXX,XX +XXX,XX @@ for fmt in qcow qcow2 qed vdi vmdk vpc; do
27
echo "=== Writing a $fmt header into raw ==="
28
echo
29
30
- _make_test_img 64M
31
TEST_IMG="$TEST_IMG.src" IMGFMT=$fmt _make_test_img 64M
32
+ _make_test_img $(du -b "$TEST_IMG.src" | cut -f1) | _filter_img_create_size
33
34
# This first test should fail: The image format was probed, we may not
35
# write an image header at the start of the image
36
run_qemu "$TEST_IMG" "$TEST_IMG.src" "" "BLOCK_JOB_ERROR" |
37
_filter_block_job_len
38
- $QEMU_IO -c 'read -P 0 0 64k' "$TEST_IMG" | _filter_qemu_io
39
+ $QEMU_IO -c 'read -P 0 0 512' "$TEST_IMG" | _filter_qemu_io
40
41
42
# When raw was explicitly specified, the same must succeed
43
@@ -XXX,XX +XXX,XX @@ for sample_img in empty.bochs iotest-dirtylog-10G-4M.vhdx parallels-v1 \
44
45
# Can't use _use_sample_img because that isn't designed to be used multiple
46
# times and it overwrites $TEST_IMG (both breaks cleanup)
47
- _make_test_img 64M
48
bzcat "$SAMPLE_IMG_DIR/$sample_img.bz2" > "$TEST_IMG.src"
49
+ _make_test_img $(du -b "$TEST_IMG.src" | cut -f1) | _filter_img_create_size
50
51
run_qemu "$TEST_IMG" "$TEST_IMG.src" "" "BLOCK_JOB_ERROR" |
52
_filter_block_job_offset | _filter_block_job_len
53
- $QEMU_IO -c 'read -P 0 0 64k' "$TEST_IMG" | _filter_qemu_io
54
+ $QEMU_IO -c 'read -P 0 0 512' "$TEST_IMG" | _filter_qemu_io
55
56
run_qemu "$TEST_IMG" "$TEST_IMG.src" "'format': 'raw'," "BLOCK_JOB_READY"
57
$QEMU_IMG compare -f raw -F raw "$TEST_IMG" "$TEST_IMG.src"
58
@@ -XXX,XX +XXX,XX @@ echo "=== Write legitimate MBR into raw ==="
59
echo
60
61
for sample_img in grub_mbr.raw; do
62
- _make_test_img 64M
63
bzcat "$SAMPLE_IMG_DIR/$sample_img.bz2" > "$TEST_IMG.src"
64
+ _make_test_img $(du -b "$TEST_IMG.src" | cut -f1) | _filter_img_create_size
65
66
run_qemu "$TEST_IMG" "$TEST_IMG.src" "" "BLOCK_JOB_READY"
67
$QEMU_IMG compare -f raw -F raw "$TEST_IMG" "$TEST_IMG.src"
68
diff --git a/tests/qemu-iotests/109.out b/tests/qemu-iotests/109.out
69
index XXXXXXX..XXXXXXX 100644
70
--- a/tests/qemu-iotests/109.out
71
+++ b/tests/qemu-iotests/109.out
72
@@ -XXX,XX +XXX,XX @@ QA output created by 109
73
74
=== Writing a qcow header into raw ===
75
76
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
77
Formatting 'TEST_DIR/t.raw.src', fmt=IMGFMT size=67108864
78
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=SIZE
79
{ 'execute': 'qmp_capabilities' }
80
{"return": {}}
81
{'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'mode': 'existing', 'sync': 'full'}}
82
@@ -XXX,XX +XXX,XX @@ WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed
83
{"execute":"quit"}
84
{"return": {}}
85
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
86
-read 65536/65536 bytes at offset 0
87
-64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
88
+read 512/512 bytes at offset 0
89
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
90
{ 'execute': 'qmp_capabilities' }
91
{"return": {}}
92
{'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'format': 'IMGFMT', 'mode': 'existing', 'sync': 'full'}}
93
@@ -XXX,XX +XXX,XX @@ read 65536/65536 bytes at offset 0
94
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 1024, "offset": 1024, "speed": 0, "type": "mirror"}}
95
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "src"}}
96
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "src"}}
97
-Warning: Image size mismatch!
98
Images are identical.
99
100
=== Writing a qcow2 header into raw ===
101
102
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
103
Formatting 'TEST_DIR/t.raw.src', fmt=IMGFMT size=67108864
104
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=SIZE
105
{ 'execute': 'qmp_capabilities' }
106
{"return": {}}
107
{'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'mode': 'existing', 'sync': 'full'}}
108
@@ -XXX,XX +XXX,XX @@ WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed
109
{"execute":"quit"}
110
{"return": {}}
111
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
112
-read 65536/65536 bytes at offset 0
113
-64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
114
+read 512/512 bytes at offset 0
115
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
116
{ 'execute': 'qmp_capabilities' }
117
{"return": {}}
118
{'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'format': 'IMGFMT', 'mode': 'existing', 'sync': 'full'}}
119
@@ -XXX,XX +XXX,XX @@ read 65536/65536 bytes at offset 0
120
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 197120, "offset": 197120, "speed": 0, "type": "mirror"}}
121
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "src"}}
122
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "src"}}
123
-Warning: Image size mismatch!
124
Images are identical.
125
126
=== Writing a qed header into raw ===
127
128
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
129
Formatting 'TEST_DIR/t.raw.src', fmt=IMGFMT size=67108864
130
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=SIZE
131
{ 'execute': 'qmp_capabilities' }
132
{"return": {}}
133
{'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'mode': 'existing', 'sync': 'full'}}
134
@@ -XXX,XX +XXX,XX @@ WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed
135
{"execute":"quit"}
136
{"return": {}}
137
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
138
-read 65536/65536 bytes at offset 0
139
-64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
140
+read 512/512 bytes at offset 0
141
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
142
{ 'execute': 'qmp_capabilities' }
143
{"return": {}}
144
{'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'format': 'IMGFMT', 'mode': 'existing', 'sync': 'full'}}
145
@@ -XXX,XX +XXX,XX @@ read 65536/65536 bytes at offset 0
146
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 327680, "offset": 327680, "speed": 0, "type": "mirror"}}
147
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "src"}}
148
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "src"}}
149
-Warning: Image size mismatch!
150
Images are identical.
151
152
=== Writing a vdi header into raw ===
153
154
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
155
Formatting 'TEST_DIR/t.raw.src', fmt=IMGFMT size=67108864
156
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=SIZE
157
{ 'execute': 'qmp_capabilities' }
158
{"return": {}}
159
{'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'mode': 'existing', 'sync': 'full'}}
160
@@ -XXX,XX +XXX,XX @@ WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed
161
{"execute":"quit"}
162
{"return": {}}
163
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
164
-read 65536/65536 bytes at offset 0
165
-64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
166
+read 512/512 bytes at offset 0
167
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
168
{ 'execute': 'qmp_capabilities' }
169
{"return": {}}
170
{'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'format': 'IMGFMT', 'mode': 'existing', 'sync': 'full'}}
171
@@ -XXX,XX +XXX,XX @@ read 65536/65536 bytes at offset 0
172
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 1024, "offset": 1024, "speed": 0, "type": "mirror"}}
173
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "src"}}
174
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "src"}}
175
-Warning: Image size mismatch!
176
Images are identical.
177
178
=== Writing a vmdk header into raw ===
179
180
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
181
Formatting 'TEST_DIR/t.raw.src', fmt=IMGFMT size=67108864
182
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=SIZE
183
{ 'execute': 'qmp_capabilities' }
184
{"return": {}}
185
{'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'mode': 'existing', 'sync': 'full'}}
186
@@ -XXX,XX +XXX,XX @@ WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed
187
{"execute":"quit"}
188
{"return": {}}
189
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
190
-read 65536/65536 bytes at offset 0
191
-64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
192
+read 512/512 bytes at offset 0
193
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
194
{ 'execute': 'qmp_capabilities' }
195
{"return": {}}
196
{'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'format': 'IMGFMT', 'mode': 'existing', 'sync': 'full'}}
197
@@ -XXX,XX +XXX,XX @@ read 65536/65536 bytes at offset 0
198
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 65536, "offset": 65536, "speed": 0, "type": "mirror"}}
199
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "src"}}
200
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "src"}}
201
-Warning: Image size mismatch!
202
Images are identical.
203
204
=== Writing a vpc header into raw ===
205
206
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
207
Formatting 'TEST_DIR/t.raw.src', fmt=IMGFMT size=67108864
208
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=SIZE
209
{ 'execute': 'qmp_capabilities' }
210
{"return": {}}
211
{'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'mode': 'existing', 'sync': 'full'}}
212
@@ -XXX,XX +XXX,XX @@ WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed
213
{"execute":"quit"}
214
{"return": {}}
215
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
216
-read 65536/65536 bytes at offset 0
217
-64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
218
+read 512/512 bytes at offset 0
219
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
220
{ 'execute': 'qmp_capabilities' }
221
{"return": {}}
222
{'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'format': 'IMGFMT', 'mode': 'existing', 'sync': 'full'}}
223
@@ -XXX,XX +XXX,XX @@ read 65536/65536 bytes at offset 0
224
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 2560, "offset": 2560, "speed": 0, "type": "mirror"}}
225
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "src"}}
226
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "src"}}
227
-Warning: Image size mismatch!
228
Images are identical.
229
230
=== Copying sample image empty.bochs into raw ===
231
232
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
233
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=SIZE
234
{ 'execute': 'qmp_capabilities' }
235
{"return": {}}
236
{'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'mode': 'existing', 'sync': 'full'}}
237
@@ -XXX,XX +XXX,XX @@ WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed
238
{"execute":"quit"}
239
{"return": {}}
240
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
241
-read 65536/65536 bytes at offset 0
242
-64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
243
+read 512/512 bytes at offset 0
244
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
245
{ 'execute': 'qmp_capabilities' }
246
{"return": {}}
247
{'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'format': 'IMGFMT', 'mode': 'existing', 'sync': 'full'}}
248
@@ -XXX,XX +XXX,XX @@ read 65536/65536 bytes at offset 0
249
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 2560, "offset": 2560, "speed": 0, "type": "mirror"}}
250
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "src"}}
251
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "src"}}
252
-Warning: Image size mismatch!
253
Images are identical.
254
255
=== Copying sample image iotest-dirtylog-10G-4M.vhdx into raw ===
256
257
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
258
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=SIZE
259
{ 'execute': 'qmp_capabilities' }
260
{"return": {}}
261
{'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'mode': 'existing', 'sync': 'full'}}
262
@@ -XXX,XX +XXX,XX @@ WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed
263
{"execute":"quit"}
264
{"return": {}}
265
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
266
-read 65536/65536 bytes at offset 0
267
-64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
268
+read 512/512 bytes at offset 0
269
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
270
{ 'execute': 'qmp_capabilities' }
271
{"return": {}}
272
{'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'format': 'IMGFMT', 'mode': 'existing', 'sync': 'full'}}
273
@@ -XXX,XX +XXX,XX @@ read 65536/65536 bytes at offset 0
274
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 31457280, "offset": 31457280, "speed": 0, "type": "mirror"}}
275
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "src"}}
276
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "src"}}
277
-Warning: Image size mismatch!
278
Images are identical.
279
280
=== Copying sample image parallels-v1 into raw ===
281
282
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
283
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=SIZE
284
{ 'execute': 'qmp_capabilities' }
285
{"return": {}}
286
{'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'mode': 'existing', 'sync': 'full'}}
287
@@ -XXX,XX +XXX,XX @@ WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed
288
{"execute":"quit"}
289
{"return": {}}
290
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
291
-read 65536/65536 bytes at offset 0
292
-64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
293
+read 512/512 bytes at offset 0
294
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
295
{ 'execute': 'qmp_capabilities' }
296
{"return": {}}
297
{'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'format': 'IMGFMT', 'mode': 'existing', 'sync': 'full'}}
298
@@ -XXX,XX +XXX,XX @@ read 65536/65536 bytes at offset 0
299
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 327680, "offset": 327680, "speed": 0, "type": "mirror"}}
300
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "src"}}
301
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "src"}}
302
-Warning: Image size mismatch!
303
Images are identical.
304
305
=== Copying sample image simple-pattern.cloop into raw ===
306
307
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
308
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=SIZE
309
{ 'execute': 'qmp_capabilities' }
310
{"return": {}}
311
{'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'mode': 'existing', 'sync': 'full'}}
312
@@ -XXX,XX +XXX,XX @@ WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed
313
{"execute":"quit"}
314
{"return": {}}
315
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
316
-read 65536/65536 bytes at offset 0
317
-64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
318
+read 512/512 bytes at offset 0
319
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
320
{ 'execute': 'qmp_capabilities' }
321
{"return": {}}
322
{'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'format': 'IMGFMT', 'mode': 'existing', 'sync': 'full'}}
323
@@ -XXX,XX +XXX,XX @@ read 65536/65536 bytes at offset 0
324
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 2048, "offset": 2048, "speed": 0, "type": "mirror"}}
325
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "src"}}
326
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "src"}}
327
-Warning: Image size mismatch!
328
Images are identical.
329
330
=== Write legitimate MBR into raw ===
331
332
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
333
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=SIZE
334
{ 'execute': 'qmp_capabilities' }
335
{"return": {}}
336
{'execute':'drive-mirror', 'arguments':{ 'device': 'src', 'target': 'TEST_DIR/t.IMGFMT', 'mode': 'existing', 'sync': 'full'}}
337
@@ -XXX,XX +XXX,XX @@ WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed
338
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 512, "offset": 512, "speed": 0, "type": "mirror"}}
339
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "src"}}
340
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "src"}}
341
-Warning: Image size mismatch!
342
Images are identical.
343
{ 'execute': 'qmp_capabilities' }
344
{"return": {}}
345
@@ -XXX,XX +XXX,XX @@ Images are identical.
346
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 512, "offset": 512, "speed": 0, "type": "mirror"}}
347
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "src"}}
348
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "src"}}
349
-Warning: Image size mismatch!
350
Images are identical.
351
*** done
352
diff --git a/tests/qemu-iotests/common.filter b/tests/qemu-iotests/common.filter
353
index XXXXXXX..XXXXXXX 100644
354
--- a/tests/qemu-iotests/common.filter
355
+++ b/tests/qemu-iotests/common.filter
356
@@ -XXX,XX +XXX,XX @@ _filter_img_create()
357
-e "s# compression_type=[a-zA-Z0-9]\\+##g"
358
}
359
360
+_filter_img_create_size()
361
+{
362
+ $SED -e "s# size=[0-9]\\+# size=SIZE#g"
363
+}
364
+
365
_filter_img_info()
366
{
367
if [[ "$1" == "--format-specific" ]]; then
368
--
369
2.25.4
370
371
diff view generated by jsdifflib
New patch
1
229 relies on the mirror running into an I/O error when the target is
2
smaller than the source. After changing mirror to catch this condition
3
while starting the job, this test case won't get a job that is paused
4
for an I/O error any more. Use blkdebug instead to inject an error.
1
5
6
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
7
Reviewed-by: Eric Blake <eblake@redhat.com>
8
Message-Id: <20200511135825.219437-3-kwolf@redhat.com>
9
Reviewed-by: Max Reitz <mreitz@redhat.com>
10
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
---
13
tests/qemu-iotests/229 | 15 +++++++++++----
14
tests/qemu-iotests/229.out | 6 +++---
15
2 files changed, 14 insertions(+), 7 deletions(-)
16
17
diff --git a/tests/qemu-iotests/229 b/tests/qemu-iotests/229
18
index XXXXXXX..XXXXXXX 100755
19
--- a/tests/qemu-iotests/229
20
+++ b/tests/qemu-iotests/229
21
@@ -XXX,XX +XXX,XX @@ _cleanup()
22
_cleanup_test_img
23
_rm_test_img "$TEST_IMG"
24
_rm_test_img "$DEST_IMG"
25
+ rm -f "$TEST_DIR/blkdebug.conf"
26
}
27
trap "_cleanup; exit \$status" 0 1 2 3 15
28
29
@@ -XXX,XX +XXX,XX @@ _supported_os Linux
30
31
DEST_IMG="$TEST_DIR/d.$IMGFMT"
32
TEST_IMG="$TEST_DIR/b.$IMGFMT"
33
+BLKDEBUG_CONF="$TEST_DIR/blkdebug.conf"
34
35
_make_test_img 2M
36
-
37
-# destination for mirror will be too small, causing error
38
-TEST_IMG=$DEST_IMG _make_test_img 1M
39
+TEST_IMG=$DEST_IMG _make_test_img 2M
40
41
$QEMU_IO -c 'write 0 2M' "$TEST_IMG" | _filter_qemu_io
42
43
@@ -XXX,XX +XXX,XX @@ echo
44
echo '=== Starting drive-mirror, causing error & stop ==='
45
echo
46
47
+cat > "$BLKDEBUG_CONF" <<EOF
48
+[inject-error]
49
+event = "write_aio"
50
+errno = "5"
51
+once = "on"
52
+EOF
53
+
54
_send_qemu_cmd $QEMU_HANDLE \
55
"{'execute': 'drive-mirror',
56
'arguments': {'device': 'testdisk',
57
'format': '$IMGFMT',
58
- 'target': '$DEST_IMG',
59
+ 'target': 'blkdebug:$BLKDEBUG_CONF:$DEST_IMG',
60
'sync': 'full',
61
'mode': 'existing',
62
'on-source-error': 'stop',
63
diff --git a/tests/qemu-iotests/229.out b/tests/qemu-iotests/229.out
64
index XXXXXXX..XXXXXXX 100644
65
--- a/tests/qemu-iotests/229.out
66
+++ b/tests/qemu-iotests/229.out
67
@@ -XXX,XX +XXX,XX @@
68
QA output created by 229
69
Formatting 'TEST_DIR/b.IMGFMT', fmt=IMGFMT size=2097152
70
-Formatting 'TEST_DIR/d.IMGFMT', fmt=IMGFMT size=1048576
71
+Formatting 'TEST_DIR/d.IMGFMT', fmt=IMGFMT size=2097152
72
wrote 2097152/2097152 bytes at offset 0
73
2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
74
{'execute': 'qmp_capabilities'}
75
@@ -XXX,XX +XXX,XX @@ wrote 2097152/2097152 bytes at offset 0
76
77
=== Starting drive-mirror, causing error & stop ===
78
79
-{'execute': 'drive-mirror', 'arguments': {'device': 'testdisk', 'format': 'IMGFMT', 'target': 'TEST_DIR/d.IMGFMT', 'sync': 'full', 'mode': 'existing', 'on-source-error': 'stop', 'on-target-error': 'stop' }}
80
+{'execute': 'drive-mirror', 'arguments': {'device': 'testdisk', 'format': 'IMGFMT', 'target': 'blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/d.IMGFMT', 'sync': 'full', 'mode': 'existing', 'on-source-error': 'stop', 'on-target-error': 'stop' }}
81
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "testdisk"}}
82
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "testdisk"}}
83
{"return": {}}
84
@@ -XXX,XX +XXX,XX @@ wrote 2097152/2097152 bytes at offset 0
85
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "testdisk"}}
86
{"return": {}}
87
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "aborting", "id": "testdisk"}}
88
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "testdisk", "len": 2097152, "offset": 1048576, "speed": 0, "type": "mirror"}}
89
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "testdisk", "len": 2097152, "offset": 2097152, "speed": 0, "type": "mirror"}}
90
*** done
91
--
92
2.25.4
93
94
diff view generated by jsdifflib
New patch
1
If the target is shorter than the source, mirror would copy data until
2
it reaches the end of the target and then fail with an I/O error when
3
trying to write past the end.
1
4
5
If the target is longer than the source, the mirror job would complete
6
successfully, but the target wouldn't actually be an accurate copy of
7
the source image (it would contain some additional garbage at the end).
8
9
Fix this by checking that both images have the same size when the job
10
starts.
11
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
Reviewed-by: Eric Blake <eblake@redhat.com>
14
Message-Id: <20200511135825.219437-4-kwolf@redhat.com>
15
Reviewed-by: Max Reitz <mreitz@redhat.com>
16
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
17
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
18
---
19
block/mirror.c | 21 ++++++++++++---------
20
1 file changed, 12 insertions(+), 9 deletions(-)
21
22
diff --git a/block/mirror.c b/block/mirror.c
23
index XXXXXXX..XXXXXXX 100644
24
--- a/block/mirror.c
25
+++ b/block/mirror.c
26
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn mirror_run(Job *job, Error **errp)
27
BlockDriverState *target_bs = blk_bs(s->target);
28
bool need_drain = true;
29
int64_t length;
30
+ int64_t target_length;
31
BlockDriverInfo bdi;
32
char backing_filename[2]; /* we only need 2 characters because we are only
33
checking for a NULL string */
34
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn mirror_run(Job *job, Error **errp)
35
goto immediate_exit;
36
}
37
38
+ target_length = blk_getlength(s->target);
39
+ if (target_length < 0) {
40
+ ret = target_length;
41
+ goto immediate_exit;
42
+ }
43
+
44
/* Active commit must resize the base image if its size differs from the
45
* active layer. */
46
if (s->base == blk_bs(s->target)) {
47
- int64_t base_length;
48
-
49
- base_length = blk_getlength(s->target);
50
- if (base_length < 0) {
51
- ret = base_length;
52
- goto immediate_exit;
53
- }
54
-
55
- if (s->bdev_length > base_length) {
56
+ if (s->bdev_length > target_length) {
57
ret = blk_truncate(s->target, s->bdev_length, false,
58
PREALLOC_MODE_OFF, 0, NULL);
59
if (ret < 0) {
60
goto immediate_exit;
61
}
62
}
63
+ } else if (s->bdev_length != target_length) {
64
+ error_setg(errp, "Source and target image have different sizes");
65
+ ret = -EINVAL;
66
+ goto immediate_exit;
67
}
68
69
if (s->bdev_length == 0) {
70
--
71
2.25.4
72
73
diff view generated by jsdifflib
New patch
1
This tests that the mirror job catches situations where the target node
2
has a different size than the source node. It must also forbid resize
3
operations when the job is already running.
1
4
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
Reviewed-by: Eric Blake <eblake@redhat.com>
7
Message-Id: <20200511135825.219437-5-kwolf@redhat.com>
8
Reviewed-by: Max Reitz <mreitz@redhat.com>
9
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
---
12
tests/qemu-iotests/041 | 45 ++++++++++++++++++++++++++++++++++++++
13
tests/qemu-iotests/041.out | 4 ++--
14
2 files changed, 47 insertions(+), 2 deletions(-)
15
16
diff --git a/tests/qemu-iotests/041 b/tests/qemu-iotests/041
17
index XXXXXXX..XXXXXXX 100755
18
--- a/tests/qemu-iotests/041
19
+++ b/tests/qemu-iotests/041
20
@@ -XXX,XX +XXX,XX @@ class TestSingleBlockdev(TestSingleDrive):
21
target=self.qmp_target)
22
self.assert_qmp(result, 'error/class', 'GenericError')
23
24
+ def do_test_resize(self, device, node):
25
+ def pre_finalize():
26
+ if device:
27
+ result = self.vm.qmp('block_resize', device=device, size=65536)
28
+ self.assert_qmp(result, 'error/class', 'GenericError')
29
+
30
+ result = self.vm.qmp('block_resize', node_name=node, size=65536)
31
+ self.assert_qmp(result, 'error/class', 'GenericError')
32
+
33
+ result = self.vm.qmp(self.qmp_cmd, job_id='job0', device='drive0',
34
+ sync='full', target=self.qmp_target,
35
+ auto_finalize=False, auto_dismiss=False)
36
+ self.assert_qmp(result, 'return', {})
37
+
38
+ result = self.vm.run_job('job0', auto_finalize=False,
39
+ pre_finalize=pre_finalize)
40
+ self.assertEqual(result, None)
41
+
42
+ def test_source_resize(self):
43
+ self.do_test_resize('drive0', 'top')
44
+
45
+ def test_target_resize(self):
46
+ self.do_test_resize(None, self.qmp_target)
47
+
48
+ def do_test_target_size(self, size):
49
+ result = self.vm.qmp('block_resize', node_name=self.qmp_target,
50
+ size=size)
51
+ self.assert_qmp(result, 'return', {})
52
+
53
+ result = self.vm.qmp(self.qmp_cmd, job_id='job0',
54
+ device='drive0', sync='full', auto_dismiss=False,
55
+ target=self.qmp_target)
56
+ self.assert_qmp(result, 'return', {})
57
+
58
+ result = self.vm.run_job('job0')
59
+ self.assertEqual(result, 'Source and target image have different sizes')
60
+
61
+ def test_small_target(self):
62
+ self.do_test_target_size(self.image_len // 2)
63
+
64
+ def test_large_target(self):
65
+ self.do_test_target_size(self.image_len * 2)
66
+
67
test_large_cluster = None
68
test_image_not_found = None
69
test_small_buffer2 = None
70
@@ -XXX,XX +XXX,XX @@ class TestSingleDriveZeroLength(TestSingleDrive):
71
72
class TestSingleBlockdevZeroLength(TestSingleBlockdev):
73
image_len = 0
74
+ test_small_target = None
75
+ test_large_target = None
76
77
class TestSingleDriveUnalignedLength(TestSingleDrive):
78
image_len = 1025 * 1024
79
diff --git a/tests/qemu-iotests/041.out b/tests/qemu-iotests/041.out
80
index XXXXXXX..XXXXXXX 100644
81
--- a/tests/qemu-iotests/041.out
82
+++ b/tests/qemu-iotests/041.out
83
@@ -XXX,XX +XXX,XX @@
84
-..............................................................................................
85
+........................................................................................................
86
----------------------------------------------------------------------
87
-Ran 94 tests
88
+Ran 104 tests
89
90
OK
91
--
92
2.25.4
93
94
diff view generated by jsdifflib
New patch
1
From: Lukas Straub <lukasstraub2@web.de>
1
2
3
If qemu in colo secondary mode is stopped, it crashes because
4
s->backup_job is canceled twice: First with job_cancel_sync_all()
5
in qemu_cleanup() and then in replication_stop().
6
7
Fix this by assigning NULL to s->backup_job when the job completes
8
so replication_stop() and replication_do_checkpoint() won't touch
9
the job.
10
11
Signed-off-by: Lukas Straub <lukasstraub2@web.de>
12
Message-Id: <20200511090801.7ed5d8f3@luklap>
13
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
---
15
block/replication.c | 2 ++
16
1 file changed, 2 insertions(+)
17
18
diff --git a/block/replication.c b/block/replication.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/block/replication.c
21
+++ b/block/replication.c
22
@@ -XXX,XX +XXX,XX @@ static void backup_job_cleanup(BlockDriverState *bs)
23
BDRVReplicationState *s = bs->opaque;
24
BlockDriverState *top_bs;
25
26
+ s->backup_job = NULL;
27
+
28
top_bs = bdrv_lookup_bs(s->top_id, s->top_id, NULL);
29
if (!top_bs) {
30
return;
31
--
32
2.25.4
33
34
diff view generated by jsdifflib
1
From: Max Reitz <mreitz@redhat.com>
1
We need to fix only a few places so that iotests.py can pass
2
mypy --disallow-incomplete-defs, which seems to be a desirable option to
3
have enabled in the long run.
2
4
3
log() is in the current module, there is no need to prefix it. In fact,
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
4
doing so may make VM.run_job() unusable in tests that never use
6
Message-Id: <20200511163529.349329-2-kwolf@redhat.com>
5
iotests.log() themselves.
7
Reviewed-by: Max Reitz <mreitz@redhat.com>
6
8
Reviewed-by: John Snow <jsnow@redhat.com>
7
Signed-off-by: Max Reitz <mreitz@redhat.com>
8
Reviewed-by: Alberto Garcia <berto@igalia.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
10
---
11
tests/qemu-iotests/iotests.py | 2 +-
11
tests/qemu-iotests/iotests.py | 8 ++++----
12
1 file changed, 1 insertion(+), 1 deletion(-)
12
1 file changed, 4 insertions(+), 4 deletions(-)
13
13
14
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
14
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
15
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
16
--- a/tests/qemu-iotests/iotests.py
16
--- a/tests/qemu-iotests/iotests.py
17
+++ b/tests/qemu-iotests/iotests.py
17
+++ b/tests/qemu-iotests/iotests.py
18
@@ -XXX,XX +XXX,XX @@ class VM(qtest.QEMUQtestMachine):
18
@@ -XXX,XX +XXX,XX @@ def _verify_cache_mode(supported_cache_modes: Sequence[str] = ()) -> None:
19
elif status == 'null':
19
if supported_cache_modes and (cachemode not in supported_cache_modes):
20
return error
20
notrun('not suitable for this cache mode: %s' % cachemode)
21
else:
21
22
- iotests.log(ev)
22
-def _verify_aio_mode(supported_aio_modes: Sequence[str] = ()):
23
+ log(ev)
23
+def _verify_aio_mode(supported_aio_modes: Sequence[str] = ()) -> None:
24
24
if supported_aio_modes and (aiomode not in supported_aio_modes):
25
def node_info(self, node_name):
25
notrun('not suitable for this aio mode: %s' % aiomode)
26
nodes = self.qmp('query-named-block-nodes')
26
27
@@ -XXX,XX +XXX,XX @@ def skip_if_unsupported(required_formats=(), read_only=False):
28
'''Skip Test Decorator
29
Runs the test if all the required formats are whitelisted'''
30
def skip_test_decorator(func):
31
- def func_wrapper(test_case: QMPTestCase, *args, **kwargs):
32
+ def func_wrapper(test_case: QMPTestCase, *args: List[Any],
33
+ **kwargs: Dict[str, Any]) -> None:
34
if callable(required_formats):
35
fmts = required_formats(test_case)
36
else:
37
@@ -XXX,XX +XXX,XX @@ def skip_if_unsupported(required_formats=(), read_only=False):
38
if usf_list:
39
msg = f'{test_case}: formats {usf_list} are not whitelisted'
40
test_case.case_skip(msg)
41
- return None
42
else:
43
- return func(test_case, *args, **kwargs)
44
+ func(test_case, *args, **kwargs)
45
return func_wrapper
46
return skip_test_decorator
47
27
--
48
--
28
2.20.1
49
2.25.4
29
50
30
51
diff view generated by jsdifflib
1
From: Max Reitz <mreitz@redhat.com>
1
We made sure that iotests.py passes pylint. It would be a shame if we
2
allowed new patches in that break this again, so let's just add a
3
meta-test case that runs pylint on it.
2
4
3
We already have 221 for accesses through the page cache, but it is
5
While we don't pass mypy --strict yet, we can already run it with a few
4
better to create a new file for O_DIRECT instead of integrating those
6
options that would be part of --strict to make sure that we won't
5
test cases into 221. This way, we can make use of
7
regress on these aspects at least until we can enable the full thing.
6
_supported_cache_modes (and _default_cache_mode) so the test is
7
automatically skipped on filesystems that do not support O_DIRECT.
8
8
9
As part of the split, add _supported_cache_modes to 221. With that, it
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
no longer fails when run with -c none or -c directsync.
10
Message-Id: <20200511163529.349329-3-kwolf@redhat.com>
11
11
Reviewed-by: Max Reitz <mreitz@redhat.com>
12
Signed-off-by: Max Reitz <mreitz@redhat.com>
12
Reviewed-by: John Snow <jsnow@redhat.com>
13
Reviewed-by: Eric Blake <eblake@redhat.com>
14
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
15
---
14
---
16
tests/qemu-iotests/221 | 4 ++
15
tests/qemu-iotests/297 | 44 ++++++++++++++++++++++++++++++++++++++
17
tests/qemu-iotests/253 | 84 ++++++++++++++++++++++++++++++++++++++
16
tests/qemu-iotests/297.out | 3 +++
18
tests/qemu-iotests/253.out | 14 +++++++
19
tests/qemu-iotests/group | 1 +
17
tests/qemu-iotests/group | 1 +
20
4 files changed, 103 insertions(+)
18
3 files changed, 48 insertions(+)
21
create mode 100755 tests/qemu-iotests/253
19
create mode 100755 tests/qemu-iotests/297
22
create mode 100644 tests/qemu-iotests/253.out
20
create mode 100644 tests/qemu-iotests/297.out
23
21
24
diff --git a/tests/qemu-iotests/221 b/tests/qemu-iotests/221
22
diff --git a/tests/qemu-iotests/297 b/tests/qemu-iotests/297
25
index XXXXXXX..XXXXXXX 100755
26
--- a/tests/qemu-iotests/221
27
+++ b/tests/qemu-iotests/221
28
@@ -XXX,XX +XXX,XX @@
29
#!/usr/bin/env bash
30
#
31
# Test qemu-img vs. unaligned images
32
+# (See also 253, which is the O_DIRECT version)
33
#
34
# Copyright (C) 2018-2019 Red Hat, Inc.
35
#
36
@@ -XXX,XX +XXX,XX @@ _supported_fmt raw
37
_supported_proto file
38
_supported_os Linux
39
40
+_default_cache_mode writeback
41
+_supported_cache_modes writeback writethrough unsafe
42
+
43
echo
44
echo "=== Check mapping of unaligned raw image ==="
45
echo
46
diff --git a/tests/qemu-iotests/253 b/tests/qemu-iotests/253
47
new file mode 100755
23
new file mode 100755
48
index XXXXXXX..XXXXXXX
24
index XXXXXXX..XXXXXXX
49
--- /dev/null
25
--- /dev/null
50
+++ b/tests/qemu-iotests/253
26
+++ b/tests/qemu-iotests/297
51
@@ -XXX,XX +XXX,XX @@
27
@@ -XXX,XX +XXX,XX @@
52
+#!/usr/bin/env bash
28
+#!/usr/bin/env bash
53
+#
29
+#
54
+# Test qemu-img vs. unaligned images; O_DIRECT version
30
+# Copyright (C) 2020 Red Hat, Inc.
55
+# (Originates from 221)
56
+#
57
+# Copyright (C) 2019 Red Hat, Inc.
58
+#
31
+#
59
+# This program is free software; you can redistribute it and/or modify
32
+# This program is free software; you can redistribute it and/or modify
60
+# it under the terms of the GNU General Public License as published by
33
+# it under the terms of the GNU General Public License as published by
61
+# the Free Software Foundation; either version 2 of the License, or
34
+# the Free Software Foundation; either version 2 of the License, or
62
+# (at your option) any later version.
35
+# (at your option) any later version.
...
...
66
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
39
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
67
+# GNU General Public License for more details.
40
+# GNU General Public License for more details.
68
+#
41
+#
69
+# You should have received a copy of the GNU General Public License
42
+# You should have received a copy of the GNU General Public License
70
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
43
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
71
+#
72
+
44
+
73
+seq="$(basename $0)"
45
+seq=$(basename $0)
74
+echo "QA output created by $seq"
46
+echo "QA output created by $seq"
75
+
47
+
76
+status=1 # failure is the default!
48
+status=1    # failure is the default!
77
+
49
+
78
+_cleanup()
50
+# get standard environment
79
+{
51
+. ./common.rc
80
+ _cleanup_test_img
81
+}
82
+trap "_cleanup; exit \$status" 0 1 2 3 15
83
+
52
+
84
+# get standard environment, filters and checks
53
+if ! type -p "pylint-3" > /dev/null; then
85
+. ./common.rc
54
+ _notrun "pylint-3 not found"
86
+. ./common.filter
55
+fi
56
+if ! type -p "mypy" > /dev/null; then
57
+ _notrun "mypy not found"
58
+fi
87
+
59
+
88
+_supported_fmt raw
60
+pylint-3 --score=n iotests.py
89
+_supported_proto file
90
+_supported_os Linux
91
+
61
+
92
+_default_cache_mode none
62
+MYPYPATH=../../python/ mypy --warn-unused-configs --disallow-subclassing-any \
93
+_supported_cache_modes none directsync
63
+ --disallow-any-generics --disallow-incomplete-defs \
94
+
64
+ --disallow-untyped-decorators --no-implicit-optional \
95
+echo
65
+ --warn-redundant-casts --warn-unused-ignores \
96
+echo "=== Check mapping of unaligned raw image ==="
66
+ --no-implicit-reexport iotests.py
97
+echo
98
+
99
+# We do not know how large a physical sector is, but it is certainly
100
+# going to be a factor of 1 MB
101
+size=$((1 * 1024 * 1024 - 1))
102
+
103
+# qemu-img create rounds size up to BDRV_SECTOR_SIZE
104
+_make_test_img $size
105
+$QEMU_IMG map --output=json --image-opts \
106
+ "driver=$IMGFMT,file.driver=file,file.filename=$TEST_IMG,cache.direct=on" \
107
+ | _filter_qemu_img_map
108
+
109
+# so we resize it and check again
110
+truncate --size=$size "$TEST_IMG"
111
+$QEMU_IMG map --output=json --image-opts \
112
+ "driver=$IMGFMT,file.driver=file,file.filename=$TEST_IMG,cache.direct=on" \
113
+ | _filter_qemu_img_map
114
+
115
+# qemu-io with O_DIRECT always writes whole physical sectors. Again,
116
+# we do not know how large a physical sector is, so we just start
117
+# writing from a 64 kB boundary, which should always be aligned.
118
+offset=$((1 * 1024 * 1024 - 64 * 1024))
119
+$QEMU_IO -c "w $offset $((size - offset))" "$TEST_IMG" | _filter_qemu_io
120
+$QEMU_IMG map --output=json --image-opts \
121
+ "driver=$IMGFMT,file.driver=file,file.filename=$TEST_IMG,cache.direct=on" \
122
+ | _filter_qemu_img_map
123
+
124
+# Resize it and check again -- contrary to 221, we may not get partial
125
+# sectors here, so there should be only two areas (one zero, one
126
+# data).
127
+truncate --size=$size "$TEST_IMG"
128
+$QEMU_IMG map --output=json --image-opts \
129
+ "driver=$IMGFMT,file.driver=file,file.filename=$TEST_IMG,cache.direct=on" \
130
+ | _filter_qemu_img_map
131
+
67
+
132
+# success, all done
68
+# success, all done
133
+echo '*** done'
69
+echo "*** done"
134
+rm -f $seq.full
70
+rm -f $seq.full
135
+status=0
71
+status=0
136
diff --git a/tests/qemu-iotests/253.out b/tests/qemu-iotests/253.out
72
diff --git a/tests/qemu-iotests/297.out b/tests/qemu-iotests/297.out
137
new file mode 100644
73
new file mode 100644
138
index XXXXXXX..XXXXXXX
74
index XXXXXXX..XXXXXXX
139
--- /dev/null
75
--- /dev/null
140
+++ b/tests/qemu-iotests/253.out
76
+++ b/tests/qemu-iotests/297.out
141
@@ -XXX,XX +XXX,XX @@
77
@@ -XXX,XX +XXX,XX @@
142
+QA output created by 253
78
+QA output created by 297
143
+
79
+Success: no issues found in 1 source file
144
+=== Check mapping of unaligned raw image ===
145
+
146
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048575
147
+[{ "start": 0, "length": 1048576, "depth": 0, "zero": true, "data": false, "offset": OFFSET}]
148
+[{ "start": 0, "length": 1048576, "depth": 0, "zero": true, "data": false, "offset": OFFSET}]
149
+wrote 65535/65535 bytes at offset 983040
150
+63.999 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
151
+[{ "start": 0, "length": 983040, "depth": 0, "zero": true, "data": false, "offset": OFFSET},
152
+{ "start": 983040, "length": 65536, "depth": 0, "zero": false, "data": true, "offset": OFFSET}]
153
+[{ "start": 0, "length": 983040, "depth": 0, "zero": true, "data": false, "offset": OFFSET},
154
+{ "start": 983040, "length": 65536, "depth": 0, "zero": false, "data": true, "offset": OFFSET}]
155
+*** done
80
+*** done
156
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
81
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
157
index XXXXXXX..XXXXXXX 100644
82
index XXXXXXX..XXXXXXX 100644
158
--- a/tests/qemu-iotests/group
83
--- a/tests/qemu-iotests/group
159
+++ b/tests/qemu-iotests/group
84
+++ b/tests/qemu-iotests/group
160
@@ -XXX,XX +XXX,XX @@
85
@@ -XXX,XX +XXX,XX @@
161
248 rw auto quick
86
289 rw quick
162
249 rw auto quick
87
290 rw auto quick
163
252 rw auto backing quick
88
292 rw auto quick
164
+253 rw auto quick
89
+297 meta
165
--
90
--
166
2.20.1
91
2.25.4
167
92
168
93
diff view generated by jsdifflib
New patch
1
From: Max Reitz <mreitz@redhat.com>
1
2
3
Right now, all users of bdrv_make_empty() call the BlockDriver method
4
directly. That is not only bad style, it is also wrong, unless the
5
caller has a BdrvChild with a WRITE or WRITE_UNCHANGED permission.
6
(WRITE_UNCHANGED suffices, because callers generally use this function
7
to clear a node with a backing file after a commit operation.)
8
9
Introduce bdrv_make_empty() that verifies that it does.
10
11
Signed-off-by: Max Reitz <mreitz@redhat.com>
12
Message-Id: <20200429141126.85159-2-mreitz@redhat.com>
13
Reviewed-by: Eric Blake <eblake@redhat.com>
14
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
15
---
16
include/block/block.h | 1 +
17
block.c | 23 +++++++++++++++++++++++
18
2 files changed, 24 insertions(+)
19
20
diff --git a/include/block/block.h b/include/block/block.h
21
index XXXXXXX..XXXXXXX 100644
22
--- a/include/block/block.h
23
+++ b/include/block/block.h
24
@@ -XXX,XX +XXX,XX @@ BlockMeasureInfo *bdrv_measure(BlockDriver *drv, QemuOpts *opts,
25
void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr);
26
void bdrv_refresh_limits(BlockDriverState *bs, Error **errp);
27
int bdrv_commit(BlockDriverState *bs);
28
+int bdrv_make_empty(BdrvChild *c, Error **errp);
29
int bdrv_change_backing_file(BlockDriverState *bs,
30
const char *backing_file, const char *backing_fmt);
31
void bdrv_register(BlockDriver *bdrv);
32
diff --git a/block.c b/block.c
33
index XXXXXXX..XXXXXXX 100644
34
--- a/block.c
35
+++ b/block.c
36
@@ -XXX,XX +XXX,XX @@ void bdrv_del_child(BlockDriverState *parent_bs, BdrvChild *child, Error **errp)
37
38
parent_bs->drv->bdrv_del_child(parent_bs, child, errp);
39
}
40
+
41
+int bdrv_make_empty(BdrvChild *c, Error **errp)
42
+{
43
+ BlockDriver *drv = c->bs->drv;
44
+ int ret;
45
+
46
+ assert(c->perm & (BLK_PERM_WRITE | BLK_PERM_WRITE_UNCHANGED));
47
+
48
+ if (!drv->bdrv_make_empty) {
49
+ error_setg(errp, "%s does not support emptying nodes",
50
+ drv->format_name);
51
+ return -ENOTSUP;
52
+ }
53
+
54
+ ret = drv->bdrv_make_empty(c->bs);
55
+ if (ret < 0) {
56
+ error_setg_errno(errp, -ret, "Failed to empty %s",
57
+ c->bs->filename);
58
+ return ret;
59
+ }
60
+
61
+ return 0;
62
+}
63
--
64
2.25.4
65
66
diff view generated by jsdifflib
1
Some users (like block jobs) can tolerate an AioContext change for their
1
From: Max Reitz <mreitz@redhat.com>
2
BlockBackend. Add a function that tells the BlockBackend that it can
3
allow changes.
4
2
3
Two callers of BlockDriver.bdrv_make_empty() remain that should not call
4
this method directly. Both do not have access to a BdrvChild, but they
5
can use a BlockBackend, so we add this function that lets them use it.
6
7
Signed-off-by: Max Reitz <mreitz@redhat.com>
8
Message-Id: <20200429141126.85159-4-mreitz@redhat.com>
9
Reviewed-by: Eric Blake <eblake@redhat.com>
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
---
11
---
7
include/sysemu/block-backend.h | 1 +
12
include/sysemu/block-backend.h | 2 ++
8
block/block-backend.c | 10 ++++++++++
13
block/block-backend.c | 10 ++++++++++
9
2 files changed, 11 insertions(+)
14
2 files changed, 12 insertions(+)
10
15
11
diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h
16
diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h
12
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
13
--- a/include/sysemu/block-backend.h
18
--- a/include/sysemu/block-backend.h
14
+++ b/include/sysemu/block-backend.h
19
+++ b/include/sysemu/block-backend.h
15
@@ -XXX,XX +XXX,XX @@ int blk_set_perm(BlockBackend *blk, uint64_t perm, uint64_t shared_perm,
20
@@ -XXX,XX +XXX,XX @@ int coroutine_fn blk_co_copy_range(BlockBackend *blk_in, int64_t off_in,
16
void blk_get_perm(BlockBackend *blk, uint64_t *perm, uint64_t *shared_perm);
21
17
22
const BdrvChild *blk_root(BlockBackend *blk);
18
void blk_set_allow_write_beyond_eof(BlockBackend *blk, bool allow);
23
19
+void blk_set_allow_aio_context_change(BlockBackend *blk, bool allow);
24
+int blk_make_empty(BlockBackend *blk, Error **errp);
20
void blk_iostatus_enable(BlockBackend *blk);
25
+
21
bool blk_iostatus_is_enabled(const BlockBackend *blk);
26
#endif
22
BlockDeviceIoStatus blk_iostatus(const BlockBackend *blk);
23
diff --git a/block/block-backend.c b/block/block-backend.c
27
diff --git a/block/block-backend.c b/block/block-backend.c
24
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
25
--- a/block/block-backend.c
29
--- a/block/block-backend.c
26
+++ b/block/block-backend.c
30
+++ b/block/block-backend.c
27
@@ -XXX,XX +XXX,XX @@ struct BlockBackend {
31
@@ -XXX,XX +XXX,XX @@ const BdrvChild *blk_root(BlockBackend *blk)
28
uint64_t shared_perm;
32
{
29
bool disable_perm;
33
return blk->root;
30
31
+ bool allow_aio_context_change;
32
bool allow_write_beyond_eof;
33
34
NotifierList remove_bs_notifiers, insert_bs_notifiers;
35
@@ -XXX,XX +XXX,XX @@ void blk_set_allow_write_beyond_eof(BlockBackend *blk, bool allow)
36
blk->allow_write_beyond_eof = allow;
37
}
34
}
38
35
+
39
+void blk_set_allow_aio_context_change(BlockBackend *blk, bool allow)
36
+int blk_make_empty(BlockBackend *blk, Error **errp)
40
+{
37
+{
41
+ blk->allow_aio_context_change = allow;
38
+ if (!blk_is_available(blk)) {
42
+}
39
+ error_setg(errp, "No medium inserted");
43
+
40
+ return -ENOMEDIUM;
44
static int blk_check_byte_request(BlockBackend *blk, int64_t offset,
45
size_t size)
46
{
47
@@ -XXX,XX +XXX,XX @@ static bool blk_root_can_set_aio_ctx(BdrvChild *child, AioContext *ctx,
48
{
49
BlockBackend *blk = child->opaque;
50
51
+ if (blk->allow_aio_context_change) {
52
+ return true;
53
+ }
41
+ }
54
+
42
+
55
/* Only manually created BlockBackends that are not attached to anything
43
+ return bdrv_make_empty(blk->root, errp);
56
* can change their AioContext without updating their user. */
44
+}
57
if (!blk->name || blk->dev) {
58
--
45
--
59
2.20.1
46
2.25.4
60
47
61
48
diff view generated by jsdifflib
New patch
1
From: Max Reitz <mreitz@redhat.com>
1
2
3
bdrv_commit() already has a BlockBackend pointing to the BDS that we
4
want to empty, it just has the wrong permissions.
5
6
qemu-img commit has no BlockBackend pointing to the old backing file
7
yet, but introducing one is simple.
8
9
After this commit, bdrv_make_empty() is the only remaining caller of
10
BlockDriver.bdrv_make_empty().
11
12
Signed-off-by: Max Reitz <mreitz@redhat.com>
13
Message-Id: <20200429141126.85159-5-mreitz@redhat.com>
14
Reviewed-by: Eric Blake <eblake@redhat.com>
15
[kwolf: Fixed up reference output for 098]
16
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
17
---
18
block/commit.c | 16 +++++++++-------
19
qemu-img.c | 19 ++++++++++++++-----
20
tests/qemu-iotests/098.out | 8 ++++----
21
3 files changed, 27 insertions(+), 16 deletions(-)
22
23
diff --git a/block/commit.c b/block/commit.c
24
index XXXXXXX..XXXXXXX 100644
25
--- a/block/commit.c
26
+++ b/block/commit.c
27
@@ -XXX,XX +XXX,XX @@ int bdrv_commit(BlockDriverState *bs)
28
}
29
30
ctx = bdrv_get_aio_context(bs);
31
- src = blk_new(ctx, BLK_PERM_CONSISTENT_READ, BLK_PERM_ALL);
32
+ /* WRITE_UNCHANGED is required for bdrv_make_empty() */
33
+ src = blk_new(ctx, BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE_UNCHANGED,
34
+ BLK_PERM_ALL);
35
backing = blk_new(ctx, BLK_PERM_WRITE | BLK_PERM_RESIZE, BLK_PERM_ALL);
36
37
ret = blk_insert_bs(src, bs, &local_err);
38
@@ -XXX,XX +XXX,XX @@ int bdrv_commit(BlockDriverState *bs)
39
}
40
}
41
42
- if (drv->bdrv_make_empty) {
43
- ret = drv->bdrv_make_empty(bs);
44
- if (ret < 0) {
45
- goto ro_cleanup;
46
- }
47
- blk_flush(src);
48
+ ret = blk_make_empty(src, NULL);
49
+ /* Ignore -ENOTSUP */
50
+ if (ret < 0 && ret != -ENOTSUP) {
51
+ goto ro_cleanup;
52
}
53
54
+ blk_flush(src);
55
+
56
/*
57
* Make sure all data we wrote to the backing device is actually
58
* stable on disk.
59
diff --git a/qemu-img.c b/qemu-img.c
60
index XXXXXXX..XXXXXXX 100644
61
--- a/qemu-img.c
62
+++ b/qemu-img.c
63
@@ -XXX,XX +XXX,XX @@ static int img_commit(int argc, char **argv)
64
goto unref_backing;
65
}
66
67
- if (!drop && bs->drv->bdrv_make_empty) {
68
- ret = bs->drv->bdrv_make_empty(bs);
69
- if (ret) {
70
- error_setg_errno(&local_err, -ret, "Could not empty %s",
71
- filename);
72
+ if (!drop) {
73
+ BlockBackend *old_backing_blk;
74
+
75
+ old_backing_blk = blk_new_with_bs(bs, BLK_PERM_WRITE, BLK_PERM_ALL,
76
+ &local_err);
77
+ if (!old_backing_blk) {
78
+ goto unref_backing;
79
+ }
80
+ ret = blk_make_empty(old_backing_blk, &local_err);
81
+ blk_unref(old_backing_blk);
82
+ if (ret == -ENOTSUP) {
83
+ error_free(local_err);
84
+ local_err = NULL;
85
+ } else if (ret < 0) {
86
goto unref_backing;
87
}
88
}
89
diff --git a/tests/qemu-iotests/098.out b/tests/qemu-iotests/098.out
90
index XXXXXXX..XXXXXXX 100644
91
--- a/tests/qemu-iotests/098.out
92
+++ b/tests/qemu-iotests/098.out
93
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864
94
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file=TEST_DIR/t.IMGFMT.base
95
wrote 65536/65536 bytes at offset 0
96
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
97
-qemu-img: Could not empty blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.IMGFMT: Input/output error
98
+qemu-img: Failed to empty blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.IMGFMT: Input/output error
99
No errors were found on the image.
100
101
=== empty_image_prepare ===
102
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864
103
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file=TEST_DIR/t.IMGFMT.base
104
wrote 65536/65536 bytes at offset 0
105
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
106
-qemu-img: Could not empty blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.IMGFMT: Input/output error
107
+qemu-img: Failed to empty blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.IMGFMT: Input/output error
108
Leaked cluster 4 refcount=1 reference=0
109
Leaked cluster 5 refcount=1 reference=0
110
Repairing cluster 4 refcount=1 reference=0
111
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864
112
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file=TEST_DIR/t.IMGFMT.base
113
wrote 65536/65536 bytes at offset 0
114
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
115
-qemu-img: Could not empty blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.IMGFMT: Input/output error
116
+qemu-img: Failed to empty blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.IMGFMT: Input/output error
117
ERROR cluster 0 refcount=0 reference=1
118
ERROR cluster 1 refcount=0 reference=1
119
ERROR cluster 3 refcount=0 reference=1
120
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864
121
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file=TEST_DIR/t.IMGFMT.base
122
wrote 65536/65536 bytes at offset 0
123
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
124
-qemu-img: Could not empty blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.IMGFMT: Input/output error
125
+qemu-img: Failed to empty blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.IMGFMT: Input/output error
126
ERROR cluster 0 refcount=0 reference=1
127
ERROR cluster 1 refcount=0 reference=1
128
ERROR cluster 3 refcount=0 reference=1
129
--
130
2.25.4
131
132
diff view generated by jsdifflib
New patch
1
This is just a bandaid to keep tests/test-replication working after
2
bdrv_make_empty() starts to assert that we're not trying to call it on a
3
read-only child.
1
4
5
For the real solution in the future, replication should not steal the
6
BdrvChild from its backing file (this is never correct to do!), but
7
instead have its own child node references, with the appropriate
8
permissions.
9
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
---
12
block/replication.c | 13 +++++++++++--
13
1 file changed, 11 insertions(+), 2 deletions(-)
14
15
diff --git a/block/replication.c b/block/replication.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/block/replication.c
18
+++ b/block/replication.c
19
@@ -XXX,XX +XXX,XX @@ static void secondary_do_checkpoint(BDRVReplicationState *s, Error **errp)
20
return;
21
}
22
23
- ret = s->hidden_disk->bs->drv->bdrv_make_empty(s->hidden_disk->bs);
24
+ BlockBackend *blk = blk_new(qemu_get_current_aio_context(),
25
+ BLK_PERM_WRITE, BLK_PERM_ALL);
26
+ blk_insert_bs(blk, s->hidden_disk->bs, &local_err);
27
+ if (local_err) {
28
+ error_propagate(errp, local_err);
29
+ blk_unref(blk);
30
+ return;
31
+ }
32
+
33
+ ret = blk_make_empty(blk, errp);
34
+ blk_unref(blk);
35
if (ret < 0) {
36
- error_setg(errp, "Cannot make hidden disk empty");
37
return;
38
}
39
}
40
--
41
2.25.4
42
43
diff view generated by jsdifflib
New patch
1
From: Max Reitz <mreitz@redhat.com>
1
2
3
Signed-off-by: Max Reitz <mreitz@redhat.com>
4
Reviewed-by: Eric Blake <eblake@redhat.com>
5
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
6
Message-Id: <20200429141126.85159-3-mreitz@redhat.com>
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
---
9
block/replication.c | 3 +--
10
block/vvfat.c | 4 +---
11
2 files changed, 2 insertions(+), 5 deletions(-)
12
13
diff --git a/block/replication.c b/block/replication.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/block/replication.c
16
+++ b/block/replication.c
17
@@ -XXX,XX +XXX,XX @@ static void secondary_do_checkpoint(BDRVReplicationState *s, Error **errp)
18
return;
19
}
20
21
- ret = s->active_disk->bs->drv->bdrv_make_empty(s->active_disk->bs);
22
+ ret = bdrv_make_empty(s->active_disk, errp);
23
if (ret < 0) {
24
- error_setg(errp, "Cannot make active disk empty");
25
return;
26
}
27
28
diff --git a/block/vvfat.c b/block/vvfat.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/block/vvfat.c
31
+++ b/block/vvfat.c
32
@@ -XXX,XX +XXX,XX @@ static int do_commit(BDRVVVFATState* s)
33
return ret;
34
}
35
36
- if (s->qcow->bs->drv && s->qcow->bs->drv->bdrv_make_empty) {
37
- s->qcow->bs->drv->bdrv_make_empty(s->qcow->bs);
38
- }
39
+ bdrv_make_empty(s->qcow, NULL);
40
41
memset(s->used_clusters, 0, sector2cluster(s, s->sector_count));
42
43
--
44
2.25.4
45
46
diff view generated by jsdifflib
New patch
1
From: Max Reitz <mreitz@redhat.com>
1
2
3
The commit, mirror, and blkreplay block nodes are filters, so they should
4
be marked as such.
5
6
Signed-off-by: Max Reitz <mreitz@redhat.com>
7
Message-Id: <20200513110544.176672-2-mreitz@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
---
10
block/blkreplay.c | 1 +
11
block/commit.c | 2 ++
12
block/mirror.c | 2 ++
13
3 files changed, 5 insertions(+)
14
15
diff --git a/block/blkreplay.c b/block/blkreplay.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/block/blkreplay.c
18
+++ b/block/blkreplay.c
19
@@ -XXX,XX +XXX,XX @@ static int blkreplay_snapshot_goto(BlockDriverState *bs,
20
static BlockDriver bdrv_blkreplay = {
21
.format_name = "blkreplay",
22
.instance_size = 0,
23
+ .is_filter = true,
24
25
.bdrv_open = blkreplay_open,
26
.bdrv_child_perm = bdrv_filter_default_perms,
27
diff --git a/block/commit.c b/block/commit.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/block/commit.c
30
+++ b/block/commit.c
31
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_commit_top = {
32
.bdrv_co_block_status = bdrv_co_block_status_from_backing,
33
.bdrv_refresh_filename = bdrv_commit_top_refresh_filename,
34
.bdrv_child_perm = bdrv_commit_top_child_perm,
35
+
36
+ .is_filter = true,
37
};
38
39
void commit_start(const char *job_id, BlockDriverState *bs,
40
diff --git a/block/mirror.c b/block/mirror.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/block/mirror.c
43
+++ b/block/mirror.c
44
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_mirror_top = {
45
.bdrv_co_block_status = bdrv_co_block_status_from_backing,
46
.bdrv_refresh_filename = bdrv_mirror_top_refresh_filename,
47
.bdrv_child_perm = bdrv_mirror_top_child_perm,
48
+
49
+ .is_filter = true,
50
};
51
52
static BlockJob *mirror_start_job(
53
--
54
2.25.4
55
56
diff view generated by jsdifflib
New patch
1
1
From: Max Reitz <mreitz@redhat.com>
2
3
We want to unify child_format and child_file at some point. One of the
4
important things that set format drivers apart from other drivers is
5
that they do not expect other format nodes under them (except in the
6
backing chain), i.e. we must not probe formats inside of formats. That
7
means we need something on which to distinguish format drivers from
8
others, and hence this flag.
9
10
Signed-off-by: Max Reitz <mreitz@redhat.com>
11
Reviewed-by: Eric Blake <eblake@redhat.com>
12
Reviewed-by: Alberto Garcia <berto@igalia.com>
13
Message-Id: <20200513110544.176672-3-mreitz@redhat.com>
14
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
15
---
16
include/block/block_int.h | 7 +++++++
17
block/bochs.c | 1 +
18
block/cloop.c | 1 +
19
block/crypto.c | 2 ++
20
block/dmg.c | 1 +
21
block/parallels.c | 1 +
22
block/qcow.c | 1 +
23
block/qcow2.c | 1 +
24
block/qed.c | 1 +
25
block/raw-format.c | 1 +
26
block/vdi.c | 1 +
27
block/vhdx.c | 1 +
28
block/vmdk.c | 1 +
29
block/vpc.c | 1 +
30
14 files changed, 21 insertions(+)
31
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
* must implement them and return -ENOTSUP.
38
*/
39
bool is_filter;
40
+ /*
41
+ * Set to true if the BlockDriver is a format driver. Format nodes
42
+ * generally do not expect their children to be other format nodes
43
+ * (except for backing files), and so format probing is disabled
44
+ * on those children.
45
+ */
46
+ bool is_format;
47
/*
48
* Return true if @to_replace can be replaced by a BDS with the
49
* same data as @bs without it affecting @bs's behavior (that is,
50
diff --git a/block/bochs.c b/block/bochs.c
51
index XXXXXXX..XXXXXXX 100644
52
--- a/block/bochs.c
53
+++ b/block/bochs.c
54
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_bochs = {
55
.bdrv_refresh_limits = bochs_refresh_limits,
56
.bdrv_co_preadv = bochs_co_preadv,
57
.bdrv_close        = bochs_close,
58
+ .is_format = true,
59
};
60
61
static void bdrv_bochs_init(void)
62
diff --git a/block/cloop.c b/block/cloop.c
63
index XXXXXXX..XXXXXXX 100644
64
--- a/block/cloop.c
65
+++ b/block/cloop.c
66
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_cloop = {
67
.bdrv_refresh_limits = cloop_refresh_limits,
68
.bdrv_co_preadv = cloop_co_preadv,
69
.bdrv_close = cloop_close,
70
+ .is_format = true,
71
};
72
73
static void bdrv_cloop_init(void)
74
diff --git a/block/crypto.c b/block/crypto.c
75
index XXXXXXX..XXXXXXX 100644
76
--- a/block/crypto.c
77
+++ b/block/crypto.c
78
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_crypto_luks = {
79
.bdrv_get_info = block_crypto_get_info_luks,
80
.bdrv_get_specific_info = block_crypto_get_specific_info_luks,
81
82
+ .is_format = true,
83
+
84
.strong_runtime_opts = block_crypto_strong_runtime_opts,
85
};
86
87
diff --git a/block/dmg.c b/block/dmg.c
88
index XXXXXXX..XXXXXXX 100644
89
--- a/block/dmg.c
90
+++ b/block/dmg.c
91
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_dmg = {
92
.bdrv_child_perm = bdrv_format_default_perms,
93
.bdrv_co_preadv = dmg_co_preadv,
94
.bdrv_close = dmg_close,
95
+ .is_format = true,
96
};
97
98
static void bdrv_dmg_init(void)
99
diff --git a/block/parallels.c b/block/parallels.c
100
index XXXXXXX..XXXXXXX 100644
101
--- a/block/parallels.c
102
+++ b/block/parallels.c
103
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_parallels = {
104
.bdrv_co_flush_to_os = parallels_co_flush_to_os,
105
.bdrv_co_readv = parallels_co_readv,
106
.bdrv_co_writev = parallels_co_writev,
107
+ .is_format = true,
108
.supports_backing = true,
109
.bdrv_co_create = parallels_co_create,
110
.bdrv_co_create_opts = parallels_co_create_opts,
111
diff --git a/block/qcow.c b/block/qcow.c
112
index XXXXXXX..XXXXXXX 100644
113
--- a/block/qcow.c
114
+++ b/block/qcow.c
115
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_qcow = {
116
.bdrv_co_create = qcow_co_create,
117
.bdrv_co_create_opts = qcow_co_create_opts,
118
.bdrv_has_zero_init = bdrv_has_zero_init_1,
119
+ .is_format = true,
120
.supports_backing = true,
121
.bdrv_refresh_limits = qcow_refresh_limits,
122
123
diff --git a/block/qcow2.c b/block/qcow2.c
124
index XXXXXXX..XXXXXXX 100644
125
--- a/block/qcow2.c
126
+++ b/block/qcow2.c
127
@@ -XXX,XX +XXX,XX @@ BlockDriver bdrv_qcow2 = {
128
.bdrv_save_vmstate = qcow2_save_vmstate,
129
.bdrv_load_vmstate = qcow2_load_vmstate,
130
131
+ .is_format = true,
132
.supports_backing = true,
133
.bdrv_change_backing_file = qcow2_change_backing_file,
134
135
diff --git a/block/qed.c b/block/qed.c
136
index XXXXXXX..XXXXXXX 100644
137
--- a/block/qed.c
138
+++ b/block/qed.c
139
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_qed = {
140
.format_name = "qed",
141
.instance_size = sizeof(BDRVQEDState),
142
.create_opts = &qed_create_opts,
143
+ .is_format = true,
144
.supports_backing = true,
145
146
.bdrv_probe = bdrv_qed_probe,
147
diff --git a/block/raw-format.c b/block/raw-format.c
148
index XXXXXXX..XXXXXXX 100644
149
--- a/block/raw-format.c
150
+++ b/block/raw-format.c
151
@@ -XXX,XX +XXX,XX @@ BlockDriver bdrv_raw = {
152
.bdrv_co_copy_range_to = &raw_co_copy_range_to,
153
.bdrv_co_truncate = &raw_co_truncate,
154
.bdrv_getlength = &raw_getlength,
155
+ .is_format = true,
156
.has_variable_length = true,
157
.bdrv_measure = &raw_measure,
158
.bdrv_get_info = &raw_get_info,
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 BlockDriver bdrv_vdi = {
164
165
.bdrv_get_info = vdi_get_info,
166
167
+ .is_format = true,
168
.create_opts = &vdi_create_opts,
169
.bdrv_co_check = vdi_co_check,
170
};
171
diff --git a/block/vhdx.c b/block/vhdx.c
172
index XXXXXXX..XXXXXXX 100644
173
--- a/block/vhdx.c
174
+++ b/block/vhdx.c
175
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_vhdx = {
176
.bdrv_co_check = vhdx_co_check,
177
.bdrv_has_zero_init = vhdx_has_zero_init,
178
179
+ .is_format = true,
180
.create_opts = &vhdx_create_opts,
181
};
182
183
diff --git a/block/vmdk.c b/block/vmdk.c
184
index XXXXXXX..XXXXXXX 100644
185
--- a/block/vmdk.c
186
+++ b/block/vmdk.c
187
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_vmdk = {
188
.bdrv_get_info = vmdk_get_info,
189
.bdrv_gather_child_options = vmdk_gather_child_options,
190
191
+ .is_format = true,
192
.supports_backing = true,
193
.create_opts = &vmdk_create_opts,
194
};
195
diff --git a/block/vpc.c b/block/vpc.c
196
index XXXXXXX..XXXXXXX 100644
197
--- a/block/vpc.c
198
+++ b/block/vpc.c
199
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_vpc = {
200
201
.bdrv_get_info = vpc_get_info,
202
203
+ .is_format = true,
204
.create_opts = &vpc_create_opts,
205
.bdrv_has_zero_init = vpc_has_zero_init,
206
.strong_runtime_opts = vpc_strong_runtime_opts,
207
--
208
2.25.4
209
210
diff view generated by jsdifflib
1
Block jobs require that all of the nodes the job is using are in the
1
From: Max Reitz <mreitz@redhat.com>
2
same AioContext. Therefore all BdrvChild objects of the job propagate
3
.(can_)set_aio_context to all other job nodes, so that the switch is
4
checked and performed consistently even if both nodes are in different
5
subtrees.
6
2
3
This structure nearly only contains parent callbacks for child state
4
changes. It cannot really reflect a child's role, because different
5
roles may overlap (as we will see when real roles are introduced), and
6
because parents can have custom callbacks even when the child fulfills a
7
standard role.
8
9
Signed-off-by: Max Reitz <mreitz@redhat.com>
10
Reviewed-by: Eric Blake <eblake@redhat.com>
11
Reviewed-by: Alberto Garcia <berto@igalia.com>
12
Message-Id: <20200513110544.176672-4-mreitz@redhat.com>
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
---
14
---
9
block/backup.c | 8 --------
15
include/block/block.h | 6 +-
10
block/mirror.c | 10 +---------
16
include/block/block_int.h | 22 +++---
11
blockjob.c | 34 ++++++++++++++++++++++++++++++++++
17
block.c | 142 ++++++++++++++++++------------------
12
3 files changed, 35 insertions(+), 17 deletions(-)
18
block/backup-top.c | 8 +-
19
block/blkdebug.c | 4 +-
20
block/blklogwrites.c | 8 +-
21
block/block-backend.c | 6 +-
22
block/commit.c | 2 +-
23
block/copy-on-read.c | 2 +-
24
block/io.c | 22 +++---
25
block/mirror.c | 2 +-
26
block/quorum.c | 2 +-
27
block/replication.c | 2 +-
28
block/vvfat.c | 6 +-
29
blockjob.c | 2 +-
30
tests/test-bdrv-drain.c | 36 ++++-----
31
tests/test-bdrv-graph-mod.c | 2 +-
32
17 files changed, 141 insertions(+), 133 deletions(-)
13
33
14
diff --git a/block/backup.c b/block/backup.c
34
diff --git a/include/block/block.h b/include/block/block.h
15
index XXXXXXX..XXXXXXX 100644
35
index XXXXXXX..XXXXXXX 100644
16
--- a/block/backup.c
36
--- a/include/block/block.h
17
+++ b/block/backup.c
37
+++ b/include/block/block.h
18
@@ -XXX,XX +XXX,XX @@ static void backup_clean(Job *job)
38
@@ -XXX,XX +XXX,XX @@
19
s->target = NULL;
39
/* block.c */
20
}
40
typedef struct BlockDriver BlockDriver;
21
41
typedef struct BdrvChild BdrvChild;
22
-static void backup_attached_aio_context(BlockJob *job, AioContext *aio_context)
42
-typedef struct BdrvChildRole BdrvChildRole;
23
-{
43
+typedef struct BdrvChildClass BdrvChildClass;
24
- BackupBlockJob *s = container_of(job, BackupBlockJob, common);
44
25
-
45
typedef struct BlockDriverInfo {
26
- blk_set_aio_context(s->target, aio_context);
46
/* in bytes, 0 if irrelevant */
27
-}
47
@@ -XXX,XX +XXX,XX @@ int bdrv_parse_discard_flags(const char *mode, int *flags);
28
-
48
BdrvChild *bdrv_open_child(const char *filename,
29
void backup_do_checkpoint(BlockJob *job, Error **errp)
49
QDict *options, const char *bdref_key,
30
{
50
BlockDriverState* parent,
31
BackupBlockJob *backup_job = container_of(job, BackupBlockJob, common);
51
- const BdrvChildRole *child_role,
32
@@ -XXX,XX +XXX,XX @@ static const BlockJobDriver backup_job_driver = {
52
+ const BdrvChildClass *child_class,
33
.abort = backup_abort,
53
bool allow_none, Error **errp);
34
.clean = backup_clean,
54
BlockDriverState *bdrv_open_blockdev_ref(BlockdevRef *ref, Error **errp);
35
},
55
void bdrv_set_backing_hd(BlockDriverState *bs, BlockDriverState *backing_hd,
36
- .attached_aio_context = backup_attached_aio_context,
56
@@ -XXX,XX +XXX,XX @@ void bdrv_unref_child(BlockDriverState *parent, BdrvChild *child);
37
.drain = backup_drain,
57
BdrvChild *bdrv_attach_child(BlockDriverState *parent_bs,
58
BlockDriverState *child_bs,
59
const char *child_name,
60
- const BdrvChildRole *child_role,
61
+ const BdrvChildClass *child_class,
62
Error **errp);
63
64
bool bdrv_op_is_blocked(BlockDriverState *bs, BlockOpType op, Error **errp);
65
diff --git a/include/block/block_int.h b/include/block/block_int.h
66
index XXXXXXX..XXXXXXX 100644
67
--- a/include/block/block_int.h
68
+++ b/include/block/block_int.h
69
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
70
* the parents in @parent_perm and @parent_shared.
71
*
72
* If @c is NULL, return the permissions for attaching a new child for the
73
- * given @role.
74
+ * given @child_class.
75
*
76
* If @reopen_queue is non-NULL, don't return the currently needed
77
* permissions, but those that will be needed after applying the
78
* @reopen_queue.
79
*/
80
void (*bdrv_child_perm)(BlockDriverState *bs, BdrvChild *c,
81
- const BdrvChildRole *role,
82
+ const BdrvChildClass *child_class,
83
BlockReopenQueue *reopen_queue,
84
uint64_t parent_perm, uint64_t parent_shared,
85
uint64_t *nperm, uint64_t *nshared);
86
@@ -XXX,XX +XXX,XX @@ typedef struct BdrvAioNotifier {
87
QLIST_ENTRY(BdrvAioNotifier) list;
88
} BdrvAioNotifier;
89
90
-struct BdrvChildRole {
91
+struct BdrvChildClass {
92
/* If true, bdrv_replace_node() doesn't change the node this BdrvChild
93
* points to. */
94
bool stay_at_node;
95
@@ -XXX,XX +XXX,XX @@ struct BdrvChildRole {
96
void (*set_aio_ctx)(BdrvChild *child, AioContext *ctx, GSList **ignore);
38
};
97
};
39
98
99
-extern const BdrvChildRole child_file;
100
-extern const BdrvChildRole child_format;
101
-extern const BdrvChildRole child_backing;
102
+extern const BdrvChildClass child_file;
103
+extern const BdrvChildClass child_format;
104
+extern const BdrvChildClass child_backing;
105
106
struct BdrvChild {
107
BlockDriverState *bs;
108
char *name;
109
- const BdrvChildRole *role;
110
+ const BdrvChildClass *klass;
111
void *opaque;
112
113
/**
114
@@ -XXX,XX +XXX,XX @@ struct BdrvChild {
115
116
/*
117
* How many times the parent of this child has been drained
118
- * (through role->drained_*).
119
+ * (through klass->drained_*).
120
* Usually, this is equal to bs->quiesce_counter (potentially
121
* reduced by bdrv_drain_all_count). It may differ while the
122
* child is entering or leaving a drained section.
123
@@ -XXX,XX +XXX,XX @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
124
125
BdrvChild *bdrv_root_attach_child(BlockDriverState *child_bs,
126
const char *child_name,
127
- const BdrvChildRole *child_role,
128
+ const BdrvChildClass *child_class,
129
AioContext *ctx,
130
uint64_t perm, uint64_t shared_perm,
131
void *opaque, Error **errp);
132
@@ -XXX,XX +XXX,XX @@ int bdrv_child_refresh_perms(BlockDriverState *bs, BdrvChild *c, Error **errp);
133
* block filters: Forward CONSISTENT_READ, WRITE, WRITE_UNCHANGED and RESIZE to
134
* all children */
135
void bdrv_filter_default_perms(BlockDriverState *bs, BdrvChild *c,
136
- const BdrvChildRole *role,
137
+ const BdrvChildClass *child_class,
138
BlockReopenQueue *reopen_queue,
139
uint64_t perm, uint64_t shared,
140
uint64_t *nperm, uint64_t *nshared);
141
@@ -XXX,XX +XXX,XX @@ void bdrv_filter_default_perms(BlockDriverState *bs, BdrvChild *c,
142
* requires WRITE | RESIZE for read-write images, always requires
143
* CONSISTENT_READ and doesn't share WRITE. */
144
void bdrv_format_default_perms(BlockDriverState *bs, BdrvChild *c,
145
- const BdrvChildRole *role,
146
+ const BdrvChildClass *child_class,
147
BlockReopenQueue *reopen_queue,
148
uint64_t perm, uint64_t shared,
149
uint64_t *nperm, uint64_t *nshared);
150
diff --git a/block.c b/block.c
151
index XXXXXXX..XXXXXXX 100644
152
--- a/block.c
153
+++ b/block.c
154
@@ -XXX,XX +XXX,XX @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
155
const char *reference,
156
QDict *options, int flags,
157
BlockDriverState *parent,
158
- const BdrvChildRole *child_role,
159
+ const BdrvChildClass *child_class,
160
Error **errp);
161
162
/* If non-zero, use only whitelisted block drivers */
163
@@ -XXX,XX +XXX,XX @@ static void bdrv_inherited_options(int *child_flags, QDict *child_options,
164
*child_flags = flags;
165
}
166
167
-const BdrvChildRole child_file = {
168
+const BdrvChildClass child_file = {
169
.parent_is_bds = true,
170
.get_parent_desc = bdrv_child_get_parent_desc,
171
.inherit_options = bdrv_inherited_options,
172
@@ -XXX,XX +XXX,XX @@ static void bdrv_inherited_fmt_options(int *child_flags, QDict *child_options,
173
*child_flags &= ~(BDRV_O_PROTOCOL | BDRV_O_NO_IO);
174
}
175
176
-const BdrvChildRole child_format = {
177
+const BdrvChildClass child_format = {
178
.parent_is_bds = true,
179
.get_parent_desc = bdrv_child_get_parent_desc,
180
.inherit_options = bdrv_inherited_fmt_options,
181
@@ -XXX,XX +XXX,XX @@ static int bdrv_backing_update_filename(BdrvChild *c, BlockDriverState *base,
182
return ret;
183
}
184
185
-const BdrvChildRole child_backing = {
186
+const BdrvChildClass child_backing = {
187
.parent_is_bds = true,
188
.get_parent_desc = bdrv_child_get_parent_desc,
189
.attach = bdrv_backing_attach,
190
@@ -XXX,XX +XXX,XX @@ bool bdrv_is_writable(BlockDriverState *bs)
191
}
192
193
static void bdrv_child_perm(BlockDriverState *bs, BlockDriverState *child_bs,
194
- BdrvChild *c, const BdrvChildRole *role,
195
+ BdrvChild *c, const BdrvChildClass *child_class,
196
BlockReopenQueue *reopen_queue,
197
uint64_t parent_perm, uint64_t parent_shared,
198
uint64_t *nperm, uint64_t *nshared)
199
{
200
assert(bs->drv && bs->drv->bdrv_child_perm);
201
- bs->drv->bdrv_child_perm(bs, c, role, reopen_queue,
202
+ bs->drv->bdrv_child_perm(bs, c, child_class, reopen_queue,
203
parent_perm, parent_shared,
204
nperm, nshared);
205
/* TODO Take force_share from reopen_queue */
206
@@ -XXX,XX +XXX,XX @@ static int bdrv_check_perm(BlockDriverState *bs, BlockReopenQueue *q,
207
uint64_t cur_perm, cur_shared;
208
bool child_tighten_restr;
209
210
- bdrv_child_perm(bs, c->bs, c, c->role, q,
211
+ bdrv_child_perm(bs, c->bs, c, c->klass, q,
212
cumulative_perms, cumulative_shared_perms,
213
&cur_perm, &cur_shared);
214
ret = bdrv_child_check_perm(c, q, cur_perm, cur_shared, ignore_children,
215
@@ -XXX,XX +XXX,XX @@ static void bdrv_set_perm(BlockDriverState *bs, uint64_t cumulative_perms,
216
/* Update all children */
217
QLIST_FOREACH(c, &bs->children, next) {
218
uint64_t cur_perm, cur_shared;
219
- bdrv_child_perm(bs, c->bs, c, c->role, NULL,
220
+ bdrv_child_perm(bs, c->bs, c, c->klass, NULL,
221
cumulative_perms, cumulative_shared_perms,
222
&cur_perm, &cur_shared);
223
bdrv_child_set_perm(c, cur_perm, cur_shared);
224
@@ -XXX,XX +XXX,XX @@ void bdrv_get_cumulative_perm(BlockDriverState *bs, uint64_t *perm,
225
226
static char *bdrv_child_user_desc(BdrvChild *c)
227
{
228
- if (c->role->get_parent_desc) {
229
- return c->role->get_parent_desc(c);
230
+ if (c->klass->get_parent_desc) {
231
+ return c->klass->get_parent_desc(c);
232
}
233
234
return g_strdup("another user");
235
@@ -XXX,XX +XXX,XX @@ int bdrv_child_refresh_perms(BlockDriverState *bs, BdrvChild *c, Error **errp)
236
uint64_t perms, shared;
237
238
bdrv_get_cumulative_perm(bs, &parent_perms, &parent_shared);
239
- bdrv_child_perm(bs, c->bs, c, c->role, NULL, parent_perms, parent_shared,
240
+ bdrv_child_perm(bs, c->bs, c, c->klass, NULL, parent_perms, parent_shared,
241
&perms, &shared);
242
243
return bdrv_child_try_set_perm(c, perms, shared, errp);
244
}
245
246
void bdrv_filter_default_perms(BlockDriverState *bs, BdrvChild *c,
247
- const BdrvChildRole *role,
248
+ const BdrvChildClass *child_class,
249
BlockReopenQueue *reopen_queue,
250
uint64_t perm, uint64_t shared,
251
uint64_t *nperm, uint64_t *nshared)
252
@@ -XXX,XX +XXX,XX @@ void bdrv_filter_default_perms(BlockDriverState *bs, BdrvChild *c,
253
}
254
255
void bdrv_format_default_perms(BlockDriverState *bs, BdrvChild *c,
256
- const BdrvChildRole *role,
257
+ const BdrvChildClass *child_class,
258
BlockReopenQueue *reopen_queue,
259
uint64_t perm, uint64_t shared,
260
uint64_t *nperm, uint64_t *nshared)
261
{
262
- bool backing = (role == &child_backing);
263
- assert(role == &child_backing || role == &child_file);
264
+ bool backing = (child_class == &child_backing);
265
+ assert(child_class == &child_backing || child_class == &child_file);
266
267
if (!backing) {
268
int flags = bdrv_reopen_get_flags(reopen_queue, bs);
269
270
/* Apart from the modifications below, the same permissions are
271
* forwarded and left alone as for filters */
272
- bdrv_filter_default_perms(bs, c, role, reopen_queue, perm, shared,
273
- &perm, &shared);
274
+ bdrv_filter_default_perms(bs, c, child_class, reopen_queue,
275
+ perm, shared, &perm, &shared);
276
277
/* Format drivers may touch metadata even if the guest doesn't write */
278
if (bdrv_is_writable_after_reopen(bs, reopen_queue)) {
279
@@ -XXX,XX +XXX,XX @@ static void bdrv_replace_child_noperm(BdrvChild *child,
280
* If the new child node is drained but the old one was not, flush
281
* all outstanding requests to the old child node.
282
*/
283
- while (drain_saldo > 0 && child->role->drained_begin) {
284
+ while (drain_saldo > 0 && child->klass->drained_begin) {
285
bdrv_parent_drained_begin_single(child, true);
286
drain_saldo--;
287
}
288
@@ -XXX,XX +XXX,XX @@ static void bdrv_replace_child_noperm(BdrvChild *child,
289
/* Detach first so that the recursive drain sections coming from @child
290
* are already gone and we only end the drain sections that came from
291
* elsewhere. */
292
- if (child->role->detach) {
293
- child->role->detach(child);
294
+ if (child->klass->detach) {
295
+ child->klass->detach(child);
296
}
297
QLIST_REMOVE(child, next_parent);
298
}
299
@@ -XXX,XX +XXX,XX @@ static void bdrv_replace_child_noperm(BdrvChild *child,
300
/* Attach only after starting new drained sections, so that recursive
301
* drain sections coming from @child don't get an extra .drained_begin
302
* callback. */
303
- if (child->role->attach) {
304
- child->role->attach(child);
305
+ if (child->klass->attach) {
306
+ child->klass->attach(child);
307
}
308
}
309
310
@@ -XXX,XX +XXX,XX @@ static void bdrv_replace_child_noperm(BdrvChild *child,
311
* If the old child node was drained but the new one is not, allow
312
* requests to come in only after the new node has been attached.
313
*/
314
- while (drain_saldo < 0 && child->role->drained_end) {
315
+ while (drain_saldo < 0 && child->klass->drained_end) {
316
bdrv_parent_drained_end_single(child);
317
drain_saldo++;
318
}
319
@@ -XXX,XX +XXX,XX @@ static void bdrv_replace_child(BdrvChild *child, BlockDriverState *new_bs)
320
*/
321
BdrvChild *bdrv_root_attach_child(BlockDriverState *child_bs,
322
const char *child_name,
323
- const BdrvChildRole *child_role,
324
+ const BdrvChildClass *child_class,
325
AioContext *ctx,
326
uint64_t perm, uint64_t shared_perm,
327
void *opaque, Error **errp)
328
@@ -XXX,XX +XXX,XX @@ BdrvChild *bdrv_root_attach_child(BlockDriverState *child_bs,
329
*child = (BdrvChild) {
330
.bs = NULL,
331
.name = g_strdup(child_name),
332
- .role = child_role,
333
+ .klass = child_class,
334
.perm = perm,
335
.shared_perm = shared_perm,
336
.opaque = opaque,
337
@@ -XXX,XX +XXX,XX @@ BdrvChild *bdrv_root_attach_child(BlockDriverState *child_bs,
338
* try moving the parent into the AioContext of child_bs instead. */
339
if (bdrv_get_aio_context(child_bs) != ctx) {
340
ret = bdrv_try_set_aio_context(child_bs, ctx, &local_err);
341
- if (ret < 0 && child_role->can_set_aio_ctx) {
342
+ if (ret < 0 && child_class->can_set_aio_ctx) {
343
GSList *ignore = g_slist_prepend(NULL, child);
344
ctx = bdrv_get_aio_context(child_bs);
345
- if (child_role->can_set_aio_ctx(child, ctx, &ignore, NULL)) {
346
+ if (child_class->can_set_aio_ctx(child, ctx, &ignore, NULL)) {
347
error_free(local_err);
348
ret = 0;
349
g_slist_free(ignore);
350
ignore = g_slist_prepend(NULL, child);
351
- child_role->set_aio_ctx(child, ctx, &ignore);
352
+ child_class->set_aio_ctx(child, ctx, &ignore);
353
}
354
g_slist_free(ignore);
355
}
356
@@ -XXX,XX +XXX,XX @@ BdrvChild *bdrv_root_attach_child(BlockDriverState *child_bs,
357
BdrvChild *bdrv_attach_child(BlockDriverState *parent_bs,
358
BlockDriverState *child_bs,
359
const char *child_name,
360
- const BdrvChildRole *child_role,
361
+ const BdrvChildClass *child_class,
362
Error **errp)
363
{
364
BdrvChild *child;
365
@@ -XXX,XX +XXX,XX @@ BdrvChild *bdrv_attach_child(BlockDriverState *parent_bs,
366
bdrv_get_cumulative_perm(parent_bs, &perm, &shared_perm);
367
368
assert(parent_bs->drv);
369
- bdrv_child_perm(parent_bs, child_bs, NULL, child_role, NULL,
370
+ bdrv_child_perm(parent_bs, child_bs, NULL, child_class, NULL,
371
perm, shared_perm, &perm, &shared_perm);
372
373
- child = bdrv_root_attach_child(child_bs, child_name, child_role,
374
+ child = bdrv_root_attach_child(child_bs, child_name, child_class,
375
bdrv_get_aio_context(parent_bs),
376
perm, shared_perm, parent_bs, errp);
377
if (child == NULL) {
378
@@ -XXX,XX +XXX,XX @@ static void bdrv_parent_cb_change_media(BlockDriverState *bs, bool load)
379
{
380
BdrvChild *c;
381
QLIST_FOREACH(c, &bs->parents, next_parent) {
382
- if (c->role->change_media) {
383
- c->role->change_media(c, load);
384
+ if (c->klass->change_media) {
385
+ c->klass->change_media(c, load);
386
}
387
}
388
}
389
@@ -XXX,XX +XXX,XX @@ free_exit:
390
391
static BlockDriverState *
392
bdrv_open_child_bs(const char *filename, QDict *options, const char *bdref_key,
393
- BlockDriverState *parent, const BdrvChildRole *child_role,
394
+ BlockDriverState *parent, const BdrvChildClass *child_class,
395
bool allow_none, Error **errp)
396
{
397
BlockDriverState *bs = NULL;
398
@@ -XXX,XX +XXX,XX @@ bdrv_open_child_bs(const char *filename, QDict *options, const char *bdref_key,
399
char *bdref_key_dot;
400
const char *reference;
401
402
- assert(child_role != NULL);
403
+ assert(child_class != NULL);
404
405
bdref_key_dot = g_strdup_printf("%s.", bdref_key);
406
qdict_extract_subqdict(options, &image_options, bdref_key_dot);
407
@@ -XXX,XX +XXX,XX @@ bdrv_open_child_bs(const char *filename, QDict *options, const char *bdref_key,
408
}
409
410
bs = bdrv_open_inherit(filename, reference, image_options, 0,
411
- parent, child_role, errp);
412
+ parent, child_class, errp);
413
if (!bs) {
414
goto done;
415
}
416
@@ -XXX,XX +XXX,XX @@ done:
417
BdrvChild *bdrv_open_child(const char *filename,
418
QDict *options, const char *bdref_key,
419
BlockDriverState *parent,
420
- const BdrvChildRole *child_role,
421
+ const BdrvChildClass *child_class,
422
bool allow_none, Error **errp)
423
{
424
BlockDriverState *bs;
425
426
- bs = bdrv_open_child_bs(filename, options, bdref_key, parent, child_role,
427
+ bs = bdrv_open_child_bs(filename, options, bdref_key, parent, child_class,
428
allow_none, errp);
429
if (bs == NULL) {
430
return NULL;
431
}
432
433
- return bdrv_attach_child(parent, bs, bdref_key, child_role, errp);
434
+ return bdrv_attach_child(parent, bs, bdref_key, child_class, errp);
435
}
436
437
-/* TODO Future callers may need to specify parent/child_role in order for
438
- * option inheritance to work. Existing callers use it for the root node. */
439
+/*
440
+ * TODO Future callers may need to specify parent/child_class in order for
441
+ * option inheritance to work. Existing callers use it for the root node.
442
+ */
443
BlockDriverState *bdrv_open_blockdev_ref(BlockdevRef *ref, Error **errp)
444
{
445
BlockDriverState *bs = NULL;
446
@@ -XXX,XX +XXX,XX @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
447
const char *reference,
448
QDict *options, int flags,
449
BlockDriverState *parent,
450
- const BdrvChildRole *child_role,
451
+ const BdrvChildClass *child_class,
452
Error **errp)
453
{
454
int ret;
455
@@ -XXX,XX +XXX,XX @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
456
QDict *snapshot_options = NULL;
457
int snapshot_flags = 0;
458
459
- assert(!child_role || !flags);
460
- assert(!child_role == !parent);
461
+ assert(!child_class || !flags);
462
+ assert(!child_class == !parent);
463
464
if (reference) {
465
bool options_non_empty = options ? qdict_size(options) : false;
466
@@ -XXX,XX +XXX,XX @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
467
468
bs->explicit_options = qdict_clone_shallow(options);
469
470
- if (child_role) {
471
+ if (child_class) {
472
bs->inherits_from = parent;
473
- child_role->inherit_options(&flags, options,
474
- parent->open_flags, parent->options);
475
+ child_class->inherit_options(&flags, options,
476
+ parent->open_flags, parent->options);
477
}
478
479
ret = bdrv_fill_options(&options, filename, &flags, &local_err);
480
@@ -XXX,XX +XXX,XX @@ static bool bdrv_recurse_has_child(BlockDriverState *bs,
481
static BlockReopenQueue *bdrv_reopen_queue_child(BlockReopenQueue *bs_queue,
482
BlockDriverState *bs,
483
QDict *options,
484
- const BdrvChildRole *role,
485
+ const BdrvChildClass *klass,
486
QDict *parent_options,
487
int parent_flags,
488
bool keep_old_opts)
489
@@ -XXX,XX +XXX,XX @@ static BlockReopenQueue *bdrv_reopen_queue_child(BlockReopenQueue *bs_queue,
490
/* Inherit from parent node */
491
if (parent_options) {
492
flags = 0;
493
- role->inherit_options(&flags, options, parent_flags, parent_options);
494
+ klass->inherit_options(&flags, options, parent_flags, parent_options);
495
} else {
496
flags = bdrv_get_flags(bs);
497
}
498
@@ -XXX,XX +XXX,XX @@ static BlockReopenQueue *bdrv_reopen_queue_child(BlockReopenQueue *bs_queue,
499
}
500
501
bdrv_reopen_queue_child(bs_queue, child->bs, new_child_options,
502
- child->role, options, flags, child_keep_old);
503
+ child->klass, options, flags, child_keep_old);
504
}
505
506
return bs_queue;
507
@@ -XXX,XX +XXX,XX @@ static void bdrv_reopen_perm(BlockReopenQueue *q, BlockDriverState *bs,
508
} else {
509
uint64_t nperm, nshared;
510
511
- bdrv_child_perm(parent->state.bs, bs, c, c->role, q,
512
+ bdrv_child_perm(parent->state.bs, bs, c, c->klass, q,
513
parent->state.perm, parent->state.shared_perm,
514
&nperm, &nshared);
515
516
@@ -XXX,XX +XXX,XX @@ static bool should_update_child(BdrvChild *c, BlockDriverState *to)
517
GHashTable *found;
518
bool ret;
519
520
- if (c->role->stay_at_node) {
521
+ if (c->klass->stay_at_node) {
522
return false;
523
}
524
525
@@ -XXX,XX +XXX,XX @@ int bdrv_drop_intermediate(BlockDriverState *top, BlockDriverState *base,
526
}
527
528
/* If so, update the backing file path in the image file */
529
- if (c->role->update_filename) {
530
- ret = c->role->update_filename(c, base, backing_file_str,
531
- &local_err);
532
+ if (c->klass->update_filename) {
533
+ ret = c->klass->update_filename(c, base, backing_file_str,
534
+ &local_err);
535
if (ret < 0) {
536
bdrv_abort_perm_update(base);
537
error_report_err(local_err);
538
@@ -XXX,XX +XXX,XX @@ const char *bdrv_get_parent_name(const BlockDriverState *bs)
539
540
/* If multiple parents have a name, just pick the first one. */
541
QLIST_FOREACH(c, &bs->parents, next_parent) {
542
- if (c->role->get_name) {
543
- name = c->role->get_name(c);
544
+ if (c->klass->get_name) {
545
+ name = c->klass->get_name(c);
546
if (name && *name) {
547
return name;
548
}
549
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn bdrv_co_invalidate_cache(BlockDriverState *bs,
550
}
551
552
QLIST_FOREACH(parent, &bs->parents, next_parent) {
553
- if (parent->role->activate) {
554
- parent->role->activate(parent, &local_err);
555
+ if (parent->klass->activate) {
556
+ parent->klass->activate(parent, &local_err);
557
if (local_err) {
558
bs->open_flags |= BDRV_O_INACTIVE;
559
error_propagate(errp, local_err);
560
@@ -XXX,XX +XXX,XX @@ static bool bdrv_has_bds_parent(BlockDriverState *bs, bool only_active)
561
BdrvChild *parent;
562
563
QLIST_FOREACH(parent, &bs->parents, next_parent) {
564
- if (parent->role->parent_is_bds) {
565
+ if (parent->klass->parent_is_bds) {
566
BlockDriverState *parent_bs = parent->opaque;
567
if (!only_active || !(parent_bs->open_flags & BDRV_O_INACTIVE)) {
568
return true;
569
@@ -XXX,XX +XXX,XX @@ static int bdrv_inactivate_recurse(BlockDriverState *bs)
570
}
571
572
QLIST_FOREACH(parent, &bs->parents, next_parent) {
573
- if (parent->role->inactivate) {
574
- ret = parent->role->inactivate(parent);
575
+ if (parent->klass->inactivate) {
576
+ ret = parent->klass->inactivate(parent);
577
if (ret < 0) {
578
return ret;
579
}
580
@@ -XXX,XX +XXX,XX @@ void bdrv_set_aio_context_ignore(BlockDriverState *bs,
581
if (g_slist_find(*ignore, child)) {
582
continue;
583
}
584
- assert(child->role->set_aio_ctx);
585
+ assert(child->klass->set_aio_ctx);
586
*ignore = g_slist_prepend(*ignore, child);
587
- child->role->set_aio_ctx(child, new_context, ignore);
588
+ child->klass->set_aio_ctx(child, new_context, ignore);
589
}
590
591
bdrv_detach_aio_context(bs);
592
@@ -XXX,XX +XXX,XX @@ static bool bdrv_parent_can_set_aio_context(BdrvChild *c, AioContext *ctx,
593
}
594
*ignore = g_slist_prepend(*ignore, c);
595
596
- /* A BdrvChildRole that doesn't handle AioContext changes cannot
597
- * tolerate any AioContext changes */
598
- if (!c->role->can_set_aio_ctx) {
599
+ /*
600
+ * A BdrvChildClass that doesn't handle AioContext changes cannot
601
+ * tolerate any AioContext changes
602
+ */
603
+ if (!c->klass->can_set_aio_ctx) {
604
char *user = bdrv_child_user_desc(c);
605
error_setg(errp, "Changing iothreads is not supported by %s", user);
606
g_free(user);
607
return false;
608
}
609
- if (!c->role->can_set_aio_ctx(c, ctx, ignore, errp)) {
610
+ if (!c->klass->can_set_aio_ctx(c, ctx, ignore, errp)) {
611
assert(!errp || *errp);
612
return false;
613
}
614
@@ -XXX,XX +XXX,XX @@ void bdrv_refresh_filename(BlockDriverState *bs)
615
drv->bdrv_gather_child_options(bs, opts, backing_overridden);
616
} else {
617
QLIST_FOREACH(child, &bs->children, next) {
618
- if (child->role == &child_backing && !backing_overridden) {
619
+ if (child->klass == &child_backing && !backing_overridden) {
620
/* We can skip the backing BDS if it has not been overridden */
621
continue;
622
}
623
diff --git a/block/backup-top.c b/block/backup-top.c
624
index XXXXXXX..XXXXXXX 100644
625
--- a/block/backup-top.c
626
+++ b/block/backup-top.c
627
@@ -XXX,XX +XXX,XX @@ static void backup_top_refresh_filename(BlockDriverState *bs)
628
}
629
630
static void backup_top_child_perm(BlockDriverState *bs, BdrvChild *c,
631
- const BdrvChildRole *role,
632
+ const BdrvChildClass *child_class,
633
BlockReopenQueue *reopen_queue,
634
uint64_t perm, uint64_t shared,
635
uint64_t *nperm, uint64_t *nshared)
636
@@ -XXX,XX +XXX,XX @@ static void backup_top_child_perm(BlockDriverState *bs, BdrvChild *c,
637
return;
638
}
639
640
- if (role == &child_file) {
641
+ if (child_class == &child_file) {
642
/*
643
* Target child
644
*
645
@@ -XXX,XX +XXX,XX @@ static void backup_top_child_perm(BlockDriverState *bs, BdrvChild *c,
646
*nperm = BLK_PERM_WRITE;
647
} else {
648
/* Source child */
649
- bdrv_filter_default_perms(bs, c, role, reopen_queue, perm, shared,
650
- nperm, nshared);
651
+ bdrv_filter_default_perms(bs, c, child_class, reopen_queue,
652
+ perm, shared, nperm, nshared);
653
654
if (perm & BLK_PERM_WRITE) {
655
*nperm = *nperm | BLK_PERM_CONSISTENT_READ;
656
diff --git a/block/blkdebug.c b/block/blkdebug.c
657
index XXXXXXX..XXXXXXX 100644
658
--- a/block/blkdebug.c
659
+++ b/block/blkdebug.c
660
@@ -XXX,XX +XXX,XX @@ static int blkdebug_reopen_prepare(BDRVReopenState *reopen_state,
661
}
662
663
static void blkdebug_child_perm(BlockDriverState *bs, BdrvChild *c,
664
- const BdrvChildRole *role,
665
+ const BdrvChildClass *child_class,
666
BlockReopenQueue *reopen_queue,
667
uint64_t perm, uint64_t shared,
668
uint64_t *nperm, uint64_t *nshared)
669
{
670
BDRVBlkdebugState *s = bs->opaque;
671
672
- bdrv_filter_default_perms(bs, c, role, reopen_queue, perm, shared,
673
+ bdrv_filter_default_perms(bs, c, child_class, reopen_queue, perm, shared,
674
nperm, nshared);
675
676
*nperm |= s->take_child_perms;
677
diff --git a/block/blklogwrites.c b/block/blklogwrites.c
678
index XXXXXXX..XXXXXXX 100644
679
--- a/block/blklogwrites.c
680
+++ b/block/blklogwrites.c
681
@@ -XXX,XX +XXX,XX @@ static int64_t blk_log_writes_getlength(BlockDriverState *bs)
682
}
683
684
static void blk_log_writes_child_perm(BlockDriverState *bs, BdrvChild *c,
685
- const BdrvChildRole *role,
686
+ const BdrvChildClass *child_class,
687
BlockReopenQueue *ro_q,
688
uint64_t perm, uint64_t shrd,
689
uint64_t *nperm, uint64_t *nshrd)
690
@@ -XXX,XX +XXX,XX @@ static void blk_log_writes_child_perm(BlockDriverState *bs, BdrvChild *c,
691
}
692
693
if (!strcmp(c->name, "log")) {
694
- bdrv_format_default_perms(bs, c, role, ro_q, perm, shrd, nperm, nshrd);
695
+ bdrv_format_default_perms(bs, c, child_class, ro_q, perm, shrd, nperm,
696
+ nshrd);
697
} else {
698
- bdrv_filter_default_perms(bs, c, role, ro_q, perm, shrd, nperm, nshrd);
699
+ bdrv_filter_default_perms(bs, c, child_class, ro_q, perm, shrd, nperm,
700
+ nshrd);
701
}
702
}
703
704
diff --git a/block/block-backend.c b/block/block-backend.c
705
index XXXXXXX..XXXXXXX 100644
706
--- a/block/block-backend.c
707
+++ b/block/block-backend.c
708
@@ -XXX,XX +XXX,XX @@ static void blk_root_detach(BdrvChild *child)
709
}
710
}
711
712
-static const BdrvChildRole child_root = {
713
+static const BdrvChildClass child_root = {
714
.inherit_options = blk_root_inherit_options,
715
716
.change_media = blk_root_change_media,
717
@@ -XXX,XX +XXX,XX @@ static BlockBackend *bdrv_first_blk(BlockDriverState *bs)
718
{
719
BdrvChild *child;
720
QLIST_FOREACH(child, &bs->parents, next_parent) {
721
- if (child->role == &child_root) {
722
+ if (child->klass == &child_root) {
723
return child->opaque;
724
}
725
}
726
@@ -XXX,XX +XXX,XX @@ bool bdrv_is_root_node(BlockDriverState *bs)
727
BdrvChild *c;
728
729
QLIST_FOREACH(c, &bs->parents, next_parent) {
730
- if (c->role != &child_root) {
731
+ if (c->klass != &child_root) {
732
return false;
733
}
734
}
735
diff --git a/block/commit.c b/block/commit.c
736
index XXXXXXX..XXXXXXX 100644
737
--- a/block/commit.c
738
+++ b/block/commit.c
739
@@ -XXX,XX +XXX,XX @@ static void bdrv_commit_top_refresh_filename(BlockDriverState *bs)
740
}
741
742
static void bdrv_commit_top_child_perm(BlockDriverState *bs, BdrvChild *c,
743
- const BdrvChildRole *role,
744
+ const BdrvChildClass *child_class,
745
BlockReopenQueue *reopen_queue,
746
uint64_t perm, uint64_t shared,
747
uint64_t *nperm, uint64_t *nshared)
748
diff --git a/block/copy-on-read.c b/block/copy-on-read.c
749
index XXXXXXX..XXXXXXX 100644
750
--- a/block/copy-on-read.c
751
+++ b/block/copy-on-read.c
752
@@ -XXX,XX +XXX,XX @@ static int cor_open(BlockDriverState *bs, QDict *options, int flags,
753
#define PERM_UNCHANGED (BLK_PERM_ALL & ~PERM_PASSTHROUGH)
754
755
static void cor_child_perm(BlockDriverState *bs, BdrvChild *c,
756
- const BdrvChildRole *role,
757
+ const BdrvChildClass *child_class,
758
BlockReopenQueue *reopen_queue,
759
uint64_t perm, uint64_t shared,
760
uint64_t *nperm, uint64_t *nshared)
761
diff --git a/block/io.c b/block/io.c
762
index XXXXXXX..XXXXXXX 100644
763
--- a/block/io.c
764
+++ b/block/io.c
765
@@ -XXX,XX +XXX,XX @@ static void bdrv_parent_drained_begin(BlockDriverState *bs, BdrvChild *ignore,
766
BdrvChild *c, *next;
767
768
QLIST_FOREACH_SAFE(c, &bs->parents, next_parent, next) {
769
- if (c == ignore || (ignore_bds_parents && c->role->parent_is_bds)) {
770
+ if (c == ignore || (ignore_bds_parents && c->klass->parent_is_bds)) {
771
continue;
772
}
773
bdrv_parent_drained_begin_single(c, false);
774
@@ -XXX,XX +XXX,XX @@ static void bdrv_parent_drained_end_single_no_poll(BdrvChild *c,
775
{
776
assert(c->parent_quiesce_counter > 0);
777
c->parent_quiesce_counter--;
778
- if (c->role->drained_end) {
779
- c->role->drained_end(c, drained_end_counter);
780
+ if (c->klass->drained_end) {
781
+ c->klass->drained_end(c, drained_end_counter);
782
}
783
}
784
785
@@ -XXX,XX +XXX,XX @@ static void bdrv_parent_drained_end(BlockDriverState *bs, BdrvChild *ignore,
786
BdrvChild *c;
787
788
QLIST_FOREACH(c, &bs->parents, next_parent) {
789
- if (c == ignore || (ignore_bds_parents && c->role->parent_is_bds)) {
790
+ if (c == ignore || (ignore_bds_parents && c->klass->parent_is_bds)) {
791
continue;
792
}
793
bdrv_parent_drained_end_single_no_poll(c, drained_end_counter);
794
@@ -XXX,XX +XXX,XX @@ static void bdrv_parent_drained_end(BlockDriverState *bs, BdrvChild *ignore,
795
796
static bool bdrv_parent_drained_poll_single(BdrvChild *c)
797
{
798
- if (c->role->drained_poll) {
799
- return c->role->drained_poll(c);
800
+ if (c->klass->drained_poll) {
801
+ return c->klass->drained_poll(c);
802
}
803
return false;
804
}
805
@@ -XXX,XX +XXX,XX @@ static bool bdrv_parent_drained_poll(BlockDriverState *bs, BdrvChild *ignore,
806
bool busy = false;
807
808
QLIST_FOREACH_SAFE(c, &bs->parents, next_parent, next) {
809
- if (c == ignore || (ignore_bds_parents && c->role->parent_is_bds)) {
810
+ if (c == ignore || (ignore_bds_parents && c->klass->parent_is_bds)) {
811
continue;
812
}
813
busy |= bdrv_parent_drained_poll_single(c);
814
@@ -XXX,XX +XXX,XX @@ static bool bdrv_parent_drained_poll(BlockDriverState *bs, BdrvChild *ignore,
815
void bdrv_parent_drained_begin_single(BdrvChild *c, bool poll)
816
{
817
c->parent_quiesce_counter++;
818
- if (c->role->drained_begin) {
819
- c->role->drained_begin(c);
820
+ if (c->klass->drained_begin) {
821
+ c->klass->drained_begin(c);
822
}
823
if (poll) {
824
BDRV_POLL_WHILE(c->bs, bdrv_parent_drained_poll_single(c));
825
@@ -XXX,XX +XXX,XX @@ static void bdrv_parent_cb_resize(BlockDriverState *bs)
826
{
827
BdrvChild *c;
828
QLIST_FOREACH(c, &bs->parents, next_parent) {
829
- if (c->role->resize) {
830
- c->role->resize(c);
831
+ if (c->klass->resize) {
832
+ c->klass->resize(c);
833
}
834
}
835
}
40
diff --git a/block/mirror.c b/block/mirror.c
836
diff --git a/block/mirror.c b/block/mirror.c
41
index XXXXXXX..XXXXXXX 100644
837
index XXXXXXX..XXXXXXX 100644
42
--- a/block/mirror.c
838
--- a/block/mirror.c
43
+++ b/block/mirror.c
839
+++ b/block/mirror.c
44
@@ -XXX,XX +XXX,XX @@ static bool mirror_drained_poll(BlockJob *job)
840
@@ -XXX,XX +XXX,XX @@ static void bdrv_mirror_top_refresh_filename(BlockDriverState *bs)
45
return !!s->in_flight;
841
}
46
}
842
47
843
static void bdrv_mirror_top_child_perm(BlockDriverState *bs, BdrvChild *c,
48
-static void mirror_attached_aio_context(BlockJob *job, AioContext *new_context)
844
- const BdrvChildRole *role,
49
-{
845
+ const BdrvChildClass *child_class,
50
- MirrorBlockJob *s = container_of(job, MirrorBlockJob, common);
846
BlockReopenQueue *reopen_queue,
51
-
847
uint64_t perm, uint64_t shared,
52
- blk_set_aio_context(s->target, new_context);
848
uint64_t *nperm, uint64_t *nshared)
53
-}
849
diff --git a/block/quorum.c b/block/quorum.c
54
-
850
index XXXXXXX..XXXXXXX 100644
55
static void mirror_drain(BlockJob *job)
851
--- a/block/quorum.c
56
{
852
+++ b/block/quorum.c
57
MirrorBlockJob *s = container_of(job, MirrorBlockJob, common);
853
@@ -XXX,XX +XXX,XX @@ static char *quorum_dirname(BlockDriverState *bs, Error **errp)
58
@@ -XXX,XX +XXX,XX @@ static const BlockJobDriver mirror_job_driver = {
854
}
59
.complete = mirror_complete,
855
60
},
856
static void quorum_child_perm(BlockDriverState *bs, BdrvChild *c,
61
.drained_poll = mirror_drained_poll,
857
- const BdrvChildRole *role,
62
- .attached_aio_context = mirror_attached_aio_context,
858
+ const BdrvChildClass *child_class,
63
.drain = mirror_drain,
859
BlockReopenQueue *reopen_queue,
860
uint64_t perm, uint64_t shared,
861
uint64_t *nperm, uint64_t *nshared)
862
diff --git a/block/replication.c b/block/replication.c
863
index XXXXXXX..XXXXXXX 100644
864
--- a/block/replication.c
865
+++ b/block/replication.c
866
@@ -XXX,XX +XXX,XX @@ static void replication_close(BlockDriverState *bs)
867
}
868
869
static void replication_child_perm(BlockDriverState *bs, BdrvChild *c,
870
- const BdrvChildRole *role,
871
+ const BdrvChildClass *child_class,
872
BlockReopenQueue *reopen_queue,
873
uint64_t perm, uint64_t shared,
874
uint64_t *nperm, uint64_t *nshared)
875
diff --git a/block/vvfat.c b/block/vvfat.c
876
index XXXXXXX..XXXXXXX 100644
877
--- a/block/vvfat.c
878
+++ b/block/vvfat.c
879
@@ -XXX,XX +XXX,XX @@ static void vvfat_qcow_options(int *child_flags, QDict *child_options,
880
qdict_set_default_str(child_options, BDRV_OPT_CACHE_NO_FLUSH, "on");
881
}
882
883
-static const BdrvChildRole child_vvfat_qcow = {
884
+static const BdrvChildClass child_vvfat_qcow = {
885
.parent_is_bds = true,
886
.inherit_options = vvfat_qcow_options,
64
};
887
};
65
888
@@ -XXX,XX +XXX,XX @@ err:
66
@@ -XXX,XX +XXX,XX @@ static const BlockJobDriver commit_active_job_driver = {
889
}
67
.complete = mirror_complete,
890
68
},
891
static void vvfat_child_perm(BlockDriverState *bs, BdrvChild *c,
69
.drained_poll = mirror_drained_poll,
892
- const BdrvChildRole *role,
70
- .attached_aio_context = mirror_attached_aio_context,
893
+ const BdrvChildClass *child_class,
71
.drain = mirror_drain,
894
BlockReopenQueue *reopen_queue,
72
};
895
uint64_t perm, uint64_t shared,
73
896
uint64_t *nperm, uint64_t *nshared)
74
@@ -XXX,XX +XXX,XX @@ static void mirror_start_job(const char *job_id, BlockDriverState *bs,
897
{
75
* ensure that. */
898
BDRVVVFATState *s = bs->opaque;
76
blk_set_force_allow_inactivate(s->target);
899
77
}
900
- assert(c == s->qcow || role == &child_backing);
78
+ blk_set_allow_aio_context_change(s->target, true);
901
+ assert(c == s->qcow || child_class == &child_backing);
79
902
80
s->replaces = g_strdup(replaces);
903
if (c == s->qcow) {
81
s->on_source_error = on_source_error;
904
/* This is a private node, nobody should try to attach to it */
82
diff --git a/blockjob.c b/blockjob.c
905
diff --git a/blockjob.c b/blockjob.c
83
index XXXXXXX..XXXXXXX 100644
906
index XXXXXXX..XXXXXXX 100644
84
--- a/blockjob.c
907
--- a/blockjob.c
85
+++ b/blockjob.c
908
+++ b/blockjob.c
86
@@ -XXX,XX +XXX,XX @@ static void child_job_drained_end(BdrvChild *c)
909
@@ -XXX,XX +XXX,XX @@ static void child_job_set_aio_ctx(BdrvChild *c, AioContext *ctx,
87
job_resume(&job->job);
910
job->job.aio_context = ctx;
88
}
911
}
89
912
90
+static bool child_job_can_set_aio_ctx(BdrvChild *c, AioContext *ctx,
913
-static const BdrvChildRole child_job = {
91
+ GSList **ignore, Error **errp)
914
+static const BdrvChildClass child_job = {
92
+{
93
+ BlockJob *job = c->opaque;
94
+ GSList *l;
95
+
96
+ for (l = job->nodes; l; l = l->next) {
97
+ BdrvChild *sibling = l->data;
98
+ if (!bdrv_child_can_set_aio_context(sibling, ctx, ignore, errp)) {
99
+ return false;
100
+ }
101
+ }
102
+ return true;
103
+}
104
+
105
+static void child_job_set_aio_ctx(BdrvChild *c, AioContext *ctx,
106
+ GSList **ignore)
107
+{
108
+ BlockJob *job = c->opaque;
109
+ GSList *l;
110
+
111
+ for (l = job->nodes; l; l = l->next) {
112
+ BdrvChild *sibling = l->data;
113
+ if (g_slist_find(*ignore, sibling)) {
114
+ continue;
115
+ }
116
+ *ignore = g_slist_prepend(*ignore, sibling);
117
+ bdrv_set_aio_context_ignore(sibling->bs, ctx, ignore);
118
+ }
119
+}
120
+
121
static const BdrvChildRole child_job = {
122
.get_parent_desc = child_job_get_parent_desc,
915
.get_parent_desc = child_job_get_parent_desc,
123
.drained_begin = child_job_drained_begin,
916
.drained_begin = child_job_drained_begin,
124
.drained_poll = child_job_drained_poll,
917
.drained_poll = child_job_drained_poll,
125
.drained_end = child_job_drained_end,
918
diff --git a/tests/test-bdrv-drain.c b/tests/test-bdrv-drain.c
126
+ .can_set_aio_ctx = child_job_can_set_aio_ctx,
919
index XXXXXXX..XXXXXXX 100644
127
+ .set_aio_ctx = child_job_set_aio_ctx,
920
--- a/tests/test-bdrv-drain.c
128
.stay_at_node = true,
921
+++ b/tests/test-bdrv-drain.c
922
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_test_co_preadv(BlockDriverState *bs,
923
}
924
925
static void bdrv_test_child_perm(BlockDriverState *bs, BdrvChild *c,
926
- const BdrvChildRole *role,
927
+ const BdrvChildClass *child_class,
928
BlockReopenQueue *reopen_queue,
929
uint64_t perm, uint64_t shared,
930
uint64_t *nperm, uint64_t *nshared)
931
{
932
- /* bdrv_format_default_perms() accepts only these two, so disguise
933
- * detach_by_driver_cb_role as one of them. */
934
- if (role != &child_file && role != &child_backing) {
935
- role = &child_file;
936
+ /*
937
+ * bdrv_format_default_perms() accepts only these two, so disguise
938
+ * detach_by_driver_cb_parent as one of them.
939
+ */
940
+ if (child_class != &child_file && child_class != &child_backing) {
941
+ child_class = &child_file;
942
}
943
944
- bdrv_format_default_perms(bs, c, role, reopen_queue, perm, shared,
945
+ bdrv_format_default_perms(bs, c, child_class, reopen_queue, perm, shared,
946
nperm, nshared);
947
}
948
949
@@ -XXX,XX +XXX,XX @@ static void detach_by_driver_cb_drained_begin(BdrvChild *child)
950
child_file.drained_begin(child);
951
}
952
953
-static BdrvChildRole detach_by_driver_cb_role;
954
+static BdrvChildClass detach_by_driver_cb_class;
955
956
/*
957
* Initial graph:
958
@@ -XXX,XX +XXX,XX @@ static BdrvChildRole detach_by_driver_cb_role;
959
*
960
* by_parent_cb == false: Test that bdrv_drain_invoke() doesn't poll
961
*
962
- * PA's BdrvChildRole has a .drained_begin callback that schedules a BH
963
+ * PA's BdrvChildClass has a .drained_begin callback that schedules a BH
964
* that does the same graph change. If bdrv_drain_invoke() calls it, the
965
* state is messed up, but if it is only polled in the single
966
* BDRV_POLL_WHILE() at the end of the drain, this should work fine.
967
@@ -XXX,XX +XXX,XX @@ static void test_detach_indirect(bool by_parent_cb)
968
QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, NULL, 0);
969
970
if (!by_parent_cb) {
971
- detach_by_driver_cb_role = child_file;
972
- detach_by_driver_cb_role.drained_begin =
973
+ detach_by_driver_cb_class = child_file;
974
+ detach_by_driver_cb_class.drained_begin =
975
detach_by_driver_cb_drained_begin;
976
}
977
978
@@ -XXX,XX +XXX,XX @@ static void test_detach_indirect(bool by_parent_cb)
979
980
bdrv_ref(a);
981
bdrv_attach_child(parent_a, a, "PA-A",
982
- by_parent_cb ? &child_file : &detach_by_driver_cb_role,
983
+ by_parent_cb ? &child_file : &detach_by_driver_cb_class,
984
&error_abort);
985
986
g_assert_cmpint(parent_a->refcnt, ==, 1);
987
@@ -XXX,XX +XXX,XX @@ static int drop_intermediate_poll_update_filename(BdrvChild *child,
988
/**
989
* Test a poll in the midst of bdrv_drop_intermediate().
990
*
991
- * bdrv_drop_intermediate() calls BdrvChildRole.update_filename(),
992
+ * bdrv_drop_intermediate() calls BdrvChildClass.update_filename(),
993
* which can yield or poll. This may lead to graph changes, unless
994
* the whole subtree in question is drained.
995
*
996
@@ -XXX,XX +XXX,XX @@ static int drop_intermediate_poll_update_filename(BdrvChild *child,
997
*
998
* The solution is for bdrv_drop_intermediate() to drain top's
999
* subtree. This prevents graph changes from happening just because
1000
- * BdrvChildRole.update_filename() yields or polls. Thus, the block
1001
+ * BdrvChildClass.update_filename() yields or polls. Thus, the block
1002
* job is paused during that drained section and must finish before or
1003
* after.
1004
*
1005
@@ -XXX,XX +XXX,XX @@ static int drop_intermediate_poll_update_filename(BdrvChild *child,
1006
*/
1007
static void test_drop_intermediate_poll(void)
1008
{
1009
- static BdrvChildRole chain_child_role;
1010
+ static BdrvChildClass chain_child_class;
1011
BlockDriverState *chain[3];
1012
TestSimpleBlockJob *job;
1013
BlockDriverState *job_node;
1014
@@ -XXX,XX +XXX,XX @@ static void test_drop_intermediate_poll(void)
1015
int i;
1016
int ret;
1017
1018
- chain_child_role = child_backing;
1019
- chain_child_role.update_filename = drop_intermediate_poll_update_filename;
1020
+ chain_child_class = child_backing;
1021
+ chain_child_class.update_filename = drop_intermediate_poll_update_filename;
1022
1023
for (i = 0; i < 3; i++) {
1024
char name[32];
1025
@@ -XXX,XX +XXX,XX @@ static void test_drop_intermediate_poll(void)
1026
if (i) {
1027
/* Takes the reference to chain[i - 1] */
1028
chain[i]->backing = bdrv_attach_child(chain[i], chain[i - 1],
1029
- "chain", &chain_child_role,
1030
+ "chain", &chain_child_class,
1031
&error_abort);
1032
}
1033
}
1034
diff --git a/tests/test-bdrv-graph-mod.c b/tests/test-bdrv-graph-mod.c
1035
index XXXXXXX..XXXXXXX 100644
1036
--- a/tests/test-bdrv-graph-mod.c
1037
+++ b/tests/test-bdrv-graph-mod.c
1038
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_pass_through = {
129
};
1039
};
130
1040
131
@@ -XXX,XX +XXX,XX @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver,
1041
static void no_perm_default_perms(BlockDriverState *bs, BdrvChild *c,
132
1042
- const BdrvChildRole *role,
133
blk_add_aio_context_notifier(blk, block_job_attached_aio_context,
1043
+ const BdrvChildClass *child_class,
134
block_job_detach_aio_context, job);
1044
BlockReopenQueue *reopen_queue,
135
+ blk_set_allow_aio_context_change(blk, true);
1045
uint64_t perm, uint64_t shared,
136
1046
uint64_t *nperm, uint64_t *nshared)
137
/* Only set speed when necessary to avoid NotSupported error */
138
if (speed != 0) {
139
--
1047
--
140
2.20.1
1048
2.25.4
141
1049
142
1050
diff view generated by jsdifflib
New patch
1
From: Max Reitz <mreitz@redhat.com>
1
2
3
This mask will supplement BdrvChildClass when it comes to what role (or
4
combination of roles) a child takes for its parent. It consists of
5
BdrvChildRoleBits values (which is an enum).
6
7
Because empty enums are not allowed, let us just start with it filled.
8
9
Signed-off-by: Max Reitz <mreitz@redhat.com>
10
Message-Id: <20200513110544.176672-5-mreitz@redhat.com>
11
Reviewed-by: Eric Blake <eblake@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
---
14
include/block/block.h | 56 +++++++++++++++++++++++++++++++++++++++++++
15
1 file changed, 56 insertions(+)
16
17
diff --git a/include/block/block.h b/include/block/block.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/include/block/block.h
20
+++ b/include/block/block.h
21
@@ -XXX,XX +XXX,XX @@ enum {
22
DEFAULT_PERM_UNCHANGED = BLK_PERM_ALL & ~DEFAULT_PERM_PASSTHROUGH,
23
};
24
25
+/*
26
+ * Flags that parent nodes assign to child nodes to specify what kind of
27
+ * role(s) they take.
28
+ *
29
+ * At least one of DATA, METADATA, FILTERED, or COW must be set for
30
+ * every child.
31
+ */
32
+enum BdrvChildRoleBits {
33
+ /*
34
+ * This child stores data.
35
+ * Any node may have an arbitrary number of such children.
36
+ */
37
+ BDRV_CHILD_DATA = (1 << 0),
38
+
39
+ /*
40
+ * This child stores metadata.
41
+ * Any node may have an arbitrary number of metadata-storing
42
+ * children.
43
+ */
44
+ BDRV_CHILD_METADATA = (1 << 1),
45
+
46
+ /*
47
+ * A child that always presents exactly the same visible data as
48
+ * the parent, e.g. by virtue of the parent forwarding all reads
49
+ * and writes.
50
+ * This flag is mutually exclusive with DATA, METADATA, and COW.
51
+ * Any node may have at most one filtered child at a time.
52
+ */
53
+ BDRV_CHILD_FILTERED = (1 << 2),
54
+
55
+ /*
56
+ * Child from which to read all data that isn’t allocated in the
57
+ * parent (i.e., the backing child); such data is copied to the
58
+ * parent through COW (and optionally COR).
59
+ * This field is mutually exclusive with DATA, METADATA, and
60
+ * FILTERED.
61
+ * Any node may have at most one such backing child at a time.
62
+ */
63
+ BDRV_CHILD_COW = (1 << 3),
64
+
65
+ /*
66
+ * The primary child. For most drivers, this is the child whose
67
+ * filename applies best to the parent node.
68
+ * Any node may have at most one primary child at a time.
69
+ */
70
+ BDRV_CHILD_PRIMARY = (1 << 4),
71
+
72
+ /* Useful combination of flags */
73
+ BDRV_CHILD_IMAGE = BDRV_CHILD_DATA
74
+ | BDRV_CHILD_METADATA
75
+ | BDRV_CHILD_PRIMARY,
76
+};
77
+
78
+/* Mask of BdrvChildRoleBits values */
79
+typedef unsigned int BdrvChildRole;
80
+
81
char *bdrv_perm_names(uint64_t perm);
82
uint64_t bdrv_qapi_perm_to_blk_perm(BlockPermission qapi_perm);
83
84
--
85
2.25.4
86
87
diff view generated by jsdifflib
1
All block nodes and users in any connected component of the block graph
1
From: Max Reitz <mreitz@redhat.com>
2
must be in the same AioContext, so changing the AioContext of one node
3
must not only change all of its children, but all of its parents (and
4
in turn their children etc.) as well.
5
2
3
For now, it is always set to 0. Later patches in this series will
4
ensure that all callers pass an appropriate combination of flags.
5
6
Signed-off-by: Max Reitz <mreitz@redhat.com>
7
Reviewed-by: Eric Blake <eblake@redhat.com>
8
Message-Id: <20200513110544.176672-6-mreitz@redhat.com>
6
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
7
---
10
---
8
include/block/block.h | 2 ++
11
include/block/block.h | 2 ++
9
include/block/block_int.h | 1 +
12
include/block/block_int.h | 2 ++
10
block.c | 48 ++++++++++++++++++++++++++++++++++-----
13
block.c | 11 ++++++++---
11
3 files changed, 45 insertions(+), 6 deletions(-)
14
block/backup-top.c | 3 ++-
15
block/blkdebug.c | 2 +-
16
block/blklogwrites.c | 6 +++---
17
block/blkreplay.c | 2 +-
18
block/blkverify.c | 4 ++--
19
block/block-backend.c | 4 ++--
20
block/bochs.c | 2 +-
21
block/cloop.c | 2 +-
22
block/copy-on-read.c | 2 +-
23
block/crypto.c | 2 +-
24
block/dmg.c | 2 +-
25
block/filter-compress.c | 2 +-
26
block/parallels.c | 2 +-
27
block/qcow.c | 2 +-
28
block/qcow2.c | 6 +++---
29
block/qed.c | 2 +-
30
block/quorum.c | 4 ++--
31
block/raw-format.c | 2 +-
32
block/replication.c | 2 +-
33
block/throttle.c | 2 +-
34
block/vdi.c | 2 +-
35
block/vhdx.c | 2 +-
36
block/vmdk.c | 4 ++--
37
block/vpc.c | 2 +-
38
block/vvfat.c | 2 +-
39
blockjob.c | 5 +++--
40
tests/test-bdrv-drain.c | 20 +++++++++++---------
41
tests/test-bdrv-graph-mod.c | 4 ++--
42
31 files changed, 62 insertions(+), 49 deletions(-)
12
43
13
diff --git a/include/block/block.h b/include/block/block.h
44
diff --git a/include/block/block.h b/include/block/block.h
14
index XXXXXXX..XXXXXXX 100644
45
index XXXXXXX..XXXXXXX 100644
15
--- a/include/block/block.h
46
--- a/include/block/block.h
16
+++ b/include/block/block.h
47
+++ b/include/block/block.h
17
@@ -XXX,XX +XXX,XX @@ void bdrv_coroutine_enter(BlockDriverState *bs, Coroutine *co);
48
@@ -XXX,XX +XXX,XX @@ BdrvChild *bdrv_open_child(const char *filename,
18
* This function must be called with iothread lock held.
49
QDict *options, const char *bdref_key,
19
*/
50
BlockDriverState* parent,
20
void bdrv_set_aio_context(BlockDriverState *bs, AioContext *new_context);
51
const BdrvChildClass *child_class,
21
+void bdrv_set_aio_context_ignore(BlockDriverState *bs,
52
+ BdrvChildRole child_role,
22
+ AioContext *new_context, GSList **ignore);
53
bool allow_none, Error **errp);
23
int bdrv_try_set_aio_context(BlockDriverState *bs, AioContext *ctx,
54
BlockDriverState *bdrv_open_blockdev_ref(BlockdevRef *ref, Error **errp);
55
void bdrv_set_backing_hd(BlockDriverState *bs, BlockDriverState *backing_hd,
56
@@ -XXX,XX +XXX,XX @@ BdrvChild *bdrv_attach_child(BlockDriverState *parent_bs,
57
BlockDriverState *child_bs,
58
const char *child_name,
59
const BdrvChildClass *child_class,
60
+ BdrvChildRole child_role,
24
Error **errp);
61
Error **errp);
25
int bdrv_child_try_set_aio_context(BlockDriverState *bs, AioContext *ctx,
62
63
bool bdrv_op_is_blocked(BlockDriverState *bs, BlockOpType op, Error **errp);
26
diff --git a/include/block/block_int.h b/include/block/block_int.h
64
diff --git a/include/block/block_int.h b/include/block/block_int.h
27
index XXXXXXX..XXXXXXX 100644
65
index XXXXXXX..XXXXXXX 100644
28
--- a/include/block/block_int.h
66
--- a/include/block/block_int.h
29
+++ b/include/block/block_int.h
67
+++ b/include/block/block_int.h
30
@@ -XXX,XX +XXX,XX @@ struct BdrvChildRole {
68
@@ -XXX,XX +XXX,XX @@ struct BdrvChild {
31
69
BlockDriverState *bs;
32
bool (*can_set_aio_ctx)(BdrvChild *child, AioContext *ctx,
70
char *name;
33
GSList **ignore, Error **errp);
71
const BdrvChildClass *klass;
34
+ void (*set_aio_ctx)(BdrvChild *child, AioContext *ctx, GSList **ignore);
72
+ BdrvChildRole role;
35
};
73
void *opaque;
36
74
37
extern const BdrvChildRole child_file;
75
/**
76
@@ -XXX,XX +XXX,XX @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
77
BdrvChild *bdrv_root_attach_child(BlockDriverState *child_bs,
78
const char *child_name,
79
const BdrvChildClass *child_class,
80
+ BdrvChildRole child_role,
81
AioContext *ctx,
82
uint64_t perm, uint64_t shared_perm,
83
void *opaque, Error **errp);
38
diff --git a/block.c b/block.c
84
diff --git a/block.c b/block.c
39
index XXXXXXX..XXXXXXX 100644
85
index XXXXXXX..XXXXXXX 100644
40
--- a/block.c
86
--- a/block.c
41
+++ b/block.c
87
+++ b/block.c
42
@@ -XXX,XX +XXX,XX @@ static bool bdrv_child_cb_can_set_aio_ctx(BdrvChild *child, AioContext *ctx,
88
@@ -XXX,XX +XXX,XX @@ static void bdrv_replace_child(BdrvChild *child, BlockDriverState *new_bs)
43
return bdrv_can_set_aio_context(bs, ctx, ignore, errp);
89
BdrvChild *bdrv_root_attach_child(BlockDriverState *child_bs,
44
}
90
const char *child_name,
45
91
const BdrvChildClass *child_class,
46
+static void bdrv_child_cb_set_aio_ctx(BdrvChild *child, AioContext *ctx,
92
+ BdrvChildRole child_role,
47
+ GSList **ignore)
93
AioContext *ctx,
48
+{
94
uint64_t perm, uint64_t shared_perm,
49
+ BlockDriverState *bs = child->opaque;
95
void *opaque, Error **errp)
50
+ return bdrv_set_aio_context_ignore(bs, ctx, ignore);
96
@@ -XXX,XX +XXX,XX @@ BdrvChild *bdrv_root_attach_child(BlockDriverState *child_bs,
51
+}
97
.bs = NULL,
52
+
98
.name = g_strdup(child_name),
53
/*
99
.klass = child_class,
54
* Returns the options and flags that a temporary snapshot should get, based on
100
+ .role = child_role,
55
* the originally requested flags (the originally requested image will have
101
.perm = perm,
56
@@ -XXX,XX +XXX,XX @@ const BdrvChildRole child_file = {
102
.shared_perm = shared_perm,
57
.detach = bdrv_child_cb_detach,
103
.opaque = opaque,
58
.inactivate = bdrv_child_cb_inactivate,
104
@@ -XXX,XX +XXX,XX @@ BdrvChild *bdrv_attach_child(BlockDriverState *parent_bs,
59
.can_set_aio_ctx = bdrv_child_cb_can_set_aio_ctx,
105
BlockDriverState *child_bs,
60
+ .set_aio_ctx = bdrv_child_cb_set_aio_ctx,
106
const char *child_name,
61
};
107
const BdrvChildClass *child_class,
62
108
+ BdrvChildRole child_role,
63
/*
109
Error **errp)
64
@@ -XXX,XX +XXX,XX @@ const BdrvChildRole child_format = {
65
.detach = bdrv_child_cb_detach,
66
.inactivate = bdrv_child_cb_inactivate,
67
.can_set_aio_ctx = bdrv_child_cb_can_set_aio_ctx,
68
+ .set_aio_ctx = bdrv_child_cb_set_aio_ctx,
69
};
70
71
static void bdrv_backing_attach(BdrvChild *c)
72
@@ -XXX,XX +XXX,XX @@ const BdrvChildRole child_backing = {
73
.inactivate = bdrv_child_cb_inactivate,
74
.update_filename = bdrv_backing_update_filename,
75
.can_set_aio_ctx = bdrv_child_cb_can_set_aio_ctx,
76
+ .set_aio_ctx = bdrv_child_cb_set_aio_ctx,
77
};
78
79
static int bdrv_open_flags(BlockDriverState *bs, int flags)
80
@@ -XXX,XX +XXX,XX @@ static void bdrv_attach_aio_context(BlockDriverState *bs,
81
bs->walking_aio_notifiers = false;
82
}
83
84
-/* The caller must own the AioContext lock for the old AioContext of bs, but it
85
- * must not own the AioContext lock for new_context (unless new_context is
86
- * the same as the current context of bs). */
87
-void bdrv_set_aio_context(BlockDriverState *bs, AioContext *new_context)
88
+/* @ignore will accumulate all visited BdrvChild object. The caller is
89
+ * responsible for freeing the list afterwards. */
90
+void bdrv_set_aio_context_ignore(BlockDriverState *bs,
91
+ AioContext *new_context, GSList **ignore)
92
{
110
{
93
BdrvChild *child;
111
BdrvChild *child;
94
112
@@ -XXX,XX +XXX,XX @@ BdrvChild *bdrv_attach_child(BlockDriverState *parent_bs,
95
@@ -XXX,XX +XXX,XX @@ void bdrv_set_aio_context(BlockDriverState *bs, AioContext *new_context)
113
perm, shared_perm, &perm, &shared_perm);
96
bdrv_drained_begin(bs);
114
97
115
child = bdrv_root_attach_child(child_bs, child_name, child_class,
98
QLIST_FOREACH(child, &bs->children, next) {
116
- bdrv_get_aio_context(parent_bs),
99
- bdrv_set_aio_context(child->bs, new_context);
117
+ child_role, bdrv_get_aio_context(parent_bs),
100
+ if (g_slist_find(*ignore, child)) {
118
perm, shared_perm, parent_bs, errp);
101
+ continue;
119
if (child == NULL) {
102
+ }
120
return NULL;
103
+ *ignore = g_slist_prepend(*ignore, child);
121
@@ -XXX,XX +XXX,XX @@ void bdrv_set_backing_hd(BlockDriverState *bs, BlockDriverState *backing_hd,
104
+ bdrv_set_aio_context_ignore(child->bs, new_context, ignore);
122
}
105
+ }
123
106
+ QLIST_FOREACH(child, &bs->parents, next_parent) {
124
bs->backing = bdrv_attach_child(bs, backing_hd, "backing", &child_backing,
107
+ if (g_slist_find(*ignore, child)) {
125
- errp);
108
+ continue;
126
+ 0, errp);
109
+ }
127
/* If backing_hd was already part of bs's backing chain, and
110
+ if (child->role->set_aio_ctx) {
128
* inherits_from pointed recursively to bs then let's update it to
111
+ *ignore = g_slist_prepend(*ignore, child);
129
* point directly to bs (else it will become NULL). */
112
+ child->role->set_aio_ctx(child, new_context, ignore);
130
@@ -XXX,XX +XXX,XX @@ BdrvChild *bdrv_open_child(const char *filename,
113
+ }
131
QDict *options, const char *bdref_key,
114
}
132
BlockDriverState *parent,
115
133
const BdrvChildClass *child_class,
116
bdrv_detach_aio_context(bs);
134
+ BdrvChildRole child_role,
117
@@ -XXX,XX +XXX,XX @@ void bdrv_set_aio_context(BlockDriverState *bs, AioContext *new_context)
135
bool allow_none, Error **errp)
118
aio_context_release(new_context);
136
{
137
BlockDriverState *bs;
138
@@ -XXX,XX +XXX,XX @@ BdrvChild *bdrv_open_child(const char *filename,
139
return NULL;
140
}
141
142
- return bdrv_attach_child(parent, bs, bdref_key, child_class, errp);
143
+ return bdrv_attach_child(parent, bs, bdref_key, child_class, child_role,
144
+ errp);
119
}
145
}
120
146
121
+/* The caller must own the AioContext lock for the old AioContext of bs, but it
147
/*
122
+ * must not own the AioContext lock for new_context (unless new_context is
148
diff --git a/block/backup-top.c b/block/backup-top.c
123
+ * the same as the current context of bs). */
149
index XXXXXXX..XXXXXXX 100644
124
+void bdrv_set_aio_context(BlockDriverState *bs, AioContext *new_context)
150
--- a/block/backup-top.c
125
+{
151
+++ b/block/backup-top.c
126
+ GSList *ignore_list = NULL;
152
@@ -XXX,XX +XXX,XX @@ BlockDriverState *bdrv_backup_top_append(BlockDriverState *source,
127
+ bdrv_set_aio_context_ignore(bs, new_context, &ignore_list);
153
source->supported_zero_flags);
128
+ g_slist_free(ignore_list);
154
129
+}
155
bdrv_ref(target);
130
+
156
- state->target = bdrv_attach_child(top, target, "target", &child_file, errp);
131
static bool bdrv_parent_can_set_aio_context(BdrvChild *c, AioContext *ctx,
157
+ state->target = bdrv_attach_child(top, target, "target", &child_file, 0,
132
GSList **ignore, Error **errp)
158
+ errp);
159
if (!state->target) {
160
bdrv_unref(target);
161
bdrv_unref(top);
162
diff --git a/block/blkdebug.c b/block/blkdebug.c
163
index XXXXXXX..XXXXXXX 100644
164
--- a/block/blkdebug.c
165
+++ b/block/blkdebug.c
166
@@ -XXX,XX +XXX,XX @@ static int blkdebug_open(BlockDriverState *bs, QDict *options, int flags,
167
168
/* Open the image file */
169
bs->file = bdrv_open_child(qemu_opt_get(opts, "x-image"), options, "image",
170
- bs, &child_file, false, &local_err);
171
+ bs, &child_file, 0, false, &local_err);
172
if (local_err) {
173
ret = -EINVAL;
174
error_propagate(errp, local_err);
175
diff --git a/block/blklogwrites.c b/block/blklogwrites.c
176
index XXXXXXX..XXXXXXX 100644
177
--- a/block/blklogwrites.c
178
+++ b/block/blklogwrites.c
179
@@ -XXX,XX +XXX,XX @@ static int blk_log_writes_open(BlockDriverState *bs, QDict *options, int flags,
180
}
181
182
/* Open the file */
183
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file, false,
184
+ bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file, 0, false,
185
&local_err);
186
if (local_err) {
187
ret = -EINVAL;
188
@@ -XXX,XX +XXX,XX @@ static int blk_log_writes_open(BlockDriverState *bs, QDict *options, int flags,
189
}
190
191
/* Open the log file */
192
- s->log_file = bdrv_open_child(NULL, options, "log", bs, &child_file, false,
193
- &local_err);
194
+ s->log_file = bdrv_open_child(NULL, options, "log", bs, &child_file, 0,
195
+ false, &local_err);
196
if (local_err) {
197
ret = -EINVAL;
198
error_propagate(errp, local_err);
199
diff --git a/block/blkreplay.c b/block/blkreplay.c
200
index XXXXXXX..XXXXXXX 100644
201
--- a/block/blkreplay.c
202
+++ b/block/blkreplay.c
203
@@ -XXX,XX +XXX,XX @@ static int blkreplay_open(BlockDriverState *bs, QDict *options, int flags,
204
205
/* Open the image file */
206
bs->file = bdrv_open_child(NULL, options, "image",
207
- bs, &child_file, false, &local_err);
208
+ bs, &child_file, 0, false, &local_err);
209
if (local_err) {
210
ret = -EINVAL;
211
error_propagate(errp, local_err);
212
diff --git a/block/blkverify.c b/block/blkverify.c
213
index XXXXXXX..XXXXXXX 100644
214
--- a/block/blkverify.c
215
+++ b/block/blkverify.c
216
@@ -XXX,XX +XXX,XX @@ static int blkverify_open(BlockDriverState *bs, QDict *options, int flags,
217
218
/* Open the raw file */
219
bs->file = bdrv_open_child(qemu_opt_get(opts, "x-raw"), options, "raw",
220
- bs, &child_file, false, &local_err);
221
+ bs, &child_file, 0, false, &local_err);
222
if (local_err) {
223
ret = -EINVAL;
224
error_propagate(errp, local_err);
225
@@ -XXX,XX +XXX,XX @@ static int blkverify_open(BlockDriverState *bs, QDict *options, int flags,
226
227
/* Open the test file */
228
s->test_file = bdrv_open_child(qemu_opt_get(opts, "x-image"), options,
229
- "test", bs, &child_format, false,
230
+ "test", bs, &child_format, 0, false,
231
&local_err);
232
if (local_err) {
233
ret = -EINVAL;
234
diff --git a/block/block-backend.c b/block/block-backend.c
235
index XXXXXXX..XXXXXXX 100644
236
--- a/block/block-backend.c
237
+++ b/block/block-backend.c
238
@@ -XXX,XX +XXX,XX @@ BlockBackend *blk_new_open(const char *filename, const char *reference,
239
return NULL;
240
}
241
242
- blk->root = bdrv_root_attach_child(bs, "root", &child_root, blk->ctx,
243
+ blk->root = bdrv_root_attach_child(bs, "root", &child_root, 0, blk->ctx,
244
perm, BLK_PERM_ALL, blk, errp);
245
if (!blk->root) {
246
blk_unref(blk);
247
@@ -XXX,XX +XXX,XX @@ int blk_insert_bs(BlockBackend *blk, BlockDriverState *bs, Error **errp)
133
{
248
{
134
@@ -XXX,XX +XXX,XX @@ int bdrv_child_try_set_aio_context(BlockDriverState *bs, AioContext *ctx,
249
ThrottleGroupMember *tgm = &blk->public.throttle_group_member;
250
bdrv_ref(bs);
251
- blk->root = bdrv_root_attach_child(bs, "root", &child_root, blk->ctx,
252
+ blk->root = bdrv_root_attach_child(bs, "root", &child_root, 0, blk->ctx,
253
blk->perm, blk->shared_perm, blk, errp);
254
if (blk->root == NULL) {
135
return -EPERM;
255
return -EPERM;
136
}
256
diff --git a/block/bochs.c b/block/bochs.c
137
257
index XXXXXXX..XXXXXXX 100644
138
- bdrv_set_aio_context(bs, ctx);
258
--- a/block/bochs.c
139
+ ignore = ignore_child ? g_slist_prepend(NULL, ignore_child) : NULL;
259
+++ b/block/bochs.c
140
+ bdrv_set_aio_context_ignore(bs, ctx, &ignore);
260
@@ -XXX,XX +XXX,XX @@ static int bochs_open(BlockDriverState *bs, QDict *options, int flags,
141
+ g_slist_free(ignore);
261
return ret;
142
+
262
}
143
return 0;
263
264
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file,
265
+ bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file, 0,
266
false, errp);
267
if (!bs->file) {
268
return -EINVAL;
269
diff --git a/block/cloop.c b/block/cloop.c
270
index XXXXXXX..XXXXXXX 100644
271
--- a/block/cloop.c
272
+++ b/block/cloop.c
273
@@ -XXX,XX +XXX,XX @@ static int cloop_open(BlockDriverState *bs, QDict *options, int flags,
274
return ret;
275
}
276
277
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file,
278
+ bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file, 0,
279
false, errp);
280
if (!bs->file) {
281
return -EINVAL;
282
diff --git a/block/copy-on-read.c b/block/copy-on-read.c
283
index XXXXXXX..XXXXXXX 100644
284
--- a/block/copy-on-read.c
285
+++ b/block/copy-on-read.c
286
@@ -XXX,XX +XXX,XX @@
287
static int cor_open(BlockDriverState *bs, QDict *options, int flags,
288
Error **errp)
289
{
290
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file, false,
291
+ bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file, 0, false,
292
errp);
293
if (!bs->file) {
294
return -EINVAL;
295
diff --git a/block/crypto.c b/block/crypto.c
296
index XXXXXXX..XXXXXXX 100644
297
--- a/block/crypto.c
298
+++ b/block/crypto.c
299
@@ -XXX,XX +XXX,XX @@ static int block_crypto_open_generic(QCryptoBlockFormat format,
300
unsigned int cflags = 0;
301
QDict *cryptoopts = NULL;
302
303
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file,
304
+ bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file, 0,
305
false, errp);
306
if (!bs->file) {
307
return -EINVAL;
308
diff --git a/block/dmg.c b/block/dmg.c
309
index XXXXXXX..XXXXXXX 100644
310
--- a/block/dmg.c
311
+++ b/block/dmg.c
312
@@ -XXX,XX +XXX,XX @@ static int dmg_open(BlockDriverState *bs, QDict *options, int flags,
313
return ret;
314
}
315
316
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file,
317
+ bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file, 0,
318
false, errp);
319
if (!bs->file) {
320
return -EINVAL;
321
diff --git a/block/filter-compress.c b/block/filter-compress.c
322
index XXXXXXX..XXXXXXX 100644
323
--- a/block/filter-compress.c
324
+++ b/block/filter-compress.c
325
@@ -XXX,XX +XXX,XX @@
326
static int compress_open(BlockDriverState *bs, QDict *options, int flags,
327
Error **errp)
328
{
329
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file, false,
330
+ bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file, 0, false,
331
errp);
332
if (!bs->file) {
333
return -EINVAL;
334
diff --git a/block/parallels.c b/block/parallels.c
335
index XXXXXXX..XXXXXXX 100644
336
--- a/block/parallels.c
337
+++ b/block/parallels.c
338
@@ -XXX,XX +XXX,XX @@ static int parallels_open(BlockDriverState *bs, QDict *options, int flags,
339
Error *local_err = NULL;
340
char *buf;
341
342
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file,
343
+ bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file, 0,
344
false, errp);
345
if (!bs->file) {
346
return -EINVAL;
347
diff --git a/block/qcow.c b/block/qcow.c
348
index XXXXXXX..XXXXXXX 100644
349
--- a/block/qcow.c
350
+++ b/block/qcow.c
351
@@ -XXX,XX +XXX,XX @@ static int qcow_open(BlockDriverState *bs, QDict *options, int flags,
352
qdict_extract_subqdict(options, &encryptopts, "encrypt.");
353
encryptfmt = qdict_get_try_str(encryptopts, "format");
354
355
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file,
356
+ bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file, 0,
357
false, errp);
358
if (!bs->file) {
359
ret = -EINVAL;
360
diff --git a/block/qcow2.c b/block/qcow2.c
361
index XXXXXXX..XXXXXXX 100644
362
--- a/block/qcow2.c
363
+++ b/block/qcow2.c
364
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options,
365
366
/* Open external data file */
367
s->data_file = bdrv_open_child(NULL, options, "data-file", bs, &child_file,
368
- true, &local_err);
369
+ 0, true, &local_err);
370
if (local_err) {
371
error_propagate(errp, local_err);
372
ret = -EINVAL;
373
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options,
374
if (s->incompatible_features & QCOW2_INCOMPAT_DATA_FILE) {
375
if (!s->data_file && s->image_data_file) {
376
s->data_file = bdrv_open_child(s->image_data_file, options,
377
- "data-file", bs, &child_file,
378
+ "data-file", bs, &child_file, 0,
379
false, errp);
380
if (!s->data_file) {
381
ret = -EINVAL;
382
@@ -XXX,XX +XXX,XX @@ static int qcow2_open(BlockDriverState *bs, QDict *options, int flags,
383
.ret = -EINPROGRESS
384
};
385
386
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file,
387
+ bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file, 0,
388
false, errp);
389
if (!bs->file) {
390
return -EINVAL;
391
diff --git a/block/qed.c b/block/qed.c
392
index XXXXXXX..XXXXXXX 100644
393
--- a/block/qed.c
394
+++ b/block/qed.c
395
@@ -XXX,XX +XXX,XX @@ static int bdrv_qed_open(BlockDriverState *bs, QDict *options, int flags,
396
.ret = -EINPROGRESS
397
};
398
399
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file,
400
+ bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file, 0,
401
false, errp);
402
if (!bs->file) {
403
return -EINVAL;
404
diff --git a/block/quorum.c b/block/quorum.c
405
index XXXXXXX..XXXXXXX 100644
406
--- a/block/quorum.c
407
+++ b/block/quorum.c
408
@@ -XXX,XX +XXX,XX @@ static int quorum_open(BlockDriverState *bs, QDict *options, int flags,
409
assert(ret < 32);
410
411
s->children[i] = bdrv_open_child(NULL, options, indexstr, bs,
412
- &child_format, false, &local_err);
413
+ &child_format, 0, false, &local_err);
414
if (local_err) {
415
ret = -EINVAL;
416
goto close_exit;
417
@@ -XXX,XX +XXX,XX @@ static void quorum_add_child(BlockDriverState *bs, BlockDriverState *child_bs,
418
/* We can safely add the child now */
419
bdrv_ref(child_bs);
420
421
- child = bdrv_attach_child(bs, child_bs, indexstr, &child_format, errp);
422
+ child = bdrv_attach_child(bs, child_bs, indexstr, &child_format, 0, errp);
423
if (child == NULL) {
424
s->next_child_index--;
425
goto out;
426
diff --git a/block/raw-format.c b/block/raw-format.c
427
index XXXXXXX..XXXXXXX 100644
428
--- a/block/raw-format.c
429
+++ b/block/raw-format.c
430
@@ -XXX,XX +XXX,XX @@ static int raw_open(BlockDriverState *bs, QDict *options, int flags,
431
BDRVRawState *s = bs->opaque;
432
int ret;
433
434
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file,
435
+ bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file, 0,
436
false, errp);
437
if (!bs->file) {
438
return -EINVAL;
439
diff --git a/block/replication.c b/block/replication.c
440
index XXXXXXX..XXXXXXX 100644
441
--- a/block/replication.c
442
+++ b/block/replication.c
443
@@ -XXX,XX +XXX,XX @@ static int replication_open(BlockDriverState *bs, QDict *options,
444
const char *mode;
445
const char *top_id;
446
447
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file,
448
+ bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file, 0,
449
false, errp);
450
if (!bs->file) {
451
return -EINVAL;
452
diff --git a/block/throttle.c b/block/throttle.c
453
index XXXXXXX..XXXXXXX 100644
454
--- a/block/throttle.c
455
+++ b/block/throttle.c
456
@@ -XXX,XX +XXX,XX @@ static int throttle_open(BlockDriverState *bs, QDict *options,
457
int ret;
458
459
bs->file = bdrv_open_child(NULL, options, "file", bs,
460
- &child_file, false, errp);
461
+ &child_file, 0, false, errp);
462
if (!bs->file) {
463
return -EINVAL;
464
}
465
diff --git a/block/vdi.c b/block/vdi.c
466
index XXXXXXX..XXXXXXX 100644
467
--- a/block/vdi.c
468
+++ b/block/vdi.c
469
@@ -XXX,XX +XXX,XX @@ static int vdi_open(BlockDriverState *bs, QDict *options, int flags,
470
Error *local_err = NULL;
471
QemuUUID uuid_link, uuid_parent;
472
473
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file,
474
+ bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file, 0,
475
false, errp);
476
if (!bs->file) {
477
return -EINVAL;
478
diff --git a/block/vhdx.c b/block/vhdx.c
479
index XXXXXXX..XXXXXXX 100644
480
--- a/block/vhdx.c
481
+++ b/block/vhdx.c
482
@@ -XXX,XX +XXX,XX @@ static int vhdx_open(BlockDriverState *bs, QDict *options, int flags,
483
uint64_t signature;
484
Error *local_err = NULL;
485
486
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file,
487
+ bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file, 0,
488
false, errp);
489
if (!bs->file) {
490
return -EINVAL;
491
diff --git a/block/vmdk.c b/block/vmdk.c
492
index XXXXXXX..XXXXXXX 100644
493
--- a/block/vmdk.c
494
+++ b/block/vmdk.c
495
@@ -XXX,XX +XXX,XX @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
496
assert(ret < 32);
497
498
extent_file = bdrv_open_child(extent_path, options, extent_opt_prefix,
499
- bs, &child_file, false, &local_err);
500
+ bs, &child_file, 0, false, &local_err);
501
g_free(extent_path);
502
if (local_err) {
503
error_propagate(errp, local_err);
504
@@ -XXX,XX +XXX,XX @@ static int vmdk_open(BlockDriverState *bs, QDict *options, int flags,
505
uint32_t magic;
506
Error *local_err = NULL;
507
508
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file,
509
+ bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file, 0,
510
false, errp);
511
if (!bs->file) {
512
return -EINVAL;
513
diff --git a/block/vpc.c b/block/vpc.c
514
index XXXXXXX..XXXXXXX 100644
515
--- a/block/vpc.c
516
+++ b/block/vpc.c
517
@@ -XXX,XX +XXX,XX @@ static int vpc_open(BlockDriverState *bs, QDict *options, int flags,
518
int ret;
519
int64_t bs_size;
520
521
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file,
522
+ bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file, 0,
523
false, errp);
524
if (!bs->file) {
525
return -EINVAL;
526
diff --git a/block/vvfat.c b/block/vvfat.c
527
index XXXXXXX..XXXXXXX 100644
528
--- a/block/vvfat.c
529
+++ b/block/vvfat.c
530
@@ -XXX,XX +XXX,XX @@ static int enable_write_target(BlockDriverState *bs, Error **errp)
531
options = qdict_new();
532
qdict_put_str(options, "write-target.driver", "qcow");
533
s->qcow = bdrv_open_child(s->qcow_filename, options, "write-target", bs,
534
- &child_vvfat_qcow, false, errp);
535
+ &child_vvfat_qcow, 0, false, errp);
536
qobject_unref(options);
537
if (!s->qcow) {
538
ret = -EINVAL;
539
diff --git a/blockjob.c b/blockjob.c
540
index XXXXXXX..XXXXXXX 100644
541
--- a/blockjob.c
542
+++ b/blockjob.c
543
@@ -XXX,XX +XXX,XX @@ int block_job_add_bdrv(BlockJob *job, const char *name, BlockDriverState *bs,
544
if (job->job.aio_context != qemu_get_aio_context()) {
545
aio_context_release(job->job.aio_context);
546
}
547
- c = bdrv_root_attach_child(bs, name, &child_job, job->job.aio_context,
548
- perm, shared_perm, job, errp);
549
+ c = bdrv_root_attach_child(bs, name, &child_job, 0,
550
+ job->job.aio_context, perm, shared_perm, job,
551
+ errp);
552
if (job->job.aio_context != qemu_get_aio_context()) {
553
aio_context_acquire(job->job.aio_context);
554
}
555
diff --git a/tests/test-bdrv-drain.c b/tests/test-bdrv-drain.c
556
index XXXXXXX..XXXXXXX 100644
557
--- a/tests/test-bdrv-drain.c
558
+++ b/tests/test-bdrv-drain.c
559
@@ -XXX,XX +XXX,XX @@ static void do_test_delete_by_drain(bool detach_instead_of_delete,
560
561
null_bs = bdrv_open("null-co://", NULL, NULL, BDRV_O_RDWR | BDRV_O_PROTOCOL,
562
&error_abort);
563
- bdrv_attach_child(bs, null_bs, "null-child", &child_file, &error_abort);
564
+ bdrv_attach_child(bs, null_bs, "null-child", &child_file, 0, &error_abort);
565
566
/* This child will be the one to pass to requests through to, and
567
* it will stall until a drain occurs */
568
@@ -XXX,XX +XXX,XX @@ static void do_test_delete_by_drain(bool detach_instead_of_delete,
569
child_bs->total_sectors = 65536 >> BDRV_SECTOR_BITS;
570
/* Takes our reference to child_bs */
571
tts->wait_child = bdrv_attach_child(bs, child_bs, "wait-child", &child_file,
572
- &error_abort);
573
+ 0, &error_abort);
574
575
/* This child is just there to be deleted
576
* (for detach_instead_of_delete == true) */
577
null_bs = bdrv_open("null-co://", NULL, NULL, BDRV_O_RDWR | BDRV_O_PROTOCOL,
578
&error_abort);
579
- bdrv_attach_child(bs, null_bs, "null-child", &child_file, &error_abort);
580
+ bdrv_attach_child(bs, null_bs, "null-child", &child_file, 0, &error_abort);
581
582
blk = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL);
583
blk_insert_bs(blk, bs, &error_abort);
584
@@ -XXX,XX +XXX,XX @@ static void detach_indirect_bh(void *opaque)
585
586
bdrv_ref(data->c);
587
data->child_c = bdrv_attach_child(data->parent_b, data->c, "PB-C",
588
- &child_file, &error_abort);
589
+ &child_file, 0, &error_abort);
144
}
590
}
145
591
592
static void detach_by_parent_aio_cb(void *opaque, int ret)
593
@@ -XXX,XX +XXX,XX @@ static void test_detach_indirect(bool by_parent_cb)
594
/* Set child relationships */
595
bdrv_ref(b);
596
bdrv_ref(a);
597
- child_b = bdrv_attach_child(parent_b, b, "PB-B", &child_file, &error_abort);
598
- child_a = bdrv_attach_child(parent_b, a, "PB-A", &child_backing, &error_abort);
599
+ child_b = bdrv_attach_child(parent_b, b, "PB-B", &child_file, 0,
600
+ &error_abort);
601
+ child_a = bdrv_attach_child(parent_b, a, "PB-A", &child_backing, 0,
602
+ &error_abort);
603
604
bdrv_ref(a);
605
bdrv_attach_child(parent_a, a, "PA-A",
606
by_parent_cb ? &child_file : &detach_by_driver_cb_class,
607
- &error_abort);
608
+ 0, &error_abort);
609
610
g_assert_cmpint(parent_a->refcnt, ==, 1);
611
g_assert_cmpint(parent_b->refcnt, ==, 1);
612
@@ -XXX,XX +XXX,XX @@ static void test_drop_intermediate_poll(void)
613
/* Takes the reference to chain[i - 1] */
614
chain[i]->backing = bdrv_attach_child(chain[i], chain[i - 1],
615
"chain", &chain_child_class,
616
- &error_abort);
617
+ 0, &error_abort);
618
}
619
}
620
621
@@ -XXX,XX +XXX,XX @@ static void do_test_replace_child_mid_drain(int old_drain_count,
622
623
bdrv_ref(old_child_bs);
624
parent_bs->backing = bdrv_attach_child(parent_bs, old_child_bs, "child",
625
- &child_backing, &error_abort);
626
+ &child_backing, 0, &error_abort);
627
628
for (i = 0; i < old_drain_count; i++) {
629
bdrv_drained_begin(old_child_bs);
630
diff --git a/tests/test-bdrv-graph-mod.c b/tests/test-bdrv-graph-mod.c
631
index XXXXXXX..XXXXXXX 100644
632
--- a/tests/test-bdrv-graph-mod.c
633
+++ b/tests/test-bdrv-graph-mod.c
634
@@ -XXX,XX +XXX,XX @@ static void test_update_perm_tree(void)
635
636
blk_insert_bs(root, bs, &error_abort);
637
638
- bdrv_attach_child(filter, bs, "child", &child_file, &error_abort);
639
+ bdrv_attach_child(filter, bs, "child", &child_file, 0, &error_abort);
640
641
bdrv_append(filter, bs, &local_err);
642
643
@@ -XXX,XX +XXX,XX @@ static void test_should_update_child(void)
644
bdrv_set_backing_hd(target, bs, &error_abort);
645
646
g_assert(target->backing->bs == bs);
647
- bdrv_attach_child(filter, target, "target", &child_file, &error_abort);
648
+ bdrv_attach_child(filter, target, "target", &child_file, 0, &error_abort);
649
bdrv_append(filter, bs, &error_abort);
650
g_assert(target->backing->bs == bs);
651
146
--
652
--
147
2.20.1
653
2.25.4
148
654
149
655
diff view generated by jsdifflib
New patch
1
1
From: Max Reitz <mreitz@redhat.com>
2
3
For now, all callers pass 0 and no callee evaluates this value. Later
4
patches will change both.
5
6
Signed-off-by: Max Reitz <mreitz@redhat.com>
7
Reviewed-by: Eric Blake <eblake@redhat.com>
8
Message-Id: <20200513110544.176672-7-mreitz@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
11
include/block/block_int.h | 5 ++++-
12
block.c | 22 ++++++++++++----------
13
block/backup-top.c | 3 ++-
14
block/blkdebug.c | 5 +++--
15
block/blklogwrites.c | 9 +++++----
16
block/commit.c | 1 +
17
block/copy-on-read.c | 1 +
18
block/mirror.c | 1 +
19
block/quorum.c | 1 +
20
block/replication.c | 1 +
21
block/vvfat.c | 1 +
22
tests/test-bdrv-drain.c | 5 +++--
23
tests/test-bdrv-graph-mod.c | 1 +
24
13 files changed, 36 insertions(+), 20 deletions(-)
25
26
diff --git a/include/block/block_int.h b/include/block/block_int.h
27
index XXXXXXX..XXXXXXX 100644
28
--- a/include/block/block_int.h
29
+++ b/include/block/block_int.h
30
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
31
* the parents in @parent_perm and @parent_shared.
32
*
33
* If @c is NULL, return the permissions for attaching a new child for the
34
- * given @child_class.
35
+ * given @child_class and @role.
36
*
37
* If @reopen_queue is non-NULL, don't return the currently needed
38
* permissions, but those that will be needed after applying the
39
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
40
*/
41
void (*bdrv_child_perm)(BlockDriverState *bs, BdrvChild *c,
42
const BdrvChildClass *child_class,
43
+ BdrvChildRole role,
44
BlockReopenQueue *reopen_queue,
45
uint64_t parent_perm, uint64_t parent_shared,
46
uint64_t *nperm, uint64_t *nshared);
47
@@ -XXX,XX +XXX,XX @@ int bdrv_child_refresh_perms(BlockDriverState *bs, BdrvChild *c, Error **errp);
48
* all children */
49
void bdrv_filter_default_perms(BlockDriverState *bs, BdrvChild *c,
50
const BdrvChildClass *child_class,
51
+ BdrvChildRole child_role,
52
BlockReopenQueue *reopen_queue,
53
uint64_t perm, uint64_t shared,
54
uint64_t *nperm, uint64_t *nshared);
55
@@ -XXX,XX +XXX,XX @@ void bdrv_filter_default_perms(BlockDriverState *bs, BdrvChild *c,
56
* CONSISTENT_READ and doesn't share WRITE. */
57
void bdrv_format_default_perms(BlockDriverState *bs, BdrvChild *c,
58
const BdrvChildClass *child_class,
59
+ BdrvChildRole child_role,
60
BlockReopenQueue *reopen_queue,
61
uint64_t perm, uint64_t shared,
62
uint64_t *nperm, uint64_t *nshared);
63
diff --git a/block.c b/block.c
64
index XXXXXXX..XXXXXXX 100644
65
--- a/block.c
66
+++ b/block.c
67
@@ -XXX,XX +XXX,XX @@ bool bdrv_is_writable(BlockDriverState *bs)
68
69
static void bdrv_child_perm(BlockDriverState *bs, BlockDriverState *child_bs,
70
BdrvChild *c, const BdrvChildClass *child_class,
71
- BlockReopenQueue *reopen_queue,
72
+ BdrvChildRole role, BlockReopenQueue *reopen_queue,
73
uint64_t parent_perm, uint64_t parent_shared,
74
uint64_t *nperm, uint64_t *nshared)
75
{
76
assert(bs->drv && bs->drv->bdrv_child_perm);
77
- bs->drv->bdrv_child_perm(bs, c, child_class, reopen_queue,
78
+ bs->drv->bdrv_child_perm(bs, c, child_class, role, reopen_queue,
79
parent_perm, parent_shared,
80
nperm, nshared);
81
/* TODO Take force_share from reopen_queue */
82
@@ -XXX,XX +XXX,XX @@ static int bdrv_check_perm(BlockDriverState *bs, BlockReopenQueue *q,
83
uint64_t cur_perm, cur_shared;
84
bool child_tighten_restr;
85
86
- bdrv_child_perm(bs, c->bs, c, c->klass, q,
87
+ bdrv_child_perm(bs, c->bs, c, c->klass, c->role, q,
88
cumulative_perms, cumulative_shared_perms,
89
&cur_perm, &cur_shared);
90
ret = bdrv_child_check_perm(c, q, cur_perm, cur_shared, ignore_children,
91
@@ -XXX,XX +XXX,XX @@ static void bdrv_set_perm(BlockDriverState *bs, uint64_t cumulative_perms,
92
/* Update all children */
93
QLIST_FOREACH(c, &bs->children, next) {
94
uint64_t cur_perm, cur_shared;
95
- bdrv_child_perm(bs, c->bs, c, c->klass, NULL,
96
+ bdrv_child_perm(bs, c->bs, c, c->klass, c->role, NULL,
97
cumulative_perms, cumulative_shared_perms,
98
&cur_perm, &cur_shared);
99
bdrv_child_set_perm(c, cur_perm, cur_shared);
100
@@ -XXX,XX +XXX,XX @@ int bdrv_child_refresh_perms(BlockDriverState *bs, BdrvChild *c, Error **errp)
101
uint64_t perms, shared;
102
103
bdrv_get_cumulative_perm(bs, &parent_perms, &parent_shared);
104
- bdrv_child_perm(bs, c->bs, c, c->klass, NULL, parent_perms, parent_shared,
105
- &perms, &shared);
106
+ bdrv_child_perm(bs, c->bs, c, c->klass, c->role, NULL,
107
+ parent_perms, parent_shared, &perms, &shared);
108
109
return bdrv_child_try_set_perm(c, perms, shared, errp);
110
}
111
112
void bdrv_filter_default_perms(BlockDriverState *bs, BdrvChild *c,
113
const BdrvChildClass *child_class,
114
+ BdrvChildRole role,
115
BlockReopenQueue *reopen_queue,
116
uint64_t perm, uint64_t shared,
117
uint64_t *nperm, uint64_t *nshared)
118
@@ -XXX,XX +XXX,XX @@ void bdrv_filter_default_perms(BlockDriverState *bs, BdrvChild *c,
119
120
void bdrv_format_default_perms(BlockDriverState *bs, BdrvChild *c,
121
const BdrvChildClass *child_class,
122
+ BdrvChildRole role,
123
BlockReopenQueue *reopen_queue,
124
uint64_t perm, uint64_t shared,
125
uint64_t *nperm, uint64_t *nshared)
126
@@ -XXX,XX +XXX,XX @@ void bdrv_format_default_perms(BlockDriverState *bs, BdrvChild *c,
127
128
/* Apart from the modifications below, the same permissions are
129
* forwarded and left alone as for filters */
130
- bdrv_filter_default_perms(bs, c, child_class, reopen_queue,
131
+ bdrv_filter_default_perms(bs, c, child_class, role, reopen_queue,
132
perm, shared, &perm, &shared);
133
134
/* Format drivers may touch metadata even if the guest doesn't write */
135
@@ -XXX,XX +XXX,XX @@ BdrvChild *bdrv_attach_child(BlockDriverState *parent_bs,
136
bdrv_get_cumulative_perm(parent_bs, &perm, &shared_perm);
137
138
assert(parent_bs->drv);
139
- bdrv_child_perm(parent_bs, child_bs, NULL, child_class, NULL,
140
+ bdrv_child_perm(parent_bs, child_bs, NULL, child_class, child_role, NULL,
141
perm, shared_perm, &perm, &shared_perm);
142
143
child = bdrv_root_attach_child(child_bs, child_name, child_class,
144
@@ -XXX,XX +XXX,XX @@ int bdrv_reopen_multiple(BlockReopenQueue *bs_queue, Error **errp)
145
if (state->replace_backing_bs && state->new_backing_bs) {
146
uint64_t nperm, nshared;
147
bdrv_child_perm(state->bs, state->new_backing_bs,
148
- NULL, &child_backing, bs_queue,
149
+ NULL, &child_backing, 0, bs_queue,
150
state->perm, state->shared_perm,
151
&nperm, &nshared);
152
ret = bdrv_check_update_perm(state->new_backing_bs, NULL,
153
@@ -XXX,XX +XXX,XX @@ static void bdrv_reopen_perm(BlockReopenQueue *q, BlockDriverState *bs,
154
} else {
155
uint64_t nperm, nshared;
156
157
- bdrv_child_perm(parent->state.bs, bs, c, c->klass, q,
158
+ bdrv_child_perm(parent->state.bs, bs, c, c->klass, c->role, q,
159
parent->state.perm, parent->state.shared_perm,
160
&nperm, &nshared);
161
162
diff --git a/block/backup-top.c b/block/backup-top.c
163
index XXXXXXX..XXXXXXX 100644
164
--- a/block/backup-top.c
165
+++ b/block/backup-top.c
166
@@ -XXX,XX +XXX,XX @@ static void backup_top_refresh_filename(BlockDriverState *bs)
167
168
static void backup_top_child_perm(BlockDriverState *bs, BdrvChild *c,
169
const BdrvChildClass *child_class,
170
+ BdrvChildRole role,
171
BlockReopenQueue *reopen_queue,
172
uint64_t perm, uint64_t shared,
173
uint64_t *nperm, uint64_t *nshared)
174
@@ -XXX,XX +XXX,XX @@ static void backup_top_child_perm(BlockDriverState *bs, BdrvChild *c,
175
*nperm = BLK_PERM_WRITE;
176
} else {
177
/* Source child */
178
- bdrv_filter_default_perms(bs, c, child_class, reopen_queue,
179
+ bdrv_filter_default_perms(bs, c, child_class, role, reopen_queue,
180
perm, shared, nperm, nshared);
181
182
if (perm & BLK_PERM_WRITE) {
183
diff --git a/block/blkdebug.c b/block/blkdebug.c
184
index XXXXXXX..XXXXXXX 100644
185
--- a/block/blkdebug.c
186
+++ b/block/blkdebug.c
187
@@ -XXX,XX +XXX,XX @@ static int blkdebug_reopen_prepare(BDRVReopenState *reopen_state,
188
189
static void blkdebug_child_perm(BlockDriverState *bs, BdrvChild *c,
190
const BdrvChildClass *child_class,
191
+ BdrvChildRole role,
192
BlockReopenQueue *reopen_queue,
193
uint64_t perm, uint64_t shared,
194
uint64_t *nperm, uint64_t *nshared)
195
{
196
BDRVBlkdebugState *s = bs->opaque;
197
198
- bdrv_filter_default_perms(bs, c, child_class, reopen_queue, perm, shared,
199
- nperm, nshared);
200
+ bdrv_filter_default_perms(bs, c, child_class, role, reopen_queue,
201
+ perm, shared, nperm, nshared);
202
203
*nperm |= s->take_child_perms;
204
*nshared &= ~s->unshare_child_perms;
205
diff --git a/block/blklogwrites.c b/block/blklogwrites.c
206
index XXXXXXX..XXXXXXX 100644
207
--- a/block/blklogwrites.c
208
+++ b/block/blklogwrites.c
209
@@ -XXX,XX +XXX,XX @@ static int64_t blk_log_writes_getlength(BlockDriverState *bs)
210
211
static void blk_log_writes_child_perm(BlockDriverState *bs, BdrvChild *c,
212
const BdrvChildClass *child_class,
213
+ BdrvChildRole role,
214
BlockReopenQueue *ro_q,
215
uint64_t perm, uint64_t shrd,
216
uint64_t *nperm, uint64_t *nshrd)
217
@@ -XXX,XX +XXX,XX @@ static void blk_log_writes_child_perm(BlockDriverState *bs, BdrvChild *c,
218
}
219
220
if (!strcmp(c->name, "log")) {
221
- bdrv_format_default_perms(bs, c, child_class, ro_q, perm, shrd, nperm,
222
- nshrd);
223
+ bdrv_format_default_perms(bs, c, child_class, role, ro_q, perm, shrd,
224
+ nperm, nshrd);
225
} else {
226
- bdrv_filter_default_perms(bs, c, child_class, ro_q, perm, shrd, nperm,
227
- nshrd);
228
+ bdrv_filter_default_perms(bs, c, child_class, role, ro_q, perm, shrd,
229
+ nperm, nshrd);
230
}
231
}
232
233
diff --git a/block/commit.c b/block/commit.c
234
index XXXXXXX..XXXXXXX 100644
235
--- a/block/commit.c
236
+++ b/block/commit.c
237
@@ -XXX,XX +XXX,XX @@ static void bdrv_commit_top_refresh_filename(BlockDriverState *bs)
238
239
static void bdrv_commit_top_child_perm(BlockDriverState *bs, BdrvChild *c,
240
const BdrvChildClass *child_class,
241
+ BdrvChildRole role,
242
BlockReopenQueue *reopen_queue,
243
uint64_t perm, uint64_t shared,
244
uint64_t *nperm, uint64_t *nshared)
245
diff --git a/block/copy-on-read.c b/block/copy-on-read.c
246
index XXXXXXX..XXXXXXX 100644
247
--- a/block/copy-on-read.c
248
+++ b/block/copy-on-read.c
249
@@ -XXX,XX +XXX,XX @@ static int cor_open(BlockDriverState *bs, QDict *options, int flags,
250
251
static void cor_child_perm(BlockDriverState *bs, BdrvChild *c,
252
const BdrvChildClass *child_class,
253
+ BdrvChildRole role,
254
BlockReopenQueue *reopen_queue,
255
uint64_t perm, uint64_t shared,
256
uint64_t *nperm, uint64_t *nshared)
257
diff --git a/block/mirror.c b/block/mirror.c
258
index XXXXXXX..XXXXXXX 100644
259
--- a/block/mirror.c
260
+++ b/block/mirror.c
261
@@ -XXX,XX +XXX,XX @@ static void bdrv_mirror_top_refresh_filename(BlockDriverState *bs)
262
263
static void bdrv_mirror_top_child_perm(BlockDriverState *bs, BdrvChild *c,
264
const BdrvChildClass *child_class,
265
+ BdrvChildRole role,
266
BlockReopenQueue *reopen_queue,
267
uint64_t perm, uint64_t shared,
268
uint64_t *nperm, uint64_t *nshared)
269
diff --git a/block/quorum.c b/block/quorum.c
270
index XXXXXXX..XXXXXXX 100644
271
--- a/block/quorum.c
272
+++ b/block/quorum.c
273
@@ -XXX,XX +XXX,XX @@ static char *quorum_dirname(BlockDriverState *bs, Error **errp)
274
275
static void quorum_child_perm(BlockDriverState *bs, BdrvChild *c,
276
const BdrvChildClass *child_class,
277
+ BdrvChildRole role,
278
BlockReopenQueue *reopen_queue,
279
uint64_t perm, uint64_t shared,
280
uint64_t *nperm, uint64_t *nshared)
281
diff --git a/block/replication.c b/block/replication.c
282
index XXXXXXX..XXXXXXX 100644
283
--- a/block/replication.c
284
+++ b/block/replication.c
285
@@ -XXX,XX +XXX,XX @@ static void replication_close(BlockDriverState *bs)
286
287
static void replication_child_perm(BlockDriverState *bs, BdrvChild *c,
288
const BdrvChildClass *child_class,
289
+ BdrvChildRole role,
290
BlockReopenQueue *reopen_queue,
291
uint64_t perm, uint64_t shared,
292
uint64_t *nperm, uint64_t *nshared)
293
diff --git a/block/vvfat.c b/block/vvfat.c
294
index XXXXXXX..XXXXXXX 100644
295
--- a/block/vvfat.c
296
+++ b/block/vvfat.c
297
@@ -XXX,XX +XXX,XX @@ err:
298
299
static void vvfat_child_perm(BlockDriverState *bs, BdrvChild *c,
300
const BdrvChildClass *child_class,
301
+ BdrvChildRole role,
302
BlockReopenQueue *reopen_queue,
303
uint64_t perm, uint64_t shared,
304
uint64_t *nperm, uint64_t *nshared)
305
diff --git a/tests/test-bdrv-drain.c b/tests/test-bdrv-drain.c
306
index XXXXXXX..XXXXXXX 100644
307
--- a/tests/test-bdrv-drain.c
308
+++ b/tests/test-bdrv-drain.c
309
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_test_co_preadv(BlockDriverState *bs,
310
311
static void bdrv_test_child_perm(BlockDriverState *bs, BdrvChild *c,
312
const BdrvChildClass *child_class,
313
+ BdrvChildRole role,
314
BlockReopenQueue *reopen_queue,
315
uint64_t perm, uint64_t shared,
316
uint64_t *nperm, uint64_t *nshared)
317
@@ -XXX,XX +XXX,XX @@ static void bdrv_test_child_perm(BlockDriverState *bs, BdrvChild *c,
318
child_class = &child_file;
319
}
320
321
- bdrv_format_default_perms(bs, c, child_class, reopen_queue, perm, shared,
322
- nperm, nshared);
323
+ bdrv_format_default_perms(bs, c, child_class, role, reopen_queue,
324
+ perm, shared, nperm, nshared);
325
}
326
327
static int bdrv_test_change_backing_file(BlockDriverState *bs,
328
diff --git a/tests/test-bdrv-graph-mod.c b/tests/test-bdrv-graph-mod.c
329
index XXXXXXX..XXXXXXX 100644
330
--- a/tests/test-bdrv-graph-mod.c
331
+++ b/tests/test-bdrv-graph-mod.c
332
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_pass_through = {
333
334
static void no_perm_default_perms(BlockDriverState *bs, BdrvChild *c,
335
const BdrvChildClass *child_class,
336
+ BdrvChildRole role,
337
BlockReopenQueue *reopen_queue,
338
uint64_t perm, uint64_t shared,
339
uint64_t *nperm, uint64_t *nshared)
340
--
341
2.25.4
342
343
diff view generated by jsdifflib
New patch
1
1
From: Max Reitz <mreitz@redhat.com>
2
3
For now, all callers (effectively) pass 0 and no callee evaluates thie
4
value. Later patches will change both.
5
6
Signed-off-by: Max Reitz <mreitz@redhat.com>
7
Reviewed-by: Eric Blake <eblake@redhat.com>
8
Message-Id: <20200513110544.176672-8-mreitz@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
11
include/block/block_int.h | 3 ++-
12
block.c | 40 +++++++++++++++++++++++----------------
13
block/block-backend.c | 3 ++-
14
block/vvfat.c | 3 ++-
15
4 files changed, 30 insertions(+), 19 deletions(-)
16
17
diff --git a/include/block/block_int.h b/include/block/block_int.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/include/block/block_int.h
20
+++ b/include/block/block_int.h
21
@@ -XXX,XX +XXX,XX @@ struct BdrvChildClass {
22
* non-BDS parents. */
23
bool parent_is_bds;
24
25
- void (*inherit_options)(int *child_flags, QDict *child_options,
26
+ void (*inherit_options)(BdrvChildRole role,
27
+ int *child_flags, QDict *child_options,
28
int parent_flags, QDict *parent_options);
29
30
void (*change_media)(BdrvChild *child, bool load);
31
diff --git a/block.c b/block.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/block.c
34
+++ b/block.c
35
@@ -XXX,XX +XXX,XX @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
36
QDict *options, int flags,
37
BlockDriverState *parent,
38
const BdrvChildClass *child_class,
39
+ BdrvChildRole child_role,
40
Error **errp);
41
42
/* If non-zero, use only whitelisted block drivers */
43
@@ -XXX,XX +XXX,XX @@ static void bdrv_temp_snapshot_options(int *child_flags, QDict *child_options,
44
* Returns the options and flags that bs->file should get if a protocol driver
45
* is expected, based on the given options and flags for the parent BDS
46
*/
47
-static void bdrv_inherited_options(int *child_flags, QDict *child_options,
48
+static void bdrv_inherited_options(BdrvChildRole role,
49
+ int *child_flags, QDict *child_options,
50
int parent_flags, QDict *parent_options)
51
{
52
int flags = parent_flags;
53
@@ -XXX,XX +XXX,XX @@ const BdrvChildClass child_file = {
54
* (and not only protocols) is permitted for it, based on the given options and
55
* flags for the parent BDS
56
*/
57
-static void bdrv_inherited_fmt_options(int *child_flags, QDict *child_options,
58
+static void bdrv_inherited_fmt_options(BdrvChildRole role,
59
+ int *child_flags, QDict *child_options,
60
int parent_flags, QDict *parent_options)
61
{
62
- child_file.inherit_options(child_flags, child_options,
63
+ child_file.inherit_options(role, child_flags, child_options,
64
parent_flags, parent_options);
65
66
*child_flags &= ~(BDRV_O_PROTOCOL | BDRV_O_NO_IO);
67
@@ -XXX,XX +XXX,XX @@ static void bdrv_backing_detach(BdrvChild *c)
68
* Returns the options and flags that bs->backing should get, based on the
69
* given options and flags for the parent BDS
70
*/
71
-static void bdrv_backing_options(int *child_flags, QDict *child_options,
72
+static void bdrv_backing_options(BdrvChildRole role,
73
+ int *child_flags, QDict *child_options,
74
int parent_flags, QDict *parent_options)
75
{
76
int flags = parent_flags;
77
@@ -XXX,XX +XXX,XX @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *parent_options,
78
}
79
80
backing_hd = bdrv_open_inherit(backing_filename, reference, options, 0, bs,
81
- &child_backing, errp);
82
+ &child_backing, 0, errp);
83
if (!backing_hd) {
84
bs->open_flags |= BDRV_O_NO_BACKING;
85
error_prepend(errp, "Could not open backing file: ");
86
@@ -XXX,XX +XXX,XX @@ free_exit:
87
static BlockDriverState *
88
bdrv_open_child_bs(const char *filename, QDict *options, const char *bdref_key,
89
BlockDriverState *parent, const BdrvChildClass *child_class,
90
- bool allow_none, Error **errp)
91
+ BdrvChildRole child_role, bool allow_none, Error **errp)
92
{
93
BlockDriverState *bs = NULL;
94
QDict *image_options;
95
@@ -XXX,XX +XXX,XX @@ bdrv_open_child_bs(const char *filename, QDict *options, const char *bdref_key,
96
}
97
98
bs = bdrv_open_inherit(filename, reference, image_options, 0,
99
- parent, child_class, errp);
100
+ parent, child_class, child_role, errp);
101
if (!bs) {
102
goto done;
103
}
104
@@ -XXX,XX +XXX,XX @@ BdrvChild *bdrv_open_child(const char *filename,
105
BlockDriverState *bs;
106
107
bs = bdrv_open_child_bs(filename, options, bdref_key, parent, child_class,
108
- allow_none, errp);
109
+ child_role, allow_none, errp);
110
if (bs == NULL) {
111
return NULL;
112
}
113
@@ -XXX,XX +XXX,XX @@ BlockDriverState *bdrv_open_blockdev_ref(BlockdevRef *ref, Error **errp)
114
115
}
116
117
- bs = bdrv_open_inherit(NULL, reference, qdict, 0, NULL, NULL, errp);
118
+ bs = bdrv_open_inherit(NULL, reference, qdict, 0, NULL, NULL, 0, errp);
119
obj = NULL;
120
qobject_unref(obj);
121
visit_free(v);
122
@@ -XXX,XX +XXX,XX @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
123
QDict *options, int flags,
124
BlockDriverState *parent,
125
const BdrvChildClass *child_class,
126
+ BdrvChildRole child_role,
127
Error **errp)
128
{
129
int ret;
130
@@ -XXX,XX +XXX,XX @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
131
132
if (child_class) {
133
bs->inherits_from = parent;
134
- child_class->inherit_options(&flags, options,
135
+ child_class->inherit_options(child_role, &flags, options,
136
parent->open_flags, parent->options);
137
}
138
139
@@ -XXX,XX +XXX,XX @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
140
flags, options);
141
/* Let bdrv_backing_options() override "read-only" */
142
qdict_del(options, BDRV_OPT_READ_ONLY);
143
- bdrv_backing_options(&flags, options, flags, options);
144
+ bdrv_backing_options(0, &flags, options, flags, options);
145
}
146
147
bs->open_flags = flags;
148
@@ -XXX,XX +XXX,XX @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
149
BlockDriverState *file_bs;
150
151
file_bs = bdrv_open_child_bs(filename, options, "file", bs,
152
- &child_file, true, &local_err);
153
+ &child_file, 0, true, &local_err);
154
if (local_err) {
155
goto fail;
156
}
157
@@ -XXX,XX +XXX,XX @@ BlockDriverState *bdrv_open(const char *filename, const char *reference,
158
QDict *options, int flags, Error **errp)
159
{
160
return bdrv_open_inherit(filename, reference, options, flags, NULL,
161
- NULL, errp);
162
+ NULL, 0, errp);
163
}
164
165
/* Return true if the NULL-terminated @list contains @str */
166
@@ -XXX,XX +XXX,XX @@ static BlockReopenQueue *bdrv_reopen_queue_child(BlockReopenQueue *bs_queue,
167
BlockDriverState *bs,
168
QDict *options,
169
const BdrvChildClass *klass,
170
+ BdrvChildRole role,
171
QDict *parent_options,
172
int parent_flags,
173
bool keep_old_opts)
174
@@ -XXX,XX +XXX,XX @@ static BlockReopenQueue *bdrv_reopen_queue_child(BlockReopenQueue *bs_queue,
175
/* Inherit from parent node */
176
if (parent_options) {
177
flags = 0;
178
- klass->inherit_options(&flags, options, parent_flags, parent_options);
179
+ klass->inherit_options(role, &flags, options,
180
+ parent_flags, parent_options);
181
} else {
182
flags = bdrv_get_flags(bs);
183
}
184
@@ -XXX,XX +XXX,XX @@ static BlockReopenQueue *bdrv_reopen_queue_child(BlockReopenQueue *bs_queue,
185
}
186
187
bdrv_reopen_queue_child(bs_queue, child->bs, new_child_options,
188
- child->klass, options, flags, child_keep_old);
189
+ child->klass, child->role, options, flags,
190
+ child_keep_old);
191
}
192
193
return bs_queue;
194
@@ -XXX,XX +XXX,XX @@ BlockReopenQueue *bdrv_reopen_queue(BlockReopenQueue *bs_queue,
195
BlockDriverState *bs,
196
QDict *options, bool keep_old_opts)
197
{
198
- return bdrv_reopen_queue_child(bs_queue, bs, options, NULL, NULL, 0,
199
+ return bdrv_reopen_queue_child(bs_queue, bs, options, NULL, 0, NULL, 0,
200
keep_old_opts);
201
}
202
203
diff --git a/block/block-backend.c b/block/block-backend.c
204
index XXXXXXX..XXXXXXX 100644
205
--- a/block/block-backend.c
206
+++ b/block/block-backend.c
207
@@ -XXX,XX +XXX,XX @@ static QTAILQ_HEAD(, BlockBackend) block_backends =
208
static QTAILQ_HEAD(, BlockBackend) monitor_block_backends =
209
QTAILQ_HEAD_INITIALIZER(monitor_block_backends);
210
211
-static void blk_root_inherit_options(int *child_flags, QDict *child_options,
212
+static void blk_root_inherit_options(BdrvChildRole role,
213
+ int *child_flags, QDict *child_options,
214
int parent_flags, QDict *parent_options)
215
{
216
/* We're not supposed to call this function for root nodes */
217
diff --git a/block/vvfat.c b/block/vvfat.c
218
index XXXXXXX..XXXXXXX 100644
219
--- a/block/vvfat.c
220
+++ b/block/vvfat.c
221
@@ -XXX,XX +XXX,XX @@ static BlockDriver vvfat_write_target = {
222
.bdrv_co_pwritev = write_target_commit,
223
};
224
225
-static void vvfat_qcow_options(int *child_flags, QDict *child_options,
226
+static void vvfat_qcow_options(BdrvChildRole role,
227
+ int *child_flags, QDict *child_options,
228
int parent_flags, QDict *parent_options)
229
{
230
qdict_set_default_str(child_options, BDRV_OPT_READ_ONLY, "off");
231
--
232
2.25.4
233
234
diff view generated by jsdifflib
New patch
1
From: Max Reitz <mreitz@redhat.com>
1
2
3
We plan to unify the generic .inherit_options() functions. The
4
resulting common function will need to decide whether to force-enable
5
format probing, force-disable it, or leave it as-is. To make this
6
decision, it will need to know whether the parent node is a format node
7
or not (because we never want format probing if the parent is a format
8
node already (except for the backing chain)).
9
10
Signed-off-by: Max Reitz <mreitz@redhat.com>
11
Reviewed-by: Eric Blake <eblake@redhat.com>
12
Message-Id: <20200513110544.176672-9-mreitz@redhat.com>
13
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
---
15
include/block/block_int.h | 2 +-
16
block.c | 37 +++++++++++++++++++++++++++----------
17
block/block-backend.c | 2 +-
18
block/vvfat.c | 2 +-
19
4 files changed, 30 insertions(+), 13 deletions(-)
20
21
diff --git a/include/block/block_int.h b/include/block/block_int.h
22
index XXXXXXX..XXXXXXX 100644
23
--- a/include/block/block_int.h
24
+++ b/include/block/block_int.h
25
@@ -XXX,XX +XXX,XX @@ struct BdrvChildClass {
26
* non-BDS parents. */
27
bool parent_is_bds;
28
29
- void (*inherit_options)(BdrvChildRole role,
30
+ void (*inherit_options)(BdrvChildRole role, bool parent_is_format,
31
int *child_flags, QDict *child_options,
32
int parent_flags, QDict *parent_options);
33
34
diff --git a/block.c b/block.c
35
index XXXXXXX..XXXXXXX 100644
36
--- a/block.c
37
+++ b/block.c
38
@@ -XXX,XX +XXX,XX @@ static void bdrv_temp_snapshot_options(int *child_flags, QDict *child_options,
39
* Returns the options and flags that bs->file should get if a protocol driver
40
* is expected, based on the given options and flags for the parent BDS
41
*/
42
-static void bdrv_inherited_options(BdrvChildRole role,
43
+static void bdrv_inherited_options(BdrvChildRole role, bool parent_is_format,
44
int *child_flags, QDict *child_options,
45
int parent_flags, QDict *parent_options)
46
{
47
@@ -XXX,XX +XXX,XX @@ const BdrvChildClass child_file = {
48
* flags for the parent BDS
49
*/
50
static void bdrv_inherited_fmt_options(BdrvChildRole role,
51
+ bool parent_is_format,
52
int *child_flags, QDict *child_options,
53
int parent_flags, QDict *parent_options)
54
{
55
- child_file.inherit_options(role, child_flags, child_options,
56
+ child_file.inherit_options(role, parent_is_format,
57
+ child_flags, child_options,
58
parent_flags, parent_options);
59
60
*child_flags &= ~(BDRV_O_PROTOCOL | BDRV_O_NO_IO);
61
@@ -XXX,XX +XXX,XX @@ static void bdrv_backing_detach(BdrvChild *c)
62
* Returns the options and flags that bs->backing should get, based on the
63
* given options and flags for the parent BDS
64
*/
65
-static void bdrv_backing_options(BdrvChildRole role,
66
+static void bdrv_backing_options(BdrvChildRole role, bool parent_is_format,
67
int *child_flags, QDict *child_options,
68
int parent_flags, QDict *parent_options)
69
{
70
@@ -XXX,XX +XXX,XX @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
71
bs->explicit_options = qdict_clone_shallow(options);
72
73
if (child_class) {
74
+ bool parent_is_format;
75
+
76
+ if (parent->drv) {
77
+ parent_is_format = parent->drv->is_format;
78
+ } else {
79
+ /*
80
+ * parent->drv is not set yet because this node is opened for
81
+ * (potential) format probing. That means that @parent is going
82
+ * to be a format node.
83
+ */
84
+ parent_is_format = true;
85
+ }
86
+
87
bs->inherits_from = parent;
88
- child_class->inherit_options(child_role, &flags, options,
89
+ child_class->inherit_options(child_role, parent_is_format,
90
+ &flags, options,
91
parent->open_flags, parent->options);
92
}
93
94
@@ -XXX,XX +XXX,XX @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
95
flags, options);
96
/* Let bdrv_backing_options() override "read-only" */
97
qdict_del(options, BDRV_OPT_READ_ONLY);
98
- bdrv_backing_options(0, &flags, options, flags, options);
99
+ bdrv_backing_options(0, true, &flags, options, flags, options);
100
}
101
102
bs->open_flags = flags;
103
@@ -XXX,XX +XXX,XX @@ static BlockReopenQueue *bdrv_reopen_queue_child(BlockReopenQueue *bs_queue,
104
QDict *options,
105
const BdrvChildClass *klass,
106
BdrvChildRole role,
107
+ bool parent_is_format,
108
QDict *parent_options,
109
int parent_flags,
110
bool keep_old_opts)
111
@@ -XXX,XX +XXX,XX @@ static BlockReopenQueue *bdrv_reopen_queue_child(BlockReopenQueue *bs_queue,
112
/* Inherit from parent node */
113
if (parent_options) {
114
flags = 0;
115
- klass->inherit_options(role, &flags, options,
116
+ klass->inherit_options(role, parent_is_format, &flags, options,
117
parent_flags, parent_options);
118
} else {
119
flags = bdrv_get_flags(bs);
120
@@ -XXX,XX +XXX,XX @@ static BlockReopenQueue *bdrv_reopen_queue_child(BlockReopenQueue *bs_queue,
121
}
122
123
bdrv_reopen_queue_child(bs_queue, child->bs, new_child_options,
124
- child->klass, child->role, options, flags,
125
- child_keep_old);
126
+ child->klass, child->role, bs->drv->is_format,
127
+ options, flags, child_keep_old);
128
}
129
130
return bs_queue;
131
@@ -XXX,XX +XXX,XX @@ BlockReopenQueue *bdrv_reopen_queue(BlockReopenQueue *bs_queue,
132
BlockDriverState *bs,
133
QDict *options, bool keep_old_opts)
134
{
135
- return bdrv_reopen_queue_child(bs_queue, bs, options, NULL, 0, NULL, 0,
136
- keep_old_opts);
137
+ return bdrv_reopen_queue_child(bs_queue, bs, options, NULL, 0, false,
138
+ NULL, 0, keep_old_opts);
139
}
140
141
/*
142
diff --git a/block/block-backend.c b/block/block-backend.c
143
index XXXXXXX..XXXXXXX 100644
144
--- a/block/block-backend.c
145
+++ b/block/block-backend.c
146
@@ -XXX,XX +XXX,XX @@ static QTAILQ_HEAD(, BlockBackend) block_backends =
147
static QTAILQ_HEAD(, BlockBackend) monitor_block_backends =
148
QTAILQ_HEAD_INITIALIZER(monitor_block_backends);
149
150
-static void blk_root_inherit_options(BdrvChildRole role,
151
+static void blk_root_inherit_options(BdrvChildRole role, bool parent_is_format,
152
int *child_flags, QDict *child_options,
153
int parent_flags, QDict *parent_options)
154
{
155
diff --git a/block/vvfat.c b/block/vvfat.c
156
index XXXXXXX..XXXXXXX 100644
157
--- a/block/vvfat.c
158
+++ b/block/vvfat.c
159
@@ -XXX,XX +XXX,XX @@ static BlockDriver vvfat_write_target = {
160
.bdrv_co_pwritev = write_target_commit,
161
};
162
163
-static void vvfat_qcow_options(BdrvChildRole role,
164
+static void vvfat_qcow_options(BdrvChildRole role, bool parent_is_format,
165
int *child_flags, QDict *child_options,
166
int parent_flags, QDict *parent_options)
167
{
168
--
169
2.25.4
170
171
diff view generated by jsdifflib
New patch
1
From: Max Reitz <mreitz@redhat.com>
1
2
3
The other two .inherit_options implementations specify exactly for what
4
case they are used in their name, so do it for this one as well.
5
6
(The actual intention behind this patch is to follow it up with a
7
generic bdrv_inherited_options() that works for all three cases.)
8
9
Signed-off-by: Max Reitz <mreitz@redhat.com>
10
Reviewed-by: Eric Blake <eblake@redhat.com>
11
Message-Id: <20200513110544.176672-10-mreitz@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
---
14
block.c | 8 ++++----
15
1 file changed, 4 insertions(+), 4 deletions(-)
16
17
diff --git a/block.c b/block.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/block.c
20
+++ b/block.c
21
@@ -XXX,XX +XXX,XX @@ static void bdrv_temp_snapshot_options(int *child_flags, QDict *child_options,
22
* Returns the options and flags that bs->file should get if a protocol driver
23
* is expected, based on the given options and flags for the parent BDS
24
*/
25
-static void bdrv_inherited_options(BdrvChildRole role, bool parent_is_format,
26
- int *child_flags, QDict *child_options,
27
- int parent_flags, QDict *parent_options)
28
+static void bdrv_protocol_options(BdrvChildRole role, bool parent_is_format,
29
+ int *child_flags, QDict *child_options,
30
+ int parent_flags, QDict *parent_options)
31
{
32
int flags = parent_flags;
33
34
@@ -XXX,XX +XXX,XX @@ static void bdrv_inherited_options(BdrvChildRole role, bool parent_is_format,
35
const BdrvChildClass child_file = {
36
.parent_is_bds = true,
37
.get_parent_desc = bdrv_child_get_parent_desc,
38
- .inherit_options = bdrv_inherited_options,
39
+ .inherit_options = bdrv_protocol_options,
40
.drained_begin = bdrv_child_cb_drained_begin,
41
.drained_poll = bdrv_child_cb_drained_poll,
42
.drained_end = bdrv_child_cb_drained_end,
43
--
44
2.25.4
45
46
diff view generated by jsdifflib
New patch
1
From: Max Reitz <mreitz@redhat.com>
1
2
3
After the series this patch belongs to, we want to have a common
4
BdrvChildClass that encompasses all of child_file, child_format, and
5
child_backing. Such a single class needs a single .inherit_options()
6
implementation, and this patch introduces it.
7
8
The next patch will show how the existing implementations can fall back
9
to it just by passing appropriate BdrvChildRole and parent_is_format
10
values.
11
12
Signed-off-by: Max Reitz <mreitz@redhat.com>
13
Message-Id: <20200513110544.176672-11-mreitz@redhat.com>
14
Reviewed-by: Eric Blake <eblake@redhat.com>
15
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
16
---
17
block.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
18
1 file changed, 81 insertions(+)
19
20
diff --git a/block.c b/block.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/block.c
23
+++ b/block.c
24
@@ -XXX,XX +XXX,XX @@ const BdrvChildClass child_backing = {
25
.set_aio_ctx = bdrv_child_cb_set_aio_ctx,
26
};
27
28
+/*
29
+ * Returns the options and flags that a generic child of a BDS should
30
+ * get, based on the given options and flags for the parent BDS.
31
+ */
32
+static void __attribute__((unused))
33
+ bdrv_inherited_options(BdrvChildRole role, bool parent_is_format,
34
+ int *child_flags, QDict *child_options,
35
+ int parent_flags, QDict *parent_options)
36
+{
37
+ int flags = parent_flags;
38
+
39
+ /*
40
+ * First, decide whether to set, clear, or leave BDRV_O_PROTOCOL.
41
+ * Generally, the question to answer is: Should this child be
42
+ * format-probed by default?
43
+ */
44
+
45
+ /*
46
+ * Pure and non-filtered data children of non-format nodes should
47
+ * be probed by default (even when the node itself has BDRV_O_PROTOCOL
48
+ * set). This only affects a very limited set of drivers (namely
49
+ * quorum and blkverify when this comment was written).
50
+ * Force-clear BDRV_O_PROTOCOL then.
51
+ */
52
+ if (!parent_is_format &&
53
+ (role & BDRV_CHILD_DATA) &&
54
+ !(role & (BDRV_CHILD_METADATA | BDRV_CHILD_FILTERED)))
55
+ {
56
+ flags &= ~BDRV_O_PROTOCOL;
57
+ }
58
+
59
+ /*
60
+ * All children of format nodes (except for COW children) and all
61
+ * metadata children in general should never be format-probed.
62
+ * Force-set BDRV_O_PROTOCOL then.
63
+ */
64
+ if ((parent_is_format && !(role & BDRV_CHILD_COW)) ||
65
+ (role & BDRV_CHILD_METADATA))
66
+ {
67
+ flags |= BDRV_O_PROTOCOL;
68
+ }
69
+
70
+ /*
71
+ * If the cache mode isn't explicitly set, inherit direct and no-flush from
72
+ * the parent.
73
+ */
74
+ qdict_copy_default(child_options, parent_options, BDRV_OPT_CACHE_DIRECT);
75
+ qdict_copy_default(child_options, parent_options, BDRV_OPT_CACHE_NO_FLUSH);
76
+ qdict_copy_default(child_options, parent_options, BDRV_OPT_FORCE_SHARE);
77
+
78
+ if (role & BDRV_CHILD_COW) {
79
+ /* backing files are opened read-only by default */
80
+ qdict_set_default_str(child_options, BDRV_OPT_READ_ONLY, "on");
81
+ qdict_set_default_str(child_options, BDRV_OPT_AUTO_READ_ONLY, "off");
82
+ } else {
83
+ /* Inherit the read-only option from the parent if it's not set */
84
+ qdict_copy_default(child_options, parent_options, BDRV_OPT_READ_ONLY);
85
+ qdict_copy_default(child_options, parent_options,
86
+ BDRV_OPT_AUTO_READ_ONLY);
87
+ }
88
+
89
+ /*
90
+ * bdrv_co_pdiscard() respects unmap policy for the parent, so we
91
+ * can default to enable it on lower layers regardless of the
92
+ * parent option.
93
+ */
94
+ qdict_set_default_str(child_options, BDRV_OPT_DISCARD, "unmap");
95
+
96
+ /* Clear flags that only apply to the top layer */
97
+ flags &= ~(BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING | BDRV_O_COPY_ON_READ);
98
+
99
+ if (role & BDRV_CHILD_METADATA) {
100
+ flags &= ~BDRV_O_NO_IO;
101
+ }
102
+ if (role & BDRV_CHILD_COW) {
103
+ flags &= ~BDRV_O_TEMPORARY;
104
+ }
105
+
106
+ *child_flags = flags;
107
+}
108
+
109
static int bdrv_open_flags(BlockDriverState *bs, int flags)
110
{
111
int open_flags = flags;
112
--
113
2.25.4
114
115
diff view generated by jsdifflib
New patch
1
From: Max Reitz <mreitz@redhat.com>
1
2
3
Let child_file's, child_format's, and child_backing's .inherit_options()
4
implementations fall back to bdrv_inherited_options() to show that it
5
would really work for all of these cases, if only the parents passed the
6
appropriate BdrvChildRole and parent_is_format values.
7
8
(Also, make bdrv_open_inherit(), the only place to explicitly call
9
bdrv_backing_options(), call bdrv_inherited_options() instead.)
10
11
This patch should incur only two visible changes, both for child_format
12
children, both of which are effectively bug fixes:
13
14
First, they no longer have discard=unmap set by default. This reason it
15
was set is because bdrv_inherited_fmt_options() fell through to
16
bdrv_protocol_options(), and that set it because "format drivers take
17
care to send flushes and respect unmap policy". None of the drivers
18
that use child_format for their children (quorum and blkverify) are
19
format drivers, though, so this reasoning does not apply here.
20
21
Second, they no longer have BDRV_O_NO_IO force-cleared. child_format
22
was used solely for children that do not store any metadata and as such
23
will not be accessed by their parents as long as those parents do not
24
receive I/O themselves. Thus, such children should inherit
25
BDRV_O_NO_IO.
26
27
Signed-off-by: Max Reitz <mreitz@redhat.com>
28
Message-Id: <20200513110544.176672-12-mreitz@redhat.com>
29
Reviewed-by: Eric Blake <eblake@redhat.com>
30
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
31
---
32
block.c | 71 +++++++++++++++------------------------------------------
33
1 file changed, 19 insertions(+), 52 deletions(-)
34
35
diff --git a/block.c b/block.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/block.c
38
+++ b/block.c
39
@@ -XXX,XX +XXX,XX @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
40
BdrvChildRole child_role,
41
Error **errp);
42
43
+/* TODO: Remove when no longer needed */
44
+static void bdrv_inherited_options(BdrvChildRole role, bool parent_is_format,
45
+ int *child_flags, QDict *child_options,
46
+ int parent_flags, QDict *parent_options);
47
+
48
/* If non-zero, use only whitelisted block drivers */
49
static int use_bdrv_whitelist;
50
51
@@ -XXX,XX +XXX,XX @@ static void bdrv_protocol_options(BdrvChildRole role, bool parent_is_format,
52
int *child_flags, QDict *child_options,
53
int parent_flags, QDict *parent_options)
54
{
55
- int flags = parent_flags;
56
-
57
- /* Enable protocol handling, disable format probing for bs->file */
58
- flags |= BDRV_O_PROTOCOL;
59
-
60
- /* If the cache mode isn't explicitly set, inherit direct and no-flush from
61
- * the parent. */
62
- qdict_copy_default(child_options, parent_options, BDRV_OPT_CACHE_DIRECT);
63
- qdict_copy_default(child_options, parent_options, BDRV_OPT_CACHE_NO_FLUSH);
64
- qdict_copy_default(child_options, parent_options, BDRV_OPT_FORCE_SHARE);
65
-
66
- /* Inherit the read-only option from the parent if it's not set */
67
- qdict_copy_default(child_options, parent_options, BDRV_OPT_READ_ONLY);
68
- qdict_copy_default(child_options, parent_options, BDRV_OPT_AUTO_READ_ONLY);
69
-
70
- /* Our block drivers take care to send flushes and respect unmap policy,
71
- * so we can default to enable both on lower layers regardless of the
72
- * corresponding parent options. */
73
- qdict_set_default_str(child_options, BDRV_OPT_DISCARD, "unmap");
74
-
75
- /* Clear flags that only apply to the top layer */
76
- flags &= ~(BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING | BDRV_O_COPY_ON_READ |
77
- BDRV_O_NO_IO);
78
-
79
- *child_flags = flags;
80
+ bdrv_inherited_options(BDRV_CHILD_IMAGE, true,
81
+ child_flags, child_options,
82
+ parent_flags, parent_options);
83
}
84
85
const BdrvChildClass child_file = {
86
@@ -XXX,XX +XXX,XX @@ static void bdrv_inherited_fmt_options(BdrvChildRole role,
87
int *child_flags, QDict *child_options,
88
int parent_flags, QDict *parent_options)
89
{
90
- child_file.inherit_options(role, parent_is_format,
91
- child_flags, child_options,
92
- parent_flags, parent_options);
93
-
94
- *child_flags &= ~(BDRV_O_PROTOCOL | BDRV_O_NO_IO);
95
+ bdrv_inherited_options(BDRV_CHILD_DATA, false,
96
+ child_flags, child_options,
97
+ parent_flags, parent_options);
98
}
99
100
const BdrvChildClass child_format = {
101
@@ -XXX,XX +XXX,XX @@ static void bdrv_backing_options(BdrvChildRole role, bool parent_is_format,
102
int *child_flags, QDict *child_options,
103
int parent_flags, QDict *parent_options)
104
{
105
- int flags = parent_flags;
106
-
107
- /* The cache mode is inherited unmodified for backing files; except WCE,
108
- * which is only applied on the top level (BlockBackend) */
109
- qdict_copy_default(child_options, parent_options, BDRV_OPT_CACHE_DIRECT);
110
- qdict_copy_default(child_options, parent_options, BDRV_OPT_CACHE_NO_FLUSH);
111
- qdict_copy_default(child_options, parent_options, BDRV_OPT_FORCE_SHARE);
112
-
113
- /* backing files always opened read-only */
114
- qdict_set_default_str(child_options, BDRV_OPT_READ_ONLY, "on");
115
- qdict_set_default_str(child_options, BDRV_OPT_AUTO_READ_ONLY, "off");
116
- flags &= ~BDRV_O_COPY_ON_READ;
117
-
118
- /* snapshot=on is handled on the top layer */
119
- flags &= ~(BDRV_O_SNAPSHOT | BDRV_O_TEMPORARY);
120
-
121
- *child_flags = flags;
122
+ bdrv_inherited_options(BDRV_CHILD_COW, true,
123
+ child_flags, child_options,
124
+ parent_flags, parent_options);
125
}
126
127
static int bdrv_backing_update_filename(BdrvChild *c, BlockDriverState *base,
128
@@ -XXX,XX +XXX,XX @@ const BdrvChildClass child_backing = {
129
* Returns the options and flags that a generic child of a BDS should
130
* get, based on the given options and flags for the parent BDS.
131
*/
132
-static void __attribute__((unused))
133
- bdrv_inherited_options(BdrvChildRole role, bool parent_is_format,
134
- int *child_flags, QDict *child_options,
135
- int parent_flags, QDict *parent_options)
136
+static void bdrv_inherited_options(BdrvChildRole role, bool parent_is_format,
137
+ int *child_flags, QDict *child_options,
138
+ int parent_flags, QDict *parent_options)
139
{
140
int flags = parent_flags;
141
142
@@ -XXX,XX +XXX,XX @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
143
flags, options);
144
/* Let bdrv_backing_options() override "read-only" */
145
qdict_del(options, BDRV_OPT_READ_ONLY);
146
- bdrv_backing_options(0, true, &flags, options, flags, options);
147
+ bdrv_inherited_options(BDRV_CHILD_COW, true,
148
+ &flags, options, flags, options);
149
}
150
151
bs->open_flags = flags;
152
--
153
2.25.4
154
155
diff view generated by jsdifflib
New patch
1
From: Max Reitz <mreitz@redhat.com>
1
2
3
Make bdrv_child_cb_attach() call bdrv_backing_attach() for children with
4
a COW role (and drop the reverse call from bdrv_backing_attach()), so it
5
can be used for any child (with a proper role set).
6
7
Because so far no child has a proper role set, we need a temporary new
8
callback for child_backing.attach that ensures bdrv_backing_attach() is
9
called for all COW children that do not have their role set yet.
10
11
(Also, move bdrv_child_cb_attach() down to group it with
12
bdrv_inherited_options().)
13
14
Signed-off-by: Max Reitz <mreitz@redhat.com>
15
Message-Id: <20200513110544.176672-13-mreitz@redhat.com>
16
Reviewed-by: Eric Blake <eblake@redhat.com>
17
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
18
---
19
block.c | 27 ++++++++++++++++++++-------
20
1 file changed, 20 insertions(+), 7 deletions(-)
21
22
diff --git a/block.c b/block.c
23
index XXXXXXX..XXXXXXX 100644
24
--- a/block.c
25
+++ b/block.c
26
@@ -XXX,XX +XXX,XX @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
27
static void bdrv_inherited_options(BdrvChildRole role, bool parent_is_format,
28
int *child_flags, QDict *child_options,
29
int parent_flags, QDict *parent_options);
30
+static void bdrv_child_cb_attach(BdrvChild *child);
31
32
/* If non-zero, use only whitelisted block drivers */
33
static int use_bdrv_whitelist;
34
@@ -XXX,XX +XXX,XX @@ static void bdrv_child_cb_drained_end(BdrvChild *child,
35
bdrv_drained_end_no_poll(bs, drained_end_counter);
36
}
37
38
-static void bdrv_child_cb_attach(BdrvChild *child)
39
-{
40
- BlockDriverState *bs = child->opaque;
41
- bdrv_apply_subtree_drain(child, bs);
42
-}
43
-
44
static void bdrv_child_cb_detach(BdrvChild *child)
45
{
46
BlockDriverState *bs = child->opaque;
47
@@ -XXX,XX +XXX,XX @@ static void bdrv_backing_attach(BdrvChild *c)
48
parent->backing_blocker);
49
bdrv_op_unblock(backing_hd, BLOCK_OP_TYPE_BACKUP_TARGET,
50
parent->backing_blocker);
51
+}
52
53
+/* XXX: Will be removed along with child_backing */
54
+static void bdrv_child_cb_attach_backing(BdrvChild *c)
55
+{
56
+ if (!(c->role & BDRV_CHILD_COW)) {
57
+ bdrv_backing_attach(c);
58
+ }
59
bdrv_child_cb_attach(c);
60
}
61
62
@@ -XXX,XX +XXX,XX @@ static int bdrv_backing_update_filename(BdrvChild *c, BlockDriverState *base,
63
const BdrvChildClass child_backing = {
64
.parent_is_bds = true,
65
.get_parent_desc = bdrv_child_get_parent_desc,
66
- .attach = bdrv_backing_attach,
67
+ .attach = bdrv_child_cb_attach_backing,
68
.detach = bdrv_backing_detach,
69
.inherit_options = bdrv_backing_options,
70
.drained_begin = bdrv_child_cb_drained_begin,
71
@@ -XXX,XX +XXX,XX @@ static void bdrv_inherited_options(BdrvChildRole role, bool parent_is_format,
72
*child_flags = flags;
73
}
74
75
+static void bdrv_child_cb_attach(BdrvChild *child)
76
+{
77
+ BlockDriverState *bs = child->opaque;
78
+
79
+ if (child->role & BDRV_CHILD_COW) {
80
+ bdrv_backing_attach(child);
81
+ }
82
+
83
+ bdrv_apply_subtree_drain(child, bs);
84
+}
85
+
86
static int bdrv_open_flags(BlockDriverState *bs, int flags)
87
{
88
int open_flags = flags;
89
--
90
2.25.4
91
92
diff view generated by jsdifflib
New patch
1
From: Max Reitz <mreitz@redhat.com>
1
2
3
Make bdrv_child_cb_detach() call bdrv_backing_detach() for children with
4
a COW role (and drop the reverse call from bdrv_backing_detach()), so it
5
can be used for any child (with a proper role set).
6
7
Because so far no child has a proper role set, we need a temporary new
8
callback for child_backing.detach that ensures bdrv_backing_detach() is
9
called for all COW children that do not have their role set yet.
10
11
(Also, move bdrv_child_cb_detach() down to group it with
12
bdrv_inherited_options() and bdrv_child_cb_attach().)
13
14
Signed-off-by: Max Reitz <mreitz@redhat.com>
15
Message-Id: <20200513110544.176672-14-mreitz@redhat.com>
16
Reviewed-by: Eric Blake <eblake@redhat.com>
17
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
18
---
19
block.c | 27 ++++++++++++++++++++-------
20
1 file changed, 20 insertions(+), 7 deletions(-)
21
22
diff --git a/block.c b/block.c
23
index XXXXXXX..XXXXXXX 100644
24
--- a/block.c
25
+++ b/block.c
26
@@ -XXX,XX +XXX,XX @@ static void bdrv_inherited_options(BdrvChildRole role, bool parent_is_format,
27
int *child_flags, QDict *child_options,
28
int parent_flags, QDict *parent_options);
29
static void bdrv_child_cb_attach(BdrvChild *child);
30
+static void bdrv_child_cb_detach(BdrvChild *child);
31
32
/* If non-zero, use only whitelisted block drivers */
33
static int use_bdrv_whitelist;
34
@@ -XXX,XX +XXX,XX @@ static void bdrv_child_cb_drained_end(BdrvChild *child,
35
bdrv_drained_end_no_poll(bs, drained_end_counter);
36
}
37
38
-static void bdrv_child_cb_detach(BdrvChild *child)
39
-{
40
- BlockDriverState *bs = child->opaque;
41
- bdrv_unapply_subtree_drain(child, bs);
42
-}
43
-
44
static int bdrv_child_cb_inactivate(BdrvChild *child)
45
{
46
BlockDriverState *bs = child->opaque;
47
@@ -XXX,XX +XXX,XX @@ static void bdrv_backing_detach(BdrvChild *c)
48
bdrv_op_unblock_all(c->bs, parent->backing_blocker);
49
error_free(parent->backing_blocker);
50
parent->backing_blocker = NULL;
51
+}
52
53
+/* XXX: Will be removed along with child_backing */
54
+static void bdrv_child_cb_detach_backing(BdrvChild *c)
55
+{
56
+ if (!(c->role & BDRV_CHILD_COW)) {
57
+ bdrv_backing_detach(c);
58
+ }
59
bdrv_child_cb_detach(c);
60
}
61
62
@@ -XXX,XX +XXX,XX @@ const BdrvChildClass child_backing = {
63
.parent_is_bds = true,
64
.get_parent_desc = bdrv_child_get_parent_desc,
65
.attach = bdrv_child_cb_attach_backing,
66
- .detach = bdrv_backing_detach,
67
+ .detach = bdrv_child_cb_detach_backing,
68
.inherit_options = bdrv_backing_options,
69
.drained_begin = bdrv_child_cb_drained_begin,
70
.drained_poll = bdrv_child_cb_drained_poll,
71
@@ -XXX,XX +XXX,XX @@ static void bdrv_child_cb_attach(BdrvChild *child)
72
bdrv_apply_subtree_drain(child, bs);
73
}
74
75
+static void bdrv_child_cb_detach(BdrvChild *child)
76
+{
77
+ BlockDriverState *bs = child->opaque;
78
+
79
+ if (child->role & BDRV_CHILD_COW) {
80
+ bdrv_backing_detach(child);
81
+ }
82
+
83
+ bdrv_unapply_subtree_drain(child, bs);
84
+}
85
+
86
static int bdrv_open_flags(BlockDriverState *bs, int flags)
87
{
88
int open_flags = flags;
89
--
90
2.25.4
91
92
diff view generated by jsdifflib
1
Eventually, we want to make sure that all parents and all children of a
1
From: Max Reitz <mreitz@redhat.com>
2
node are in the same AioContext as the node itself. This means that
3
changing the AioContext may fail because one of the other involved
4
parties (e.g. a guest device that was configured with an iothread)
5
cannot allow switching to a different AioContext.
6
2
7
Introduce a set of functions that allow to first check whether all
3
Any current user of child_file, child_format, and child_backing can and
8
involved nodes can switch to a new context and only then do the actual
4
should use this generic BdrvChildClass instead, as it can handle all of
9
switch. The check recursively covers children and parents.
5
these cases. However, to be able to do so, the users must pass the
6
appropriate BdrvChildRole when the child is created/attached. (The
7
following commits will take care of that.)
10
8
9
Signed-off-by: Max Reitz <mreitz@redhat.com>
10
Message-Id: <20200513110544.176672-15-mreitz@redhat.com>
11
Reviewed-by: Eric Blake <eblake@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
---
13
---
13
include/block/block.h | 8 ++++
14
include/block/block_int.h | 1 +
14
include/block/block_int.h | 3 ++
15
block.c | 24 ++++++++++++++++++++++++
15
block.c | 92 +++++++++++++++++++++++++++++++++++++++
16
2 files changed, 25 insertions(+)
16
3 files changed, 103 insertions(+)
17
17
18
diff --git a/include/block/block.h b/include/block/block.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/include/block/block.h
21
+++ b/include/block/block.h
22
@@ -XXX,XX +XXX,XX @@ void bdrv_coroutine_enter(BlockDriverState *bs, Coroutine *co);
23
* This function must be called with iothread lock held.
24
*/
25
void bdrv_set_aio_context(BlockDriverState *bs, AioContext *new_context);
26
+int bdrv_try_set_aio_context(BlockDriverState *bs, AioContext *ctx,
27
+ Error **errp);
28
+int bdrv_child_try_set_aio_context(BlockDriverState *bs, AioContext *ctx,
29
+ BdrvChild *ignore_child, Error **errp);
30
+bool bdrv_child_can_set_aio_context(BdrvChild *c, AioContext *ctx,
31
+ GSList **ignore, Error **errp);
32
+bool bdrv_can_set_aio_context(BlockDriverState *bs, AioContext *ctx,
33
+ GSList **ignore, Error **errp);
34
int bdrv_probe_blocksizes(BlockDriverState *bs, BlockSizes *bsz);
35
int bdrv_probe_geometry(BlockDriverState *bs, HDGeometry *geo);
36
37
diff --git a/include/block/block_int.h b/include/block/block_int.h
18
diff --git a/include/block/block_int.h b/include/block/block_int.h
38
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
39
--- a/include/block/block_int.h
20
--- a/include/block/block_int.h
40
+++ b/include/block/block_int.h
21
+++ b/include/block/block_int.h
41
@@ -XXX,XX +XXX,XX @@ struct BdrvChildRole {
22
@@ -XXX,XX +XXX,XX @@ struct BdrvChildClass {
42
* can update its reference. */
23
void (*set_aio_ctx)(BdrvChild *child, AioContext *ctx, GSList **ignore);
43
int (*update_filename)(BdrvChild *child, BlockDriverState *new_base,
44
const char *filename, Error **errp);
45
+
46
+ bool (*can_set_aio_ctx)(BdrvChild *child, AioContext *ctx,
47
+ GSList **ignore, Error **errp);
48
};
24
};
49
25
50
extern const BdrvChildRole child_file;
26
+extern const BdrvChildClass child_of_bds;
27
extern const BdrvChildClass child_file;
28
extern const BdrvChildClass child_format;
29
extern const BdrvChildClass child_backing;
51
diff --git a/block.c b/block.c
30
diff --git a/block.c b/block.c
52
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
53
--- a/block.c
32
--- a/block.c
54
+++ b/block.c
33
+++ b/block.c
55
@@ -XXX,XX +XXX,XX @@ static int bdrv_child_cb_inactivate(BdrvChild *child)
34
@@ -XXX,XX +XXX,XX @@ static void bdrv_child_cb_detach(BdrvChild *child)
56
return 0;
35
bdrv_unapply_subtree_drain(child, bs);
57
}
36
}
58
37
59
+static bool bdrv_child_cb_can_set_aio_ctx(BdrvChild *child, AioContext *ctx,
38
+static int bdrv_child_cb_update_filename(BdrvChild *c, BlockDriverState *base,
60
+ GSList **ignore, Error **errp)
39
+ const char *filename, Error **errp)
61
+{
40
+{
62
+ BlockDriverState *bs = child->opaque;
41
+ if (c->role & BDRV_CHILD_COW) {
63
+ return bdrv_can_set_aio_context(bs, ctx, ignore, errp);
42
+ return bdrv_backing_update_filename(c, base, filename, errp);
64
+}
65
+
66
/*
67
* Returns the options and flags that a temporary snapshot should get, based on
68
* the originally requested flags (the originally requested image will have
69
@@ -XXX,XX +XXX,XX @@ const BdrvChildRole child_file = {
70
.attach = bdrv_child_cb_attach,
71
.detach = bdrv_child_cb_detach,
72
.inactivate = bdrv_child_cb_inactivate,
73
+ .can_set_aio_ctx = bdrv_child_cb_can_set_aio_ctx,
74
};
75
76
/*
77
@@ -XXX,XX +XXX,XX @@ const BdrvChildRole child_format = {
78
.attach = bdrv_child_cb_attach,
79
.detach = bdrv_child_cb_detach,
80
.inactivate = bdrv_child_cb_inactivate,
81
+ .can_set_aio_ctx = bdrv_child_cb_can_set_aio_ctx,
82
};
83
84
static void bdrv_backing_attach(BdrvChild *c)
85
@@ -XXX,XX +XXX,XX @@ const BdrvChildRole child_backing = {
86
.drained_end = bdrv_child_cb_drained_end,
87
.inactivate = bdrv_child_cb_inactivate,
88
.update_filename = bdrv_backing_update_filename,
89
+ .can_set_aio_ctx = bdrv_child_cb_can_set_aio_ctx,
90
};
91
92
static int bdrv_open_flags(BlockDriverState *bs, int flags)
93
@@ -XXX,XX +XXX,XX @@ void bdrv_set_aio_context(BlockDriverState *bs, AioContext *new_context)
94
aio_context_release(new_context);
95
}
96
97
+static bool bdrv_parent_can_set_aio_context(BdrvChild *c, AioContext *ctx,
98
+ GSList **ignore, Error **errp)
99
+{
100
+ if (g_slist_find(*ignore, c)) {
101
+ return true;
102
+ }
43
+ }
103
+ *ignore = g_slist_prepend(*ignore, c);
104
+
105
+ /* A BdrvChildRole that doesn't handle AioContext changes cannot
106
+ * tolerate any AioContext changes */
107
+ if (!c->role->can_set_aio_ctx) {
108
+ char *user = bdrv_child_user_desc(c);
109
+ error_setg(errp, "Changing iothreads is not supported by %s", user);
110
+ g_free(user);
111
+ return false;
112
+ }
113
+ if (!c->role->can_set_aio_ctx(c, ctx, ignore, errp)) {
114
+ assert(!errp || *errp);
115
+ return false;
116
+ }
117
+ return true;
118
+}
119
+
120
+bool bdrv_child_can_set_aio_context(BdrvChild *c, AioContext *ctx,
121
+ GSList **ignore, Error **errp)
122
+{
123
+ if (g_slist_find(*ignore, c)) {
124
+ return true;
125
+ }
126
+ *ignore = g_slist_prepend(*ignore, c);
127
+ return bdrv_can_set_aio_context(c->bs, ctx, ignore, errp);
128
+}
129
+
130
+/* @ignore will accumulate all visited BdrvChild object. The caller is
131
+ * responsible for freeing the list afterwards. */
132
+bool bdrv_can_set_aio_context(BlockDriverState *bs, AioContext *ctx,
133
+ GSList **ignore, Error **errp)
134
+{
135
+ BdrvChild *c;
136
+
137
+ if (bdrv_get_aio_context(bs) == ctx) {
138
+ return true;
139
+ }
140
+
141
+ QLIST_FOREACH(c, &bs->parents, next_parent) {
142
+ if (!bdrv_parent_can_set_aio_context(c, ctx, ignore, errp)) {
143
+ return false;
144
+ }
145
+ }
146
+ QLIST_FOREACH(c, &bs->children, next) {
147
+ if (!bdrv_child_can_set_aio_context(c, ctx, ignore, errp)) {
148
+ return false;
149
+ }
150
+ }
151
+
152
+ return true;
153
+}
154
+
155
+int bdrv_child_try_set_aio_context(BlockDriverState *bs, AioContext *ctx,
156
+ BdrvChild *ignore_child, Error **errp)
157
+{
158
+ GSList *ignore;
159
+ bool ret;
160
+
161
+ ignore = ignore_child ? g_slist_prepend(NULL, ignore_child) : NULL;
162
+ ret = bdrv_can_set_aio_context(bs, ctx, &ignore, errp);
163
+ g_slist_free(ignore);
164
+
165
+ if (!ret) {
166
+ return -EPERM;
167
+ }
168
+
169
+ bdrv_set_aio_context(bs, ctx);
170
+ return 0;
44
+ return 0;
171
+}
45
+}
172
+
46
+
173
+int bdrv_try_set_aio_context(BlockDriverState *bs, AioContext *ctx,
47
+const BdrvChildClass child_of_bds = {
174
+ Error **errp)
48
+ .parent_is_bds = true,
175
+{
49
+ .get_parent_desc = bdrv_child_get_parent_desc,
176
+ return bdrv_child_try_set_aio_context(bs, ctx, NULL, errp);
50
+ .inherit_options = bdrv_inherited_options,
177
+}
51
+ .drained_begin = bdrv_child_cb_drained_begin,
52
+ .drained_poll = bdrv_child_cb_drained_poll,
53
+ .drained_end = bdrv_child_cb_drained_end,
54
+ .attach = bdrv_child_cb_attach,
55
+ .detach = bdrv_child_cb_detach,
56
+ .inactivate = bdrv_child_cb_inactivate,
57
+ .can_set_aio_ctx = bdrv_child_cb_can_set_aio_ctx,
58
+ .set_aio_ctx = bdrv_child_cb_set_aio_ctx,
59
+ .update_filename = bdrv_child_cb_update_filename,
60
+};
178
+
61
+
179
void bdrv_add_aio_context_notifier(BlockDriverState *bs,
62
static int bdrv_open_flags(BlockDriverState *bs, int flags)
180
void (*attached_aio_context)(AioContext *new_context, void *opaque),
63
{
181
void (*detach_aio_context)(void *opaque), void *opaque)
64
int open_flags = flags;
182
--
65
--
183
2.20.1
66
2.25.4
184
67
185
68
diff view generated by jsdifflib
1
From: Max Reitz <mreitz@redhat.com>
1
From: Max Reitz <mreitz@redhat.com>
2
2
3
Sometimes, 245 fails for me because some stream job has already finished
3
bdrv_format_default_perms() has one code path for backing files, and one
4
while the test expects it to still be active. (With -c none, it fails
4
for storage files. We want to pull them out into their own functions,
5
basically every time.) The most reliable way to fix this is to simply
5
so make sure they are completely distinct before so the next patches
6
set auto_finalize=false so the job will remain in the block graph as
6
will be a bit cleaner.
7
long as we need it. This allows us to drop the rate limiting, too,
8
which makes the test faster.
9
10
The only problem with this is that there is a single place that yields a
11
different error message depending on whether the stream job is still
12
copying data (so COR is enabled) or not (COR has been disabled, but the
13
job still has the WRITE_UNCHANGED permission on the target node). We
14
can easily address that by expecting either error message.
15
16
Note that we do not need auto_finalize=false (or rate limiting) for the
17
active commit job, because It never completes without an explicit
18
block-job-complete anyway.
19
7
20
Signed-off-by: Max Reitz <mreitz@redhat.com>
8
Signed-off-by: Max Reitz <mreitz@redhat.com>
21
Reviewed-by: Alberto Garcia <berto@igalia.com>
9
Reviewed-by: Eric Blake <eblake@redhat.com>
10
Message-Id: <20200513110544.176672-16-mreitz@redhat.com>
22
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
23
---
12
---
24
tests/qemu-iotests/245 | 22 ++++++++++++++--------
13
block.c | 19 +++++++++++++------
25
tests/qemu-iotests/245.out | 12 ++++++++++++
14
1 file changed, 13 insertions(+), 6 deletions(-)
26
2 files changed, 26 insertions(+), 8 deletions(-)
27
15
28
diff --git a/tests/qemu-iotests/245 b/tests/qemu-iotests/245
16
diff --git a/block.c b/block.c
29
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
30
--- a/tests/qemu-iotests/245
18
--- a/block.c
31
+++ b/tests/qemu-iotests/245
19
+++ b/block.c
32
@@ -XXX,XX +XXX,XX @@ class TestBlockdevReopen(iotests.QMPTestCase):
20
@@ -XXX,XX +XXX,XX @@ void bdrv_format_default_perms(BlockDriverState *bs, BdrvChild *c,
33
21
perm |= BLK_PERM_CONSISTENT_READ;
34
# hd2 <- hd0
22
}
35
result = self.vm.qmp('block-stream', conv_keys = True, job_id = 'stream0',
23
shared &= ~(BLK_PERM_WRITE | BLK_PERM_RESIZE);
36
- device = 'hd0', base_node = 'hd2', speed = 512 * 1024)
24
+
37
+ device = 'hd0', base_node = 'hd2',
25
+ if (bs->open_flags & BDRV_O_INACTIVE) {
38
+ auto_finalize = False)
26
+ shared |= BLK_PERM_WRITE | BLK_PERM_RESIZE;
39
self.assert_qmp(result, 'return', {})
27
+ }
40
28
+
41
# We can't remove hd2 while the stream job is ongoing
29
+ *nperm = perm;
42
@@ -XXX,XX +XXX,XX @@ class TestBlockdevReopen(iotests.QMPTestCase):
30
+ *nshared = shared;
43
opts['backing'] = None
31
} else {
44
self.reopen(opts, {}, "Cannot change 'backing' link from 'hd0' to 'hd1'")
32
/* We want consistent read from backing files if the parent needs it.
45
33
* No other operations are performed on backing files. */
46
- self.wait_until_completed(drive = 'stream0')
34
@@ -XXX,XX +XXX,XX @@ void bdrv_format_default_perms(BlockDriverState *bs, BdrvChild *c,
47
+ self.vm.run_job('stream0', auto_finalize = False, auto_dismiss = True)
35
48
36
shared |= BLK_PERM_CONSISTENT_READ | BLK_PERM_GRAPH_MOD |
49
# Reopen the chain during a block-stream job (from hd2 to hd1)
37
BLK_PERM_WRITE_UNCHANGED;
50
def test_block_stream_4(self):
38
- }
51
@@ -XXX,XX +XXX,XX @@ class TestBlockdevReopen(iotests.QMPTestCase):
39
52
40
- if (bs->open_flags & BDRV_O_INACTIVE) {
53
# hd1 <- hd0
41
- shared |= BLK_PERM_WRITE | BLK_PERM_RESIZE;
54
result = self.vm.qmp('block-stream', conv_keys = True, job_id = 'stream0',
42
- }
55
- device = 'hd1', speed = 512 * 1024)
43
+ if (bs->open_flags & BDRV_O_INACTIVE) {
56
+ device = 'hd1', auto_finalize = False)
44
+ shared |= BLK_PERM_WRITE | BLK_PERM_RESIZE;
57
self.assert_qmp(result, 'return', {})
45
+ }
58
46
59
# We can't reopen with the original options because that would
47
- *nperm = perm;
60
# make hd1 read-only and block-stream requires it to be read-write
48
- *nshared = shared;
61
- self.reopen(opts, {}, "Can't set node 'hd1' to r/o with copy-on-read enabled")
49
+ *nperm = perm;
62
+ # (Which error message appears depends on whether the stream job is
50
+ *nshared = shared;
63
+ # already done with copying at this point.)
51
+ }
64
+ self.reopen(opts, {},
52
}
65
+ ["Can't set node 'hd1' to r/o with copy-on-read enabled",
53
66
+ "Cannot make block node read-only, there is a writer on it"])
54
uint64_t bdrv_qapi_perm_to_blk_perm(BlockPermission qapi_perm)
67
68
# We can't remove hd2 while the stream job is ongoing
69
opts['backing']['backing'] = None
70
@@ -XXX,XX +XXX,XX @@ class TestBlockdevReopen(iotests.QMPTestCase):
71
opts['backing'] = None
72
self.reopen(opts)
73
74
- self.wait_until_completed(drive = 'stream0')
75
+ self.vm.run_job('stream0', auto_finalize = False, auto_dismiss = True)
76
77
# Reopen the chain during a block-commit job (from hd0 to hd2)
78
def test_block_commit_1(self):
79
@@ -XXX,XX +XXX,XX @@ class TestBlockdevReopen(iotests.QMPTestCase):
80
self.assert_qmp(result, 'return', {})
81
82
result = self.vm.qmp('block-commit', conv_keys = True, job_id = 'commit0',
83
- device = 'hd0', speed = 1024 * 1024)
84
+ device = 'hd0')
85
self.assert_qmp(result, 'return', {})
86
87
# We can't remove hd2 while the commit job is ongoing
88
@@ -XXX,XX +XXX,XX @@ class TestBlockdevReopen(iotests.QMPTestCase):
89
self.assert_qmp(result, 'return', {})
90
91
result = self.vm.qmp('block-commit', conv_keys = True, job_id = 'commit0',
92
- device = 'hd0', top_node = 'hd1', speed = 1024 * 1024)
93
+ device = 'hd0', top_node = 'hd1',
94
+ auto_finalize = False)
95
self.assert_qmp(result, 'return', {})
96
97
# We can't remove hd2 while the commit job is ongoing
98
@@ -XXX,XX +XXX,XX @@ class TestBlockdevReopen(iotests.QMPTestCase):
99
self.reopen(opts, {}, "Cannot change backing link if 'hd0' has an implicit backing file")
100
101
# hd2 <- hd0
102
- self.wait_until_completed(drive = 'commit0')
103
+ self.vm.run_job('commit0', auto_finalize = False, auto_dismiss = True)
104
105
self.assert_qmp(self.get_node('hd0'), 'ro', False)
106
self.assertEqual(self.get_node('hd1'), None)
107
diff --git a/tests/qemu-iotests/245.out b/tests/qemu-iotests/245.out
108
index XXXXXXX..XXXXXXX 100644
109
--- a/tests/qemu-iotests/245.out
110
+++ b/tests/qemu-iotests/245.out
111
@@ -XXX,XX +XXX,XX @@
112
Ran 18 tests
113
114
OK
115
+{"execute": "job-finalize", "arguments": {"id": "commit0"}}
116
+{"return": {}}
117
+{"data": {"id": "commit0", "type": "commit"}, "event": "BLOCK_JOB_PENDING", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
118
+{"data": {"device": "commit0", "len": 3145728, "offset": 3145728, "speed": 0, "type": "commit"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
119
+{"execute": "job-finalize", "arguments": {"id": "stream0"}}
120
+{"return": {}}
121
+{"data": {"id": "stream0", "type": "stream"}, "event": "BLOCK_JOB_PENDING", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
122
+{"data": {"device": "stream0", "len": 3145728, "offset": 3145728, "speed": 0, "type": "stream"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
123
+{"execute": "job-finalize", "arguments": {"id": "stream0"}}
124
+{"return": {}}
125
+{"data": {"id": "stream0", "type": "stream"}, "event": "BLOCK_JOB_PENDING", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
126
+{"data": {"device": "stream0", "len": 3145728, "offset": 3145728, "speed": 0, "type": "stream"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
127
--
55
--
128
2.20.1
56
2.25.4
129
57
130
58
diff view generated by jsdifflib
1
Instead of having two recursions, in bdrv_attach_aio_context() and in
1
From: Max Reitz <mreitz@redhat.com>
2
bdrv_detach_aio_context(), just having one recursion is enough. Said
3
functions are only about a single node now.
4
2
5
It is important that the recursion doesn't happen between detaching and
3
Right now, bdrv_format_default_perms() is used by format parents
6
attaching a context to the current node because the nested call will
4
(generally). We want to switch to a model where most parents use a
7
drain the node, and draining with a NULL context would segfault.
5
single BdrvChildClass, which then decides the permissions based on the
6
child role. To do so, we have to split bdrv_format_default_perms() into
7
separate functions for each such role.
8
8
9
Signed-off-by: Max Reitz <mreitz@redhat.com>
10
Message-Id: <20200513110544.176672-17-mreitz@redhat.com>
11
Reviewed-by: Eric Blake <eblake@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
13
---
11
block.c | 15 +++++++--------
14
block.c | 62 +++++++++++++++++++++++++++++++++++++--------------------
12
1 file changed, 7 insertions(+), 8 deletions(-)
15
1 file changed, 40 insertions(+), 22 deletions(-)
13
16
14
diff --git a/block.c b/block.c
17
diff --git a/block.c b/block.c
15
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
16
--- a/block.c
19
--- a/block.c
17
+++ b/block.c
20
+++ b/block.c
18
@@ -XXX,XX +XXX,XX @@ static void bdrv_do_remove_aio_context_notifier(BdrvAioNotifier *ban)
21
@@ -XXX,XX +XXX,XX @@ void bdrv_filter_default_perms(BlockDriverState *bs, BdrvChild *c,
19
static void bdrv_detach_aio_context(BlockDriverState *bs)
22
*nshared = (shared & DEFAULT_PERM_PASSTHROUGH) | DEFAULT_PERM_UNCHANGED;
20
{
23
}
21
BdrvAioNotifier *baf, *baf_tmp;
24
22
- BdrvChild *child;
25
+static void bdrv_default_perms_for_cow(BlockDriverState *bs, BdrvChild *c,
23
26
+ const BdrvChildClass *child_class,
24
assert(!bs->walking_aio_notifiers);
27
+ BdrvChildRole role,
25
bs->walking_aio_notifiers = true;
28
+ BlockReopenQueue *reopen_queue,
26
@@ -XXX,XX +XXX,XX @@ static void bdrv_detach_aio_context(BlockDriverState *bs)
29
+ uint64_t perm, uint64_t shared,
27
if (bs->drv && bs->drv->bdrv_detach_aio_context) {
30
+ uint64_t *nperm, uint64_t *nshared)
28
bs->drv->bdrv_detach_aio_context(bs);
31
+{
29
}
32
+ assert(child_class == &child_backing ||
30
- QLIST_FOREACH(child, &bs->children, next) {
33
+ (child_class == &child_of_bds && (role & BDRV_CHILD_COW)));
31
- bdrv_detach_aio_context(child->bs);
32
- }
33
34
if (bs->quiesce_counter) {
35
aio_enable_external(bs->aio_context);
36
@@ -XXX,XX +XXX,XX @@ static void bdrv_attach_aio_context(BlockDriverState *bs,
37
AioContext *new_context)
38
{
39
BdrvAioNotifier *ban, *ban_tmp;
40
- BdrvChild *child;
41
42
if (bs->quiesce_counter) {
43
aio_disable_external(new_context);
44
@@ -XXX,XX +XXX,XX @@ static void bdrv_attach_aio_context(BlockDriverState *bs,
45
46
bs->aio_context = new_context;
47
48
- QLIST_FOREACH(child, &bs->children, next) {
49
- bdrv_attach_aio_context(child->bs, new_context);
50
- }
51
if (bs->drv && bs->drv->bdrv_attach_aio_context) {
52
bs->drv->bdrv_attach_aio_context(bs, new_context);
53
}
54
@@ -XXX,XX +XXX,XX @@ static void bdrv_attach_aio_context(BlockDriverState *bs,
55
* the same as the current context of bs). */
56
void bdrv_set_aio_context(BlockDriverState *bs, AioContext *new_context)
57
{
58
+ BdrvChild *child;
59
+
34
+
60
if (bdrv_get_aio_context(bs) == new_context) {
35
+ /*
61
return;
36
+ * We want consistent read from backing files if the parent needs it.
62
}
37
+ * No other operations are performed on backing files.
63
38
+ */
64
bdrv_drained_begin(bs);
39
+ perm &= BLK_PERM_CONSISTENT_READ;
65
+
40
+
66
+ QLIST_FOREACH(child, &bs->children, next) {
41
+ /*
67
+ bdrv_set_aio_context(child->bs, new_context);
42
+ * If the parent can deal with changing data, we're okay with a
43
+ * writable and resizable backing file.
44
+ * TODO Require !(perm & BLK_PERM_CONSISTENT_READ), too?
45
+ */
46
+ if (shared & BLK_PERM_WRITE) {
47
+ shared = BLK_PERM_WRITE | BLK_PERM_RESIZE;
48
+ } else {
49
+ shared = 0;
68
+ }
50
+ }
69
+
51
+
70
bdrv_detach_aio_context(bs);
52
+ shared |= BLK_PERM_CONSISTENT_READ | BLK_PERM_GRAPH_MOD |
71
53
+ BLK_PERM_WRITE_UNCHANGED;
72
/* This function executes in the old AioContext so acquire the new one in
54
+
55
+ if (bs->open_flags & BDRV_O_INACTIVE) {
56
+ shared |= BLK_PERM_WRITE | BLK_PERM_RESIZE;
57
+ }
58
+
59
+ *nperm = perm;
60
+ *nshared = shared;
61
+}
62
+
63
void bdrv_format_default_perms(BlockDriverState *bs, BdrvChild *c,
64
const BdrvChildClass *child_class,
65
BdrvChildRole role,
66
@@ -XXX,XX +XXX,XX @@ void bdrv_format_default_perms(BlockDriverState *bs, BdrvChild *c,
67
*nperm = perm;
68
*nshared = shared;
69
} else {
70
- /* We want consistent read from backing files if the parent needs it.
71
- * No other operations are performed on backing files. */
72
- perm &= BLK_PERM_CONSISTENT_READ;
73
-
74
- /* If the parent can deal with changing data, we're okay with a
75
- * writable and resizable backing file. */
76
- /* TODO Require !(perm & BLK_PERM_CONSISTENT_READ), too? */
77
- if (shared & BLK_PERM_WRITE) {
78
- shared = BLK_PERM_WRITE | BLK_PERM_RESIZE;
79
- } else {
80
- shared = 0;
81
- }
82
-
83
- shared |= BLK_PERM_CONSISTENT_READ | BLK_PERM_GRAPH_MOD |
84
- BLK_PERM_WRITE_UNCHANGED;
85
-
86
- if (bs->open_flags & BDRV_O_INACTIVE) {
87
- shared |= BLK_PERM_WRITE | BLK_PERM_RESIZE;
88
- }
89
-
90
- *nperm = perm;
91
- *nshared = shared;
92
+ bdrv_default_perms_for_cow(bs, c, child_class, role, reopen_queue,
93
+ perm, shared, nperm, nshared);
94
}
95
}
96
73
--
97
--
74
2.20.1
98
2.25.4
75
99
76
100
diff view generated by jsdifflib
1
From: Max Reitz <mreitz@redhat.com>
1
From: Max Reitz <mreitz@redhat.com>
2
2
3
XFS_IOC_ZERO_RANGE does not increase the file length:
3
Right now, bdrv_format_default_perms() is used by format parents
4
$ touch foo
4
(generally). We want to switch to a model where most parents use a
5
$ xfs_io -c 'zero 0 65536' foo
5
single BdrvChildClass, which then decides the permissions based on the
6
$ stat -c "size=%s, blocks=%b" foo
6
child role. To do so, we have to split bdrv_format_default_perms() into
7
size=0, blocks=128
7
separate functions for each such role.
8
8
9
We do want writes beyond the EOF to automatically increase the file
9
Note that bdrv_default_perms_for_storage() currently handles all DATA |
10
length, however. This is evidenced by the fact that iotest 061 is
10
METADATA children. A follow-up patch is going to split it further into
11
broken on XFS since qcow2's check implementation checks for blocks
11
one function for each case.
12
beyond the EOF.
13
12
14
Reported-by: Kevin Wolf <kwolf@redhat.com>
15
Signed-off-by: Max Reitz <mreitz@redhat.com>
13
Signed-off-by: Max Reitz <mreitz@redhat.com>
14
Reviewed-by: Eric Blake <eblake@redhat.com>
15
Message-Id: <20200513110544.176672-18-mreitz@redhat.com>
16
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
16
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
17
---
17
---
18
block/file-posix.c | 13 +++++++++++++
18
block.c | 71 +++++++++++++++++++++++++++++++++++++--------------------
19
1 file changed, 13 insertions(+)
19
1 file changed, 46 insertions(+), 25 deletions(-)
20
20
21
diff --git a/block/file-posix.c b/block/file-posix.c
21
diff --git a/block.c b/block.c
22
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
23
--- a/block/file-posix.c
23
--- a/block.c
24
+++ b/block/file-posix.c
24
+++ b/block.c
25
@@ -XXX,XX +XXX,XX @@ out:
25
@@ -XXX,XX +XXX,XX @@ static void bdrv_default_perms_for_cow(BlockDriverState *bs, BdrvChild *c,
26
#ifdef CONFIG_XFS
26
*nshared = shared;
27
static int xfs_write_zeroes(BDRVRawState *s, int64_t offset, uint64_t bytes)
27
}
28
{
28
29
+ int64_t len;
29
+static void bdrv_default_perms_for_storage(BlockDriverState *bs, BdrvChild *c,
30
struct xfs_flock64 fl;
30
+ const BdrvChildClass *child_class,
31
int err;
31
+ BdrvChildRole role,
32
32
+ BlockReopenQueue *reopen_queue,
33
+ len = lseek(s->fd, 0, SEEK_END);
33
+ uint64_t perm, uint64_t shared,
34
+ if (len < 0) {
34
+ uint64_t *nperm, uint64_t *nshared)
35
+ return -errno;
35
+{
36
+ int flags;
37
+
38
+ assert(child_class == &child_file ||
39
+ (child_class == &child_of_bds &&
40
+ (role & (BDRV_CHILD_METADATA | BDRV_CHILD_DATA))));
41
+
42
+ flags = bdrv_reopen_get_flags(reopen_queue, bs);
43
+
44
+ /*
45
+ * Apart from the modifications below, the same permissions are
46
+ * forwarded and left alone as for filters
47
+ */
48
+ bdrv_filter_default_perms(bs, c, child_class, role, reopen_queue,
49
+ perm, shared, &perm, &shared);
50
+
51
+ /* Format drivers may touch metadata even if the guest doesn't write */
52
+ if (bdrv_is_writable_after_reopen(bs, reopen_queue)) {
53
+ perm |= BLK_PERM_WRITE | BLK_PERM_RESIZE;
36
+ }
54
+ }
37
+
55
+
38
+ if (offset + bytes > len) {
56
+ /*
39
+ /* XFS_IOC_ZERO_RANGE does not increase the file length */
57
+ * bs->file always needs to be consistent because of the metadata. We
40
+ if (ftruncate(s->fd, offset + bytes) < 0) {
58
+ * can never allow other users to resize or write to it.
41
+ return -errno;
59
+ */
42
+ }
60
+ if (!(flags & BDRV_O_NO_IO)) {
61
+ perm |= BLK_PERM_CONSISTENT_READ;
62
+ }
63
+ shared &= ~(BLK_PERM_WRITE | BLK_PERM_RESIZE);
64
+
65
+ if (bs->open_flags & BDRV_O_INACTIVE) {
66
+ shared |= BLK_PERM_WRITE | BLK_PERM_RESIZE;
43
+ }
67
+ }
44
+
68
+
45
memset(&fl, 0, sizeof(fl));
69
+ *nperm = perm;
46
fl.l_whence = SEEK_SET;
70
+ *nshared = shared;
47
fl.l_start = offset;
71
+}
72
+
73
void bdrv_format_default_perms(BlockDriverState *bs, BdrvChild *c,
74
const BdrvChildClass *child_class,
75
BdrvChildRole role,
76
@@ -XXX,XX +XXX,XX @@ void bdrv_format_default_perms(BlockDriverState *bs, BdrvChild *c,
77
assert(child_class == &child_backing || child_class == &child_file);
78
79
if (!backing) {
80
- int flags = bdrv_reopen_get_flags(reopen_queue, bs);
81
-
82
- /* Apart from the modifications below, the same permissions are
83
- * forwarded and left alone as for filters */
84
- bdrv_filter_default_perms(bs, c, child_class, role, reopen_queue,
85
- perm, shared, &perm, &shared);
86
-
87
- /* Format drivers may touch metadata even if the guest doesn't write */
88
- if (bdrv_is_writable_after_reopen(bs, reopen_queue)) {
89
- perm |= BLK_PERM_WRITE | BLK_PERM_RESIZE;
90
- }
91
-
92
- /* bs->file always needs to be consistent because of the metadata. We
93
- * can never allow other users to resize or write to it. */
94
- if (!(flags & BDRV_O_NO_IO)) {
95
- perm |= BLK_PERM_CONSISTENT_READ;
96
- }
97
- shared &= ~(BLK_PERM_WRITE | BLK_PERM_RESIZE);
98
-
99
- if (bs->open_flags & BDRV_O_INACTIVE) {
100
- shared |= BLK_PERM_WRITE | BLK_PERM_RESIZE;
101
- }
102
-
103
- *nperm = perm;
104
- *nshared = shared;
105
+ bdrv_default_perms_for_storage(bs, c, child_class, role, reopen_queue,
106
+ perm, shared, nperm, nshared);
107
} else {
108
bdrv_default_perms_for_cow(bs, c, child_class, role, reopen_queue,
109
perm, shared, nperm, nshared);
48
--
110
--
49
2.20.1
111
2.25.4
50
112
51
113
diff view generated by jsdifflib
1
From: Max Reitz <mreitz@redhat.com>
1
From: Max Reitz <mreitz@redhat.com>
2
2
3
This message does not make any sense when it appears as the response to
3
We can be less restrictive about pure data children than those with
4
making an R/W node read-only. We should detect that case and emit a
4
metadata on them, so let bdrv_default_perms_for_storage() handle
5
different message, then.
5
metadata children differently from pure data children.
6
7
As explained in the code, the restrictions on metadata children are
8
strictly stricter than those for pure data children, so in theory we
9
just have to distinguish between pure-data and all other storage
10
children (pure metadata or data+metadata). In practice, that is not
11
obvious, though, so we have two independent code paths for metadata and
12
for data children, and data+metadata children will go through both
13
(without the path for data children doing anything meaningful).
6
14
7
Signed-off-by: Max Reitz <mreitz@redhat.com>
15
Signed-off-by: Max Reitz <mreitz@redhat.com>
8
Reviewed-by: Alberto Garcia <berto@igalia.com>
16
Message-Id: <20200513110544.176672-19-mreitz@redhat.com>
17
Reviewed-by: Eric Blake <eblake@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
18
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
19
---
11
block.c | 17 ++++++++++++++++-
20
block.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++----------
12
1 file changed, 16 insertions(+), 1 deletion(-)
21
1 file changed, 48 insertions(+), 10 deletions(-)
13
22
14
diff --git a/block.c b/block.c
23
diff --git a/block.c b/block.c
15
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
16
--- a/block.c
25
--- a/block.c
17
+++ b/block.c
26
+++ b/block.c
18
@@ -XXX,XX +XXX,XX @@ static int bdrv_child_check_perm(BdrvChild *c, BlockReopenQueue *q,
27
@@ -XXX,XX +XXX,XX @@ static void bdrv_default_perms_for_storage(BlockDriverState *bs, BdrvChild *c,
19
GSList *ignore_children, Error **errp);
28
bdrv_filter_default_perms(bs, c, child_class, role, reopen_queue,
20
static void bdrv_child_abort_perm_update(BdrvChild *c);
29
perm, shared, &perm, &shared);
21
static void bdrv_child_set_perm(BdrvChild *c, uint64_t perm, uint64_t shared);
30
22
+static void bdrv_get_cumulative_perm(BlockDriverState *bs, uint64_t *perm,
31
- /* Format drivers may touch metadata even if the guest doesn't write */
23
+ uint64_t *shared_perm);
32
- if (bdrv_is_writable_after_reopen(bs, reopen_queue)) {
24
33
- perm |= BLK_PERM_WRITE | BLK_PERM_RESIZE;
25
typedef struct BlockReopenQueueEntry {
34
+ if (role & BDRV_CHILD_METADATA) {
26
bool prepared;
35
+ /* Format drivers may touch metadata even if the guest doesn't write */
27
@@ -XXX,XX +XXX,XX @@ static int bdrv_check_perm(BlockDriverState *bs, BlockReopenQueue *q,
36
+ if (bdrv_is_writable_after_reopen(bs, reopen_queue)) {
28
if ((cumulative_perms & (BLK_PERM_WRITE | BLK_PERM_WRITE_UNCHANGED)) &&
37
+ perm |= BLK_PERM_WRITE | BLK_PERM_RESIZE;
29
!bdrv_is_writable_after_reopen(bs, q))
30
{
31
- error_setg(errp, "Block node is read-only");
32
+ if (!bdrv_is_writable_after_reopen(bs, NULL)) {
33
+ error_setg(errp, "Block node is read-only");
34
+ } else {
35
+ uint64_t current_perms, current_shared;
36
+ bdrv_get_cumulative_perm(bs, &current_perms, &current_shared);
37
+ if (current_perms & (BLK_PERM_WRITE | BLK_PERM_WRITE_UNCHANGED)) {
38
+ error_setg(errp, "Cannot make block node read-only, there is "
39
+ "a writer on it");
40
+ } else {
41
+ error_setg(errp, "Cannot make block node read-only and create "
42
+ "a writer on it");
43
+ }
44
+ }
38
+ }
45
+
39
+
46
return -EPERM;
40
+ /*
41
+ * bs->file always needs to be consistent because of the
42
+ * metadata. We can never allow other users to resize or write
43
+ * to it.
44
+ */
45
+ if (!(flags & BDRV_O_NO_IO)) {
46
+ perm |= BLK_PERM_CONSISTENT_READ;
47
+ }
48
+ shared &= ~(BLK_PERM_WRITE | BLK_PERM_RESIZE);
47
}
49
}
48
50
51
- /*
52
- * bs->file always needs to be consistent because of the metadata. We
53
- * can never allow other users to resize or write to it.
54
- */
55
- if (!(flags & BDRV_O_NO_IO)) {
56
- perm |= BLK_PERM_CONSISTENT_READ;
57
+ if (role & BDRV_CHILD_DATA) {
58
+ /*
59
+ * Technically, everything in this block is a subset of the
60
+ * BDRV_CHILD_METADATA path taken above, and so this could
61
+ * be an "else if" branch. However, that is not obvious, and
62
+ * this function is not performance critical, therefore we let
63
+ * this be an independent "if".
64
+ */
65
+
66
+ /*
67
+ * We cannot allow other users to resize the file because the
68
+ * format driver might have some assumptions about the size
69
+ * (e.g. because it is stored in metadata, or because the file
70
+ * is split into fixed-size data files).
71
+ */
72
+ shared &= ~BLK_PERM_RESIZE;
73
+
74
+ /*
75
+ * WRITE_UNCHANGED often cannot be performed as such on the
76
+ * data file. For example, the qcow2 driver may still need to
77
+ * write copied clusters on copy-on-read.
78
+ */
79
+ if (perm & BLK_PERM_WRITE_UNCHANGED) {
80
+ perm |= BLK_PERM_WRITE;
81
+ }
82
+
83
+ /*
84
+ * If the data file is written to, the format driver may
85
+ * expect to be able to resize it by writing beyond the EOF.
86
+ */
87
+ if (perm & BLK_PERM_WRITE) {
88
+ perm |= BLK_PERM_RESIZE;
89
+ }
90
}
91
- shared &= ~(BLK_PERM_WRITE | BLK_PERM_RESIZE);
92
93
if (bs->open_flags & BDRV_O_INACTIVE) {
94
shared |= BLK_PERM_WRITE | BLK_PERM_RESIZE;
49
--
95
--
50
2.20.1
96
2.25.4
51
97
52
98
diff view generated by jsdifflib
1
From: Max Reitz <mreitz@redhat.com>
2
3
This callback can be used by BDSs that use child_of_bds with the
4
appropriate BdrvChildRole for their children.
5
6
Also, make bdrv_format_default_perms() use it for child_of_bds children
7
(just a temporary solution until we can drop bdrv_format_default_perms()
8
altogether).
9
10
Signed-off-by: Max Reitz <mreitz@redhat.com>
11
Message-Id: <20200513110544.176672-20-mreitz@redhat.com>
12
Reviewed-by: Eric Blake <eblake@redhat.com>
1
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2
---
14
---
3
tests/test-block-iothread.c | 71 +++++++++++++++++++++++++++++++++++++
15
include/block/block_int.h | 11 +++++++++++
4
1 file changed, 71 insertions(+)
16
block.c | 32 ++++++++++++++++++++++++++++++++
17
2 files changed, 43 insertions(+)
5
18
6
diff --git a/tests/test-block-iothread.c b/tests/test-block-iothread.c
19
diff --git a/include/block/block_int.h b/include/block/block_int.h
7
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
8
--- a/tests/test-block-iothread.c
21
--- a/include/block/block_int.h
9
+++ b/tests/test-block-iothread.c
22
+++ b/include/block/block_int.h
10
@@ -XXX,XX +XXX,XX @@ static void test_propagate_diamond(void)
23
@@ -XXX,XX +XXX,XX @@ void bdrv_format_default_perms(BlockDriverState *bs, BdrvChild *c,
11
bdrv_unref(bs_a);
24
bool bdrv_recurse_can_replace(BlockDriverState *bs,
25
BlockDriverState *to_replace);
26
27
+/*
28
+ * Default implementation for BlockDriver.bdrv_child_perm() that can
29
+ * be used by block filters and image formats, as long as they use the
30
+ * child_of_bds child class and set an appropriate BdrvChildRole.
31
+ */
32
+void bdrv_default_perms(BlockDriverState *bs, BdrvChild *c,
33
+ const BdrvChildClass *child_class, BdrvChildRole role,
34
+ BlockReopenQueue *reopen_queue,
35
+ uint64_t perm, uint64_t shared,
36
+ uint64_t *nperm, uint64_t *nshared);
37
+
38
/*
39
* Default implementation for drivers to pass bdrv_co_block_status() to
40
* their file.
41
diff --git a/block.c b/block.c
42
index XXXXXXX..XXXXXXX 100644
43
--- a/block.c
44
+++ b/block.c
45
@@ -XXX,XX +XXX,XX @@ void bdrv_format_default_perms(BlockDriverState *bs, BdrvChild *c,
46
uint64_t *nperm, uint64_t *nshared)
47
{
48
bool backing = (child_class == &child_backing);
49
+
50
+ if (child_class == &child_of_bds) {
51
+ bdrv_default_perms(bs, c, child_class, role, reopen_queue,
52
+ perm, shared, nperm, nshared);
53
+ return;
54
+ }
55
+
56
assert(child_class == &child_backing || child_class == &child_file);
57
58
if (!backing) {
59
@@ -XXX,XX +XXX,XX @@ void bdrv_format_default_perms(BlockDriverState *bs, BdrvChild *c,
60
}
12
}
61
}
13
62
14
+static void test_propagate_mirror(void)
63
+void bdrv_default_perms(BlockDriverState *bs, BdrvChild *c,
64
+ const BdrvChildClass *child_class, BdrvChildRole role,
65
+ BlockReopenQueue *reopen_queue,
66
+ uint64_t perm, uint64_t shared,
67
+ uint64_t *nperm, uint64_t *nshared)
15
+{
68
+{
16
+ IOThread *iothread = iothread_new();
69
+ assert(child_class == &child_of_bds);
17
+ AioContext *ctx = iothread_get_aio_context(iothread);
18
+ AioContext *main_ctx = qemu_get_aio_context();
19
+ BlockDriverState *src, *target;
20
+ BlockBackend *blk;
21
+ Job *job;
22
+ Error *local_err = NULL;
23
+
70
+
24
+ /* Create src and target*/
71
+ if (role & BDRV_CHILD_FILTERED) {
25
+ src = bdrv_new_open_driver(&bdrv_test, "src", BDRV_O_RDWR, &error_abort);
72
+ assert(!(role & (BDRV_CHILD_DATA | BDRV_CHILD_METADATA |
26
+ target = bdrv_new_open_driver(&bdrv_test, "target", BDRV_O_RDWR,
73
+ BDRV_CHILD_COW)));
27
+ &error_abort);
74
+ bdrv_filter_default_perms(bs, c, child_class, role, reopen_queue,
28
+
75
+ perm, shared, nperm, nshared);
29
+ /* Start a mirror job */
76
+ } else if (role & BDRV_CHILD_COW) {
30
+ mirror_start("job0", src, target, NULL, JOB_DEFAULT, 0, 0, 0,
77
+ assert(!(role & (BDRV_CHILD_DATA | BDRV_CHILD_METADATA)));
31
+ MIRROR_SYNC_MODE_NONE, MIRROR_OPEN_BACKING_CHAIN,
78
+ bdrv_default_perms_for_cow(bs, c, child_class, role, reopen_queue,
32
+ BLOCKDEV_ON_ERROR_REPORT, BLOCKDEV_ON_ERROR_REPORT,
79
+ perm, shared, nperm, nshared);
33
+ false, "filter_node", MIRROR_COPY_MODE_BACKGROUND,
80
+ } else if (role & (BDRV_CHILD_METADATA | BDRV_CHILD_DATA)) {
34
+ &error_abort);
81
+ bdrv_default_perms_for_storage(bs, c, child_class, role, reopen_queue,
35
+ job = job_get("job0");
82
+ perm, shared, nperm, nshared);
36
+
83
+ } else {
37
+ /* Change the AioContext of src */
84
+ g_assert_not_reached();
38
+ bdrv_try_set_aio_context(src, ctx, &error_abort);
85
+ }
39
+ g_assert(bdrv_get_aio_context(src) == ctx);
40
+ g_assert(bdrv_get_aio_context(target) == ctx);
41
+ g_assert(job->aio_context == ctx);
42
+
43
+ /* Change the AioContext of target */
44
+ aio_context_acquire(ctx);
45
+ bdrv_try_set_aio_context(target, main_ctx, &error_abort);
46
+ aio_context_release(ctx);
47
+ g_assert(bdrv_get_aio_context(src) == main_ctx);
48
+ g_assert(bdrv_get_aio_context(target) == main_ctx);
49
+
50
+ /* With a BlockBackend on src, changing target must fail */
51
+ blk = blk_new(0, BLK_PERM_ALL);
52
+ blk_insert_bs(blk, src, &error_abort);
53
+
54
+ bdrv_try_set_aio_context(target, ctx, &local_err);
55
+ g_assert(local_err);
56
+ error_free(local_err);
57
+
58
+ g_assert(blk_get_aio_context(blk) == main_ctx);
59
+ g_assert(bdrv_get_aio_context(src) == main_ctx);
60
+ g_assert(bdrv_get_aio_context(target) == main_ctx);
61
+
62
+ /* ...unless we explicitly allow it */
63
+ aio_context_acquire(ctx);
64
+ blk_set_allow_aio_context_change(blk, true);
65
+ bdrv_try_set_aio_context(target, ctx, &error_abort);
66
+ aio_context_release(ctx);
67
+
68
+ g_assert(blk_get_aio_context(blk) == ctx);
69
+ g_assert(bdrv_get_aio_context(src) == ctx);
70
+ g_assert(bdrv_get_aio_context(target) == ctx);
71
+
72
+ job_cancel_sync_all();
73
+
74
+ aio_context_acquire(ctx);
75
+ blk_set_aio_context(blk, main_ctx);
76
+ bdrv_try_set_aio_context(target, main_ctx, &error_abort);
77
+ aio_context_release(ctx);
78
+
79
+ blk_unref(blk);
80
+ bdrv_unref(src);
81
+ bdrv_unref(target);
82
+}
86
+}
83
+
87
+
84
int main(int argc, char **argv)
88
uint64_t bdrv_qapi_perm_to_blk_perm(BlockPermission qapi_perm)
85
{
89
{
86
int i;
90
static const uint64_t permissions[] = {
87
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv)
88
g_test_add_func("/attach/blockjob", test_attach_blockjob);
89
g_test_add_func("/propagate/basic", test_propagate_basic);
90
g_test_add_func("/propagate/diamond", test_propagate_diamond);
91
+ g_test_add_func("/propagate/mirror", test_propagate_mirror);
92
93
return g_test_run();
94
}
95
--
91
--
96
2.20.1
92
2.25.4
97
93
98
94
diff view generated by jsdifflib
1
From: Max Reitz <mreitz@redhat.com>
1
From: Max Reitz <mreitz@redhat.com>
2
2
3
Currently, qemu crashes whenever someone queries the block status of an
3
Split raw_read_options() into one function that actually just reads the
4
unaligned image tail of an O_DIRECT image:
4
options, and another that applies them. This will allow us to detect
5
$ echo > foo
5
whether the user has specified any options before attaching the file
6
$ qemu-img map --image-opts driver=file,filename=foo,cache.direct=on
6
child (so we can decide on its role based on the options).
7
Offset Length Mapped to File
8
qemu-img: block/io.c:2093: bdrv_co_block_status: Assertion `*pnum &&
9
QEMU_IS_ALIGNED(*pnum, align) && align > offset - aligned_offset'
10
failed.
11
7
12
This is because bdrv_co_block_status() checks that the result returned
13
by the driver's implementation is aligned to the request_alignment, but
14
file-posix can fail to do so, which is actually mentioned in a comment
15
there: "[...] possibly including a partial sector at EOF".
16
17
Fix this by rounding up those partial sectors.
18
19
There are two possible alternative fixes:
20
(1) We could refuse to open unaligned image files with O_DIRECT
21
altogether. That sounds reasonable until you realize that qcow2
22
does necessarily not fill up its metadata clusters, and that nobody
23
runs qemu-img create with O_DIRECT. Therefore, unpreallocated qcow2
24
files usually have an unaligned image tail.
25
26
(2) bdrv_co_block_status() could ignore unaligned tails. It actually
27
throws away everything past the EOF already, so that sounds
28
reasonable.
29
Unfortunately, the block layer knows file lengths only with a
30
granularity of BDRV_SECTOR_SIZE, so bdrv_co_block_status() usually
31
would have to guess whether its file length information is inexact
32
or whether the driver is broken.
33
34
Fixing what raw_co_block_status() returns is the safest thing to do.
35
36
There seems to be no other block driver that sets request_alignment and
37
does not make sure that it always returns aligned values.
38
39
Cc: qemu-stable@nongnu.org
40
Signed-off-by: Max Reitz <mreitz@redhat.com>
8
Signed-off-by: Max Reitz <mreitz@redhat.com>
41
Reviewed-by: Eric Blake <eblake@redhat.com>
9
Reviewed-by: Eric Blake <eblake@redhat.com>
10
Message-Id: <20200513110544.176672-21-mreitz@redhat.com>
42
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
43
---
12
---
44
block/file-posix.c | 16 ++++++++++++++++
13
block/raw-format.c | 110 ++++++++++++++++++++++++++-------------------
45
1 file changed, 16 insertions(+)
14
1 file changed, 65 insertions(+), 45 deletions(-)
46
15
47
diff --git a/block/file-posix.c b/block/file-posix.c
16
diff --git a/block/raw-format.c b/block/raw-format.c
48
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
49
--- a/block/file-posix.c
18
--- a/block/raw-format.c
50
+++ b/block/file-posix.c
19
+++ b/block/raw-format.c
51
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn raw_co_block_status(BlockDriverState *bs,
20
@@ -XXX,XX +XXX,XX @@ static QemuOptsList raw_create_opts = {
52
off_t data = 0, hole = 0;
21
}
22
};
23
24
-static int raw_read_options(QDict *options, BlockDriverState *bs,
25
- BDRVRawState *s, Error **errp)
26
+static int raw_read_options(QDict *options, uint64_t *offset, bool *has_size,
27
+ uint64_t *size, Error **errp)
28
{
29
Error *local_err = NULL;
30
QemuOpts *opts = NULL;
31
- int64_t real_size = 0;
53
int ret;
32
int ret;
54
33
55
+ assert(QEMU_IS_ALIGNED(offset | bytes, bs->bl.request_alignment));
34
- real_size = bdrv_getlength(bs->file->bs);
35
- if (real_size < 0) {
36
- error_setg_errno(errp, -real_size, "Could not get image size");
37
- return real_size;
38
- }
39
-
40
opts = qemu_opts_create(&raw_runtime_opts, NULL, 0, &error_abort);
41
qemu_opts_absorb_qdict(opts, options, &local_err);
42
if (local_err) {
43
@@ -XXX,XX +XXX,XX @@ static int raw_read_options(QDict *options, BlockDriverState *bs,
44
goto end;
45
}
46
47
- s->offset = qemu_opt_get_size(opts, "offset", 0);
48
- if (s->offset > real_size) {
49
- error_setg(errp, "Offset (%" PRIu64 ") cannot be greater than "
50
- "size of the containing file (%" PRId64 ")",
51
- s->offset, real_size);
52
- ret = -EINVAL;
53
- goto end;
54
- }
55
+ *offset = qemu_opt_get_size(opts, "offset", 0);
56
+ *has_size = qemu_opt_find(opts, "size");
57
+ *size = qemu_opt_get_size(opts, "size", 0);
58
59
- if (qemu_opt_find(opts, "size") != NULL) {
60
- s->size = qemu_opt_get_size(opts, "size", 0);
61
- s->has_size = true;
62
- } else {
63
- s->has_size = false;
64
- s->size = real_size - s->offset;
65
+ ret = 0;
66
+end:
67
+ qemu_opts_del(opts);
68
+ return ret;
69
+}
56
+
70
+
57
ret = fd_open(bs);
71
+static int raw_apply_options(BlockDriverState *bs, BDRVRawState *s,
72
+ uint64_t offset, bool has_size, uint64_t size,
73
+ Error **errp)
74
+{
75
+ int64_t real_size = 0;
76
+
77
+ real_size = bdrv_getlength(bs->file->bs);
78
+ if (real_size < 0) {
79
+ error_setg_errno(errp, -real_size, "Could not get image size");
80
+ return real_size;
81
}
82
83
/* Check size and offset */
84
- if ((real_size - s->offset) < s->size) {
85
+ if (offset > real_size) {
86
+ error_setg(errp, "Offset (%" PRIu64 ") cannot be greater than "
87
+ "size of the containing file (%" PRId64 ")",
88
+ s->offset, real_size);
89
+ return -EINVAL;
90
+ }
91
+
92
+ if (has_size && (real_size - offset) < size) {
93
error_setg(errp, "The sum of offset (%" PRIu64 ") and size "
94
- "(%" PRIu64 ") has to be smaller or equal to the "
95
- " actual size of the containing file (%" PRId64 ")",
96
- s->offset, s->size, real_size);
97
- ret = -EINVAL;
98
- goto end;
99
+ "(%" PRIu64 ") has to be smaller or equal to the "
100
+ " actual size of the containing file (%" PRId64 ")",
101
+ s->offset, s->size, real_size);
102
+ return -EINVAL;
103
}
104
105
/* Make sure size is multiple of BDRV_SECTOR_SIZE to prevent rounding
106
* up and leaking out of the specified area. */
107
- if (s->has_size && !QEMU_IS_ALIGNED(s->size, BDRV_SECTOR_SIZE)) {
108
+ if (has_size && !QEMU_IS_ALIGNED(size, BDRV_SECTOR_SIZE)) {
109
error_setg(errp, "Specified size is not multiple of %llu",
110
- BDRV_SECTOR_SIZE);
111
- ret = -EINVAL;
112
- goto end;
113
+ BDRV_SECTOR_SIZE);
114
+ return -EINVAL;
115
}
116
117
- ret = 0;
118
-
119
-end:
120
+ s->offset = offset;
121
+ s->has_size = has_size;
122
+ s->size = has_size ? size : real_size - offset;
123
124
- qemu_opts_del(opts);
125
-
126
- return ret;
127
+ return 0;
128
}
129
130
static int raw_reopen_prepare(BDRVReopenState *reopen_state,
131
BlockReopenQueue *queue, Error **errp)
132
{
133
+ bool has_size;
134
+ uint64_t offset, size;
135
+ int ret;
136
+
137
assert(reopen_state != NULL);
138
assert(reopen_state->bs != NULL);
139
140
reopen_state->opaque = g_new0(BDRVRawState, 1);
141
142
- return raw_read_options(
143
- reopen_state->options,
144
- reopen_state->bs,
145
- reopen_state->opaque,
146
- errp);
147
+ ret = raw_read_options(reopen_state->options, &offset, &has_size, &size,
148
+ errp);
149
+ if (ret < 0) {
150
+ return ret;
151
+ }
152
+
153
+ ret = raw_apply_options(reopen_state->bs, reopen_state->opaque,
154
+ offset, has_size, size, errp);
155
+ if (ret < 0) {
156
+ return ret;
157
+ }
158
+
159
+ return 0;
160
}
161
162
static void raw_reopen_commit(BDRVReopenState *state)
163
@@ -XXX,XX +XXX,XX @@ static int raw_open(BlockDriverState *bs, QDict *options, int flags,
164
Error **errp)
165
{
166
BDRVRawState *s = bs->opaque;
167
+ bool has_size;
168
+ uint64_t offset, size;
169
int ret;
170
171
+ ret = raw_read_options(options, &offset, &has_size, &size, errp);
172
+ if (ret < 0) {
173
+ return ret;
174
+ }
175
+
176
bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file, 0,
177
false, errp);
178
if (!bs->file) {
179
@@ -XXX,XX +XXX,XX @@ static int raw_open(BlockDriverState *bs, QDict *options, int flags,
180
bs->file->bs->filename);
181
}
182
183
- ret = raw_read_options(options, bs, s, errp);
184
+ ret = raw_apply_options(bs, s, offset, has_size, size, errp);
58
if (ret < 0) {
185
if (ret < 0) {
59
return ret;
186
return ret;
60
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn raw_co_block_status(BlockDriverState *bs,
187
}
61
/* On a data extent, compute bytes to the end of the extent,
62
* possibly including a partial sector at EOF. */
63
*pnum = MIN(bytes, hole - offset);
64
+
65
+ /*
66
+ * We are not allowed to return partial sectors, though, so
67
+ * round up if necessary.
68
+ */
69
+ if (!QEMU_IS_ALIGNED(*pnum, bs->bl.request_alignment)) {
70
+ int64_t file_length = raw_getlength(bs);
71
+ if (file_length > 0) {
72
+ /* Ignore errors, this is just a safeguard */
73
+ assert(hole == file_length);
74
+ }
75
+ *pnum = ROUND_UP(*pnum, bs->bl.request_alignment);
76
+ }
77
+
78
ret = BDRV_BLOCK_DATA;
79
} else {
80
/* On a hole, compute bytes to the beginning of the next extent. */
81
--
188
--
82
2.20.1
189
2.25.4
83
190
84
191
diff view generated by jsdifflib
1
From: Max Reitz <mreitz@redhat.com>
1
From: Max Reitz <mreitz@redhat.com>
2
2
3
Ideally, it should be self-explanatory. However, keys like "disk size"
3
Both users (quorum and blkverify) use child_format for
4
arguably really are not self-explanatory. In any case, there is no harm
4
not-really-filtered children, so the appropriate BdrvChildRole in both
5
in going into a some more detail here.
5
cases is DATA. (Note that this will cause bdrv_inherited_options() to
6
force-allow format probing.)
6
7
7
Signed-off-by: Max Reitz <mreitz@redhat.com>
8
Signed-off-by: Max Reitz <mreitz@redhat.com>
9
Reviewed-by: Eric Blake <eblake@redhat.com>
10
Message-Id: <20200513110544.176672-22-mreitz@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
---
12
---
10
qemu-img.texi | 41 +++++++++++++++++++++++++++++++++++++++++
13
block/blkverify.c | 4 ++--
11
1 file changed, 41 insertions(+)
14
block/quorum.c | 6 ++++--
15
2 files changed, 6 insertions(+), 4 deletions(-)
12
16
13
diff --git a/qemu-img.texi b/qemu-img.texi
17
diff --git a/block/blkverify.c b/block/blkverify.c
14
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
15
--- a/qemu-img.texi
19
--- a/block/blkverify.c
16
+++ b/qemu-img.texi
20
+++ b/block/blkverify.c
17
@@ -XXX,XX +XXX,XX @@ The command can output in the format @var{ofmt} which is either @code{human} or
21
@@ -XXX,XX +XXX,XX @@ static int blkverify_open(BlockDriverState *bs, QDict *options, int flags,
18
@code{json}. The JSON output is an object of QAPI type @code{ImageInfo}; with
22
19
@code{--backing-chain}, it is an array of @code{ImageInfo} objects.
23
/* Open the test file */
20
24
s->test_file = bdrv_open_child(qemu_opt_get(opts, "x-image"), options,
21
+@code{--output=human} reports the following information (for every image in the
25
- "test", bs, &child_format, 0, false,
22
+chain):
26
- &local_err);
23
+@table @var
27
+ "test", bs, &child_of_bds, BDRV_CHILD_DATA,
24
+@item image
28
+ false, &local_err);
25
+The image file name
29
if (local_err) {
26
+
30
ret = -EINVAL;
27
+@item file format
31
error_propagate(errp, local_err);
28
+The image format
32
diff --git a/block/quorum.c b/block/quorum.c
29
+
33
index XXXXXXX..XXXXXXX 100644
30
+@item virtual size
34
--- a/block/quorum.c
31
+The size of the guest disk
35
+++ b/block/quorum.c
32
+
36
@@ -XXX,XX +XXX,XX @@ static int quorum_open(BlockDriverState *bs, QDict *options, int flags,
33
+@item disk size
37
assert(ret < 32);
34
+How much space the image file occupies on the host file system (may be shown as
38
35
+0 if this information is unavailable, e.g. because there is no file system)
39
s->children[i] = bdrv_open_child(NULL, options, indexstr, bs,
36
+
40
- &child_format, 0, false, &local_err);
37
+@item cluster_size
41
+ &child_of_bds, BDRV_CHILD_DATA, false,
38
+Cluster size of the image format, if applicable
42
+ &local_err);
39
+
43
if (local_err) {
40
+@item encrypted
44
ret = -EINVAL;
41
+Whether the image is encrypted (only present if so)
45
goto close_exit;
42
+
46
@@ -XXX,XX +XXX,XX @@ static void quorum_add_child(BlockDriverState *bs, BlockDriverState *child_bs,
43
+@item cleanly shut down
47
/* We can safely add the child now */
44
+This is shown as @code{no} if the image is dirty and will have to be
48
bdrv_ref(child_bs);
45
+auto-repaired the next time it is opened in qemu.
49
46
+
50
- child = bdrv_attach_child(bs, child_bs, indexstr, &child_format, 0, errp);
47
+@item backing file
51
+ child = bdrv_attach_child(bs, child_bs, indexstr, &child_of_bds,
48
+The backing file name, if present
52
+ BDRV_CHILD_DATA, errp);
49
+
53
if (child == NULL) {
50
+@item backing file format
54
s->next_child_index--;
51
+The format of the backing file, if the image enforces it
55
goto out;
52
+
53
+@item Snapshot list
54
+A list of all internal snapshots
55
+
56
+@item Format specific information
57
+Further information whose structure depends on the image format. This section
58
+is a textual representation of the respective @code{ImageInfoSpecific*} QAPI
59
+object (e.g. @code{ImageInfoSpecificQCow2} for qcow2 images).
60
+@end table
61
+
62
@item map [--object @var{objectdef}] [--image-opts] [-f @var{fmt}] [--output=@var{ofmt}] [-U] @var{filename}
63
64
Dump the metadata of image @var{filename} and its backing file chain.
65
--
56
--
66
2.20.1
57
2.25.4
67
58
68
59
diff view generated by jsdifflib
New patch
1
From: Max Reitz <mreitz@redhat.com>
1
2
3
Signed-off-by: Max Reitz <mreitz@redhat.com>
4
Reviewed-by: Eric Blake <eblake@redhat.com>
5
Message-Id: <20200513110544.176672-23-mreitz@redhat.com>
6
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
7
---
8
include/block/block_int.h | 1 -
9
block.c | 29 -----------------------------
10
2 files changed, 30 deletions(-)
11
12
diff --git a/include/block/block_int.h b/include/block/block_int.h
13
index XXXXXXX..XXXXXXX 100644
14
--- a/include/block/block_int.h
15
+++ b/include/block/block_int.h
16
@@ -XXX,XX +XXX,XX @@ struct BdrvChildClass {
17
18
extern const BdrvChildClass child_of_bds;
19
extern const BdrvChildClass child_file;
20
-extern const BdrvChildClass child_format;
21
extern const BdrvChildClass child_backing;
22
23
struct BdrvChild {
24
diff --git a/block.c b/block.c
25
index XXXXXXX..XXXXXXX 100644
26
--- a/block.c
27
+++ b/block.c
28
@@ -XXX,XX +XXX,XX @@ const BdrvChildClass child_file = {
29
.set_aio_ctx = bdrv_child_cb_set_aio_ctx,
30
};
31
32
-/*
33
- * Returns the options and flags that bs->file should get if the use of formats
34
- * (and not only protocols) is permitted for it, based on the given options and
35
- * flags for the parent BDS
36
- */
37
-static void bdrv_inherited_fmt_options(BdrvChildRole role,
38
- bool parent_is_format,
39
- int *child_flags, QDict *child_options,
40
- int parent_flags, QDict *parent_options)
41
-{
42
- bdrv_inherited_options(BDRV_CHILD_DATA, false,
43
- child_flags, child_options,
44
- parent_flags, parent_options);
45
-}
46
-
47
-const BdrvChildClass child_format = {
48
- .parent_is_bds = true,
49
- .get_parent_desc = bdrv_child_get_parent_desc,
50
- .inherit_options = bdrv_inherited_fmt_options,
51
- .drained_begin = bdrv_child_cb_drained_begin,
52
- .drained_poll = bdrv_child_cb_drained_poll,
53
- .drained_end = bdrv_child_cb_drained_end,
54
- .attach = bdrv_child_cb_attach,
55
- .detach = bdrv_child_cb_detach,
56
- .inactivate = bdrv_child_cb_inactivate,
57
- .can_set_aio_ctx = bdrv_child_cb_can_set_aio_ctx,
58
- .set_aio_ctx = bdrv_child_cb_set_aio_ctx,
59
-};
60
-
61
static void bdrv_backing_attach(BdrvChild *c)
62
{
63
BlockDriverState *parent = c->opaque;
64
--
65
2.25.4
66
67
diff view generated by jsdifflib
1
From: Max Reitz <mreitz@redhat.com>
2
3
Make all parents of backing files pass the appropriate BdrvChildRole.
4
By doing so, we can switch their BdrvChildClass over to the generic
5
child_of_bds, which will do the right thing when given a correct
6
BdrvChildRole.
7
8
Signed-off-by: Max Reitz <mreitz@redhat.com>
9
Message-Id: <20200513110544.176672-24-mreitz@redhat.com>
10
Reviewed-by: Eric Blake <eblake@redhat.com>
1
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2
---
12
---
3
tests/test-block-iothread.c | 131 ++++++++++++++++++++++++++++++++++++
13
block.c | 26 ++++++++++++++++++++------
4
1 file changed, 131 insertions(+)
14
block/backup-top.c | 2 +-
15
block/vvfat.c | 3 ++-
16
tests/test-bdrv-drain.c | 13 +++++++------
17
4 files changed, 30 insertions(+), 14 deletions(-)
5
18
6
diff --git a/tests/test-block-iothread.c b/tests/test-block-iothread.c
19
diff --git a/block.c b/block.c
7
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
8
--- a/tests/test-block-iothread.c
21
--- a/block.c
9
+++ b/tests/test-block-iothread.c
22
+++ b/block.c
10
@@ -XXX,XX +XXX,XX @@
23
@@ -XXX,XX +XXX,XX @@ static bool bdrv_inherits_from_recursive(BlockDriverState *child,
11
#include "block/blockjob_int.h"
24
return child != NULL;
12
#include "sysemu/block-backend.h"
13
#include "qapi/error.h"
14
+#include "qapi/qmp/qdict.h"
15
#include "iothread.h"
16
17
static int coroutine_fn bdrv_test_co_prwv(BlockDriverState *bs,
18
@@ -XXX,XX +XXX,XX @@ static void test_attach_blockjob(void)
19
blk_unref(blk);
20
}
25
}
21
26
22
+/*
27
+/*
23
+ * Test that changing the AioContext for one node in a tree (here through blk)
28
+ * Return the BdrvChildRole for @bs's backing child. bs->backing is
24
+ * changes all other nodes as well:
29
+ * mostly used for COW backing children (role = COW), but also for
25
+ *
30
+ * filtered children (role = FILTERED | PRIMARY).
26
+ * blk
27
+ * |
28
+ * | bs_verify [blkverify]
29
+ * | / \
30
+ * | / \
31
+ * bs_a [bdrv_test] bs_b [bdrv_test]
32
+ *
33
+ */
31
+ */
34
+static void test_propagate_basic(void)
32
+static BdrvChildRole bdrv_backing_role(BlockDriverState *bs)
35
+{
33
+{
36
+ IOThread *iothread = iothread_new();
34
+ if (bs->drv && bs->drv->is_filter) {
37
+ AioContext *ctx = iothread_get_aio_context(iothread);
35
+ return BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY;
38
+ BlockBackend *blk;
36
+ } else {
39
+ BlockDriverState *bs_a, *bs_b, *bs_verify;
37
+ return BDRV_CHILD_COW;
40
+ QDict *options;
38
+ }
41
+
42
+ /* Create bs_a and its BlockBackend */
43
+ blk = blk_new(BLK_PERM_ALL, BLK_PERM_ALL);
44
+ bs_a = bdrv_new_open_driver(&bdrv_test, "bs_a", BDRV_O_RDWR, &error_abort);
45
+ blk_insert_bs(blk, bs_a, &error_abort);
46
+
47
+ /* Create bs_b */
48
+ bs_b = bdrv_new_open_driver(&bdrv_test, "bs_b", BDRV_O_RDWR, &error_abort);
49
+
50
+ /* Create blkverify filter that references both bs_a and bs_b */
51
+ options = qdict_new();
52
+ qdict_put_str(options, "driver", "blkverify");
53
+ qdict_put_str(options, "test", "bs_a");
54
+ qdict_put_str(options, "raw", "bs_b");
55
+
56
+ bs_verify = bdrv_open(NULL, NULL, options, BDRV_O_RDWR, &error_abort);
57
+
58
+ /* Switch the AioContext */
59
+ blk_set_aio_context(blk, ctx);
60
+ g_assert(blk_get_aio_context(blk) == ctx);
61
+ g_assert(bdrv_get_aio_context(bs_a) == ctx);
62
+ g_assert(bdrv_get_aio_context(bs_verify) == ctx);
63
+ g_assert(bdrv_get_aio_context(bs_b) == ctx);
64
+
65
+ /* Switch the AioContext back */
66
+ ctx = qemu_get_aio_context();
67
+ blk_set_aio_context(blk, ctx);
68
+ g_assert(blk_get_aio_context(blk) == ctx);
69
+ g_assert(bdrv_get_aio_context(bs_a) == ctx);
70
+ g_assert(bdrv_get_aio_context(bs_verify) == ctx);
71
+ g_assert(bdrv_get_aio_context(bs_b) == ctx);
72
+
73
+ bdrv_unref(bs_verify);
74
+ bdrv_unref(bs_b);
75
+ bdrv_unref(bs_a);
76
+ blk_unref(blk);
77
+}
39
+}
78
+
40
+
79
+/*
41
/*
80
+ * Test that diamonds in the graph don't lead to endless recursion:
42
* Sets the backing file link of a BDS. A new reference is created; callers
81
+ *
43
* which don't need their own reference any more must call bdrv_unref().
82
+ * blk
44
@@ -XXX,XX +XXX,XX @@ void bdrv_set_backing_hd(BlockDriverState *bs, BlockDriverState *backing_hd,
83
+ * |
45
goto out;
84
+ * bs_verify [blkverify]
46
}
85
+ * / \
47
86
+ * / \
48
- bs->backing = bdrv_attach_child(bs, backing_hd, "backing", &child_backing,
87
+ * bs_b [raw] bs_c[raw]
49
- 0, errp);
88
+ * \ /
50
+ bs->backing = bdrv_attach_child(bs, backing_hd, "backing", &child_of_bds,
89
+ * \ /
51
+ bdrv_backing_role(bs), errp);
90
+ * bs_a [bdrv_test]
52
/* If backing_hd was already part of bs's backing chain, and
91
+ */
53
* inherits_from pointed recursively to bs then let's update it to
92
+static void test_propagate_diamond(void)
54
* point directly to bs (else it will become NULL). */
93
+{
55
@@ -XXX,XX +XXX,XX @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *parent_options,
94
+ IOThread *iothread = iothread_new();
56
}
95
+ AioContext *ctx = iothread_get_aio_context(iothread);
57
96
+ BlockBackend *blk;
58
backing_hd = bdrv_open_inherit(backing_filename, reference, options, 0, bs,
97
+ BlockDriverState *bs_a, *bs_b, *bs_c, *bs_verify;
59
- &child_backing, 0, errp);
98
+ QDict *options;
60
+ &child_of_bds, bdrv_backing_role(bs), errp);
99
+
61
if (!backing_hd) {
100
+ /* Create bs_a */
62
bs->open_flags |= BDRV_O_NO_BACKING;
101
+ bs_a = bdrv_new_open_driver(&bdrv_test, "bs_a", BDRV_O_RDWR, &error_abort);
63
error_prepend(errp, "Could not open backing file: ");
102
+
64
@@ -XXX,XX +XXX,XX @@ int bdrv_reopen_multiple(BlockReopenQueue *bs_queue, Error **errp)
103
+ /* Create bs_b and bc_c */
65
if (state->replace_backing_bs && state->new_backing_bs) {
104
+ options = qdict_new();
66
uint64_t nperm, nshared;
105
+ qdict_put_str(options, "driver", "raw");
67
bdrv_child_perm(state->bs, state->new_backing_bs,
106
+ qdict_put_str(options, "file", "bs_a");
68
- NULL, &child_backing, 0, bs_queue,
107
+ qdict_put_str(options, "node-name", "bs_b");
69
- state->perm, state->shared_perm,
108
+ bs_b = bdrv_open(NULL, NULL, options, BDRV_O_RDWR, &error_abort);
70
+ NULL, &child_of_bds, bdrv_backing_role(state->bs),
109
+
71
+ bs_queue, state->perm, state->shared_perm,
110
+ options = qdict_new();
72
&nperm, &nshared);
111
+ qdict_put_str(options, "driver", "raw");
73
ret = bdrv_check_update_perm(state->new_backing_bs, NULL,
112
+ qdict_put_str(options, "file", "bs_a");
74
nperm, nshared, NULL, NULL, errp);
113
+ qdict_put_str(options, "node-name", "bs_c");
75
@@ -XXX,XX +XXX,XX @@ void bdrv_refresh_filename(BlockDriverState *bs)
114
+ bs_c = bdrv_open(NULL, NULL, options, BDRV_O_RDWR, &error_abort);
76
drv->bdrv_gather_child_options(bs, opts, backing_overridden);
115
+
77
} else {
116
+ /* Create blkverify filter that references both bs_b and bs_c */
78
QLIST_FOREACH(child, &bs->children, next) {
117
+ options = qdict_new();
79
- if (child->klass == &child_backing && !backing_overridden) {
118
+ qdict_put_str(options, "driver", "blkverify");
80
+ if (child == bs->backing && !backing_overridden) {
119
+ qdict_put_str(options, "test", "bs_b");
81
/* We can skip the backing BDS if it has not been overridden */
120
+ qdict_put_str(options, "raw", "bs_c");
82
continue;
121
+
83
}
122
+ bs_verify = bdrv_open(NULL, NULL, options, BDRV_O_RDWR, &error_abort);
84
diff --git a/block/backup-top.c b/block/backup-top.c
123
+ blk = blk_new(BLK_PERM_ALL, BLK_PERM_ALL);
85
index XXXXXXX..XXXXXXX 100644
124
+ blk_insert_bs(blk, bs_verify, &error_abort);
86
--- a/block/backup-top.c
125
+
87
+++ b/block/backup-top.c
126
+ /* Switch the AioContext */
88
@@ -XXX,XX +XXX,XX @@ static void backup_top_child_perm(BlockDriverState *bs, BdrvChild *c,
127
+ blk_set_aio_context(blk, ctx);
89
return;
128
+ g_assert(blk_get_aio_context(blk) == ctx);
90
}
129
+ g_assert(bdrv_get_aio_context(bs_verify) == ctx);
91
130
+ g_assert(bdrv_get_aio_context(bs_a) == ctx);
92
- if (child_class == &child_file) {
131
+ g_assert(bdrv_get_aio_context(bs_b) == ctx);
93
+ if (!(role & BDRV_CHILD_FILTERED)) {
132
+ g_assert(bdrv_get_aio_context(bs_c) == ctx);
94
/*
133
+
95
* Target child
134
+ /* Switch the AioContext back */
96
*
135
+ ctx = qemu_get_aio_context();
97
diff --git a/block/vvfat.c b/block/vvfat.c
136
+ blk_set_aio_context(blk, ctx);
98
index XXXXXXX..XXXXXXX 100644
137
+ g_assert(blk_get_aio_context(blk) == ctx);
99
--- a/block/vvfat.c
138
+ g_assert(bdrv_get_aio_context(bs_verify) == ctx);
100
+++ b/block/vvfat.c
139
+ g_assert(bdrv_get_aio_context(bs_a) == ctx);
101
@@ -XXX,XX +XXX,XX @@ static void vvfat_child_perm(BlockDriverState *bs, BdrvChild *c,
140
+ g_assert(bdrv_get_aio_context(bs_b) == ctx);
141
+ g_assert(bdrv_get_aio_context(bs_c) == ctx);
142
+
143
+ blk_unref(blk);
144
+ bdrv_unref(bs_verify);
145
+ bdrv_unref(bs_c);
146
+ bdrv_unref(bs_b);
147
+ bdrv_unref(bs_a);
148
+}
149
+
150
int main(int argc, char **argv)
151
{
102
{
103
BDRVVVFATState *s = bs->opaque;
104
105
- assert(c == s->qcow || child_class == &child_backing);
106
+ assert(c == s->qcow ||
107
+ (child_class == &child_of_bds && (role & BDRV_CHILD_COW)));
108
109
if (c == s->qcow) {
110
/* This is a private node, nobody should try to attach to it */
111
diff --git a/tests/test-bdrv-drain.c b/tests/test-bdrv-drain.c
112
index XXXXXXX..XXXXXXX 100644
113
--- a/tests/test-bdrv-drain.c
114
+++ b/tests/test-bdrv-drain.c
115
@@ -XXX,XX +XXX,XX @@ static void bdrv_test_child_perm(BlockDriverState *bs, BdrvChild *c,
116
* bdrv_format_default_perms() accepts only these two, so disguise
117
* detach_by_driver_cb_parent as one of them.
118
*/
119
- if (child_class != &child_file && child_class != &child_backing) {
120
+ if (child_class != &child_file && child_class != &child_of_bds) {
121
child_class = &child_file;
122
}
123
124
@@ -XXX,XX +XXX,XX @@ static void test_detach_indirect(bool by_parent_cb)
125
bdrv_ref(a);
126
child_b = bdrv_attach_child(parent_b, b, "PB-B", &child_file, 0,
127
&error_abort);
128
- child_a = bdrv_attach_child(parent_b, a, "PB-A", &child_backing, 0,
129
- &error_abort);
130
+ child_a = bdrv_attach_child(parent_b, a, "PB-A", &child_of_bds,
131
+ BDRV_CHILD_COW, &error_abort);
132
133
bdrv_ref(a);
134
bdrv_attach_child(parent_a, a, "PA-A",
135
@@ -XXX,XX +XXX,XX @@ static void test_drop_intermediate_poll(void)
152
int i;
136
int i;
153
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv)
137
int ret;
138
139
- chain_child_class = child_backing;
140
+ chain_child_class = child_of_bds;
141
chain_child_class.update_filename = drop_intermediate_poll_update_filename;
142
143
for (i = 0; i < 3; i++) {
144
@@ -XXX,XX +XXX,XX @@ static void test_drop_intermediate_poll(void)
145
/* Takes the reference to chain[i - 1] */
146
chain[i]->backing = bdrv_attach_child(chain[i], chain[i - 1],
147
"chain", &chain_child_class,
148
- 0, &error_abort);
149
+ BDRV_CHILD_COW, &error_abort);
150
}
154
}
151
}
155
152
156
g_test_add_func("/attach/blockjob", test_attach_blockjob);
153
@@ -XXX,XX +XXX,XX @@ static void do_test_replace_child_mid_drain(int old_drain_count,
157
+ g_test_add_func("/propagate/basic", test_propagate_basic);
154
158
+ g_test_add_func("/propagate/diamond", test_propagate_diamond);
155
bdrv_ref(old_child_bs);
159
156
parent_bs->backing = bdrv_attach_child(parent_bs, old_child_bs, "child",
160
return g_test_run();
157
- &child_backing, 0, &error_abort);
161
}
158
+ &child_of_bds, BDRV_CHILD_COW,
159
+ &error_abort);
160
161
for (i = 0; i < old_drain_count; i++) {
162
bdrv_drained_begin(old_child_bs);
162
--
163
--
163
2.20.1
164
2.25.4
164
165
165
166
diff view generated by jsdifflib
1
The notifiers made sure that the job is quiesced and that the
1
From: Max Reitz <mreitz@redhat.com>
2
job->aio_context field is updated. The first part is unnecessary today
3
since bdrv_set_aio_context_ignore() drains the block node, and this
4
means drainig the block job, too. The second part can be done in the
5
.set_aio_ctx callback of the block job BdrvChildRole.
6
2
7
The notifiers were problematic because they poll the AioContext while
3
Signed-off-by: Max Reitz <mreitz@redhat.com>
8
the graph is in an inconsistent state with some nodes already in the new
4
Message-Id: <20200513110544.176672-25-mreitz@redhat.com>
9
context, but others still in the old context. So removing the notifiers
5
Reviewed-by: Eric Blake <eblake@redhat.com>
10
not only simplifies the code, but actually makes the code safer.
11
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
---
7
---
14
blockjob.c | 43 ++-----------------------------------------
8
include/block/block_int.h | 1 -
15
1 file changed, 2 insertions(+), 41 deletions(-)
9
block.c | 60 ++-------------------------------------
10
2 files changed, 3 insertions(+), 58 deletions(-)
16
11
17
diff --git a/blockjob.c b/blockjob.c
12
diff --git a/include/block/block_int.h b/include/block/block_int.h
18
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
19
--- a/blockjob.c
14
--- a/include/block/block_int.h
20
+++ b/blockjob.c
15
+++ b/include/block/block_int.h
21
@@ -XXX,XX +XXX,XX @@ BlockJob *block_job_get(const char *id)
16
@@ -XXX,XX +XXX,XX @@ struct BdrvChildClass {
22
}
17
18
extern const BdrvChildClass child_of_bds;
19
extern const BdrvChildClass child_file;
20
-extern const BdrvChildClass child_backing;
21
22
struct BdrvChild {
23
BlockDriverState *bs;
24
diff --git a/block.c b/block.c
25
index XXXXXXX..XXXXXXX 100644
26
--- a/block.c
27
+++ b/block.c
28
@@ -XXX,XX +XXX,XX @@ static void bdrv_backing_attach(BdrvChild *c)
29
parent->backing_blocker);
23
}
30
}
24
31
25
-static void block_job_attached_aio_context(AioContext *new_context,
32
-/* XXX: Will be removed along with child_backing */
26
- void *opaque);
33
-static void bdrv_child_cb_attach_backing(BdrvChild *c)
27
-static void block_job_detach_aio_context(void *opaque);
28
-
29
void block_job_free(Job *job)
30
{
31
BlockJob *bjob = container_of(job, BlockJob, job);
32
@@ -XXX,XX +XXX,XX @@ void block_job_free(Job *job)
33
34
bs->job = NULL;
35
block_job_remove_all_bdrv(bjob);
36
- blk_remove_aio_context_notifier(bjob->blk,
37
- block_job_attached_aio_context,
38
- block_job_detach_aio_context, bjob);
39
blk_unref(bjob->blk);
40
error_free(bjob->blocker);
41
}
42
43
-static void block_job_attached_aio_context(AioContext *new_context,
44
- void *opaque)
45
-{
34
-{
46
- BlockJob *job = opaque;
35
- if (!(c->role & BDRV_CHILD_COW)) {
47
- const JobDriver *drv = job->job.driver;
36
- bdrv_backing_attach(c);
48
- BlockJobDriver *bjdrv = container_of(drv, BlockJobDriver, job_driver);
49
-
50
- job->job.aio_context = new_context;
51
- if (bjdrv->attached_aio_context) {
52
- bjdrv->attached_aio_context(job, new_context);
53
- }
37
- }
54
-
38
- bdrv_child_cb_attach(c);
55
- job_resume(&job->job);
56
-}
39
-}
57
-
40
-
58
void block_job_drain(Job *job)
41
static void bdrv_backing_detach(BdrvChild *c)
59
{
42
{
60
BlockJob *bjob = container_of(job, BlockJob, job);
43
BlockDriverState *parent = c->opaque;
61
@@ -XXX,XX +XXX,XX @@ void block_job_drain(Job *job)
44
@@ -XXX,XX +XXX,XX @@ static void bdrv_backing_detach(BdrvChild *c)
62
}
45
parent->backing_blocker = NULL;
63
}
46
}
64
47
65
-static void block_job_detach_aio_context(void *opaque)
48
-/* XXX: Will be removed along with child_backing */
49
-static void bdrv_child_cb_detach_backing(BdrvChild *c)
66
-{
50
-{
67
- BlockJob *job = opaque;
51
- if (!(c->role & BDRV_CHILD_COW)) {
68
-
52
- bdrv_backing_detach(c);
69
- /* In case the job terminates during aio_poll()... */
70
- job_ref(&job->job);
71
-
72
- job_pause(&job->job);
73
-
74
- while (!job->job.paused && !job_is_completed(&job->job)) {
75
- job_drain(&job->job);
76
- }
53
- }
77
-
54
- bdrv_child_cb_detach(c);
78
- job->job.aio_context = NULL;
79
- job_unref(&job->job);
80
-}
55
-}
81
-
56
-
82
static char *child_job_get_parent_desc(BdrvChild *c)
57
-/*
58
- * Returns the options and flags that bs->backing should get, based on the
59
- * given options and flags for the parent BDS
60
- */
61
-static void bdrv_backing_options(BdrvChildRole role, bool parent_is_format,
62
- int *child_flags, QDict *child_options,
63
- int parent_flags, QDict *parent_options)
64
-{
65
- bdrv_inherited_options(BDRV_CHILD_COW, true,
66
- child_flags, child_options,
67
- parent_flags, parent_options);
68
-}
69
-
70
static int bdrv_backing_update_filename(BdrvChild *c, BlockDriverState *base,
71
const char *filename, Error **errp)
83
{
72
{
84
BlockJob *job = c->opaque;
73
@@ -XXX,XX +XXX,XX @@ static int bdrv_backing_update_filename(BdrvChild *c, BlockDriverState *base,
85
@@ -XXX,XX +XXX,XX @@ static void child_job_set_aio_ctx(BdrvChild *c, AioContext *ctx,
74
return ret;
86
*ignore = g_slist_prepend(*ignore, sibling);
75
}
87
bdrv_set_aio_context_ignore(sibling->bs, ctx, ignore);
76
77
-const BdrvChildClass child_backing = {
78
- .parent_is_bds = true,
79
- .get_parent_desc = bdrv_child_get_parent_desc,
80
- .attach = bdrv_child_cb_attach_backing,
81
- .detach = bdrv_child_cb_detach_backing,
82
- .inherit_options = bdrv_backing_options,
83
- .drained_begin = bdrv_child_cb_drained_begin,
84
- .drained_poll = bdrv_child_cb_drained_poll,
85
- .drained_end = bdrv_child_cb_drained_end,
86
- .inactivate = bdrv_child_cb_inactivate,
87
- .update_filename = bdrv_backing_update_filename,
88
- .can_set_aio_ctx = bdrv_child_cb_can_set_aio_ctx,
89
- .set_aio_ctx = bdrv_child_cb_set_aio_ctx,
90
-};
91
-
92
/*
93
* Returns the options and flags that a generic child of a BDS should
94
* get, based on the given options and flags for the parent BDS.
95
@@ -XXX,XX +XXX,XX @@ static void bdrv_default_perms_for_cow(BlockDriverState *bs, BdrvChild *c,
96
uint64_t perm, uint64_t shared,
97
uint64_t *nperm, uint64_t *nshared)
98
{
99
- assert(child_class == &child_backing ||
100
- (child_class == &child_of_bds && (role & BDRV_CHILD_COW)));
101
+ assert(child_class == &child_of_bds && (role & BDRV_CHILD_COW));
102
103
/*
104
* We want consistent read from backing files if the parent needs it.
105
@@ -XXX,XX +XXX,XX @@ void bdrv_format_default_perms(BlockDriverState *bs, BdrvChild *c,
106
uint64_t perm, uint64_t shared,
107
uint64_t *nperm, uint64_t *nshared)
108
{
109
- bool backing = (child_class == &child_backing);
110
-
111
if (child_class == &child_of_bds) {
112
bdrv_default_perms(bs, c, child_class, role, reopen_queue,
113
perm, shared, nperm, nshared);
114
return;
88
}
115
}
89
+
116
90
+ job->job.aio_context = ctx;
117
- assert(child_class == &child_backing || child_class == &child_file);
118
+ assert(child_class == &child_file);
119
120
- if (!backing) {
121
- bdrv_default_perms_for_storage(bs, c, child_class, role, reopen_queue,
122
- perm, shared, nperm, nshared);
123
- } else {
124
- bdrv_default_perms_for_cow(bs, c, child_class, role, reopen_queue,
125
+ bdrv_default_perms_for_storage(bs, c, child_class, role, reopen_queue,
126
perm, shared, nperm, nshared);
127
- }
91
}
128
}
92
129
93
static const BdrvChildRole child_job = {
130
void bdrv_default_perms(BlockDriverState *bs, BdrvChild *c,
94
@@ -XXX,XX +XXX,XX @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver,
95
96
bdrv_op_unblock(bs, BLOCK_OP_TYPE_DATAPLANE, job->blocker);
97
98
- blk_add_aio_context_notifier(blk, block_job_attached_aio_context,
99
- block_job_detach_aio_context, job);
100
blk_set_allow_aio_context_change(blk, true);
101
102
/* Only set speed when necessary to avoid NotSupported error */
103
--
131
--
104
2.20.1
132
2.25.4
105
133
106
134
diff view generated by jsdifflib
New patch
1
1
From: Max Reitz <mreitz@redhat.com>
2
3
Commonly, they need to pass the BDRV_CHILD_IMAGE set as the
4
BdrvChildRole; but there are exceptions for drivers with external data
5
files (qcow2 and vmdk).
6
7
Signed-off-by: Max Reitz <mreitz@redhat.com>
8
Reviewed-by: Eric Blake <eblake@redhat.com>
9
Message-Id: <20200513110544.176672-26-mreitz@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
---
12
block/bochs.c | 4 ++--
13
block/cloop.c | 4 ++--
14
block/crypto.c | 4 ++--
15
block/dmg.c | 4 ++--
16
block/parallels.c | 4 ++--
17
block/qcow.c | 4 ++--
18
block/qcow2.c | 19 +++++++++++++------
19
block/qed.c | 4 ++--
20
block/vdi.c | 4 ++--
21
block/vhdx.c | 4 ++--
22
block/vmdk.c | 20 +++++++++++++++++---
23
block/vpc.c | 4 ++--
24
12 files changed, 50 insertions(+), 29 deletions(-)
25
26
diff --git a/block/bochs.c b/block/bochs.c
27
index XXXXXXX..XXXXXXX 100644
28
--- a/block/bochs.c
29
+++ b/block/bochs.c
30
@@ -XXX,XX +XXX,XX @@ static int bochs_open(BlockDriverState *bs, QDict *options, int flags,
31
return ret;
32
}
33
34
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file, 0,
35
- false, errp);
36
+ bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
37
+ BDRV_CHILD_IMAGE, false, errp);
38
if (!bs->file) {
39
return -EINVAL;
40
}
41
diff --git a/block/cloop.c b/block/cloop.c
42
index XXXXXXX..XXXXXXX 100644
43
--- a/block/cloop.c
44
+++ b/block/cloop.c
45
@@ -XXX,XX +XXX,XX @@ static int cloop_open(BlockDriverState *bs, QDict *options, int flags,
46
return ret;
47
}
48
49
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file, 0,
50
- false, errp);
51
+ bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
52
+ BDRV_CHILD_IMAGE, false, errp);
53
if (!bs->file) {
54
return -EINVAL;
55
}
56
diff --git a/block/crypto.c b/block/crypto.c
57
index XXXXXXX..XXXXXXX 100644
58
--- a/block/crypto.c
59
+++ b/block/crypto.c
60
@@ -XXX,XX +XXX,XX @@ static int block_crypto_open_generic(QCryptoBlockFormat format,
61
unsigned int cflags = 0;
62
QDict *cryptoopts = NULL;
63
64
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file, 0,
65
- false, errp);
66
+ bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
67
+ BDRV_CHILD_IMAGE, false, errp);
68
if (!bs->file) {
69
return -EINVAL;
70
}
71
diff --git a/block/dmg.c b/block/dmg.c
72
index XXXXXXX..XXXXXXX 100644
73
--- a/block/dmg.c
74
+++ b/block/dmg.c
75
@@ -XXX,XX +XXX,XX @@ static int dmg_open(BlockDriverState *bs, QDict *options, int flags,
76
return ret;
77
}
78
79
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file, 0,
80
- false, errp);
81
+ bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
82
+ BDRV_CHILD_IMAGE, false, errp);
83
if (!bs->file) {
84
return -EINVAL;
85
}
86
diff --git a/block/parallels.c b/block/parallels.c
87
index XXXXXXX..XXXXXXX 100644
88
--- a/block/parallels.c
89
+++ b/block/parallels.c
90
@@ -XXX,XX +XXX,XX @@ static int parallels_open(BlockDriverState *bs, QDict *options, int flags,
91
Error *local_err = NULL;
92
char *buf;
93
94
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file, 0,
95
- false, errp);
96
+ bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
97
+ BDRV_CHILD_IMAGE, false, errp);
98
if (!bs->file) {
99
return -EINVAL;
100
}
101
diff --git a/block/qcow.c b/block/qcow.c
102
index XXXXXXX..XXXXXXX 100644
103
--- a/block/qcow.c
104
+++ b/block/qcow.c
105
@@ -XXX,XX +XXX,XX @@ static int qcow_open(BlockDriverState *bs, QDict *options, int flags,
106
qdict_extract_subqdict(options, &encryptopts, "encrypt.");
107
encryptfmt = qdict_get_try_str(encryptopts, "format");
108
109
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file, 0,
110
- false, errp);
111
+ bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
112
+ BDRV_CHILD_IMAGE, false, errp);
113
if (!bs->file) {
114
ret = -EINVAL;
115
goto fail;
116
diff --git a/block/qcow2.c b/block/qcow2.c
117
index XXXXXXX..XXXXXXX 100644
118
--- a/block/qcow2.c
119
+++ b/block/qcow2.c
120
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options,
121
}
122
123
/* Open external data file */
124
- s->data_file = bdrv_open_child(NULL, options, "data-file", bs, &child_file,
125
- 0, true, &local_err);
126
+ s->data_file = bdrv_open_child(NULL, options, "data-file", bs,
127
+ &child_of_bds, BDRV_CHILD_DATA,
128
+ true, &local_err);
129
if (local_err) {
130
error_propagate(errp, local_err);
131
ret = -EINVAL;
132
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options,
133
if (s->incompatible_features & QCOW2_INCOMPAT_DATA_FILE) {
134
if (!s->data_file && s->image_data_file) {
135
s->data_file = bdrv_open_child(s->image_data_file, options,
136
- "data-file", bs, &child_file, 0,
137
- false, errp);
138
+ "data-file", bs, &child_of_bds,
139
+ BDRV_CHILD_DATA, false, errp);
140
if (!s->data_file) {
141
ret = -EINVAL;
142
goto fail;
143
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options,
144
ret = -EINVAL;
145
goto fail;
146
}
147
+
148
+ /* No data here */
149
+ bs->file->role &= ~BDRV_CHILD_DATA;
150
+
151
+ /* Must succeed because we have given up permissions if anything */
152
+ bdrv_child_refresh_perms(bs, bs->file, &error_abort);
153
} else {
154
if (s->data_file) {
155
error_setg(errp, "'data-file' can only be set for images with an "
156
@@ -XXX,XX +XXX,XX @@ static int qcow2_open(BlockDriverState *bs, QDict *options, int flags,
157
.ret = -EINPROGRESS
158
};
159
160
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file, 0,
161
- false, errp);
162
+ bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
163
+ BDRV_CHILD_IMAGE, false, errp);
164
if (!bs->file) {
165
return -EINVAL;
166
}
167
diff --git a/block/qed.c b/block/qed.c
168
index XXXXXXX..XXXXXXX 100644
169
--- a/block/qed.c
170
+++ b/block/qed.c
171
@@ -XXX,XX +XXX,XX @@ static int bdrv_qed_open(BlockDriverState *bs, QDict *options, int flags,
172
.ret = -EINPROGRESS
173
};
174
175
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file, 0,
176
- false, errp);
177
+ bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
178
+ BDRV_CHILD_IMAGE, false, errp);
179
if (!bs->file) {
180
return -EINVAL;
181
}
182
diff --git a/block/vdi.c b/block/vdi.c
183
index XXXXXXX..XXXXXXX 100644
184
--- a/block/vdi.c
185
+++ b/block/vdi.c
186
@@ -XXX,XX +XXX,XX @@ static int vdi_open(BlockDriverState *bs, QDict *options, int flags,
187
Error *local_err = NULL;
188
QemuUUID uuid_link, uuid_parent;
189
190
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file, 0,
191
- false, errp);
192
+ bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
193
+ BDRV_CHILD_IMAGE, false, errp);
194
if (!bs->file) {
195
return -EINVAL;
196
}
197
diff --git a/block/vhdx.c b/block/vhdx.c
198
index XXXXXXX..XXXXXXX 100644
199
--- a/block/vhdx.c
200
+++ b/block/vhdx.c
201
@@ -XXX,XX +XXX,XX @@ static int vhdx_open(BlockDriverState *bs, QDict *options, int flags,
202
uint64_t signature;
203
Error *local_err = NULL;
204
205
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file, 0,
206
- false, errp);
207
+ bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
208
+ BDRV_CHILD_IMAGE, false, errp);
209
if (!bs->file) {
210
return -EINVAL;
211
}
212
diff --git a/block/vmdk.c b/block/vmdk.c
213
index XXXXXXX..XXXXXXX 100644
214
--- a/block/vmdk.c
215
+++ b/block/vmdk.c
216
@@ -XXX,XX +XXX,XX @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
217
char *desc_file_dir = NULL;
218
char *extent_path;
219
BdrvChild *extent_file;
220
+ BdrvChildRole extent_role;
221
BDRVVmdkState *s = bs->opaque;
222
VmdkExtent *extent;
223
char extent_opt_prefix[32];
224
@@ -XXX,XX +XXX,XX @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
225
ret = snprintf(extent_opt_prefix, 32, "extents.%d", s->num_extents);
226
assert(ret < 32);
227
228
+ extent_role = BDRV_CHILD_DATA;
229
+ if (strcmp(type, "FLAT") != 0 && strcmp(type, "VMFS") != 0) {
230
+ /* non-flat extents have metadata */
231
+ extent_role |= BDRV_CHILD_METADATA;
232
+ }
233
+
234
extent_file = bdrv_open_child(extent_path, options, extent_opt_prefix,
235
- bs, &child_file, 0, false, &local_err);
236
+ bs, &child_of_bds, extent_role, false,
237
+ &local_err);
238
g_free(extent_path);
239
if (local_err) {
240
error_propagate(errp, local_err);
241
@@ -XXX,XX +XXX,XX @@ static int vmdk_open(BlockDriverState *bs, QDict *options, int flags,
242
uint32_t magic;
243
Error *local_err = NULL;
244
245
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file, 0,
246
- false, errp);
247
+ bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
248
+ BDRV_CHILD_IMAGE, false, errp);
249
if (!bs->file) {
250
return -EINVAL;
251
}
252
@@ -XXX,XX +XXX,XX @@ static int vmdk_open(BlockDriverState *bs, QDict *options, int flags,
253
s->desc_offset = 0x200;
254
break;
255
default:
256
+ /* No data in the descriptor file */
257
+ bs->file->role &= ~BDRV_CHILD_DATA;
258
+
259
+ /* Must succeed because we have given up permissions if anything */
260
+ bdrv_child_refresh_perms(bs, bs->file, &error_abort);
261
+
262
ret = vmdk_open_desc_file(bs, flags, buf, options, errp);
263
break;
264
}
265
diff --git a/block/vpc.c b/block/vpc.c
266
index XXXXXXX..XXXXXXX 100644
267
--- a/block/vpc.c
268
+++ b/block/vpc.c
269
@@ -XXX,XX +XXX,XX @@ static int vpc_open(BlockDriverState *bs, QDict *options, int flags,
270
int ret;
271
int64_t bs_size;
272
273
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file, 0,
274
- false, errp);
275
+ bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
276
+ BDRV_CHILD_IMAGE, false, errp);
277
if (!bs->file) {
278
return -EINVAL;
279
}
280
--
281
2.25.4
282
283
diff view generated by jsdifflib
1
From: Max Reitz <mreitz@redhat.com>
1
From: Max Reitz <mreitz@redhat.com>
2
2
3
Just writing that --output=json outputs JSON information does not really
3
Note that some filters have secondary children, namely blkverify (the
4
help; we should also make a note of what QAPI type the result object
4
image to be verified) and blklogwrites (the log). This patch does not
5
has. (The map subcommand does not emit a QAPI-typed object, but its
5
touch those children.
6
section already describes the object structure well enough.)
6
7
Note that for blkverify, the filtered child should not be format-probed.
8
While there is nothing enforcing this here, in practice, it will not be:
9
blkverify implements .bdrv_file_open. The block layer ensures (and in
10
fact, asserts) that BDRV_O_PROTOCOL is set for every BDS whose driver
11
implements .bdrv_file_open. This flag will then be bequeathed to
12
blkverify's children, and they will thus (by default) not be probed
13
either.
14
15
("By default" refers to the fact that blkverify's other child (the
16
non-filtered one) will have BDRV_O_PROTOCOL force-unset, because that is
17
what happens for all non-filtered children of non-format drivers.)
7
18
8
Signed-off-by: Max Reitz <mreitz@redhat.com>
19
Signed-off-by: Max Reitz <mreitz@redhat.com>
20
Message-Id: <20200513110544.176672-27-mreitz@redhat.com>
21
Reviewed-by: Eric Blake <eblake@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
22
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
23
---
11
qemu-img.texi | 11 ++++++++---
24
block/blkdebug.c | 4 +++-
12
1 file changed, 8 insertions(+), 3 deletions(-)
25
block/blklogwrites.c | 3 ++-
26
block/blkreplay.c | 5 +++--
27
block/blkverify.c | 4 +++-
28
block/copy-on-read.c | 5 +++--
29
block/filter-compress.c | 5 +++--
30
block/replication.c | 3 ++-
31
block/throttle.c | 5 +++--
32
8 files changed, 22 insertions(+), 12 deletions(-)
13
33
14
diff --git a/qemu-img.texi b/qemu-img.texi
34
diff --git a/block/blkdebug.c b/block/blkdebug.c
15
index XXXXXXX..XXXXXXX 100644
35
index XXXXXXX..XXXXXXX 100644
16
--- a/qemu-img.texi
36
--- a/block/blkdebug.c
17
+++ b/qemu-img.texi
37
+++ b/block/blkdebug.c
18
@@ -XXX,XX +XXX,XX @@ overridden with a pattern byte specified by @var{pattern}.
38
@@ -XXX,XX +XXX,XX @@ static int blkdebug_open(BlockDriverState *bs, QDict *options, int flags,
19
39
20
Perform a consistency check on the disk image @var{filename}. The command can
40
/* Open the image file */
21
output in the format @var{ofmt} which is either @code{human} or @code{json}.
41
bs->file = bdrv_open_child(qemu_opt_get(opts, "x-image"), options, "image",
22
+The JSON output is an object of QAPI type @code{ImageCheck}.
42
- bs, &child_file, 0, false, &local_err);
23
43
+ bs, &child_of_bds,
24
If @code{-r} is specified, qemu-img tries to repair any inconsistencies found
44
+ BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY,
25
during the check. @code{-r leaks} repairs only cluster leaks, whereas
45
+ false, &local_err);
26
@@ -XXX,XX +XXX,XX @@ The size syntax is similar to dd(1)'s size syntax.
46
if (local_err) {
27
Give information about the disk image @var{filename}. Use it in
47
ret = -EINVAL;
28
particular to know the size reserved on disk which can be different
48
error_propagate(errp, local_err);
29
from the displayed size. If VM snapshots are stored in the disk image,
49
diff --git a/block/blklogwrites.c b/block/blklogwrites.c
30
-they are displayed too. The command can output in the format @var{ofmt}
50
index XXXXXXX..XXXXXXX 100644
31
-which is either @code{human} or @code{json}.
51
--- a/block/blklogwrites.c
32
+they are displayed too.
52
+++ b/block/blklogwrites.c
33
53
@@ -XXX,XX +XXX,XX @@ static int blk_log_writes_open(BlockDriverState *bs, QDict *options, int flags,
34
If a disk image has a backing file chain, information about each disk image in
54
}
35
the chain can be recursively enumerated by using the option @code{--backing-chain}.
55
36
@@ -XXX,XX +XXX,XX @@ To enumerate information about each disk image in the above chain, starting from
56
/* Open the file */
37
qemu-img info --backing-chain snap2.qcow2
57
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file, 0, false,
38
@end example
58
+ bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
39
59
+ BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY, false,
40
+The command can output in the format @var{ofmt} which is either @code{human} or
60
&local_err);
41
+@code{json}. The JSON output is an object of QAPI type @code{ImageInfo}; with
61
if (local_err) {
42
+@code{--backing-chain}, it is an array of @code{ImageInfo} objects.
62
ret = -EINVAL;
43
+
63
diff --git a/block/blkreplay.c b/block/blkreplay.c
44
@item map [--object @var{objectdef}] [--image-opts] [-f @var{fmt}] [--output=@var{ofmt}] [-U] @var{filename}
64
index XXXXXXX..XXXXXXX 100644
45
65
--- a/block/blkreplay.c
46
Dump the metadata of image @var{filename} and its backing file chain.
66
+++ b/block/blkreplay.c
47
@@ -XXX,XX +XXX,XX @@ Calculate the file size required for a new image. This information can be used
67
@@ -XXX,XX +XXX,XX @@ static int blkreplay_open(BlockDriverState *bs, QDict *options, int flags,
48
to size logical volumes or SAN LUNs appropriately for the image that will be
68
int ret;
49
placed in them. The values reported are guaranteed to be large enough to fit
69
50
the image. The command can output in the format @var{ofmt} which is either
70
/* Open the image file */
51
-@code{human} or @code{json}.
71
- bs->file = bdrv_open_child(NULL, options, "image",
52
+@code{human} or @code{json}. The JSON output is an object of QAPI type
72
- bs, &child_file, 0, false, &local_err);
53
+@code{BlockMeasureInfo}.
73
+ bs->file = bdrv_open_child(NULL, options, "image", bs, &child_of_bds,
54
74
+ BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY,
55
If the size @var{N} is given then act as if creating a new empty image file
75
+ false, &local_err);
56
using @command{qemu-img create}. If @var{filename} is given then act as if
76
if (local_err) {
77
ret = -EINVAL;
78
error_propagate(errp, local_err);
79
diff --git a/block/blkverify.c b/block/blkverify.c
80
index XXXXXXX..XXXXXXX 100644
81
--- a/block/blkverify.c
82
+++ b/block/blkverify.c
83
@@ -XXX,XX +XXX,XX @@ static int blkverify_open(BlockDriverState *bs, QDict *options, int flags,
84
85
/* Open the raw file */
86
bs->file = bdrv_open_child(qemu_opt_get(opts, "x-raw"), options, "raw",
87
- bs, &child_file, 0, false, &local_err);
88
+ bs, &child_of_bds,
89
+ BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY,
90
+ false, &local_err);
91
if (local_err) {
92
ret = -EINVAL;
93
error_propagate(errp, local_err);
94
diff --git a/block/copy-on-read.c b/block/copy-on-read.c
95
index XXXXXXX..XXXXXXX 100644
96
--- a/block/copy-on-read.c
97
+++ b/block/copy-on-read.c
98
@@ -XXX,XX +XXX,XX @@
99
static int cor_open(BlockDriverState *bs, QDict *options, int flags,
100
Error **errp)
101
{
102
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file, 0, false,
103
- errp);
104
+ bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
105
+ BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY,
106
+ false, errp);
107
if (!bs->file) {
108
return -EINVAL;
109
}
110
diff --git a/block/filter-compress.c b/block/filter-compress.c
111
index XXXXXXX..XXXXXXX 100644
112
--- a/block/filter-compress.c
113
+++ b/block/filter-compress.c
114
@@ -XXX,XX +XXX,XX @@
115
static int compress_open(BlockDriverState *bs, QDict *options, int flags,
116
Error **errp)
117
{
118
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file, 0, false,
119
- errp);
120
+ bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
121
+ BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY,
122
+ false, errp);
123
if (!bs->file) {
124
return -EINVAL;
125
}
126
diff --git a/block/replication.c b/block/replication.c
127
index XXXXXXX..XXXXXXX 100644
128
--- a/block/replication.c
129
+++ b/block/replication.c
130
@@ -XXX,XX +XXX,XX @@ static int replication_open(BlockDriverState *bs, QDict *options,
131
const char *mode;
132
const char *top_id;
133
134
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file, 0,
135
+ bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
136
+ BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY,
137
false, errp);
138
if (!bs->file) {
139
return -EINVAL;
140
diff --git a/block/throttle.c b/block/throttle.c
141
index XXXXXXX..XXXXXXX 100644
142
--- a/block/throttle.c
143
+++ b/block/throttle.c
144
@@ -XXX,XX +XXX,XX @@ static int throttle_open(BlockDriverState *bs, QDict *options,
145
char *group;
146
int ret;
147
148
- bs->file = bdrv_open_child(NULL, options, "file", bs,
149
- &child_file, 0, false, errp);
150
+ bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
151
+ BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY,
152
+ false, errp);
153
if (!bs->file) {
154
return -EINVAL;
155
}
57
--
156
--
58
2.20.1
157
2.25.4
59
158
60
159
diff view generated by jsdifflib
1
From: Alberto Garcia <berto@igalia.com>
1
From: Max Reitz <mreitz@redhat.com>
2
2
3
There are a few places in which we turn a number of bytes into sectors
3
Replace child_file by child_of_bds in all remaining places (excluding
4
in order to compare the result against BDRV_REQUEST_MAX_SECTORS
4
tests).
5
instead of using BDRV_REQUEST_MAX_BYTES directly.
6
5
7
Signed-off-by: Alberto Garcia <berto@igalia.com>
6
Signed-off-by: Max Reitz <mreitz@redhat.com>
8
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
7
Message-Id: <20200513110544.176672-28-mreitz@redhat.com>
8
Reviewed-by: Eric Blake <eblake@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
10
---
11
block/io.c | 6 +++---
11
block.c | 3 ++-
12
qemu-io-cmds.c | 7 +++----
12
block/backup-top.c | 4 ++--
13
2 files changed, 6 insertions(+), 7 deletions(-)
13
block/blklogwrites.c | 4 ++--
14
block/raw-format.c | 15 +++++++++++++--
15
4 files changed, 19 insertions(+), 7 deletions(-)
14
16
15
diff --git a/block/io.c b/block/io.c
17
diff --git a/block.c b/block.c
16
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
17
--- a/block/io.c
19
--- a/block.c
18
+++ b/block/io.c
20
+++ b/block.c
19
@@ -XXX,XX +XXX,XX @@ static bool coroutine_fn wait_serialising_requests(BdrvTrackedRequest *self)
21
@@ -XXX,XX +XXX,XX @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
20
static int bdrv_check_byte_request(BlockDriverState *bs, int64_t offset,
22
BlockDriverState *file_bs;
21
size_t size)
23
22
{
24
file_bs = bdrv_open_child_bs(filename, options, "file", bs,
23
- if (size > BDRV_REQUEST_MAX_SECTORS << BDRV_SECTOR_BITS) {
25
- &child_file, 0, true, &local_err);
24
+ if (size > BDRV_REQUEST_MAX_BYTES) {
26
+ &child_of_bds, BDRV_CHILD_IMAGE,
25
return -EIO;
27
+ true, &local_err);
28
if (local_err) {
29
goto fail;
30
}
31
diff --git a/block/backup-top.c b/block/backup-top.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/block/backup-top.c
34
+++ b/block/backup-top.c
35
@@ -XXX,XX +XXX,XX @@ BlockDriverState *bdrv_backup_top_append(BlockDriverState *source,
36
source->supported_zero_flags);
37
38
bdrv_ref(target);
39
- state->target = bdrv_attach_child(top, target, "target", &child_file, 0,
40
- errp);
41
+ state->target = bdrv_attach_child(top, target, "target", &child_of_bds,
42
+ BDRV_CHILD_DATA, errp);
43
if (!state->target) {
44
bdrv_unref(target);
45
bdrv_unref(top);
46
diff --git a/block/blklogwrites.c b/block/blklogwrites.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/block/blklogwrites.c
49
+++ b/block/blklogwrites.c
50
@@ -XXX,XX +XXX,XX @@ static int blk_log_writes_open(BlockDriverState *bs, QDict *options, int flags,
26
}
51
}
27
52
28
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_driver_preadv(BlockDriverState *bs,
53
/* Open the log file */
29
54
- s->log_file = bdrv_open_child(NULL, options, "log", bs, &child_file, 0,
30
assert((offset & (BDRV_SECTOR_SIZE - 1)) == 0);
55
- false, &local_err);
31
assert((bytes & (BDRV_SECTOR_SIZE - 1)) == 0);
56
+ s->log_file = bdrv_open_child(NULL, options, "log", bs, &child_of_bds,
32
- assert((bytes >> BDRV_SECTOR_BITS) <= BDRV_REQUEST_MAX_SECTORS);
57
+ BDRV_CHILD_METADATA, false, &local_err);
33
+ assert(bytes <= BDRV_REQUEST_MAX_BYTES);
58
if (local_err) {
34
assert(drv->bdrv_co_readv);
59
ret = -EINVAL;
35
60
error_propagate(errp, local_err);
36
return drv->bdrv_co_readv(bs, sector_num, nb_sectors, qiov);
61
diff --git a/block/raw-format.c b/block/raw-format.c
37
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_driver_pwritev(BlockDriverState *bs,
38
39
assert((offset & (BDRV_SECTOR_SIZE - 1)) == 0);
40
assert((bytes & (BDRV_SECTOR_SIZE - 1)) == 0);
41
- assert((bytes >> BDRV_SECTOR_BITS) <= BDRV_REQUEST_MAX_SECTORS);
42
+ assert(bytes <= BDRV_REQUEST_MAX_BYTES);
43
44
assert(drv->bdrv_co_writev);
45
ret = drv->bdrv_co_writev(bs, sector_num, nb_sectors, qiov,
46
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
47
index XXXXXXX..XXXXXXX 100644
62
index XXXXXXX..XXXXXXX 100644
48
--- a/qemu-io-cmds.c
63
--- a/block/raw-format.c
49
+++ b/qemu-io-cmds.c
64
+++ b/block/raw-format.c
50
@@ -XXX,XX +XXX,XX @@ static int do_write_compressed(BlockBackend *blk, char *buf, int64_t offset,
65
@@ -XXX,XX +XXX,XX @@ static int raw_open(BlockDriverState *bs, QDict *options, int flags,
51
{
66
BDRVRawState *s = bs->opaque;
67
bool has_size;
68
uint64_t offset, size;
69
+ BdrvChildRole file_role;
52
int ret;
70
int ret;
53
71
54
- if (bytes >> 9 > BDRV_REQUEST_MAX_SECTORS) {
72
ret = raw_read_options(options, &offset, &has_size, &size, errp);
55
+ if (bytes > BDRV_REQUEST_MAX_BYTES) {
73
@@ -XXX,XX +XXX,XX @@ static int raw_open(BlockDriverState *bs, QDict *options, int flags,
56
return -ERANGE;
74
return ret;
57
}
75
}
58
76
59
@@ -XXX,XX +XXX,XX @@ static int discard_f(BlockBackend *blk, int argc, char **argv)
77
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file, 0,
60
if (bytes < 0) {
78
- false, errp);
61
print_cvtnum_err(bytes, argv[optind]);
79
+ /*
62
return bytes;
80
+ * Without offset and a size limit, this driver behaves very much
63
- } else if (bytes >> BDRV_SECTOR_BITS > BDRV_REQUEST_MAX_SECTORS) {
81
+ * like a filter. With any such limit, it does not.
64
+ } else if (bytes > BDRV_REQUEST_MAX_BYTES) {
82
+ */
65
printf("length cannot exceed %"PRIu64", given %s\n",
83
+ if (offset || has_size) {
66
- (uint64_t)BDRV_REQUEST_MAX_SECTORS << BDRV_SECTOR_BITS,
84
+ file_role = BDRV_CHILD_DATA | BDRV_CHILD_PRIMARY;
67
- argv[optind]);
85
+ } else {
68
+ (uint64_t)BDRV_REQUEST_MAX_BYTES, argv[optind]);
86
+ file_role = BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY;
87
+ }
88
+
89
+ bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
90
+ file_role, false, errp);
91
if (!bs->file) {
69
return -EINVAL;
92
return -EINVAL;
70
}
93
}
71
72
--
94
--
73
2.20.1
95
2.25.4
74
96
75
97
diff view generated by jsdifflib
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
1
From: Max Reitz <mreitz@redhat.com>
2
2
3
qmp_cont in RUN_STATE_FINISH_MIGRATE may lead to moving vm to
3
Signed-off-by: Max Reitz <mreitz@redhat.com>
4
RUN_STATE_RUNNING, before actual migration finish. So, when migration
4
Reviewed-by: Eric Blake <eblake@redhat.com>
5
thread will try to go to RUN_STATE_POSTMIGRATE, assuming transition
5
Message-Id: <20200513110544.176672-29-mreitz@redhat.com>
6
RUN_STATE_FINISH_MIGRATE->RUN_STATE_POSTMIGRATE, it will crash, as
7
current state is RUN_STATE_RUNNING, and transition
8
RUN_STATE_RUNNING->RUN_STATE_POSTMIGRATE is forbidden.
9
10
Reported-by: Max Reitz <mreitz@redhat.com>
11
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
12
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
13
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
---
7
---
15
qmp.c | 3 +++
8
tests/test-bdrv-drain.c | 29 +++++++++++++++++------------
16
1 file changed, 3 insertions(+)
9
tests/test-bdrv-graph-mod.c | 6 ++++--
10
2 files changed, 21 insertions(+), 14 deletions(-)
17
11
18
diff --git a/qmp.c b/qmp.c
12
diff --git a/tests/test-bdrv-drain.c b/tests/test-bdrv-drain.c
19
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
20
--- a/qmp.c
14
--- a/tests/test-bdrv-drain.c
21
+++ b/qmp.c
15
+++ b/tests/test-bdrv-drain.c
22
@@ -XXX,XX +XXX,XX @@ void qmp_cont(Error **errp)
16
@@ -XXX,XX +XXX,XX @@ static void bdrv_test_child_perm(BlockDriverState *bs, BdrvChild *c,
23
return;
17
* detach_by_driver_cb_parent as one of them.
24
} else if (runstate_check(RUN_STATE_SUSPENDED)) {
18
*/
25
return;
19
if (child_class != &child_file && child_class != &child_of_bds) {
26
+ } else if (runstate_check(RUN_STATE_FINISH_MIGRATE)) {
20
- child_class = &child_file;
27
+ error_setg(errp, "Migration is not finalized yet");
21
+ child_class = &child_of_bds;
28
+ return;
29
}
22
}
30
23
31
for (blk = blk_next(NULL); blk; blk = blk_next(blk)) {
24
bdrv_format_default_perms(bs, c, child_class, role, reopen_queue,
25
@@ -XXX,XX +XXX,XX @@ static void do_test_delete_by_drain(bool detach_instead_of_delete,
26
27
null_bs = bdrv_open("null-co://", NULL, NULL, BDRV_O_RDWR | BDRV_O_PROTOCOL,
28
&error_abort);
29
- bdrv_attach_child(bs, null_bs, "null-child", &child_file, 0, &error_abort);
30
+ bdrv_attach_child(bs, null_bs, "null-child", &child_of_bds,
31
+ BDRV_CHILD_DATA, &error_abort);
32
33
/* This child will be the one to pass to requests through to, and
34
* it will stall until a drain occurs */
35
@@ -XXX,XX +XXX,XX @@ static void do_test_delete_by_drain(bool detach_instead_of_delete,
36
&error_abort);
37
child_bs->total_sectors = 65536 >> BDRV_SECTOR_BITS;
38
/* Takes our reference to child_bs */
39
- tts->wait_child = bdrv_attach_child(bs, child_bs, "wait-child", &child_file,
40
- 0, &error_abort);
41
+ tts->wait_child = bdrv_attach_child(bs, child_bs, "wait-child",
42
+ &child_of_bds,
43
+ BDRV_CHILD_DATA | BDRV_CHILD_PRIMARY,
44
+ &error_abort);
45
46
/* This child is just there to be deleted
47
* (for detach_instead_of_delete == true) */
48
null_bs = bdrv_open("null-co://", NULL, NULL, BDRV_O_RDWR | BDRV_O_PROTOCOL,
49
&error_abort);
50
- bdrv_attach_child(bs, null_bs, "null-child", &child_file, 0, &error_abort);
51
+ bdrv_attach_child(bs, null_bs, "null-child", &child_of_bds, BDRV_CHILD_DATA,
52
+ &error_abort);
53
54
blk = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL);
55
blk_insert_bs(blk, bs, &error_abort);
56
@@ -XXX,XX +XXX,XX @@ static void detach_indirect_bh(void *opaque)
57
58
bdrv_ref(data->c);
59
data->child_c = bdrv_attach_child(data->parent_b, data->c, "PB-C",
60
- &child_file, 0, &error_abort);
61
+ &child_of_bds, BDRV_CHILD_DATA,
62
+ &error_abort);
63
}
64
65
static void detach_by_parent_aio_cb(void *opaque, int ret)
66
@@ -XXX,XX +XXX,XX @@ static void detach_by_driver_cb_drained_begin(BdrvChild *child)
67
{
68
aio_bh_schedule_oneshot(qemu_get_current_aio_context(),
69
detach_indirect_bh, &detach_by_parent_data);
70
- child_file.drained_begin(child);
71
+ child_of_bds.drained_begin(child);
72
}
73
74
static BdrvChildClass detach_by_driver_cb_class;
75
@@ -XXX,XX +XXX,XX @@ static void test_detach_indirect(bool by_parent_cb)
76
QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, NULL, 0);
77
78
if (!by_parent_cb) {
79
- detach_by_driver_cb_class = child_file;
80
+ detach_by_driver_cb_class = child_of_bds;
81
detach_by_driver_cb_class.drained_begin =
82
detach_by_driver_cb_drained_begin;
83
}
84
@@ -XXX,XX +XXX,XX @@ static void test_detach_indirect(bool by_parent_cb)
85
/* Set child relationships */
86
bdrv_ref(b);
87
bdrv_ref(a);
88
- child_b = bdrv_attach_child(parent_b, b, "PB-B", &child_file, 0,
89
- &error_abort);
90
+ child_b = bdrv_attach_child(parent_b, b, "PB-B", &child_of_bds,
91
+ BDRV_CHILD_DATA, &error_abort);
92
child_a = bdrv_attach_child(parent_b, a, "PB-A", &child_of_bds,
93
BDRV_CHILD_COW, &error_abort);
94
95
bdrv_ref(a);
96
bdrv_attach_child(parent_a, a, "PA-A",
97
- by_parent_cb ? &child_file : &detach_by_driver_cb_class,
98
- 0, &error_abort);
99
+ by_parent_cb ? &child_of_bds : &detach_by_driver_cb_class,
100
+ BDRV_CHILD_DATA, &error_abort);
101
102
g_assert_cmpint(parent_a->refcnt, ==, 1);
103
g_assert_cmpint(parent_b->refcnt, ==, 1);
104
diff --git a/tests/test-bdrv-graph-mod.c b/tests/test-bdrv-graph-mod.c
105
index XXXXXXX..XXXXXXX 100644
106
--- a/tests/test-bdrv-graph-mod.c
107
+++ b/tests/test-bdrv-graph-mod.c
108
@@ -XXX,XX +XXX,XX @@ static void test_update_perm_tree(void)
109
110
blk_insert_bs(root, bs, &error_abort);
111
112
- bdrv_attach_child(filter, bs, "child", &child_file, 0, &error_abort);
113
+ bdrv_attach_child(filter, bs, "child", &child_of_bds,
114
+ BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY, &error_abort);
115
116
bdrv_append(filter, bs, &local_err);
117
118
@@ -XXX,XX +XXX,XX @@ static void test_should_update_child(void)
119
bdrv_set_backing_hd(target, bs, &error_abort);
120
121
g_assert(target->backing->bs == bs);
122
- bdrv_attach_child(filter, target, "target", &child_file, 0, &error_abort);
123
+ bdrv_attach_child(filter, target, "target", &child_of_bds,
124
+ BDRV_CHILD_DATA, &error_abort);
125
bdrv_append(filter, bs, &error_abort);
126
g_assert(target->backing->bs == bs);
127
32
--
128
--
33
2.20.1
129
2.25.4
34
130
35
131
diff view generated by jsdifflib
1
From: Alberto Garcia <berto@igalia.com>
1
From: Max Reitz <mreitz@redhat.com>
2
2
3
When an L2 table entry points to a compressed cluster the space used
3
bdrv_default_perms() can decide which permission profile to use based on
4
by the data is specified in 512-byte sectors. This size is independent
4
the BdrvChildRole, so block drivers do not need to select it explicitly.
5
from BDRV_SECTOR_SIZE and is specific to the qcow2 file format.
5
6
6
The blkverify driver now no longer shares the WRITE permission for the
7
The QCOW2_COMPRESSED_SECTOR_SIZE constant defined in this patch makes
7
image to verify. We thus have to adjust two places in
8
this explicit.
8
test-block-iothread not to take it. (Note that in theory, blkverify
9
9
should behave like quorum in this regard and share neither WRITE nor
10
Signed-off-by: Alberto Garcia <berto@igalia.com>
10
RESIZE for both of its children. In practice, it does not really
11
matter, because blkverify is used only for debugging, so we might as
12
well keep its permissions rather liberal.)
13
14
Signed-off-by: Max Reitz <mreitz@redhat.com>
15
Reviewed-by: Eric Blake <eblake@redhat.com>
16
Message-Id: <20200513110544.176672-30-mreitz@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
17
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
---
18
---
13
block/qcow2.h | 4 ++++
19
block/backup-top.c | 4 ++--
14
block/qcow2-cluster.c | 5 +++--
20
block/blkdebug.c | 4 ++--
15
block/qcow2-refcount.c | 25 ++++++++++++++-----------
21
block/blklogwrites.c | 9 ++-------
16
block/qcow2.c | 3 ++-
22
block/blkreplay.c | 2 +-
17
4 files changed, 23 insertions(+), 14 deletions(-)
23
block/blkverify.c | 2 +-
18
24
block/bochs.c | 2 +-
19
diff --git a/block/qcow2.h b/block/qcow2.h
25
block/cloop.c | 2 +-
20
index XXXXXXX..XXXXXXX 100644
26
block/crypto.c | 2 +-
21
--- a/block/qcow2.h
27
block/dmg.c | 2 +-
22
+++ b/block/qcow2.h
28
block/filter-compress.c | 2 +-
23
@@ -XXX,XX +XXX,XX @@
29
block/parallels.c | 2 +-
24
#define MIN_CLUSTER_BITS 9
30
block/qcow.c | 2 +-
25
#define MAX_CLUSTER_BITS 21
31
block/qcow2.c | 2 +-
26
32
block/qed.c | 2 +-
27
+/* Defined in the qcow2 spec (compressed cluster descriptor) */
33
block/raw-format.c | 2 +-
28
+#define QCOW2_COMPRESSED_SECTOR_SIZE 512U
34
block/throttle.c | 2 +-
29
+#define QCOW2_COMPRESSED_SECTOR_MASK (~(QCOW2_COMPRESSED_SECTOR_SIZE - 1))
35
block/vdi.c | 2 +-
30
+
36
block/vhdx.c | 2 +-
31
/* Must be at least 2 to cover COW */
37
block/vmdk.c | 2 +-
32
#define MIN_L2_CACHE_SIZE 2 /* cache entries */
38
block/vpc.c | 2 +-
33
39
tests/test-bdrv-drain.c | 10 +++++-----
34
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
40
tests/test-bdrv-graph-mod.c | 2 +-
35
index XXXXXXX..XXXXXXX 100644
41
tests/test-block-iothread.c | 17 ++++++++++++++---
36
--- a/block/qcow2-cluster.c
42
23 files changed, 43 insertions(+), 37 deletions(-)
37
+++ b/block/qcow2-cluster.c
43
38
@@ -XXX,XX +XXX,XX @@ int qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs,
44
diff --git a/block/backup-top.c b/block/backup-top.c
39
return cluster_offset;
45
index XXXXXXX..XXXXXXX 100644
46
--- a/block/backup-top.c
47
+++ b/block/backup-top.c
48
@@ -XXX,XX +XXX,XX @@ static void backup_top_child_perm(BlockDriverState *bs, BdrvChild *c,
49
*nperm = BLK_PERM_WRITE;
50
} else {
51
/* Source child */
52
- bdrv_filter_default_perms(bs, c, child_class, role, reopen_queue,
53
- perm, shared, nperm, nshared);
54
+ bdrv_default_perms(bs, c, child_class, role, reopen_queue,
55
+ perm, shared, nperm, nshared);
56
57
if (perm & BLK_PERM_WRITE) {
58
*nperm = *nperm | BLK_PERM_CONSISTENT_READ;
59
diff --git a/block/blkdebug.c b/block/blkdebug.c
60
index XXXXXXX..XXXXXXX 100644
61
--- a/block/blkdebug.c
62
+++ b/block/blkdebug.c
63
@@ -XXX,XX +XXX,XX @@ static void blkdebug_child_perm(BlockDriverState *bs, BdrvChild *c,
64
{
65
BDRVBlkdebugState *s = bs->opaque;
66
67
- bdrv_filter_default_perms(bs, c, child_class, role, reopen_queue,
68
- perm, shared, nperm, nshared);
69
+ bdrv_default_perms(bs, c, child_class, role, reopen_queue,
70
+ perm, shared, nperm, nshared);
71
72
*nperm |= s->take_child_perms;
73
*nshared &= ~s->unshare_child_perms;
74
diff --git a/block/blklogwrites.c b/block/blklogwrites.c
75
index XXXXXXX..XXXXXXX 100644
76
--- a/block/blklogwrites.c
77
+++ b/block/blklogwrites.c
78
@@ -XXX,XX +XXX,XX @@ static void blk_log_writes_child_perm(BlockDriverState *bs, BdrvChild *c,
79
return;
40
}
80
}
41
81
42
- nb_csectors = ((cluster_offset + compressed_size - 1) >> 9) -
82
- if (!strcmp(c->name, "log")) {
43
- (cluster_offset >> 9);
83
- bdrv_format_default_perms(bs, c, child_class, role, ro_q, perm, shrd,
44
+ nb_csectors =
84
- nperm, nshrd);
45
+ (cluster_offset + compressed_size - 1) / QCOW2_COMPRESSED_SECTOR_SIZE -
85
- } else {
46
+ (cluster_offset / QCOW2_COMPRESSED_SECTOR_SIZE);
86
- bdrv_filter_default_perms(bs, c, child_class, role, ro_q, perm, shrd,
47
87
- nperm, nshrd);
48
cluster_offset |= QCOW_OFLAG_COMPRESSED |
88
- }
49
((uint64_t)nb_csectors << s->csize_shift);
89
+ bdrv_default_perms(bs, c, child_class, role, ro_q, perm, shrd,
50
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
90
+ nperm, nshrd);
51
index XXXXXXX..XXXXXXX 100644
91
}
52
--- a/block/qcow2-refcount.c
92
53
+++ b/block/qcow2-refcount.c
93
static void blk_log_writes_refresh_limits(BlockDriverState *bs, Error **errp)
54
@@ -XXX,XX +XXX,XX @@ void qcow2_free_any_clusters(BlockDriverState *bs, uint64_t l2_entry,
94
diff --git a/block/blkreplay.c b/block/blkreplay.c
55
switch (ctype) {
95
index XXXXXXX..XXXXXXX 100644
56
case QCOW2_CLUSTER_COMPRESSED:
96
--- a/block/blkreplay.c
57
{
97
+++ b/block/blkreplay.c
58
- int nb_csectors;
98
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_blkreplay = {
59
- nb_csectors = ((l2_entry >> s->csize_shift) &
99
.is_filter = true,
60
- s->csize_mask) + 1;
100
61
- qcow2_free_clusters(bs,
101
.bdrv_open = blkreplay_open,
62
- (l2_entry & s->cluster_offset_mask) & ~511,
102
- .bdrv_child_perm = bdrv_filter_default_perms,
63
- nb_csectors * 512, type);
103
+ .bdrv_child_perm = bdrv_default_perms,
64
+ int64_t offset = (l2_entry & s->cluster_offset_mask)
104
.bdrv_getlength = blkreplay_getlength,
65
+ & QCOW2_COMPRESSED_SECTOR_MASK;
105
66
+ int size = QCOW2_COMPRESSED_SECTOR_SIZE *
106
.bdrv_co_preadv = blkreplay_co_preadv,
67
+ (((l2_entry >> s->csize_shift) & s->csize_mask) + 1);
107
diff --git a/block/blkverify.c b/block/blkverify.c
68
+ qcow2_free_clusters(bs, offset, size, type);
108
index XXXXXXX..XXXXXXX 100644
69
}
109
--- a/block/blkverify.c
70
break;
110
+++ b/block/blkverify.c
71
case QCOW2_CLUSTER_NORMAL:
111
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_blkverify = {
72
@@ -XXX,XX +XXX,XX @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
112
.bdrv_parse_filename = blkverify_parse_filename,
73
nb_csectors = ((entry >> s->csize_shift) &
113
.bdrv_file_open = blkverify_open,
74
s->csize_mask) + 1;
114
.bdrv_close = blkverify_close,
75
if (addend != 0) {
115
- .bdrv_child_perm = bdrv_filter_default_perms,
76
+ uint64_t coffset = (entry & s->cluster_offset_mask)
116
+ .bdrv_child_perm = bdrv_default_perms,
77
+ & QCOW2_COMPRESSED_SECTOR_MASK;
117
.bdrv_getlength = blkverify_getlength,
78
ret = update_refcount(
118
.bdrv_refresh_filename = blkverify_refresh_filename,
79
- bs, (entry & s->cluster_offset_mask) & ~511,
119
.bdrv_dirname = blkverify_dirname,
80
- nb_csectors * 512, abs(addend), addend < 0,
120
diff --git a/block/bochs.c b/block/bochs.c
81
+ bs, coffset,
121
index XXXXXXX..XXXXXXX 100644
82
+ nb_csectors * QCOW2_COMPRESSED_SECTOR_SIZE,
122
--- a/block/bochs.c
83
+ abs(addend), addend < 0,
123
+++ b/block/bochs.c
84
QCOW2_DISCARD_SNAPSHOT);
124
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_bochs = {
85
if (ret < 0) {
125
.instance_size    = sizeof(BDRVBochsState),
86
goto fail;
126
.bdrv_probe        = bochs_probe,
87
@@ -XXX,XX +XXX,XX @@ static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res,
127
.bdrv_open        = bochs_open,
88
nb_csectors = ((l2_entry >> s->csize_shift) &
128
- .bdrv_child_perm = bdrv_format_default_perms,
89
s->csize_mask) + 1;
129
+ .bdrv_child_perm = bdrv_default_perms,
90
l2_entry &= s->cluster_offset_mask;
130
.bdrv_refresh_limits = bochs_refresh_limits,
91
- ret = qcow2_inc_refcounts_imrt(bs, res,
131
.bdrv_co_preadv = bochs_co_preadv,
92
- refcount_table, refcount_table_size,
132
.bdrv_close        = bochs_close,
93
- l2_entry & ~511, nb_csectors * 512);
133
diff --git a/block/cloop.c b/block/cloop.c
94
+ ret = qcow2_inc_refcounts_imrt(
134
index XXXXXXX..XXXXXXX 100644
95
+ bs, res, refcount_table, refcount_table_size,
135
--- a/block/cloop.c
96
+ l2_entry & QCOW2_COMPRESSED_SECTOR_MASK,
136
+++ b/block/cloop.c
97
+ nb_csectors * QCOW2_COMPRESSED_SECTOR_SIZE);
137
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_cloop = {
98
if (ret < 0) {
138
.instance_size = sizeof(BDRVCloopState),
99
goto fail;
139
.bdrv_probe = cloop_probe,
100
}
140
.bdrv_open = cloop_open,
141
- .bdrv_child_perm = bdrv_format_default_perms,
142
+ .bdrv_child_perm = bdrv_default_perms,
143
.bdrv_refresh_limits = cloop_refresh_limits,
144
.bdrv_co_preadv = cloop_co_preadv,
145
.bdrv_close = cloop_close,
146
diff --git a/block/crypto.c b/block/crypto.c
147
index XXXXXXX..XXXXXXX 100644
148
--- a/block/crypto.c
149
+++ b/block/crypto.c
150
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_crypto_luks = {
151
.bdrv_close = block_crypto_close,
152
/* This driver doesn't modify LUKS metadata except when creating image.
153
* Allow share-rw=on as a special case. */
154
- .bdrv_child_perm = bdrv_filter_default_perms,
155
+ .bdrv_child_perm = bdrv_default_perms,
156
.bdrv_co_create = block_crypto_co_create_luks,
157
.bdrv_co_create_opts = block_crypto_co_create_opts_luks,
158
.bdrv_co_truncate = block_crypto_co_truncate,
159
diff --git a/block/dmg.c b/block/dmg.c
160
index XXXXXXX..XXXXXXX 100644
161
--- a/block/dmg.c
162
+++ b/block/dmg.c
163
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_dmg = {
164
.bdrv_probe = dmg_probe,
165
.bdrv_open = dmg_open,
166
.bdrv_refresh_limits = dmg_refresh_limits,
167
- .bdrv_child_perm = bdrv_format_default_perms,
168
+ .bdrv_child_perm = bdrv_default_perms,
169
.bdrv_co_preadv = dmg_co_preadv,
170
.bdrv_close = dmg_close,
171
.is_format = true,
172
diff --git a/block/filter-compress.c b/block/filter-compress.c
173
index XXXXXXX..XXXXXXX 100644
174
--- a/block/filter-compress.c
175
+++ b/block/filter-compress.c
176
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_compress = {
177
.format_name = "compress",
178
179
.bdrv_open = compress_open,
180
- .bdrv_child_perm = bdrv_filter_default_perms,
181
+ .bdrv_child_perm = bdrv_default_perms,
182
183
.bdrv_getlength = compress_getlength,
184
185
diff --git a/block/parallels.c b/block/parallels.c
186
index XXXXXXX..XXXXXXX 100644
187
--- a/block/parallels.c
188
+++ b/block/parallels.c
189
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_parallels = {
190
.bdrv_probe        = parallels_probe,
191
.bdrv_open        = parallels_open,
192
.bdrv_close        = parallels_close,
193
- .bdrv_child_perm = bdrv_format_default_perms,
194
+ .bdrv_child_perm = bdrv_default_perms,
195
.bdrv_co_block_status = parallels_co_block_status,
196
.bdrv_has_zero_init = bdrv_has_zero_init_1,
197
.bdrv_co_flush_to_os = parallels_co_flush_to_os,
198
diff --git a/block/qcow.c b/block/qcow.c
199
index XXXXXXX..XXXXXXX 100644
200
--- a/block/qcow.c
201
+++ b/block/qcow.c
202
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_qcow = {
203
.bdrv_probe        = qcow_probe,
204
.bdrv_open        = qcow_open,
205
.bdrv_close        = qcow_close,
206
- .bdrv_child_perm = bdrv_format_default_perms,
207
+ .bdrv_child_perm = bdrv_default_perms,
208
.bdrv_reopen_prepare = qcow_reopen_prepare,
209
.bdrv_co_create = qcow_co_create,
210
.bdrv_co_create_opts = qcow_co_create_opts,
101
diff --git a/block/qcow2.c b/block/qcow2.c
211
diff --git a/block/qcow2.c b/block/qcow2.c
102
index XXXXXXX..XXXXXXX 100644
212
index XXXXXXX..XXXXXXX 100644
103
--- a/block/qcow2.c
213
--- a/block/qcow2.c
104
+++ b/block/qcow2.c
214
+++ b/block/qcow2.c
105
@@ -XXX,XX +XXX,XX @@ qcow2_co_preadv_compressed(BlockDriverState *bs,
215
@@ -XXX,XX +XXX,XX @@ BlockDriver bdrv_qcow2 = {
106
216
.bdrv_reopen_commit_post = qcow2_reopen_commit_post,
107
coffset = file_cluster_offset & s->cluster_offset_mask;
217
.bdrv_reopen_abort = qcow2_reopen_abort,
108
nb_csectors = ((file_cluster_offset >> s->csize_shift) & s->csize_mask) + 1;
218
.bdrv_join_options = qcow2_join_options,
109
- csize = nb_csectors * 512 - (coffset & 511);
219
- .bdrv_child_perm = bdrv_format_default_perms,
110
+ csize = nb_csectors * QCOW2_COMPRESSED_SECTOR_SIZE -
220
+ .bdrv_child_perm = bdrv_default_perms,
111
+ (coffset & ~QCOW2_COMPRESSED_SECTOR_MASK);
221
.bdrv_co_create_opts = qcow2_co_create_opts,
112
222
.bdrv_co_create = qcow2_co_create,
113
buf = g_try_malloc(csize);
223
.bdrv_has_zero_init = qcow2_has_zero_init,
114
if (!buf) {
224
diff --git a/block/qed.c b/block/qed.c
225
index XXXXXXX..XXXXXXX 100644
226
--- a/block/qed.c
227
+++ b/block/qed.c
228
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_qed = {
229
.bdrv_open = bdrv_qed_open,
230
.bdrv_close = bdrv_qed_close,
231
.bdrv_reopen_prepare = bdrv_qed_reopen_prepare,
232
- .bdrv_child_perm = bdrv_format_default_perms,
233
+ .bdrv_child_perm = bdrv_default_perms,
234
.bdrv_co_create = bdrv_qed_co_create,
235
.bdrv_co_create_opts = bdrv_qed_co_create_opts,
236
.bdrv_has_zero_init = bdrv_has_zero_init_1,
237
diff --git a/block/raw-format.c b/block/raw-format.c
238
index XXXXXXX..XXXXXXX 100644
239
--- a/block/raw-format.c
240
+++ b/block/raw-format.c
241
@@ -XXX,XX +XXX,XX @@ BlockDriver bdrv_raw = {
242
.bdrv_reopen_commit = &raw_reopen_commit,
243
.bdrv_reopen_abort = &raw_reopen_abort,
244
.bdrv_open = &raw_open,
245
- .bdrv_child_perm = bdrv_filter_default_perms,
246
+ .bdrv_child_perm = bdrv_default_perms,
247
.bdrv_co_create_opts = &raw_co_create_opts,
248
.bdrv_co_preadv = &raw_co_preadv,
249
.bdrv_co_pwritev = &raw_co_pwritev,
250
diff --git a/block/throttle.c b/block/throttle.c
251
index XXXXXXX..XXXXXXX 100644
252
--- a/block/throttle.c
253
+++ b/block/throttle.c
254
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_throttle = {
255
.bdrv_close = throttle_close,
256
.bdrv_co_flush = throttle_co_flush,
257
258
- .bdrv_child_perm = bdrv_filter_default_perms,
259
+ .bdrv_child_perm = bdrv_default_perms,
260
261
.bdrv_getlength = throttle_getlength,
262
263
diff --git a/block/vdi.c b/block/vdi.c
264
index XXXXXXX..XXXXXXX 100644
265
--- a/block/vdi.c
266
+++ b/block/vdi.c
267
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_vdi = {
268
.bdrv_open = vdi_open,
269
.bdrv_close = vdi_close,
270
.bdrv_reopen_prepare = vdi_reopen_prepare,
271
- .bdrv_child_perm = bdrv_format_default_perms,
272
+ .bdrv_child_perm = bdrv_default_perms,
273
.bdrv_co_create = vdi_co_create,
274
.bdrv_co_create_opts = vdi_co_create_opts,
275
.bdrv_has_zero_init = vdi_has_zero_init,
276
diff --git a/block/vhdx.c b/block/vhdx.c
277
index XXXXXXX..XXXXXXX 100644
278
--- a/block/vhdx.c
279
+++ b/block/vhdx.c
280
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_vhdx = {
281
.bdrv_open = vhdx_open,
282
.bdrv_close = vhdx_close,
283
.bdrv_reopen_prepare = vhdx_reopen_prepare,
284
- .bdrv_child_perm = bdrv_format_default_perms,
285
+ .bdrv_child_perm = bdrv_default_perms,
286
.bdrv_co_readv = vhdx_co_readv,
287
.bdrv_co_writev = vhdx_co_writev,
288
.bdrv_co_create = vhdx_co_create,
289
diff --git a/block/vmdk.c b/block/vmdk.c
290
index XXXXXXX..XXXXXXX 100644
291
--- a/block/vmdk.c
292
+++ b/block/vmdk.c
293
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_vmdk = {
294
.bdrv_open = vmdk_open,
295
.bdrv_co_check = vmdk_co_check,
296
.bdrv_reopen_prepare = vmdk_reopen_prepare,
297
- .bdrv_child_perm = bdrv_format_default_perms,
298
+ .bdrv_child_perm = bdrv_default_perms,
299
.bdrv_co_preadv = vmdk_co_preadv,
300
.bdrv_co_pwritev = vmdk_co_pwritev,
301
.bdrv_co_pwritev_compressed = vmdk_co_pwritev_compressed,
302
diff --git a/block/vpc.c b/block/vpc.c
303
index XXXXXXX..XXXXXXX 100644
304
--- a/block/vpc.c
305
+++ b/block/vpc.c
306
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_vpc = {
307
.bdrv_open = vpc_open,
308
.bdrv_close = vpc_close,
309
.bdrv_reopen_prepare = vpc_reopen_prepare,
310
- .bdrv_child_perm = bdrv_format_default_perms,
311
+ .bdrv_child_perm = bdrv_default_perms,
312
.bdrv_co_create = vpc_co_create,
313
.bdrv_co_create_opts = vpc_co_create_opts,
314
315
diff --git a/tests/test-bdrv-drain.c b/tests/test-bdrv-drain.c
316
index XXXXXXX..XXXXXXX 100644
317
--- a/tests/test-bdrv-drain.c
318
+++ b/tests/test-bdrv-drain.c
319
@@ -XXX,XX +XXX,XX @@ static void bdrv_test_child_perm(BlockDriverState *bs, BdrvChild *c,
320
uint64_t *nperm, uint64_t *nshared)
321
{
322
/*
323
- * bdrv_format_default_perms() accepts only these two, so disguise
324
+ * bdrv_default_perms() accepts only these two, so disguise
325
* detach_by_driver_cb_parent as one of them.
326
*/
327
if (child_class != &child_file && child_class != &child_of_bds) {
328
child_class = &child_of_bds;
329
}
330
331
- bdrv_format_default_perms(bs, c, child_class, role, reopen_queue,
332
- perm, shared, nperm, nshared);
333
+ bdrv_default_perms(bs, c, child_class, role, reopen_queue,
334
+ perm, shared, nperm, nshared);
335
}
336
337
static int bdrv_test_change_backing_file(BlockDriverState *bs,
338
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_test_top_driver = {
339
.bdrv_close = bdrv_test_top_close,
340
.bdrv_co_preadv = bdrv_test_top_co_preadv,
341
342
- .bdrv_child_perm = bdrv_format_default_perms,
343
+ .bdrv_child_perm = bdrv_default_perms,
344
};
345
346
typedef struct TestCoDeleteByDrainData {
347
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_replace_test = {
348
.bdrv_co_drain_begin = bdrv_replace_test_co_drain_begin,
349
.bdrv_co_drain_end = bdrv_replace_test_co_drain_end,
350
351
- .bdrv_child_perm = bdrv_format_default_perms,
352
+ .bdrv_child_perm = bdrv_default_perms,
353
};
354
355
static void coroutine_fn test_replace_child_mid_drain_read_co(void *opaque)
356
diff --git a/tests/test-bdrv-graph-mod.c b/tests/test-bdrv-graph-mod.c
357
index XXXXXXX..XXXXXXX 100644
358
--- a/tests/test-bdrv-graph-mod.c
359
+++ b/tests/test-bdrv-graph-mod.c
360
@@ -XXX,XX +XXX,XX @@
361
362
static BlockDriver bdrv_pass_through = {
363
.format_name = "pass-through",
364
- .bdrv_child_perm = bdrv_filter_default_perms,
365
+ .bdrv_child_perm = bdrv_default_perms,
366
};
367
368
static void no_perm_default_perms(BlockDriverState *bs, BdrvChild *c,
369
diff --git a/tests/test-block-iothread.c b/tests/test-block-iothread.c
370
index XXXXXXX..XXXXXXX 100644
371
--- a/tests/test-block-iothread.c
372
+++ b/tests/test-block-iothread.c
373
@@ -XXX,XX +XXX,XX @@ static void test_propagate_basic(void)
374
BlockDriverState *bs_a, *bs_b, *bs_verify;
375
QDict *options;
376
377
- /* Create bs_a and its BlockBackend */
378
- blk = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL);
379
+ /*
380
+ * Create bs_a and its BlockBackend. We cannot take the RESIZE
381
+ * permission because blkverify will not share it on the test
382
+ * image.
383
+ */
384
+ blk = blk_new(qemu_get_aio_context(), BLK_PERM_ALL & ~BLK_PERM_RESIZE,
385
+ BLK_PERM_ALL);
386
bs_a = bdrv_new_open_driver(&bdrv_test, "bs_a", BDRV_O_RDWR, &error_abort);
387
blk_insert_bs(blk, bs_a, &error_abort);
388
389
@@ -XXX,XX +XXX,XX @@ static void test_propagate_diamond(void)
390
qdict_put_str(options, "raw", "bs_c");
391
392
bs_verify = bdrv_open(NULL, NULL, options, BDRV_O_RDWR, &error_abort);
393
- blk = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL);
394
+ /*
395
+ * Do not take the RESIZE permission: This would require the same
396
+ * from bs_c and thus from bs_a; however, blkverify will not share
397
+ * it on bs_b, and thus it will not be available for bs_a.
398
+ */
399
+ blk = blk_new(qemu_get_aio_context(), BLK_PERM_ALL & ~BLK_PERM_RESIZE,
400
+ BLK_PERM_ALL);
401
blk_insert_bs(blk, bs_verify, &error_abort);
402
403
/* Switch the AioContext */
115
--
404
--
116
2.20.1
405
2.25.4
117
406
118
407
diff view generated by jsdifflib
New patch
1
From: Max Reitz <mreitz@redhat.com>
1
2
3
Signed-off-by: Max Reitz <mreitz@redhat.com>
4
Reviewed-by: Eric Blake <eblake@redhat.com>
5
Message-Id: <20200513110544.176672-31-mreitz@redhat.com>
6
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
7
---
8
include/block/block_int.h | 10 ----------
9
block.c | 17 +++++++++++------
10
2 files changed, 11 insertions(+), 16 deletions(-)
11
12
diff --git a/include/block/block_int.h b/include/block/block_int.h
13
index XXXXXXX..XXXXXXX 100644
14
--- a/include/block/block_int.h
15
+++ b/include/block/block_int.h
16
@@ -XXX,XX +XXX,XX @@ int bdrv_child_try_set_perm(BdrvChild *c, uint64_t perm, uint64_t shared,
17
*/
18
int bdrv_child_refresh_perms(BlockDriverState *bs, BdrvChild *c, Error **errp);
19
20
-/* Default implementation for BlockDriver.bdrv_child_perm() that can be used by
21
- * block filters: Forward CONSISTENT_READ, WRITE, WRITE_UNCHANGED and RESIZE to
22
- * all children */
23
-void bdrv_filter_default_perms(BlockDriverState *bs, BdrvChild *c,
24
- const BdrvChildClass *child_class,
25
- BdrvChildRole child_role,
26
- BlockReopenQueue *reopen_queue,
27
- uint64_t perm, uint64_t shared,
28
- uint64_t *nperm, uint64_t *nshared);
29
-
30
/* Default implementation for BlockDriver.bdrv_child_perm() that can be used by
31
* (non-raw) image formats: Like above for bs->backing, but for bs->file it
32
* requires WRITE | RESIZE for read-write images, always requires
33
diff --git a/block.c b/block.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/block.c
36
+++ b/block.c
37
@@ -XXX,XX +XXX,XX @@ int bdrv_child_refresh_perms(BlockDriverState *bs, BdrvChild *c, Error **errp)
38
return bdrv_child_try_set_perm(c, perms, shared, errp);
39
}
40
41
-void bdrv_filter_default_perms(BlockDriverState *bs, BdrvChild *c,
42
- const BdrvChildClass *child_class,
43
- BdrvChildRole role,
44
- BlockReopenQueue *reopen_queue,
45
- uint64_t perm, uint64_t shared,
46
- uint64_t *nperm, uint64_t *nshared)
47
+/*
48
+ * Default implementation for .bdrv_child_perm() for block filters:
49
+ * Forward CONSISTENT_READ, WRITE, WRITE_UNCHANGED, and RESIZE to the
50
+ * filtered child.
51
+ */
52
+static void bdrv_filter_default_perms(BlockDriverState *bs, BdrvChild *c,
53
+ const BdrvChildClass *child_class,
54
+ BdrvChildRole role,
55
+ BlockReopenQueue *reopen_queue,
56
+ uint64_t perm, uint64_t shared,
57
+ uint64_t *nperm, uint64_t *nshared)
58
{
59
*nperm = perm & DEFAULT_PERM_PASSTHROUGH;
60
*nshared = (shared & DEFAULT_PERM_PASSTHROUGH) | DEFAULT_PERM_UNCHANGED;
61
--
62
2.25.4
63
64
diff view generated by jsdifflib
New patch
1
From: Max Reitz <mreitz@redhat.com>
1
2
3
Signed-off-by: Max Reitz <mreitz@redhat.com>
4
Reviewed-by: Eric Blake <eblake@redhat.com>
5
Message-Id: <20200513110544.176672-32-mreitz@redhat.com>
6
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
7
---
8
include/block/block_int.h | 11 -----------
9
block.c | 19 -------------------
10
2 files changed, 30 deletions(-)
11
12
diff --git a/include/block/block_int.h b/include/block/block_int.h
13
index XXXXXXX..XXXXXXX 100644
14
--- a/include/block/block_int.h
15
+++ b/include/block/block_int.h
16
@@ -XXX,XX +XXX,XX @@ int bdrv_child_try_set_perm(BdrvChild *c, uint64_t perm, uint64_t shared,
17
*/
18
int bdrv_child_refresh_perms(BlockDriverState *bs, BdrvChild *c, Error **errp);
19
20
-/* Default implementation for BlockDriver.bdrv_child_perm() that can be used by
21
- * (non-raw) image formats: Like above for bs->backing, but for bs->file it
22
- * requires WRITE | RESIZE for read-write images, always requires
23
- * CONSISTENT_READ and doesn't share WRITE. */
24
-void bdrv_format_default_perms(BlockDriverState *bs, BdrvChild *c,
25
- const BdrvChildClass *child_class,
26
- BdrvChildRole child_role,
27
- BlockReopenQueue *reopen_queue,
28
- uint64_t perm, uint64_t shared,
29
- uint64_t *nperm, uint64_t *nshared);
30
-
31
bool bdrv_recurse_can_replace(BlockDriverState *bs,
32
BlockDriverState *to_replace);
33
34
diff --git a/block.c b/block.c
35
index XXXXXXX..XXXXXXX 100644
36
--- a/block.c
37
+++ b/block.c
38
@@ -XXX,XX +XXX,XX @@ static void bdrv_default_perms_for_storage(BlockDriverState *bs, BdrvChild *c,
39
*nshared = shared;
40
}
41
42
-void bdrv_format_default_perms(BlockDriverState *bs, BdrvChild *c,
43
- const BdrvChildClass *child_class,
44
- BdrvChildRole role,
45
- BlockReopenQueue *reopen_queue,
46
- uint64_t perm, uint64_t shared,
47
- uint64_t *nperm, uint64_t *nshared)
48
-{
49
- if (child_class == &child_of_bds) {
50
- bdrv_default_perms(bs, c, child_class, role, reopen_queue,
51
- perm, shared, nperm, nshared);
52
- return;
53
- }
54
-
55
- assert(child_class == &child_file);
56
-
57
- bdrv_default_perms_for_storage(bs, c, child_class, role, reopen_queue,
58
- perm, shared, nperm, nshared);
59
-}
60
-
61
void bdrv_default_perms(BlockDriverState *bs, BdrvChild *c,
62
const BdrvChildClass *child_class, BdrvChildRole role,
63
BlockReopenQueue *reopen_queue,
64
--
65
2.25.4
66
67
diff view generated by jsdifflib
1
Since commit b97511c7bc8, there is no reason for block drivers any more
1
From: Max Reitz <mreitz@redhat.com>
2
to call these functions (see the function comment in block_int.h). They
3
are now just internal helper functions for bdrv_set_aio_context()
4
and can be made static.
5
2
3
Signed-off-by: Max Reitz <mreitz@redhat.com>
4
Message-Id: <20200513110544.176672-33-mreitz@redhat.com>
5
Reviewed-by: Eric Blake <eblake@redhat.com>
6
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
7
---
7
---
8
include/block/block_int.h | 21 ---------------------
8
include/block/block_int.h | 1 -
9
block.c | 6 +++---
9
block.c | 39 ++-------------------------------------
10
2 files changed, 3 insertions(+), 24 deletions(-)
10
tests/test-bdrv-drain.c | 8 +++-----
11
3 files changed, 5 insertions(+), 43 deletions(-)
11
12
12
diff --git a/include/block/block_int.h b/include/block/block_int.h
13
diff --git a/include/block/block_int.h b/include/block/block_int.h
13
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
14
--- a/include/block/block_int.h
15
--- a/include/block/block_int.h
15
+++ b/include/block/block_int.h
16
+++ b/include/block/block_int.h
16
@@ -XXX,XX +XXX,XX @@ void bdrv_parse_filename_strip_prefix(const char *filename, const char *prefix,
17
@@ -XXX,XX +XXX,XX @@ struct BdrvChildClass {
17
void bdrv_add_before_write_notifier(BlockDriverState *bs,
18
};
18
NotifierWithReturn *notifier);
19
19
20
extern const BdrvChildClass child_of_bds;
20
-/**
21
-extern const BdrvChildClass child_file;
21
- * bdrv_detach_aio_context:
22
22
- *
23
struct BdrvChild {
23
- * May be called from .bdrv_detach_aio_context() to detach children from the
24
BlockDriverState *bs;
24
- * current #AioContext. This is only needed by block drivers that manage their
25
- * own children. Both ->file and ->backing are automatically handled and
26
- * block drivers should not call this function on them explicitly.
27
- */
28
-void bdrv_detach_aio_context(BlockDriverState *bs);
29
-
30
-/**
31
- * bdrv_attach_aio_context:
32
- *
33
- * May be called from .bdrv_attach_aio_context() to attach children to the new
34
- * #AioContext. This is only needed by block drivers that manage their own
35
- * children. Both ->file and ->backing are automatically handled and block
36
- * drivers should not call this function on them explicitly.
37
- */
38
-void bdrv_attach_aio_context(BlockDriverState *bs,
39
- AioContext *new_context);
40
-
41
/**
42
* bdrv_add_aio_context_notifier:
43
*
44
diff --git a/block.c b/block.c
25
diff --git a/block.c b/block.c
45
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
46
--- a/block.c
27
--- a/block.c
47
+++ b/block.c
28
+++ b/block.c
48
@@ -XXX,XX +XXX,XX @@ static void bdrv_do_remove_aio_context_notifier(BdrvAioNotifier *ban)
29
@@ -XXX,XX +XXX,XX @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
49
g_free(ban);
30
BdrvChildRole child_role,
31
Error **errp);
32
33
-/* TODO: Remove when no longer needed */
34
-static void bdrv_inherited_options(BdrvChildRole role, bool parent_is_format,
35
- int *child_flags, QDict *child_options,
36
- int parent_flags, QDict *parent_options);
37
-static void bdrv_child_cb_attach(BdrvChild *child);
38
-static void bdrv_child_cb_detach(BdrvChild *child);
39
-
40
/* If non-zero, use only whitelisted block drivers */
41
static int use_bdrv_whitelist;
42
43
@@ -XXX,XX +XXX,XX @@ static void bdrv_temp_snapshot_options(int *child_flags, QDict *child_options,
44
*child_flags &= ~BDRV_O_NATIVE_AIO;
50
}
45
}
51
46
52
-void bdrv_detach_aio_context(BlockDriverState *bs)
47
-/*
53
+static void bdrv_detach_aio_context(BlockDriverState *bs)
48
- * Returns the options and flags that bs->file should get if a protocol driver
49
- * is expected, based on the given options and flags for the parent BDS
50
- */
51
-static void bdrv_protocol_options(BdrvChildRole role, bool parent_is_format,
52
- int *child_flags, QDict *child_options,
53
- int parent_flags, QDict *parent_options)
54
-{
55
- bdrv_inherited_options(BDRV_CHILD_IMAGE, true,
56
- child_flags, child_options,
57
- parent_flags, parent_options);
58
-}
59
-
60
-const BdrvChildClass child_file = {
61
- .parent_is_bds = true,
62
- .get_parent_desc = bdrv_child_get_parent_desc,
63
- .inherit_options = bdrv_protocol_options,
64
- .drained_begin = bdrv_child_cb_drained_begin,
65
- .drained_poll = bdrv_child_cb_drained_poll,
66
- .drained_end = bdrv_child_cb_drained_end,
67
- .attach = bdrv_child_cb_attach,
68
- .detach = bdrv_child_cb_detach,
69
- .inactivate = bdrv_child_cb_inactivate,
70
- .can_set_aio_ctx = bdrv_child_cb_can_set_aio_ctx,
71
- .set_aio_ctx = bdrv_child_cb_set_aio_ctx,
72
-};
73
-
74
static void bdrv_backing_attach(BdrvChild *c)
54
{
75
{
55
BdrvAioNotifier *baf, *baf_tmp;
76
BlockDriverState *parent = c->opaque;
56
BdrvChild *child;
77
@@ -XXX,XX +XXX,XX @@ static void bdrv_default_perms_for_storage(BlockDriverState *bs, BdrvChild *c,
57
@@ -XXX,XX +XXX,XX @@ void bdrv_detach_aio_context(BlockDriverState *bs)
58
bs->aio_context = NULL;
59
}
60
61
-void bdrv_attach_aio_context(BlockDriverState *bs,
62
- AioContext *new_context)
63
+static void bdrv_attach_aio_context(BlockDriverState *bs,
64
+ AioContext *new_context)
65
{
78
{
66
BdrvAioNotifier *ban, *ban_tmp;
79
int flags;
67
BdrvChild *child;
80
81
- assert(child_class == &child_file ||
82
- (child_class == &child_of_bds &&
83
- (role & (BDRV_CHILD_METADATA | BDRV_CHILD_DATA))));
84
+ assert(child_class == &child_of_bds &&
85
+ (role & (BDRV_CHILD_METADATA | BDRV_CHILD_DATA)));
86
87
flags = bdrv_reopen_get_flags(reopen_queue, bs);
88
89
diff --git a/tests/test-bdrv-drain.c b/tests/test-bdrv-drain.c
90
index XXXXXXX..XXXXXXX 100644
91
--- a/tests/test-bdrv-drain.c
92
+++ b/tests/test-bdrv-drain.c
93
@@ -XXX,XX +XXX,XX @@ static void bdrv_test_child_perm(BlockDriverState *bs, BdrvChild *c,
94
uint64_t *nperm, uint64_t *nshared)
95
{
96
/*
97
- * bdrv_default_perms() accepts only these two, so disguise
98
- * detach_by_driver_cb_parent as one of them.
99
+ * bdrv_default_perms() accepts nothing else, so disguise
100
+ * detach_by_driver_cb_parent.
101
*/
102
- if (child_class != &child_file && child_class != &child_of_bds) {
103
- child_class = &child_of_bds;
104
- }
105
+ child_class = &child_of_bds;
106
107
bdrv_default_perms(bs, c, child_class, role, reopen_queue,
108
perm, shared, nperm, nshared);
68
--
109
--
69
2.20.1
110
2.25.4
70
111
71
112
diff view generated by jsdifflib
1
bdrv_try_set_aio_context() currently fails if a BlockBackend is attached
1
From: Max Reitz <mreitz@redhat.com>
2
to a node because it doesn't implement the BdrvChildRole callbacks for
3
AioContext management.
4
2
5
We can allow changing the AioContext of monitor-owned BlockBackends as
3
These calls have no real use for the child role yet, but it will not
6
long as no device is attached to them.
4
harm to give one.
7
5
8
When setting the AioContext of the root node of a BlockBackend, we now
6
Notably, the bdrv_root_attach_child() call in blockjob.c is left
9
need to pass blk->root as an ignored child because we don't want the
7
unmodified because there is not much the generic BlockJob object wants
10
root node to recursively call back into BlockBackend and execute
8
from its children.
11
blk_do_set_aio_context() a second time.
12
9
10
Signed-off-by: Max Reitz <mreitz@redhat.com>
11
Message-Id: <20200513110544.176672-34-mreitz@redhat.com>
12
Reviewed-by: Eric Blake <eblake@redhat.com>
13
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
---
14
---
15
block/block-backend.c | 45 +++++++++++++++++++++++++++++++++++++++++--
15
block/block-backend.c | 11 +++++++----
16
1 file changed, 43 insertions(+), 2 deletions(-)
16
block/vvfat.c | 4 +++-
17
2 files changed, 10 insertions(+), 5 deletions(-)
17
18
18
diff --git a/block/block-backend.c b/block/block-backend.c
19
diff --git a/block/block-backend.c b/block/block-backend.c
19
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
20
--- a/block/block-backend.c
21
--- a/block/block-backend.c
21
+++ b/block/block-backend.c
22
+++ b/block/block-backend.c
22
@@ -XXX,XX +XXX,XX @@ static void blk_root_drained_end(BdrvChild *child);
23
@@ -XXX,XX +XXX,XX @@ BlockBackend *blk_new_open(const char *filename, const char *reference,
23
static void blk_root_change_media(BdrvChild *child, bool load);
24
return NULL;
24
static void blk_root_resize(BdrvChild *child);
25
}
25
26
26
+static bool blk_root_can_set_aio_ctx(BdrvChild *child, AioContext *ctx,
27
- blk->root = bdrv_root_attach_child(bs, "root", &child_root, 0, blk->ctx,
27
+ GSList **ignore, Error **errp);
28
- perm, BLK_PERM_ALL, blk, errp);
28
+static void blk_root_set_aio_ctx(BdrvChild *child, AioContext *ctx,
29
+ blk->root = bdrv_root_attach_child(bs, "root", &child_root,
29
+ GSList **ignore);
30
+ BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY,
30
+
31
+ blk->ctx, perm, BLK_PERM_ALL, blk, errp);
31
static char *blk_root_get_parent_desc(BdrvChild *child)
32
if (!blk->root) {
33
blk_unref(blk);
34
return NULL;
35
@@ -XXX,XX +XXX,XX @@ int blk_insert_bs(BlockBackend *blk, BlockDriverState *bs, Error **errp)
32
{
36
{
33
BlockBackend *blk = child->opaque;
34
@@ -XXX,XX +XXX,XX @@ static const BdrvChildRole child_root = {
35
36
.attach = blk_root_attach,
37
.detach = blk_root_detach,
38
+
39
+ .can_set_aio_ctx = blk_root_can_set_aio_ctx,
40
+ .set_aio_ctx = blk_root_set_aio_ctx,
41
};
42
43
/*
44
@@ -XXX,XX +XXX,XX @@ static AioContext *blk_aiocb_get_aio_context(BlockAIOCB *acb)
45
return blk_get_aio_context(blk_acb->blk);
46
}
47
48
-void blk_set_aio_context(BlockBackend *blk, AioContext *new_context)
49
+static void blk_do_set_aio_context(BlockBackend *blk, AioContext *new_context,
50
+ bool update_root_node)
51
{
52
BlockDriverState *bs = blk_bs(blk);
53
ThrottleGroupMember *tgm = &blk->public.throttle_group_member;
37
ThrottleGroupMember *tgm = &blk->public.throttle_group_member;
54
@@ -XXX,XX +XXX,XX @@ void blk_set_aio_context(BlockBackend *blk, AioContext *new_context)
38
bdrv_ref(bs);
55
throttle_group_attach_aio_context(tgm, new_context);
39
- blk->root = bdrv_root_attach_child(bs, "root", &child_root, 0, blk->ctx,
56
bdrv_drained_end(bs);
40
- blk->perm, blk->shared_perm, blk, errp);
57
}
41
+ blk->root = bdrv_root_attach_child(bs, "root", &child_root,
58
- bdrv_set_aio_context(bs, new_context);
42
+ BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY,
59
+ if (update_root_node) {
43
+ blk->ctx, blk->perm, blk->shared_perm,
60
+ GSList *ignore = g_slist_prepend(NULL, blk->root);
44
+ blk, errp);
61
+ bdrv_set_aio_context_ignore(bs, new_context, &ignore);
45
if (blk->root == NULL) {
62
+ g_slist_free(ignore);
46
return -EPERM;
63
+ }
64
}
47
}
65
}
48
diff --git a/block/vvfat.c b/block/vvfat.c
66
49
index XXXXXXX..XXXXXXX 100644
67
+void blk_set_aio_context(BlockBackend *blk, AioContext *new_context)
50
--- a/block/vvfat.c
68
+{
51
+++ b/block/vvfat.c
69
+ blk_do_set_aio_context(blk, new_context, true);
52
@@ -XXX,XX +XXX,XX @@ static int enable_write_target(BlockDriverState *bs, Error **errp)
70
+}
53
options = qdict_new();
71
+
54
qdict_put_str(options, "write-target.driver", "qcow");
72
+static bool blk_root_can_set_aio_ctx(BdrvChild *child, AioContext *ctx,
55
s->qcow = bdrv_open_child(s->qcow_filename, options, "write-target", bs,
73
+ GSList **ignore, Error **errp)
56
- &child_vvfat_qcow, 0, false, errp);
74
+{
57
+ &child_vvfat_qcow,
75
+ BlockBackend *blk = child->opaque;
58
+ BDRV_CHILD_DATA | BDRV_CHILD_METADATA,
76
+
59
+ false, errp);
77
+ /* Only manually created BlockBackends that are not attached to anything
60
qobject_unref(options);
78
+ * can change their AioContext without updating their user. */
61
if (!s->qcow) {
79
+ if (!blk->name || blk->dev) {
62
ret = -EINVAL;
80
+ /* TODO Add BB name/QOM path */
81
+ error_setg(errp, "Cannot change iothread of active block backend");
82
+ return false;
83
+ }
84
+
85
+ return true;
86
+}
87
+
88
+static void blk_root_set_aio_ctx(BdrvChild *child, AioContext *ctx,
89
+ GSList **ignore)
90
+{
91
+ BlockBackend *blk = child->opaque;
92
+ blk_do_set_aio_context(blk, ctx, false);
93
+}
94
+
95
void blk_add_aio_context_notifier(BlockBackend *blk,
96
void (*attached_aio_context)(AioContext *new_context, void *opaque),
97
void (*detach_aio_context)(void *opaque), void *opaque)
98
--
63
--
99
2.20.1
64
2.25.4
100
65
101
66
diff view generated by jsdifflib
New patch
1
1
From: Max Reitz <mreitz@redhat.com>
2
3
Implementations should decide the necessary permissions based on @role.
4
5
Signed-off-by: Max Reitz <mreitz@redhat.com>
6
Message-Id: <20200513110544.176672-35-mreitz@redhat.com>
7
Reviewed-by: Eric Blake <eblake@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
---
10
include/block/block_int.h | 4 +---
11
block.c | 39 +++++++++++++++----------------------
12
block/backup-top.c | 3 +--
13
block/blkdebug.c | 3 +--
14
block/blklogwrites.c | 3 +--
15
block/commit.c | 1 -
16
block/copy-on-read.c | 1 -
17
block/mirror.c | 1 -
18
block/quorum.c | 1 -
19
block/replication.c | 1 -
20
block/vvfat.c | 4 +---
21
tests/test-bdrv-drain.c | 19 +-----------------
22
tests/test-bdrv-graph-mod.c | 1 -
23
13 files changed, 22 insertions(+), 59 deletions(-)
24
25
diff --git a/include/block/block_int.h b/include/block/block_int.h
26
index XXXXXXX..XXXXXXX 100644
27
--- a/include/block/block_int.h
28
+++ b/include/block/block_int.h
29
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
30
* @reopen_queue.
31
*/
32
void (*bdrv_child_perm)(BlockDriverState *bs, BdrvChild *c,
33
- const BdrvChildClass *child_class,
34
BdrvChildRole role,
35
BlockReopenQueue *reopen_queue,
36
uint64_t parent_perm, uint64_t parent_shared,
37
@@ -XXX,XX +XXX,XX @@ bool bdrv_recurse_can_replace(BlockDriverState *bs,
38
* child_of_bds child class and set an appropriate BdrvChildRole.
39
*/
40
void bdrv_default_perms(BlockDriverState *bs, BdrvChild *c,
41
- const BdrvChildClass *child_class, BdrvChildRole role,
42
- BlockReopenQueue *reopen_queue,
43
+ BdrvChildRole role, BlockReopenQueue *reopen_queue,
44
uint64_t perm, uint64_t shared,
45
uint64_t *nperm, uint64_t *nshared);
46
47
diff --git a/block.c b/block.c
48
index XXXXXXX..XXXXXXX 100644
49
--- a/block.c
50
+++ b/block.c
51
@@ -XXX,XX +XXX,XX @@ bool bdrv_is_writable(BlockDriverState *bs)
52
}
53
54
static void bdrv_child_perm(BlockDriverState *bs, BlockDriverState *child_bs,
55
- BdrvChild *c, const BdrvChildClass *child_class,
56
- BdrvChildRole role, BlockReopenQueue *reopen_queue,
57
+ BdrvChild *c, BdrvChildRole role,
58
+ BlockReopenQueue *reopen_queue,
59
uint64_t parent_perm, uint64_t parent_shared,
60
uint64_t *nperm, uint64_t *nshared)
61
{
62
assert(bs->drv && bs->drv->bdrv_child_perm);
63
- bs->drv->bdrv_child_perm(bs, c, child_class, role, reopen_queue,
64
+ bs->drv->bdrv_child_perm(bs, c, role, reopen_queue,
65
parent_perm, parent_shared,
66
nperm, nshared);
67
/* TODO Take force_share from reopen_queue */
68
@@ -XXX,XX +XXX,XX @@ static int bdrv_check_perm(BlockDriverState *bs, BlockReopenQueue *q,
69
uint64_t cur_perm, cur_shared;
70
bool child_tighten_restr;
71
72
- bdrv_child_perm(bs, c->bs, c, c->klass, c->role, q,
73
+ bdrv_child_perm(bs, c->bs, c, c->role, q,
74
cumulative_perms, cumulative_shared_perms,
75
&cur_perm, &cur_shared);
76
ret = bdrv_child_check_perm(c, q, cur_perm, cur_shared, ignore_children,
77
@@ -XXX,XX +XXX,XX @@ static void bdrv_set_perm(BlockDriverState *bs, uint64_t cumulative_perms,
78
/* Update all children */
79
QLIST_FOREACH(c, &bs->children, next) {
80
uint64_t cur_perm, cur_shared;
81
- bdrv_child_perm(bs, c->bs, c, c->klass, c->role, NULL,
82
+ bdrv_child_perm(bs, c->bs, c, c->role, NULL,
83
cumulative_perms, cumulative_shared_perms,
84
&cur_perm, &cur_shared);
85
bdrv_child_set_perm(c, cur_perm, cur_shared);
86
@@ -XXX,XX +XXX,XX @@ int bdrv_child_refresh_perms(BlockDriverState *bs, BdrvChild *c, Error **errp)
87
uint64_t perms, shared;
88
89
bdrv_get_cumulative_perm(bs, &parent_perms, &parent_shared);
90
- bdrv_child_perm(bs, c->bs, c, c->klass, c->role, NULL,
91
+ bdrv_child_perm(bs, c->bs, c, c->role, NULL,
92
parent_perms, parent_shared, &perms, &shared);
93
94
return bdrv_child_try_set_perm(c, perms, shared, errp);
95
@@ -XXX,XX +XXX,XX @@ int bdrv_child_refresh_perms(BlockDriverState *bs, BdrvChild *c, Error **errp)
96
* filtered child.
97
*/
98
static void bdrv_filter_default_perms(BlockDriverState *bs, BdrvChild *c,
99
- const BdrvChildClass *child_class,
100
BdrvChildRole role,
101
BlockReopenQueue *reopen_queue,
102
uint64_t perm, uint64_t shared,
103
@@ -XXX,XX +XXX,XX @@ static void bdrv_filter_default_perms(BlockDriverState *bs, BdrvChild *c,
104
}
105
106
static void bdrv_default_perms_for_cow(BlockDriverState *bs, BdrvChild *c,
107
- const BdrvChildClass *child_class,
108
BdrvChildRole role,
109
BlockReopenQueue *reopen_queue,
110
uint64_t perm, uint64_t shared,
111
uint64_t *nperm, uint64_t *nshared)
112
{
113
- assert(child_class == &child_of_bds && (role & BDRV_CHILD_COW));
114
+ assert(role & BDRV_CHILD_COW);
115
116
/*
117
* We want consistent read from backing files if the parent needs it.
118
@@ -XXX,XX +XXX,XX @@ static void bdrv_default_perms_for_cow(BlockDriverState *bs, BdrvChild *c,
119
}
120
121
static void bdrv_default_perms_for_storage(BlockDriverState *bs, BdrvChild *c,
122
- const BdrvChildClass *child_class,
123
BdrvChildRole role,
124
BlockReopenQueue *reopen_queue,
125
uint64_t perm, uint64_t shared,
126
@@ -XXX,XX +XXX,XX @@ static void bdrv_default_perms_for_storage(BlockDriverState *bs, BdrvChild *c,
127
{
128
int flags;
129
130
- assert(child_class == &child_of_bds &&
131
- (role & (BDRV_CHILD_METADATA | BDRV_CHILD_DATA)));
132
+ assert(role & (BDRV_CHILD_METADATA | BDRV_CHILD_DATA));
133
134
flags = bdrv_reopen_get_flags(reopen_queue, bs);
135
136
@@ -XXX,XX +XXX,XX @@ static void bdrv_default_perms_for_storage(BlockDriverState *bs, BdrvChild *c,
137
* Apart from the modifications below, the same permissions are
138
* forwarded and left alone as for filters
139
*/
140
- bdrv_filter_default_perms(bs, c, child_class, role, reopen_queue,
141
+ bdrv_filter_default_perms(bs, c, role, reopen_queue,
142
perm, shared, &perm, &shared);
143
144
if (role & BDRV_CHILD_METADATA) {
145
@@ -XXX,XX +XXX,XX @@ static void bdrv_default_perms_for_storage(BlockDriverState *bs, BdrvChild *c,
146
}
147
148
void bdrv_default_perms(BlockDriverState *bs, BdrvChild *c,
149
- const BdrvChildClass *child_class, BdrvChildRole role,
150
- BlockReopenQueue *reopen_queue,
151
+ BdrvChildRole role, BlockReopenQueue *reopen_queue,
152
uint64_t perm, uint64_t shared,
153
uint64_t *nperm, uint64_t *nshared)
154
{
155
- assert(child_class == &child_of_bds);
156
-
157
if (role & BDRV_CHILD_FILTERED) {
158
assert(!(role & (BDRV_CHILD_DATA | BDRV_CHILD_METADATA |
159
BDRV_CHILD_COW)));
160
- bdrv_filter_default_perms(bs, c, child_class, role, reopen_queue,
161
+ bdrv_filter_default_perms(bs, c, role, reopen_queue,
162
perm, shared, nperm, nshared);
163
} else if (role & BDRV_CHILD_COW) {
164
assert(!(role & (BDRV_CHILD_DATA | BDRV_CHILD_METADATA)));
165
- bdrv_default_perms_for_cow(bs, c, child_class, role, reopen_queue,
166
+ bdrv_default_perms_for_cow(bs, c, role, reopen_queue,
167
perm, shared, nperm, nshared);
168
} else if (role & (BDRV_CHILD_METADATA | BDRV_CHILD_DATA)) {
169
- bdrv_default_perms_for_storage(bs, c, child_class, role, reopen_queue,
170
+ bdrv_default_perms_for_storage(bs, c, role, reopen_queue,
171
perm, shared, nperm, nshared);
172
} else {
173
g_assert_not_reached();
174
@@ -XXX,XX +XXX,XX @@ BdrvChild *bdrv_attach_child(BlockDriverState *parent_bs,
175
bdrv_get_cumulative_perm(parent_bs, &perm, &shared_perm);
176
177
assert(parent_bs->drv);
178
- bdrv_child_perm(parent_bs, child_bs, NULL, child_class, child_role, NULL,
179
+ bdrv_child_perm(parent_bs, child_bs, NULL, child_role, NULL,
180
perm, shared_perm, &perm, &shared_perm);
181
182
child = bdrv_root_attach_child(child_bs, child_name, child_class,
183
@@ -XXX,XX +XXX,XX @@ int bdrv_reopen_multiple(BlockReopenQueue *bs_queue, Error **errp)
184
if (state->replace_backing_bs && state->new_backing_bs) {
185
uint64_t nperm, nshared;
186
bdrv_child_perm(state->bs, state->new_backing_bs,
187
- NULL, &child_of_bds, bdrv_backing_role(state->bs),
188
+ NULL, bdrv_backing_role(state->bs),
189
bs_queue, state->perm, state->shared_perm,
190
&nperm, &nshared);
191
ret = bdrv_check_update_perm(state->new_backing_bs, NULL,
192
@@ -XXX,XX +XXX,XX @@ static void bdrv_reopen_perm(BlockReopenQueue *q, BlockDriverState *bs,
193
} else {
194
uint64_t nperm, nshared;
195
196
- bdrv_child_perm(parent->state.bs, bs, c, c->klass, c->role, q,
197
+ bdrv_child_perm(parent->state.bs, bs, c, c->role, q,
198
parent->state.perm, parent->state.shared_perm,
199
&nperm, &nshared);
200
201
diff --git a/block/backup-top.c b/block/backup-top.c
202
index XXXXXXX..XXXXXXX 100644
203
--- a/block/backup-top.c
204
+++ b/block/backup-top.c
205
@@ -XXX,XX +XXX,XX @@ static void backup_top_refresh_filename(BlockDriverState *bs)
206
}
207
208
static void backup_top_child_perm(BlockDriverState *bs, BdrvChild *c,
209
- const BdrvChildClass *child_class,
210
BdrvChildRole role,
211
BlockReopenQueue *reopen_queue,
212
uint64_t perm, uint64_t shared,
213
@@ -XXX,XX +XXX,XX @@ static void backup_top_child_perm(BlockDriverState *bs, BdrvChild *c,
214
*nperm = BLK_PERM_WRITE;
215
} else {
216
/* Source child */
217
- bdrv_default_perms(bs, c, child_class, role, reopen_queue,
218
+ bdrv_default_perms(bs, c, role, reopen_queue,
219
perm, shared, nperm, nshared);
220
221
if (perm & BLK_PERM_WRITE) {
222
diff --git a/block/blkdebug.c b/block/blkdebug.c
223
index XXXXXXX..XXXXXXX 100644
224
--- a/block/blkdebug.c
225
+++ b/block/blkdebug.c
226
@@ -XXX,XX +XXX,XX @@ static int blkdebug_reopen_prepare(BDRVReopenState *reopen_state,
227
}
228
229
static void blkdebug_child_perm(BlockDriverState *bs, BdrvChild *c,
230
- const BdrvChildClass *child_class,
231
BdrvChildRole role,
232
BlockReopenQueue *reopen_queue,
233
uint64_t perm, uint64_t shared,
234
@@ -XXX,XX +XXX,XX @@ static void blkdebug_child_perm(BlockDriverState *bs, BdrvChild *c,
235
{
236
BDRVBlkdebugState *s = bs->opaque;
237
238
- bdrv_default_perms(bs, c, child_class, role, reopen_queue,
239
+ bdrv_default_perms(bs, c, role, reopen_queue,
240
perm, shared, nperm, nshared);
241
242
*nperm |= s->take_child_perms;
243
diff --git a/block/blklogwrites.c b/block/blklogwrites.c
244
index XXXXXXX..XXXXXXX 100644
245
--- a/block/blklogwrites.c
246
+++ b/block/blklogwrites.c
247
@@ -XXX,XX +XXX,XX @@ static int64_t blk_log_writes_getlength(BlockDriverState *bs)
248
}
249
250
static void blk_log_writes_child_perm(BlockDriverState *bs, BdrvChild *c,
251
- const BdrvChildClass *child_class,
252
BdrvChildRole role,
253
BlockReopenQueue *ro_q,
254
uint64_t perm, uint64_t shrd,
255
@@ -XXX,XX +XXX,XX @@ static void blk_log_writes_child_perm(BlockDriverState *bs, BdrvChild *c,
256
return;
257
}
258
259
- bdrv_default_perms(bs, c, child_class, role, ro_q, perm, shrd,
260
+ bdrv_default_perms(bs, c, role, ro_q, perm, shrd,
261
nperm, nshrd);
262
}
263
264
diff --git a/block/commit.c b/block/commit.c
265
index XXXXXXX..XXXXXXX 100644
266
--- a/block/commit.c
267
+++ b/block/commit.c
268
@@ -XXX,XX +XXX,XX @@ static void bdrv_commit_top_refresh_filename(BlockDriverState *bs)
269
}
270
271
static void bdrv_commit_top_child_perm(BlockDriverState *bs, BdrvChild *c,
272
- const BdrvChildClass *child_class,
273
BdrvChildRole role,
274
BlockReopenQueue *reopen_queue,
275
uint64_t perm, uint64_t shared,
276
diff --git a/block/copy-on-read.c b/block/copy-on-read.c
277
index XXXXXXX..XXXXXXX 100644
278
--- a/block/copy-on-read.c
279
+++ b/block/copy-on-read.c
280
@@ -XXX,XX +XXX,XX @@ static int cor_open(BlockDriverState *bs, QDict *options, int flags,
281
#define PERM_UNCHANGED (BLK_PERM_ALL & ~PERM_PASSTHROUGH)
282
283
static void cor_child_perm(BlockDriverState *bs, BdrvChild *c,
284
- const BdrvChildClass *child_class,
285
BdrvChildRole role,
286
BlockReopenQueue *reopen_queue,
287
uint64_t perm, uint64_t shared,
288
diff --git a/block/mirror.c b/block/mirror.c
289
index XXXXXXX..XXXXXXX 100644
290
--- a/block/mirror.c
291
+++ b/block/mirror.c
292
@@ -XXX,XX +XXX,XX @@ static void bdrv_mirror_top_refresh_filename(BlockDriverState *bs)
293
}
294
295
static void bdrv_mirror_top_child_perm(BlockDriverState *bs, BdrvChild *c,
296
- const BdrvChildClass *child_class,
297
BdrvChildRole role,
298
BlockReopenQueue *reopen_queue,
299
uint64_t perm, uint64_t shared,
300
diff --git a/block/quorum.c b/block/quorum.c
301
index XXXXXXX..XXXXXXX 100644
302
--- a/block/quorum.c
303
+++ b/block/quorum.c
304
@@ -XXX,XX +XXX,XX @@ static char *quorum_dirname(BlockDriverState *bs, Error **errp)
305
}
306
307
static void quorum_child_perm(BlockDriverState *bs, BdrvChild *c,
308
- const BdrvChildClass *child_class,
309
BdrvChildRole role,
310
BlockReopenQueue *reopen_queue,
311
uint64_t perm, uint64_t shared,
312
diff --git a/block/replication.c b/block/replication.c
313
index XXXXXXX..XXXXXXX 100644
314
--- a/block/replication.c
315
+++ b/block/replication.c
316
@@ -XXX,XX +XXX,XX @@ static void replication_close(BlockDriverState *bs)
317
}
318
319
static void replication_child_perm(BlockDriverState *bs, BdrvChild *c,
320
- const BdrvChildClass *child_class,
321
BdrvChildRole role,
322
BlockReopenQueue *reopen_queue,
323
uint64_t perm, uint64_t shared,
324
diff --git a/block/vvfat.c b/block/vvfat.c
325
index XXXXXXX..XXXXXXX 100644
326
--- a/block/vvfat.c
327
+++ b/block/vvfat.c
328
@@ -XXX,XX +XXX,XX @@ err:
329
}
330
331
static void vvfat_child_perm(BlockDriverState *bs, BdrvChild *c,
332
- const BdrvChildClass *child_class,
333
BdrvChildRole role,
334
BlockReopenQueue *reopen_queue,
335
uint64_t perm, uint64_t shared,
336
@@ -XXX,XX +XXX,XX @@ static void vvfat_child_perm(BlockDriverState *bs, BdrvChild *c,
337
{
338
BDRVVVFATState *s = bs->opaque;
339
340
- assert(c == s->qcow ||
341
- (child_class == &child_of_bds && (role & BDRV_CHILD_COW)));
342
+ assert(c == s->qcow || (role & BDRV_CHILD_COW));
343
344
if (c == s->qcow) {
345
/* This is a private node, nobody should try to attach to it */
346
diff --git a/tests/test-bdrv-drain.c b/tests/test-bdrv-drain.c
347
index XXXXXXX..XXXXXXX 100644
348
--- a/tests/test-bdrv-drain.c
349
+++ b/tests/test-bdrv-drain.c
350
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_test_co_preadv(BlockDriverState *bs,
351
return 0;
352
}
353
354
-static void bdrv_test_child_perm(BlockDriverState *bs, BdrvChild *c,
355
- const BdrvChildClass *child_class,
356
- BdrvChildRole role,
357
- BlockReopenQueue *reopen_queue,
358
- uint64_t perm, uint64_t shared,
359
- uint64_t *nperm, uint64_t *nshared)
360
-{
361
- /*
362
- * bdrv_default_perms() accepts nothing else, so disguise
363
- * detach_by_driver_cb_parent.
364
- */
365
- child_class = &child_of_bds;
366
-
367
- bdrv_default_perms(bs, c, child_class, role, reopen_queue,
368
- perm, shared, nperm, nshared);
369
-}
370
-
371
static int bdrv_test_change_backing_file(BlockDriverState *bs,
372
const char *backing_file,
373
const char *backing_fmt)
374
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_test = {
375
.bdrv_co_drain_begin = bdrv_test_co_drain_begin,
376
.bdrv_co_drain_end = bdrv_test_co_drain_end,
377
378
- .bdrv_child_perm = bdrv_test_child_perm,
379
+ .bdrv_child_perm = bdrv_default_perms,
380
381
.bdrv_change_backing_file = bdrv_test_change_backing_file,
382
};
383
diff --git a/tests/test-bdrv-graph-mod.c b/tests/test-bdrv-graph-mod.c
384
index XXXXXXX..XXXXXXX 100644
385
--- a/tests/test-bdrv-graph-mod.c
386
+++ b/tests/test-bdrv-graph-mod.c
387
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_pass_through = {
388
};
389
390
static void no_perm_default_perms(BlockDriverState *bs, BdrvChild *c,
391
- const BdrvChildClass *child_class,
392
BdrvChildRole role,
393
BlockReopenQueue *reopen_queue,
394
uint64_t perm, uint64_t shared,
395
--
396
2.25.4
397
398
diff view generated by jsdifflib
1
From: Klaus Birkelund Jensen <klaus@birkelund.eu>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
`nvme_dma_read_prp` erronously used `qemu_iovec_*to*_buf` instead of
3
Fix when building with -Os:
4
`qemu_iovec_*from*_buf` when the request involved the controller memory
5
buffer.
6
4
7
Signed-off-by: Klaus Birkelund Jensen <klaus.jensen@cnexlabs.com>
5
CC block/block-copy.o
8
Reviewed-by: Kenneth Heitke <kenneth.heitke@intel.com>
6
block/block-copy.c: In function ‘block_copy_task_entry’:
7
block/block-copy.c:428:38: error: ‘error_is_read’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
8
428 | t->call_state->error_is_read = error_is_read;
9
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~
10
11
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
12
Message-Id: <20200507121129.29760-2-philmd@redhat.com>
13
Reviewed-by: Eric Blake <eblake@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
15
---
11
hw/block/nvme.c | 2 +-
16
block/block-copy.c | 2 +-
12
1 file changed, 1 insertion(+), 1 deletion(-)
17
1 file changed, 1 insertion(+), 1 deletion(-)
13
18
14
diff --git a/hw/block/nvme.c b/hw/block/nvme.c
19
diff --git a/block/block-copy.c b/block/block-copy.c
15
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/block/nvme.c
21
--- a/block/block-copy.c
17
+++ b/hw/block/nvme.c
22
+++ b/block/block-copy.c
18
@@ -XXX,XX +XXX,XX @@ static uint16_t nvme_dma_read_prp(NvmeCtrl *n, uint8_t *ptr, uint32_t len,
23
@@ -XXX,XX +XXX,XX @@ out:
19
}
24
static coroutine_fn int block_copy_task_entry(AioTask *task)
20
qemu_sglist_destroy(&qsg);
25
{
21
} else {
26
BlockCopyTask *t = container_of(task, BlockCopyTask, task);
22
- if (unlikely(qemu_iovec_to_buf(&iov, 0, ptr, len) != len)) {
27
- bool error_is_read;
23
+ if (unlikely(qemu_iovec_from_buf(&iov, 0, ptr, len) != len)) {
28
+ bool error_is_read = false;
24
trace_nvme_err_invalid_dma();
29
int ret;
25
status = NVME_INVALID_FIELD | NVME_DNR;
30
26
}
31
ret = block_copy_do_copy(t->s, t->offset, t->bytes, t->zeroes,
27
--
32
--
28
2.20.1
33
2.25.4
29
34
30
35
diff view generated by jsdifflib
New patch
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
2
3
block_copy_do_copy() is static, only used in block_copy_task_entry
4
with the error_is_read argument set. No need to check for it,
5
simplify.
6
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Message-Id: <20200507121129.29760-3-philmd@redhat.com>
9
Reviewed-by: Eric Blake <eblake@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
---
12
block/block-copy.c | 12 +++---------
13
1 file changed, 3 insertions(+), 9 deletions(-)
14
15
diff --git a/block/block-copy.c b/block/block-copy.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/block/block-copy.c
18
+++ b/block/block-copy.c
19
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn block_copy_do_copy(BlockCopyState *s,
20
~BDRV_REQ_WRITE_COMPRESSED);
21
if (ret < 0) {
22
trace_block_copy_write_zeroes_fail(s, offset, ret);
23
- if (error_is_read) {
24
- *error_is_read = false;
25
- }
26
+ *error_is_read = false;
27
}
28
return ret;
29
}
30
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn block_copy_do_copy(BlockCopyState *s,
31
ret = bdrv_co_pread(s->source, offset, nbytes, bounce_buffer, 0);
32
if (ret < 0) {
33
trace_block_copy_read_fail(s, offset, ret);
34
- if (error_is_read) {
35
- *error_is_read = true;
36
- }
37
+ *error_is_read = true;
38
goto out;
39
}
40
41
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn block_copy_do_copy(BlockCopyState *s,
42
s->write_flags);
43
if (ret < 0) {
44
trace_block_copy_write_fail(s, offset, ret);
45
- if (error_is_read) {
46
- *error_is_read = false;
47
- }
48
+ *error_is_read = false;
49
goto out;
50
}
51
52
--
53
2.25.4
54
55
diff view generated by jsdifflib
1
From: Max Reitz <mreitz@redhat.com>
1
From: John Snow <jsnow@redhat.com>
2
2
3
Sometimes we cannot tell which error message qemu will emit, and we do
3
Shift the logging initialization up to occur prior to validation checks,
4
not care. With this change, we can then just pass an array of all
4
so that notrun() messages still get printed to console.
5
possible messages to assert_qmp() and it will choose the right one.
6
5
7
Signed-off-by: Max Reitz <mreitz@redhat.com>
6
(Also, remove the "debugging messages active" message, because we don't
8
Reviewed-by: Alberto Garcia <berto@igalia.com>
7
need to see that hundreds of times per iotest suite run.)
8
9
Signed-off-by: John Snow <jsnow@redhat.com>
10
Message-Id: <20200514201614.19941-2-jsnow@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
12
---
11
tests/qemu-iotests/iotests.py | 18 ++++++++++++++++--
13
tests/qemu-iotests/iotests.py | 11 +++++------
12
1 file changed, 16 insertions(+), 2 deletions(-)
14
1 file changed, 5 insertions(+), 6 deletions(-)
13
15
14
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
16
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
15
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
16
--- a/tests/qemu-iotests/iotests.py
18
--- a/tests/qemu-iotests/iotests.py
17
+++ b/tests/qemu-iotests/iotests.py
19
+++ b/tests/qemu-iotests/iotests.py
18
@@ -XXX,XX +XXX,XX @@ class QMPTestCase(unittest.TestCase):
20
@@ -XXX,XX +XXX,XX @@ def execute_setup_common(supported_fmts: Sequence[str] = (),
19
self.fail('path "%s" has value "%s"' % (path, str(result)))
21
sys.stderr.write('Please run this test via the "check" script\n')
20
22
sys.exit(os.EX_USAGE)
21
def assert_qmp(self, d, path, value):
23
22
- '''Assert that the value for a specific path in a QMP dict matches'''
24
+ debug = '-d' in sys.argv
23
+ '''Assert that the value for a specific path in a QMP dict
25
+ if debug:
24
+ matches. When given a list of values, assert that any of
26
+ sys.argv.remove('-d')
25
+ them matches.'''
27
+ logging.basicConfig(level=(logging.DEBUG if debug else logging.WARN))
26
+
28
+
27
result = self.dictpath(d, path)
29
_verify_image_format(supported_fmts, unsupported_fmts)
28
- self.assertEqual(result, value, 'values not equal "%s" and "%s"' % (str(result), str(value)))
30
_verify_protocol(supported_protocols, unsupported_protocols)
29
+
31
_verify_platform(supported=supported_platforms)
30
+ # [] makes no sense as a list of valid values, so treat it as
32
_verify_cache_mode(supported_cache_modes)
31
+ # an actual single value.
33
_verify_aio_mode(supported_aio_modes)
32
+ if isinstance(value, list) and value != []:
34
33
+ for v in value:
35
- debug = '-d' in sys.argv
34
+ if result == v:
36
- if debug:
35
+ return
37
- sys.argv.remove('-d')
36
+ self.fail('no match for "%s" in %s' % (str(result), str(value)))
38
- logging.basicConfig(level=(logging.DEBUG if debug else logging.WARN))
37
+ else:
39
- logger.debug("iotests debugging messages active")
38
+ self.assertEqual(result, value,
40
-
39
+ 'values not equal "%s" and "%s"'
41
return debug
40
+ % (str(result), str(value)))
42
41
43
def execute_test(*args, test_function=None, **kwargs):
42
def assert_no_active_block_jobs(self):
43
result = self.vm.qmp('query-block-jobs')
44
--
44
--
45
2.20.1
45
2.25.4
46
46
47
47
diff view generated by jsdifflib
New patch
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
2
3
One might find interesting to look at AHCI IRQs.
4
5
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Message-Id: <20200504094858.5975-1-f4bug@amsat.org>
7
Reviewed-by: John Snow <jsnow@redhat.com>
8
Acked-by: John Snow <jsnow@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
11
hw/ide/ahci.c | 1 +
12
1 file changed, 1 insertion(+)
13
14
diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/ide/ahci.c
17
+++ b/hw/ide/ahci.c
18
@@ -XXX,XX +XXX,XX @@ static void ahci_cmd_done(IDEDMA *dma)
19
20
static void ahci_irq_set(void *opaque, int n, int level)
21
{
22
+ qemu_log_mask(LOG_UNIMP, "ahci: IRQ#%d level:%d\n", n, level);
23
}
24
25
static const IDEDMAOps ahci_dma_ops = {
26
--
27
2.25.4
28
29
diff view generated by jsdifflib
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
1
test_overlapping_3() throttles its active commit job so it can be sure
2
the job is still busy when it checks that you can't start a conflicting
3
streaming job.
2
4
3
qmp_cont fails if vm in RUN_STATE_FINISH_MIGRATE, so let's wait for
5
However, it only sets the commit job back to full speed when it is
4
final RUN_STATE_POSTMIGRATE. Also, while being here, check qmp_cont
6
ready, which takes a few seconds while it's throttled. We can already
5
result.
7
reset the limit after having checked that block-stream returns an error
8
and save these seconds.
6
9
7
Reported-by: Max Reitz <mreitz@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
11
Message-Id: <20200513100025.33543-1-kwolf@redhat.com>
9
Tested-by: Max Reitz <mreitz@redhat.com>
12
Reviewed-by: Alberto Garcia <berto@igalia.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
---
14
---
12
tests/qemu-iotests/169 | 7 ++++++-
15
tests/qemu-iotests/030 | 6 +++---
13
1 file changed, 6 insertions(+), 1 deletion(-)
16
1 file changed, 3 insertions(+), 3 deletions(-)
14
17
15
diff --git a/tests/qemu-iotests/169 b/tests/qemu-iotests/169
18
diff --git a/tests/qemu-iotests/030 b/tests/qemu-iotests/030
16
index XXXXXXX..XXXXXXX 100755
19
index XXXXXXX..XXXXXXX 100755
17
--- a/tests/qemu-iotests/169
20
--- a/tests/qemu-iotests/030
18
+++ b/tests/qemu-iotests/169
21
+++ b/tests/qemu-iotests/030
19
@@ -XXX,XX +XXX,XX @@ class TestDirtyBitmapMigration(iotests.QMPTestCase):
22
@@ -XXX,XX +XXX,XX @@ class TestParallelOps(iotests.QMPTestCase):
20
event = self.vm_a.event_wait('MIGRATION')
23
self.assert_qmp(result, 'error/desc',
21
if event['data']['status'] == 'completed':
24
"Node 'node5' is busy: block device is in use by block job: commit")
22
break
25
23
+ while True:
26
+ result = self.vm.qmp('block-job-set-speed', device='commit-drive0', speed=0)
24
+ result = self.vm_a.qmp('query-status')
25
+ if (result['return']['status'] == 'postmigrate'):
26
+ break
27
28
# test that bitmap is still here
29
removed = (not migrate_bitmaps) and persistent
30
self.check_bitmap(self.vm_a, False if removed else sha256)
31
32
- self.vm_a.qmp('cont')
33
+ result = self.vm_a.qmp('cont')
34
+ self.assert_qmp(result, 'return', {})
27
+ self.assert_qmp(result, 'return', {})
35
28
+
36
# test that bitmap is still here after invalidation
29
event = self.vm.event_wait(name='BLOCK_JOB_READY')
37
self.check_bitmap(self.vm_a, sha256)
30
self.assert_qmp(event, 'data/device', 'commit-drive0')
31
self.assert_qmp(event, 'data/type', 'commit')
32
self.assert_qmp_absent(event, 'data/error')
33
34
- result = self.vm.qmp('block-job-set-speed', device='commit-drive0', speed=0)
35
- self.assert_qmp(result, 'return', {})
36
-
37
result = self.vm.qmp('block-job-complete', device='commit-drive0')
38
self.assert_qmp(result, 'return', {})
39
38
--
40
--
39
2.20.1
41
2.25.4
40
42
41
43
diff view generated by jsdifflib