1
The following changes since commit 16aaacb307ed607b9780c12702c44f0fe52edc7e:
1
The following changes since commit 6629bf78aac7e53f83fd0bcbdbe322e2302dfd1f:
2
2
3
Merge remote-tracking branch 'remotes/cohuck/tags/s390x-20200430' into staging (2020-04-30 14:00:36 +0100)
3
Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20220302' into staging (2022-03-03 14:46:48 +0000)
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
https://gitlab.com/kmwolf/qemu.git tags/for-upstream
8
8
9
for you to fetch changes up to eaae29ef89d498d0eac553c77b554f310a47f809:
9
for you to fetch changes up to a5df6d1db7db37636c8624bf4a9df9da645853aa:
10
10
11
qemu-storage-daemon: Fix non-string --object properties (2020-04-30 17:51:07 +0200)
11
block/amend: Keep strong reference to BDS (2022-03-04 17:15:33 +0100)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
Block layer patches:
14
Block layer patches
15
15
16
- Fix resize (extending) of short overlays
16
- qemu-storage-daemon: Add --daemonize
17
- nvme: introduce PMR support from NVMe 1.4 spec
17
- Fix x-blockdev-amend and block node activation code which incorrectly
18
- qemu-storage-daemon: Fix non-string --object properties
18
executed code in the iothread that must run in the main thread.
19
- Add macros for coroutine-safe TLS variables (required for correctness
20
with LTO)
21
- Fix crashes with concurrent I/O and bdrv_refresh_limits()
22
- Split block APIs in global state and I/O
23
- iotests: Don't refuse to run at all without GNU sed, just skip tests
24
that need it
19
25
20
----------------------------------------------------------------
26
----------------------------------------------------------------
21
Alberto Garcia (1):
27
Emanuele Giuseppe Esposito (36):
22
qcow2: Add incompatibility note between backing files and raw external data files
28
crypto: perform permission checks under BQL
29
crypto: distinguish between main loop and I/O in block_crypto_amend_options_generic_luks
30
block: introduce bdrv_activate
31
block: rename bdrv_invalidate_cache_all, blk_invalidate_cache and test_sync_op_invalidate_cache
32
block: move BQL logic of bdrv_co_invalidate_cache in bdrv_activate
33
main-loop.h: introduce qemu_in_main_thread()
34
main loop: macros to mark GS and I/O functions
35
include/block/block: split header into I/O and global state API
36
assertions for block global state API
37
IO_CODE and IO_OR_GS_CODE for block I/O API
38
block/export/fuse.c: allow writable exports to take RESIZE permission
39
include/sysemu/block-backend: split header into I/O and global state (GS) API
40
block/block-backend.c: assertions for block-backend
41
IO_CODE and IO_OR_GS_CODE for block-backend I/O API
42
block.c: assertions to the block layer permissions API
43
include/block/block_int: split header into I/O and global state API
44
assertions for block_int global state API
45
IO_CODE and IO_OR_GS_CODE for block_int I/O API
46
block: introduce assert_bdrv_graph_writable
47
include/block/blockjob_int.h: split header into I/O and GS API
48
GS and IO CODE macros for blockjob_int.h
49
block.c: add assertions to static functions
50
include/block/blockjob.h: global state API
51
assertions for blockjob.h global state API
52
include/sysemu/blockdev.h: global state API
53
assertions for blockdev.h global state API
54
include/block/snapshot: global state API + assertions
55
block/copy-before-write.h: global state API + assertions
56
block/coroutines: I/O and "I/O or GS" API
57
block_int-common.h: split function pointers in BlockDriver
58
block_int-common.h: assertions in the callers of BlockDriver function pointers
59
block_int-common.h: split function pointers in BdrvChildClass
60
block_int-common.h: assertions in the callers of BdrvChildClass function pointers
61
block-backend-common.h: split function pointers in BlockDevOps
62
job.h: split function pointers in JobDriver
63
job.h: assertions in the callers of JobDriver function pointers
23
64
24
Andrzej Jakowski (1):
65
Hanna Reitz (9):
25
nvme: introduce PMR support from NVMe 1.4 spec
66
os-posix: Add os_set_daemonize()
67
qsd: Add pre-init argument parsing pass
68
qsd: Add --daemonize
69
iotests/185: Add post-READY quit tests
70
block: Make bdrv_refresh_limits() non-recursive
71
iotests: Allow using QMP with the QSD
72
iotests/graph-changes-while-io: New test
73
block/amend: Always call .bdrv_amend_clean()
74
block/amend: Keep strong reference to BDS
26
75
27
Kevin Wolf (12):
76
Stefan Hajnoczi (4):
28
block: Add flags to BlockDriver.bdrv_co_truncate()
77
tls: add macros for coroutine-safe TLS variables
29
block: Add flags to bdrv(_co)_truncate()
78
util/async: replace __thread with QEMU TLS macros
30
block-backend: Add flags to blk_truncate()
79
rcu: use coroutine TLS macros
31
qcow2: Support BDRV_REQ_ZERO_WRITE for truncate
80
cpus: use coroutine TLS macros for iothread_locked
32
raw-format: Support BDRV_REQ_ZERO_WRITE for truncate
33
file-posix: Support BDRV_REQ_ZERO_WRITE for truncate
34
block: truncate: Don't make backing file data visible
35
iotests: Filter testfiles out in filter_img_info()
36
iotests: Test committing to short backing file
37
qcow2: Forward ZERO_WRITE flag for full preallocation
38
qom: Factor out user_creatable_add_dict()
39
qemu-storage-daemon: Fix non-string --object properties
40
81
41
Paolo Bonzini (1):
82
Thomas Huth (1):
42
qemu-iotests: allow qcow2 external discarded clusters to contain stale data
83
tests/qemu-iotests: Rework the checks and spots using GNU sed
43
84
44
docs/interop/qcow2.txt | 3 +
85
docs/tools/qemu-storage-daemon.rst | 7 +
45
hw/block/nvme.h | 2 +
86
block/copy-before-write.h | 7 +
46
include/block/block.h | 5 +-
87
block/coroutines.h | 81 +-
47
include/block/block_int.h | 10 +-
88
include/block/block-common.h | 418 ++++++
48
include/block/nvme.h | 172 ++++++++++++++++++++++++++
89
include/block/block-global-state.h | 253 ++++
49
include/qom/object_interfaces.h | 16 +++
90
include/block/block-io.h | 368 +++++
50
include/sysemu/block-backend.h | 2 +-
91
include/block/block.h | 878 +-----------
51
block.c | 3 +-
92
include/block/block_int-common.h | 1222 ++++++++++++++++
52
block/block-backend.c | 4 +-
93
include/block/block_int-global-state.h | 329 +++++
53
block/commit.c | 4 +-
94
include/block/block_int-io.h | 185 +++
54
block/crypto.c | 7 +-
95
include/block/block_int.h | 1475 +-------------------
55
block/file-posix.c | 6 +-
96
include/block/blockjob.h | 29 +-
56
block/file-win32.c | 2 +-
97
include/block/blockjob_int.h | 28 +
57
block/gluster.c | 1 +
98
include/block/snapshot.h | 13 +-
58
block/io.c | 43 ++++++-
99
include/qemu/coroutine-tls.h | 165 +++
59
block/iscsi.c | 2 +-
100
include/qemu/job.h | 22 +
60
block/mirror.c | 2 +-
101
include/qemu/main-loop.h | 42 +
61
block/nfs.c | 3 +-
102
include/qemu/rcu.h | 7 +-
62
block/parallels.c | 6 +-
103
include/sysemu/block-backend-common.h | 102 ++
63
block/qcow.c | 4 +-
104
include/sysemu/block-backend-global-state.h | 116 ++
64
block/qcow2-cluster.c | 2 +-
105
include/sysemu/block-backend-io.h | 161 +++
65
block/qcow2-refcount.c | 2 +-
106
include/sysemu/block-backend.h | 269 +---
66
block/qcow2.c | 73 +++++++++--
107
include/sysemu/blockdev.h | 13 +-
67
block/qed.c | 3 +-
108
include/sysemu/os-posix.h | 1 +
68
block/raw-format.c | 6 +-
109
include/sysemu/os-win32.h | 8 +
69
block/rbd.c | 1 +
110
block.c | 321 ++++-
70
block/sheepdog.c | 4 +-
111
block/amend.c | 28 +
71
block/ssh.c | 2 +-
112
block/backup.c | 1 +
72
block/vdi.c | 2 +-
113
block/block-backend.c | 166 ++-
73
block/vhdx-log.c | 2 +-
114
block/commit.c | 4 +
74
block/vhdx.c | 6 +-
115
block/copy-before-write.c | 2 +
75
block/vmdk.c | 8 +-
116
block/create.c | 2 +
76
block/vpc.c | 2 +-
117
block/crypto.c | 68 +-
77
blockdev.c | 2 +-
118
block/dirty-bitmap.c | 5 +
78
hw/block/nvme.c | 109 ++++++++++++++++
119
block/export/export.c | 2 +-
79
qemu-img.c | 2 +-
120
block/export/fuse.c | 25 +-
80
qemu-io-cmds.c | 2 +-
121
block/io.c | 75 +-
81
qemu-storage-daemon.c | 4 +-
122
block/mirror.c | 4 +
82
qom/object_interfaces.c | 31 +++++
123
block/monitor/bitmap-qmp-cmds.c | 6 +
83
qom/qom-qmp-cmds.c | 24 +---
124
block/nbd.c | 1 +
84
tests/test-block-iothread.c | 9 +-
125
block/parallels.c | 2 +-
85
tests/qemu-iotests/iotests.py | 5 +-
126
block/snapshot.c | 28 +
86
hw/block/Makefile.objs | 2 +-
127
block/stream.c | 2 +
87
hw/block/trace-events | 4 +
128
blockdev.c | 29 +
88
tests/qemu-iotests/244 | 10 +-
129
blockjob.c | 16 +
89
tests/qemu-iotests/244.out | 9 +-
130
hw/block/pflash_cfi01.c | 2 +-
90
tests/qemu-iotests/274 | 155 +++++++++++++++++++++++
131
hw/nvram/spapr_nvram.c | 2 +-
91
tests/qemu-iotests/274.out | 268 ++++++++++++++++++++++++++++++++++++++++
132
job.c | 10 +
92
tests/qemu-iotests/group | 1 +
133
migration/block.c | 2 +-
93
49 files changed, 951 insertions(+), 96 deletions(-)
134
migration/migration.c | 14 +-
94
create mode 100755 tests/qemu-iotests/274
135
migration/savevm.c | 8 +-
95
create mode 100644 tests/qemu-iotests/274.out
136
monitor/qmp-cmds.c | 2 +-
96
137
os-posix.c | 6 +
97
138
softmmu/cpus.c | 14 +-
139
softmmu/qdev-monitor.c | 2 +
140
storage-daemon/qemu-storage-daemon.c | 58 +-
141
stubs/iothread-lock.c | 5 +
142
tests/unit/rcutorture.c | 10 +-
143
tests/unit/test-block-iothread.c | 8 +-
144
tests/unit/test-rcu-list.c | 4 +-
145
util/async.c | 12 +-
146
util/rcu.c | 10 +-
147
tests/qemu-iotests/iotests.py | 32 +-
148
block/meson.build | 7 +-
149
tests/check-block.sh | 12 -
150
tests/qemu-iotests/185 | 190 ++-
151
tests/qemu-iotests/185.out | 48 +
152
tests/qemu-iotests/271 | 2 +-
153
tests/qemu-iotests/296 | 8 +-
154
tests/qemu-iotests/296.out | 17 +-
155
tests/qemu-iotests/common.filter | 65 +-
156
tests/qemu-iotests/common.rc | 45 +-
157
tests/qemu-iotests/tests/graph-changes-while-io | 91 ++
158
.../qemu-iotests/tests/graph-changes-while-io.out | 5 +
159
74 files changed, 4854 insertions(+), 2823 deletions(-)
160
create mode 100644 include/block/block-common.h
161
create mode 100644 include/block/block-global-state.h
162
create mode 100644 include/block/block-io.h
163
create mode 100644 include/block/block_int-common.h
164
create mode 100644 include/block/block_int-global-state.h
165
create mode 100644 include/block/block_int-io.h
166
create mode 100644 include/qemu/coroutine-tls.h
167
create mode 100644 include/sysemu/block-backend-common.h
168
create mode 100644 include/sysemu/block-backend-global-state.h
169
create mode 100644 include/sysemu/block-backend-io.h
170
create mode 100755 tests/qemu-iotests/tests/graph-changes-while-io
171
create mode 100644 tests/qemu-iotests/tests/graph-changes-while-io.out
diff view generated by jsdifflib
1
This adds a new BdrvRequestFlags parameter to the .bdrv_co_truncate()
1
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
2
driver callbacks, and a supported_truncate_flags field in
2
3
BlockDriverState that allows drivers to advertise support for request
3
Move the permission API calls into driver-specific callbacks
4
flags in the context of truncate.
4
that always run under BQL. In this case, bdrv_crypto_luks
5
5
needs to perform permission checks before and after
6
For now, we always pass 0 and no drivers declare support for any flag.
6
qcrypto_block_amend_options(). The problem is that the caller,
7
7
block_crypto_amend_options_generic_luks(), can also run in I/O
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
from .bdrv_co_amend(). This does not comply with Global State-I/O API split,
9
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
9
as permissions API must always run under BQL.
10
Reviewed-by: Alberto Garcia <berto@igalia.com>
10
11
Reviewed-by: Max Reitz <mreitz@redhat.com>
11
Firstly, introduce .bdrv_amend_pre_run() and .bdrv_amend_clean()
12
Message-Id: <20200424125448.63318-2-kwolf@redhat.com>
12
callbacks. These two callbacks are guaranteed to be invoked under
13
BQL, respectively before and after .bdrv_co_amend().
14
They take care of performing the permission checks
15
in the same way as they are currently done before and after
16
qcrypto_block_amend_options().
17
These callbacks are in preparation for next patch, where we
18
delete the original permission check. Right now they just add redundant
19
control.
20
21
Then, call .bdrv_amend_pre_run() before job_start in
22
qmp_x_blockdev_amend(), so that it will be run before the job coroutine
23
is created and stay in the main loop.
24
As a cleanup, use JobDriver's .clean() callback to call
25
.bdrv_amend_clean(), and run amend-specific cleanup callbacks under BQL.
26
27
After this patch, permission failures occur early in the blockdev-amend
28
job to update a LUKS volume's keys. iotest 296 must now expect them in
29
x-blockdev-amend's QMP reply instead of waiting for the actual job to
30
fail later.
31
32
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
33
Message-Id: <20220209105452.1694545-2-eesposit@redhat.com>
34
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
35
Message-Id: <20220304153729.711387-6-hreitz@redhat.com>
13
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
36
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
---
37
---
15
include/block/block_int.h | 10 +++++++++-
38
include/block/block_int.h | 14 ++++++++++++++
16
block/crypto.c | 3 ++-
39
block/amend.c | 25 +++++++++++++++++++++++++
17
block/file-posix.c | 2 +-
40
block/crypto.c | 33 +++++++++++++++++++++++++++++++++
18
block/file-win32.c | 2 +-
41
tests/qemu-iotests/296 | 8 ++++++--
19
block/gluster.c | 1 +
42
tests/qemu-iotests/296.out | 17 +++++------------
20
block/io.c | 8 +++++++-
43
5 files changed, 83 insertions(+), 14 deletions(-)
21
block/iscsi.c | 2 +-
22
block/nfs.c | 3 ++-
23
block/qcow2.c | 2 +-
24
block/qed.c | 1 +
25
block/raw-format.c | 2 +-
26
block/rbd.c | 1 +
27
block/sheepdog.c | 4 ++--
28
block/ssh.c | 2 +-
29
tests/test-block-iothread.c | 3 ++-
30
15 files changed, 33 insertions(+), 13 deletions(-)
31
44
32
diff --git a/include/block/block_int.h b/include/block/block_int.h
45
diff --git a/include/block/block_int.h b/include/block/block_int.h
33
index XXXXXXX..XXXXXXX 100644
46
index XXXXXXX..XXXXXXX 100644
34
--- a/include/block/block_int.h
47
--- a/include/block/block_int.h
35
+++ b/include/block/block_int.h
48
+++ b/include/block/block_int.h
36
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
49
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
50
* on those children.
37
*/
51
*/
38
int coroutine_fn (*bdrv_co_truncate)(BlockDriverState *bs, int64_t offset,
52
bool is_format;
39
bool exact, PreallocMode prealloc,
53
+
40
- Error **errp);
41
+ BdrvRequestFlags flags, Error **errp);
42
43
int64_t (*bdrv_getlength)(BlockDriverState *bs);
44
bool has_variable_length;
45
@@ -XXX,XX +XXX,XX @@ struct BlockDriverState {
46
/* Flags honored during pwrite_zeroes (so far: BDRV_REQ_FUA,
47
* BDRV_REQ_MAY_UNMAP, BDRV_REQ_WRITE_UNCHANGED) */
48
unsigned int supported_zero_flags;
49
+ /*
54
+ /*
50
+ * Flags honoured during truncate (so far: BDRV_REQ_ZERO_WRITE).
55
+ * This function is invoked under BQL before .bdrv_co_amend()
51
+ *
56
+ * (which in contrast does not necessarily run under the BQL)
52
+ * If BDRV_REQ_ZERO_WRITE is given, the truncate operation must make sure
57
+ * to allow driver-specific initialization code that requires
53
+ * that any added space reads as all zeros. If this can't be guaranteed,
58
+ * the BQL, like setting up specific permission flags.
54
+ * the operation must fail.
55
+ */
59
+ */
56
+ unsigned int supported_truncate_flags;
60
+ int (*bdrv_amend_pre_run)(BlockDriverState *bs, Error **errp);
57
61
+ /*
58
/* the following member gives a name to every node on the bs graph. */
62
+ * This function is invoked under BQL after .bdrv_co_amend()
59
char node_name[32];
63
+ * to allow cleaning up what was done in .bdrv_amend_pre_run().
64
+ */
65
+ void (*bdrv_amend_clean)(BlockDriverState *bs);
66
+
67
/*
68
* Return true if @to_replace can be replaced by a BDS with the
69
* same data as @bs without it affecting @bs's behavior (that is,
70
diff --git a/block/amend.c b/block/amend.c
71
index XXXXXXX..XXXXXXX 100644
72
--- a/block/amend.c
73
+++ b/block/amend.c
74
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn blockdev_amend_run(Job *job, Error **errp)
75
return ret;
76
}
77
78
+static int blockdev_amend_pre_run(BlockdevAmendJob *s, Error **errp)
79
+{
80
+ if (s->bs->drv->bdrv_amend_pre_run) {
81
+ return s->bs->drv->bdrv_amend_pre_run(s->bs, errp);
82
+ }
83
+
84
+ return 0;
85
+}
86
+
87
+static void blockdev_amend_clean(Job *job)
88
+{
89
+ BlockdevAmendJob *s = container_of(job, BlockdevAmendJob, common);
90
+
91
+ if (s->bs->drv->bdrv_amend_clean) {
92
+ s->bs->drv->bdrv_amend_clean(s->bs);
93
+ }
94
+}
95
+
96
static const JobDriver blockdev_amend_job_driver = {
97
.instance_size = sizeof(BlockdevAmendJob),
98
.job_type = JOB_TYPE_AMEND,
99
.run = blockdev_amend_run,
100
+ .clean = blockdev_amend_clean,
101
};
102
103
void qmp_x_blockdev_amend(const char *job_id,
104
@@ -XXX,XX +XXX,XX @@ void qmp_x_blockdev_amend(const char *job_id,
105
s->bs = bs,
106
s->opts = QAPI_CLONE(BlockdevAmendOptions, options),
107
s->force = has_force ? force : false;
108
+
109
+ if (blockdev_amend_pre_run(s, errp)) {
110
+ job_early_fail(&s->common);
111
+ return;
112
+ }
113
+
114
job_start(&s->common);
115
}
60
diff --git a/block/crypto.c b/block/crypto.c
116
diff --git a/block/crypto.c b/block/crypto.c
61
index XXXXXXX..XXXXXXX 100644
117
index XXXXXXX..XXXXXXX 100644
62
--- a/block/crypto.c
118
--- a/block/crypto.c
63
+++ b/block/crypto.c
119
+++ b/block/crypto.c
64
@@ -XXX,XX +XXX,XX @@ static int block_crypto_co_create_generic(BlockDriverState *bs,
120
@@ -XXX,XX +XXX,XX @@ block_crypto_get_specific_info_luks(BlockDriverState *bs, Error **errp)
65
121
return spec_info;
66
static int coroutine_fn
122
}
67
block_crypto_co_truncate(BlockDriverState *bs, int64_t offset, bool exact,
123
68
- PreallocMode prealloc, Error **errp)
124
+static int
69
+ PreallocMode prealloc, BdrvRequestFlags flags,
125
+block_crypto_amend_prepare(BlockDriverState *bs, Error **errp)
70
+ Error **errp)
126
+{
71
{
127
+ BlockCrypto *crypto = bs->opaque;
72
BlockCrypto *crypto = bs->opaque;
128
+ int ret;
73
uint64_t payload_offset =
129
+
74
diff --git a/block/file-posix.c b/block/file-posix.c
130
+ /* apply for exclusive read/write permissions to the underlying file */
75
index XXXXXXX..XXXXXXX 100644
131
+ crypto->updating_keys = true;
76
--- a/block/file-posix.c
132
+ ret = bdrv_child_refresh_perms(bs, bs->file, errp);
77
+++ b/block/file-posix.c
133
+ if (ret < 0) {
78
@@ -XXX,XX +XXX,XX @@ raw_regular_truncate(BlockDriverState *bs, int fd, int64_t offset,
134
+ /* Well, in this case we will not be updating any keys */
79
135
+ crypto->updating_keys = false;
80
static int coroutine_fn raw_co_truncate(BlockDriverState *bs, int64_t offset,
136
+ }
81
bool exact, PreallocMode prealloc,
137
+ return ret;
82
- Error **errp)
138
+}
83
+ BdrvRequestFlags flags, Error **errp)
139
+
84
{
140
+static void
85
BDRVRawState *s = bs->opaque;
141
+block_crypto_amend_cleanup(BlockDriverState *bs)
86
struct stat st;
142
+{
87
diff --git a/block/file-win32.c b/block/file-win32.c
143
+ BlockCrypto *crypto = bs->opaque;
88
index XXXXXXX..XXXXXXX 100644
144
+ Error *errp = NULL;
89
--- a/block/file-win32.c
145
+
90
+++ b/block/file-win32.c
146
+ /* release exclusive read/write permissions to the underlying file */
91
@@ -XXX,XX +XXX,XX @@ static void raw_close(BlockDriverState *bs)
147
+ crypto->updating_keys = false;
92
148
+ bdrv_child_refresh_perms(bs, bs->file, &errp);
93
static int coroutine_fn raw_co_truncate(BlockDriverState *bs, int64_t offset,
149
+
94
bool exact, PreallocMode prealloc,
150
+ if (errp) {
95
- Error **errp)
151
+ error_report_err(errp);
96
+ BdrvRequestFlags flags, Error **errp)
152
+ }
97
{
153
+}
98
BDRVRawState *s = bs->opaque;
154
+
99
LONG low, high;
155
static int
100
diff --git a/block/gluster.c b/block/gluster.c
156
block_crypto_amend_options_generic_luks(BlockDriverState *bs,
101
index XXXXXXX..XXXXXXX 100644
157
QCryptoBlockAmendOptions *amend_options,
102
--- a/block/gluster.c
158
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_crypto_luks = {
103
+++ b/block/gluster.c
159
.bdrv_get_specific_info = block_crypto_get_specific_info_luks,
104
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int qemu_gluster_co_truncate(BlockDriverState *bs,
160
.bdrv_amend_options = block_crypto_amend_options_luks,
105
int64_t offset,
161
.bdrv_co_amend = block_crypto_co_amend_luks,
106
bool exact,
162
+ .bdrv_amend_pre_run = block_crypto_amend_prepare,
107
PreallocMode prealloc,
163
+ .bdrv_amend_clean = block_crypto_amend_cleanup,
108
+ BdrvRequestFlags flags,
164
109
Error **errp)
165
.is_format = true,
110
{
166
111
BDRVGlusterState *s = bs->opaque;
167
diff --git a/tests/qemu-iotests/296 b/tests/qemu-iotests/296
112
diff --git a/block/io.c b/block/io.c
168
index XXXXXXX..XXXXXXX 100755
113
index XXXXXXX..XXXXXXX 100644
169
--- a/tests/qemu-iotests/296
114
--- a/block/io.c
170
+++ b/tests/qemu-iotests/296
115
+++ b/block/io.c
171
@@ -XXX,XX +XXX,XX @@ class EncryptionSetupTestCase(iotests.QMPTestCase):
116
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact,
117
BlockDriverState *bs = child->bs;
118
BlockDriver *drv = bs->drv;
119
BdrvTrackedRequest req;
120
+ BdrvRequestFlags flags = 0;
121
int64_t old_size, new_bytes;
122
int ret;
123
124
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact,
125
}
126
127
if (drv->bdrv_co_truncate) {
128
- ret = drv->bdrv_co_truncate(bs, offset, exact, prealloc, errp);
129
+ if (flags & ~bs->supported_truncate_flags) {
130
+ error_setg(errp, "Block driver does not support requested flags");
131
+ ret = -ENOTSUP;
132
+ goto out;
133
+ }
134
+ ret = drv->bdrv_co_truncate(bs, offset, exact, prealloc, flags, errp);
135
} else if (bs->file && drv->is_filter) {
136
ret = bdrv_co_truncate(bs->file, offset, exact, prealloc, errp);
137
} else {
138
diff --git a/block/iscsi.c b/block/iscsi.c
139
index XXXXXXX..XXXXXXX 100644
140
--- a/block/iscsi.c
141
+++ b/block/iscsi.c
142
@@ -XXX,XX +XXX,XX @@ static void iscsi_reopen_commit(BDRVReopenState *reopen_state)
143
144
static int coroutine_fn iscsi_co_truncate(BlockDriverState *bs, int64_t offset,
145
bool exact, PreallocMode prealloc,
146
- Error **errp)
147
+ BdrvRequestFlags flags, Error **errp)
148
{
149
IscsiLun *iscsilun = bs->opaque;
150
int64_t cur_length;
151
diff --git a/block/nfs.c b/block/nfs.c
152
index XXXXXXX..XXXXXXX 100644
153
--- a/block/nfs.c
154
+++ b/block/nfs.c
155
@@ -XXX,XX +XXX,XX @@ static int64_t nfs_get_allocated_file_size(BlockDriverState *bs)
156
157
static int coroutine_fn
158
nfs_file_co_truncate(BlockDriverState *bs, int64_t offset, bool exact,
159
- PreallocMode prealloc, Error **errp)
160
+ PreallocMode prealloc, BdrvRequestFlags flags,
161
+ Error **errp)
162
{
163
NFSClient *client = bs->opaque;
164
int ret;
165
diff --git a/block/qcow2.c b/block/qcow2.c
166
index XXXXXXX..XXXXXXX 100644
167
--- a/block/qcow2.c
168
+++ b/block/qcow2.c
169
@@ -XXX,XX +XXX,XX @@ fail:
170
171
static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
172
bool exact, PreallocMode prealloc,
173
- Error **errp)
174
+ BdrvRequestFlags flags, Error **errp)
175
{
176
BDRVQcow2State *s = bs->opaque;
177
uint64_t old_length;
178
diff --git a/block/qed.c b/block/qed.c
179
index XXXXXXX..XXXXXXX 100644
180
--- a/block/qed.c
181
+++ b/block/qed.c
182
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_qed_co_truncate(BlockDriverState *bs,
183
int64_t offset,
184
bool exact,
185
PreallocMode prealloc,
186
+ BdrvRequestFlags flags,
187
Error **errp)
188
{
189
BDRVQEDState *s = bs->opaque;
190
diff --git a/block/raw-format.c b/block/raw-format.c
191
index XXXXXXX..XXXXXXX 100644
192
--- a/block/raw-format.c
193
+++ b/block/raw-format.c
194
@@ -XXX,XX +XXX,XX @@ static void raw_refresh_limits(BlockDriverState *bs, Error **errp)
195
196
static int coroutine_fn raw_co_truncate(BlockDriverState *bs, int64_t offset,
197
bool exact, PreallocMode prealloc,
198
- Error **errp)
199
+ BdrvRequestFlags flags, Error **errp)
200
{
201
BDRVRawState *s = bs->opaque;
202
203
diff --git a/block/rbd.c b/block/rbd.c
204
index XXXXXXX..XXXXXXX 100644
205
--- a/block/rbd.c
206
+++ b/block/rbd.c
207
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qemu_rbd_co_truncate(BlockDriverState *bs,
208
int64_t offset,
209
bool exact,
210
PreallocMode prealloc,
211
+ BdrvRequestFlags flags,
212
Error **errp)
213
{
214
int r;
215
diff --git a/block/sheepdog.c b/block/sheepdog.c
216
index XXXXXXX..XXXXXXX 100644
217
--- a/block/sheepdog.c
218
+++ b/block/sheepdog.c
219
@@ -XXX,XX +XXX,XX @@ static int64_t sd_getlength(BlockDriverState *bs)
220
221
static int coroutine_fn sd_co_truncate(BlockDriverState *bs, int64_t offset,
222
bool exact, PreallocMode prealloc,
223
- Error **errp)
224
+ BdrvRequestFlags flags, Error **errp)
225
{
226
BDRVSheepdogState *s = bs->opaque;
227
int ret, fd;
228
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int sd_co_writev(BlockDriverState *bs, int64_t sector_num,
229
230
assert(!flags);
231
if (offset > s->inode.vdi_size) {
232
- ret = sd_co_truncate(bs, offset, false, PREALLOC_MODE_OFF, NULL);
233
+ ret = sd_co_truncate(bs, offset, false, PREALLOC_MODE_OFF, 0, NULL);
234
if (ret < 0) {
235
return ret;
236
}
172
}
237
diff --git a/block/ssh.c b/block/ssh.c
173
238
index XXXXXXX..XXXXXXX 100644
174
result = vm.qmp('x-blockdev-amend', **args)
239
--- a/block/ssh.c
175
- assert result['return'] == {}
240
+++ b/block/ssh.c
176
- vm.run_job('job0')
241
@@ -XXX,XX +XXX,XX @@ static int64_t ssh_getlength(BlockDriverState *bs)
177
+ iotests.log(result)
242
178
+ # Run the job only if it was created
243
static int coroutine_fn ssh_co_truncate(BlockDriverState *bs, int64_t offset,
179
+ event = ('JOB_STATUS_CHANGE',
244
bool exact, PreallocMode prealloc,
180
+ {'data': {'id': 'job0', 'status': 'created'}})
245
- Error **errp)
181
+ if vm.events_wait([event], timeout=0.0) is not None:
246
+ BdrvRequestFlags flags, Error **errp)
182
+ vm.run_job('job0')
247
{
183
248
BDRVSSHState *s = bs->opaque;
184
# test that when the image opened by two qemu processes,
249
185
# neither of them can update the encryption keys
250
diff --git a/tests/test-block-iothread.c b/tests/test-block-iothread.c
186
diff --git a/tests/qemu-iotests/296.out b/tests/qemu-iotests/296.out
251
index XXXXXXX..XXXXXXX 100644
187
index XXXXXXX..XXXXXXX 100644
252
--- a/tests/test-block-iothread.c
188
--- a/tests/qemu-iotests/296.out
253
+++ b/tests/test-block-iothread.c
189
+++ b/tests/qemu-iotests/296.out
254
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_test_co_pdiscard(BlockDriverState *bs,
190
@@ -XXX,XX +XXX,XX @@
255
191
256
static int coroutine_fn
192
-{"execute": "job-dismiss", "arguments": {"id": "job0"}}
257
bdrv_test_co_truncate(BlockDriverState *bs, int64_t offset, bool exact,
193
{"return": {}}
258
- PreallocMode prealloc, Error **errp)
194
-Job failed: Failed to get shared "consistent read" lock
259
+ PreallocMode prealloc, BdrvRequestFlags flags,
195
{"execute": "job-dismiss", "arguments": {"id": "job0"}}
260
+ Error **errp)
196
{"return": {}}
261
{
197
-Job failed: Failed to get shared "consistent read" lock
262
return 0;
198
-{"execute": "job-dismiss", "arguments": {"id": "job0"}}
263
}
199
+{"error": {"class": "GenericError", "desc": "Failed to get shared \"consistent read\" lock"}}
200
+{"error": {"class": "GenericError", "desc": "Failed to get shared \"consistent read\" lock"}}
201
{"return": {}}
202
{"execute": "job-dismiss", "arguments": {"id": "job0"}}
203
{"return": {}}
204
@@ -XXX,XX +XXX,XX @@ qemu-img: Failed to get shared "consistent read" lock
205
Is another process using the image [TEST_DIR/test.img]?
206
207
.
208
-Job failed: Block node is read-only
209
-{"execute": "job-dismiss", "arguments": {"id": "job0"}}
210
-{"return": {}}
211
-Job failed: Failed to get shared "consistent read" lock
212
-{"execute": "job-dismiss", "arguments": {"id": "job0"}}
213
-{"return": {}}
214
-Job failed: Failed to get shared "consistent read" lock
215
-{"execute": "job-dismiss", "arguments": {"id": "job0"}}
216
+{"error": {"class": "GenericError", "desc": "Block node is read-only"}}
217
+{"error": {"class": "GenericError", "desc": "Failed to get shared \"consistent read\" lock"}}
218
+{"error": {"class": "GenericError", "desc": "Failed to get shared \"consistent read\" lock"}}
219
{"return": {}}
220
{"execute": "job-dismiss", "arguments": {"id": "job0"}}
221
{"return": {}}
264
--
222
--
265
2.25.3
223
2.35.1
266
267
diff view generated by jsdifflib
New patch
1
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
1
2
3
block_crypto_amend_options_generic_luks uses the block layer
4
permission API, therefore it should be called with the BQL held.
5
6
However, the same function is being called by two BlockDriver
7
callbacks: bdrv_amend_options (under BQL) and bdrv_co_amend (I/O).
8
9
The latter is I/O because it is invoked by block/amend.c's
10
blockdev_amend_run(), a .run callback of the amend JobDriver.
11
12
Therefore we want to change this function to still perform
13
the permission check, but making sure it is done under BQL regardless
14
of the caller context.
15
16
Remove the permission check in block_crypto_amend_options_generic_luks()
17
and:
18
- in block_crypto_amend_options_luks() (BQL case, called by
19
.bdrv_amend_options()), reuse helper functions
20
block_crypto_amend_{prepare/cleanup} that take care of checking
21
permissions.
22
23
- for block_crypto_co_amend_luks() (I/O case, called by
24
.bdrv_co_amend()), don't check for permissions but delegate
25
.bdrv_amend_pre_run() and .bdrv_amend_clean() to do it,
26
performing these checks before and after the job runs in its aiocontext.
27
28
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
29
Message-Id: <20220209105452.1694545-3-eesposit@redhat.com>
30
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
31
---
32
block/crypto.c | 35 +++++++++++++++--------------------
33
1 file changed, 15 insertions(+), 20 deletions(-)
34
35
diff --git a/block/crypto.c b/block/crypto.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/block/crypto.c
38
+++ b/block/crypto.c
39
@@ -XXX,XX +XXX,XX @@ block_crypto_amend_options_generic_luks(BlockDriverState *bs,
40
Error **errp)
41
{
42
BlockCrypto *crypto = bs->opaque;
43
- int ret;
44
45
assert(crypto);
46
assert(crypto->block);
47
48
- /* apply for exclusive read/write permissions to the underlying file*/
49
- crypto->updating_keys = true;
50
- ret = bdrv_child_refresh_perms(bs, bs->file, errp);
51
- if (ret) {
52
- goto cleanup;
53
- }
54
-
55
- ret = qcrypto_block_amend_options(crypto->block,
56
- block_crypto_read_func,
57
- block_crypto_write_func,
58
- bs,
59
- amend_options,
60
- force,
61
- errp);
62
-cleanup:
63
- /* release exclusive read/write permissions to the underlying file*/
64
- crypto->updating_keys = false;
65
- bdrv_child_refresh_perms(bs, bs->file, errp);
66
- return ret;
67
+ return qcrypto_block_amend_options(crypto->block,
68
+ block_crypto_read_func,
69
+ block_crypto_write_func,
70
+ bs,
71
+ amend_options,
72
+ force,
73
+ errp);
74
}
75
76
static int
77
@@ -XXX,XX +XXX,XX @@ block_crypto_amend_options_luks(BlockDriverState *bs,
78
if (!amend_options) {
79
goto cleanup;
80
}
81
+
82
+ ret = block_crypto_amend_prepare(bs, errp);
83
+ if (ret) {
84
+ goto perm_cleanup;
85
+ }
86
ret = block_crypto_amend_options_generic_luks(bs, amend_options,
87
force, errp);
88
+
89
+perm_cleanup:
90
+ block_crypto_amend_cleanup(bs);
91
cleanup:
92
qapi_free_QCryptoBlockAmendOptions(amend_options);
93
return ret;
94
--
95
2.35.1
diff view generated by jsdifflib
1
Now that block drivers can support flags for .bdrv_co_truncate, expose
1
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
2
the parameter in the node level interfaces bdrv_co_truncate() and
3
bdrv_truncate().
4
2
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
3
This function is currently just a wrapper for bdrv_invalidate_cache(),
6
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
4
but in future will contain the code of bdrv_co_invalidate_cache() that
7
Reviewed-by: Alberto Garcia <berto@igalia.com>
5
has to always be protected by BQL, and leave the rest in the I/O
8
Reviewed-by: Max Reitz <mreitz@redhat.com>
6
coroutine.
9
Message-Id: <20200424125448.63318-3-kwolf@redhat.com>
7
8
Replace all bdrv_invalidate_cache() invokations with bdrv_activate().
9
10
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
11
Reviewed-by: Hanna Reitz <hreitz@redhat.com>
12
Message-Id: <20220209105452.1694545-4-eesposit@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
---
14
---
12
include/block/block.h | 5 +++--
15
include/block/block.h | 1 +
13
block/block-backend.c | 2 +-
16
block.c | 7 ++++++-
14
block/crypto.c | 2 +-
17
block/block-backend.c | 2 +-
15
block/io.c | 12 +++++++-----
18
block/export/export.c | 2 +-
16
block/parallels.c | 6 +++---
19
block/parallels.c | 2 +-
17
block/qcow.c | 4 ++--
20
tests/unit/test-block-iothread.c | 2 +-
18
block/qcow2-refcount.c | 2 +-
21
6 files changed, 11 insertions(+), 5 deletions(-)
19
block/qcow2.c | 15 +++++++++------
20
block/raw-format.c | 2 +-
21
block/vhdx-log.c | 2 +-
22
block/vhdx.c | 2 +-
23
block/vmdk.c | 2 +-
24
tests/test-block-iothread.c | 6 +++---
25
13 files changed, 34 insertions(+), 28 deletions(-)
26
22
27
diff --git a/include/block/block.h b/include/block/block.h
23
diff --git a/include/block/block.h b/include/block/block.h
28
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
29
--- a/include/block/block.h
25
--- a/include/block/block.h
30
+++ b/include/block/block.h
26
+++ b/include/block/block.h
31
@@ -XXX,XX +XXX,XX @@ BlockDriverState *bdrv_find_backing_image(BlockDriverState *bs,
27
@@ -XXX,XX +XXX,XX @@ int bdrv_co_ioctl(BlockDriverState *bs, int req, void *buf);
32
void bdrv_refresh_filename(BlockDriverState *bs);
28
int generated_co_wrapper bdrv_invalidate_cache(BlockDriverState *bs,
33
29
Error **errp);
34
int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact,
30
void bdrv_invalidate_cache_all(Error **errp);
35
- PreallocMode prealloc, Error **errp);
31
+int bdrv_activate(BlockDriverState *bs, Error **errp);
36
+ PreallocMode prealloc, BdrvRequestFlags flags,
32
int bdrv_inactivate_all(void);
37
+ Error **errp);
33
38
int bdrv_truncate(BdrvChild *child, int64_t offset, bool exact,
34
/* Ensure contents are flushed to disk. */
39
- PreallocMode prealloc, Error **errp);
35
diff --git a/block.c b/block.c
40
+ PreallocMode prealloc, BdrvRequestFlags flags, Error **errp);
36
index XXXXXXX..XXXXXXX 100644
41
37
--- a/block.c
42
int64_t bdrv_nb_sectors(BlockDriverState *bs);
38
+++ b/block.c
43
int64_t bdrv_getlength(BlockDriverState *bs);
39
@@ -XXX,XX +XXX,XX @@ void bdrv_init_with_whitelist(void)
40
bdrv_init();
41
}
42
43
+int bdrv_activate(BlockDriverState *bs, Error **errp)
44
+{
45
+ return bdrv_invalidate_cache(bs, errp);
46
+}
47
+
48
int coroutine_fn bdrv_co_invalidate_cache(BlockDriverState *bs, Error **errp)
49
{
50
BdrvChild *child, *parent;
51
@@ -XXX,XX +XXX,XX @@ void bdrv_invalidate_cache_all(Error **errp)
52
int ret;
53
54
aio_context_acquire(aio_context);
55
- ret = bdrv_invalidate_cache(bs, errp);
56
+ ret = bdrv_activate(bs, errp);
57
aio_context_release(aio_context);
58
if (ret < 0) {
59
bdrv_next_cleanup(&it);
44
diff --git a/block/block-backend.c b/block/block-backend.c
60
diff --git a/block/block-backend.c b/block/block-backend.c
45
index XXXXXXX..XXXXXXX 100644
61
index XXXXXXX..XXXXXXX 100644
46
--- a/block/block-backend.c
62
--- a/block/block-backend.c
47
+++ b/block/block-backend.c
63
+++ b/block/block-backend.c
48
@@ -XXX,XX +XXX,XX @@ int blk_truncate(BlockBackend *blk, int64_t offset, bool exact,
64
@@ -XXX,XX +XXX,XX @@ void blk_invalidate_cache(BlockBackend *blk, Error **errp)
49
return -ENOMEDIUM;
65
return;
50
}
66
}
51
67
52
- return bdrv_truncate(blk->root, offset, exact, prealloc, errp);
68
- bdrv_invalidate_cache(bs, errp);
53
+ return bdrv_truncate(blk->root, offset, exact, prealloc, 0, errp);
69
+ bdrv_activate(bs, errp);
54
}
70
}
55
71
56
int blk_save_vmstate(BlockBackend *blk, const uint8_t *buf,
72
bool blk_is_inserted(BlockBackend *blk)
57
diff --git a/block/crypto.c b/block/crypto.c
73
diff --git a/block/export/export.c b/block/export/export.c
58
index XXXXXXX..XXXXXXX 100644
74
index XXXXXXX..XXXXXXX 100644
59
--- a/block/crypto.c
75
--- a/block/export/export.c
60
+++ b/block/crypto.c
76
+++ b/block/export/export.c
61
@@ -XXX,XX +XXX,XX @@ block_crypto_co_truncate(BlockDriverState *bs, int64_t offset, bool exact,
77
@@ -XXX,XX +XXX,XX @@ BlockExport *blk_exp_add(BlockExportOptions *export, Error **errp)
62
78
* access since the export could be available before migration handover.
63
offset += payload_offset;
79
* ctx was acquired in the caller.
64
80
*/
65
- return bdrv_co_truncate(bs->file, offset, exact, prealloc, errp);
81
- bdrv_invalidate_cache(bs, NULL);
66
+ return bdrv_co_truncate(bs->file, offset, exact, prealloc, 0, errp);
82
+ bdrv_activate(bs, NULL);
67
}
83
68
84
perm = BLK_PERM_CONSISTENT_READ;
69
static void block_crypto_close(BlockDriverState *bs)
85
if (export->writable) {
70
diff --git a/block/io.c b/block/io.c
71
index XXXXXXX..XXXXXXX 100644
72
--- a/block/io.c
73
+++ b/block/io.c
74
@@ -XXX,XX +XXX,XX @@ static void bdrv_parent_cb_resize(BlockDriverState *bs)
75
* 'offset' bytes in length.
76
*/
77
int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact,
78
- PreallocMode prealloc, Error **errp)
79
+ PreallocMode prealloc, BdrvRequestFlags flags,
80
+ Error **errp)
81
{
82
BlockDriverState *bs = child->bs;
83
BlockDriver *drv = bs->drv;
84
BdrvTrackedRequest req;
85
- BdrvRequestFlags flags = 0;
86
int64_t old_size, new_bytes;
87
int ret;
88
89
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact,
90
}
91
ret = drv->bdrv_co_truncate(bs, offset, exact, prealloc, flags, errp);
92
} else if (bs->file && drv->is_filter) {
93
- ret = bdrv_co_truncate(bs->file, offset, exact, prealloc, errp);
94
+ ret = bdrv_co_truncate(bs->file, offset, exact, prealloc, flags, errp);
95
} else {
96
error_setg(errp, "Image format driver does not support resize");
97
ret = -ENOTSUP;
98
@@ -XXX,XX +XXX,XX @@ typedef struct TruncateCo {
99
int64_t offset;
100
bool exact;
101
PreallocMode prealloc;
102
+ BdrvRequestFlags flags;
103
Error **errp;
104
int ret;
105
} TruncateCo;
106
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn bdrv_truncate_co_entry(void *opaque)
107
{
108
TruncateCo *tco = opaque;
109
tco->ret = bdrv_co_truncate(tco->child, tco->offset, tco->exact,
110
- tco->prealloc, tco->errp);
111
+ tco->prealloc, tco->flags, tco->errp);
112
aio_wait_kick();
113
}
114
115
int bdrv_truncate(BdrvChild *child, int64_t offset, bool exact,
116
- PreallocMode prealloc, Error **errp)
117
+ PreallocMode prealloc, BdrvRequestFlags flags, Error **errp)
118
{
119
Coroutine *co;
120
TruncateCo tco = {
121
@@ -XXX,XX +XXX,XX @@ int bdrv_truncate(BdrvChild *child, int64_t offset, bool exact,
122
.offset = offset,
123
.exact = exact,
124
.prealloc = prealloc,
125
+ .flags = flags,
126
.errp = errp,
127
.ret = NOT_DONE,
128
};
129
diff --git a/block/parallels.c b/block/parallels.c
86
diff --git a/block/parallels.c b/block/parallels.c
130
index XXXXXXX..XXXXXXX 100644
87
index XXXXXXX..XXXXXXX 100644
131
--- a/block/parallels.c
88
--- a/block/parallels.c
132
+++ b/block/parallels.c
89
+++ b/block/parallels.c
133
@@ -XXX,XX +XXX,XX @@ static int64_t allocate_clusters(BlockDriverState *bs, int64_t sector_num,
90
@@ -XXX,XX +XXX,XX @@ static int parallels_open(BlockDriverState *bs, QDict *options, int flags,
134
} else {
91
s->bat_dirty_bmap =
135
ret = bdrv_truncate(bs->file,
92
bitmap_new(DIV_ROUND_UP(s->header_size, s->bat_dirty_block));
136
(s->data_end + space) << BDRV_SECTOR_BITS,
93
137
- false, PREALLOC_MODE_OFF, NULL);
94
- /* Disable migration until bdrv_invalidate_cache method is added */
138
+ false, PREALLOC_MODE_OFF, 0, NULL);
95
+ /* Disable migration until bdrv_activate method is added */
139
}
96
error_setg(&s->migration_blocker, "The Parallels format used by node '%s' "
140
if (ret < 0) {
97
"does not support live migration",
141
return ret;
98
bdrv_get_device_or_node_name(bs));
142
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn parallels_co_check(BlockDriverState *bs,
99
diff --git a/tests/unit/test-block-iothread.c b/tests/unit/test-block-iothread.c
143
* That means we have to pass exact=true.
144
*/
145
ret = bdrv_truncate(bs->file, res->image_end_offset, true,
146
- PREALLOC_MODE_OFF, &local_err);
147
+ PREALLOC_MODE_OFF, 0, &local_err);
148
if (ret < 0) {
149
error_report_err(local_err);
150
res->check_errors++;
151
@@ -XXX,XX +XXX,XX @@ static void parallels_close(BlockDriverState *bs)
152
153
/* errors are ignored, so we might as well pass exact=true */
154
bdrv_truncate(bs->file, s->data_end << BDRV_SECTOR_BITS, true,
155
- PREALLOC_MODE_OFF, NULL);
156
+ PREALLOC_MODE_OFF, 0, NULL);
157
}
158
159
g_free(s->bat_dirty_bmap);
160
diff --git a/block/qcow.c b/block/qcow.c
161
index XXXXXXX..XXXXXXX 100644
100
index XXXXXXX..XXXXXXX 100644
162
--- a/block/qcow.c
101
--- a/tests/unit/test-block-iothread.c
163
+++ b/block/qcow.c
102
+++ b/tests/unit/test-block-iothread.c
164
@@ -XXX,XX +XXX,XX @@ static int get_cluster_offset(BlockDriverState *bs,
103
@@ -XXX,XX +XXX,XX @@ static void test_sync_op_check(BdrvChild *c)
165
return -E2BIG;
104
static void test_sync_op_invalidate_cache(BdrvChild *c)
166
}
105
{
167
ret = bdrv_truncate(bs->file, cluster_offset + s->cluster_size,
106
/* Early success: Image is not inactive */
168
- false, PREALLOC_MODE_OFF, NULL);
107
- bdrv_invalidate_cache(c->bs, NULL);
169
+ false, PREALLOC_MODE_OFF, 0, NULL);
108
+ bdrv_activate(c->bs, NULL);
170
if (ret < 0) {
171
return ret;
172
}
173
@@ -XXX,XX +XXX,XX @@ static int qcow_make_empty(BlockDriverState *bs)
174
l1_length) < 0)
175
return -1;
176
ret = bdrv_truncate(bs->file, s->l1_table_offset + l1_length, false,
177
- PREALLOC_MODE_OFF, NULL);
178
+ PREALLOC_MODE_OFF, 0, NULL);
179
if (ret < 0)
180
return ret;
181
182
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
183
index XXXXXXX..XXXXXXX 100644
184
--- a/block/qcow2-refcount.c
185
+++ b/block/qcow2-refcount.c
186
@@ -XXX,XX +XXX,XX @@ static int check_refblocks(BlockDriverState *bs, BdrvCheckResult *res,
187
}
188
189
ret = bdrv_truncate(bs->file, offset + s->cluster_size, false,
190
- PREALLOC_MODE_OFF, &local_err);
191
+ PREALLOC_MODE_OFF, 0, &local_err);
192
if (ret < 0) {
193
error_report_err(local_err);
194
goto resize_fail;
195
diff --git a/block/qcow2.c b/block/qcow2.c
196
index XXXXXXX..XXXXXXX 100644
197
--- a/block/qcow2.c
198
+++ b/block/qcow2.c
199
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn preallocate_co(BlockDriverState *bs, uint64_t offset,
200
mode = PREALLOC_MODE_OFF;
201
}
202
ret = bdrv_co_truncate(s->data_file, host_offset + cur_bytes, false,
203
- mode, errp);
204
+ mode, 0, errp);
205
if (ret < 0) {
206
return ret;
207
}
208
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
209
* always fulfilled, so there is no need to pass it on.)
210
*/
211
bdrv_co_truncate(bs->file, (last_cluster + 1) * s->cluster_size,
212
- false, PREALLOC_MODE_OFF, &local_err);
213
+ false, PREALLOC_MODE_OFF, 0, &local_err);
214
if (local_err) {
215
warn_reportf_err(local_err,
216
"Failed to truncate the tail of the image: ");
217
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
218
* file should be resized to the exact target size, too,
219
* so we pass @exact here.
220
*/
221
- ret = bdrv_co_truncate(s->data_file, offset, exact, prealloc, errp);
222
+ ret = bdrv_co_truncate(s->data_file, offset, exact, prealloc, 0,
223
+ errp);
224
if (ret < 0) {
225
goto fail;
226
}
227
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
228
new_file_size = allocation_start +
229
nb_new_data_clusters * s->cluster_size;
230
/* Image file grows, so @exact does not matter */
231
- ret = bdrv_co_truncate(bs->file, new_file_size, false, prealloc, errp);
232
+ ret = bdrv_co_truncate(bs->file, new_file_size, false, prealloc, 0,
233
+ errp);
234
if (ret < 0) {
235
error_prepend(errp, "Failed to resize underlying file: ");
236
qcow2_free_clusters(bs, allocation_start,
237
@@ -XXX,XX +XXX,XX @@ qcow2_co_pwritev_compressed_part(BlockDriverState *bs,
238
if (len < 0) {
239
return len;
240
}
241
- return bdrv_co_truncate(bs->file, len, false, PREALLOC_MODE_OFF, NULL);
242
+ return bdrv_co_truncate(bs->file, len, false, PREALLOC_MODE_OFF, 0,
243
+ NULL);
244
}
245
246
if (offset_into_cluster(s, offset)) {
247
@@ -XXX,XX +XXX,XX @@ static int make_completely_empty(BlockDriverState *bs)
248
}
249
250
ret = bdrv_truncate(bs->file, (3 + l1_clusters) * s->cluster_size, false,
251
- PREALLOC_MODE_OFF, &local_err);
252
+ PREALLOC_MODE_OFF, 0, &local_err);
253
if (ret < 0) {
254
error_report_err(local_err);
255
goto fail;
256
diff --git a/block/raw-format.c b/block/raw-format.c
257
index XXXXXXX..XXXXXXX 100644
258
--- a/block/raw-format.c
259
+++ b/block/raw-format.c
260
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn raw_co_truncate(BlockDriverState *bs, int64_t offset,
261
262
s->size = offset;
263
offset += s->offset;
264
- return bdrv_co_truncate(bs->file, offset, exact, prealloc, errp);
265
+ return bdrv_co_truncate(bs->file, offset, exact, prealloc, 0, errp);
266
}
109
}
267
110
268
static void raw_eject(BlockDriverState *bs, bool eject_flag)
111
269
diff --git a/block/vhdx-log.c b/block/vhdx-log.c
270
index XXXXXXX..XXXXXXX 100644
271
--- a/block/vhdx-log.c
272
+++ b/block/vhdx-log.c
273
@@ -XXX,XX +XXX,XX @@ static int vhdx_log_flush(BlockDriverState *bs, BDRVVHDXState *s,
274
goto exit;
275
}
276
ret = bdrv_truncate(bs->file, new_file_size, false,
277
- PREALLOC_MODE_OFF, NULL);
278
+ PREALLOC_MODE_OFF, 0, NULL);
279
if (ret < 0) {
280
goto exit;
281
}
282
diff --git a/block/vhdx.c b/block/vhdx.c
283
index XXXXXXX..XXXXXXX 100644
284
--- a/block/vhdx.c
285
+++ b/block/vhdx.c
286
@@ -XXX,XX +XXX,XX @@ static int vhdx_allocate_block(BlockDriverState *bs, BDRVVHDXState *s,
287
}
288
289
return bdrv_truncate(bs->file, *new_offset + s->block_size, false,
290
- PREALLOC_MODE_OFF, NULL);
291
+ PREALLOC_MODE_OFF, 0, NULL);
292
}
293
294
/*
295
diff --git a/block/vmdk.c b/block/vmdk.c
296
index XXXXXXX..XXXXXXX 100644
297
--- a/block/vmdk.c
298
+++ b/block/vmdk.c
299
@@ -XXX,XX +XXX,XX @@ vmdk_co_pwritev_compressed(BlockDriverState *bs, uint64_t offset,
300
}
301
length = QEMU_ALIGN_UP(length, BDRV_SECTOR_SIZE);
302
ret = bdrv_truncate(s->extents[i].file, length, false,
303
- PREALLOC_MODE_OFF, NULL);
304
+ PREALLOC_MODE_OFF, 0, NULL);
305
if (ret < 0) {
306
return ret;
307
}
308
diff --git a/tests/test-block-iothread.c b/tests/test-block-iothread.c
309
index XXXXXXX..XXXXXXX 100644
310
--- a/tests/test-block-iothread.c
311
+++ b/tests/test-block-iothread.c
312
@@ -XXX,XX +XXX,XX @@ static void test_sync_op_truncate(BdrvChild *c)
313
int ret;
314
315
/* Normal success path */
316
- ret = bdrv_truncate(c, 65536, false, PREALLOC_MODE_OFF, NULL);
317
+ ret = bdrv_truncate(c, 65536, false, PREALLOC_MODE_OFF, 0, NULL);
318
g_assert_cmpint(ret, ==, 0);
319
320
/* Early error: Negative offset */
321
- ret = bdrv_truncate(c, -2, false, PREALLOC_MODE_OFF, NULL);
322
+ ret = bdrv_truncate(c, -2, false, PREALLOC_MODE_OFF, 0, NULL);
323
g_assert_cmpint(ret, ==, -EINVAL);
324
325
/* Error: Read-only image */
326
c->bs->read_only = true;
327
c->bs->open_flags &= ~BDRV_O_RDWR;
328
329
- ret = bdrv_truncate(c, 65536, false, PREALLOC_MODE_OFF, NULL);
330
+ ret = bdrv_truncate(c, 65536, false, PREALLOC_MODE_OFF, 0, NULL);
331
g_assert_cmpint(ret, ==, -EACCES);
332
333
c->bs->read_only = false;
334
--
112
--
335
2.25.3
113
2.35.1
336
337
diff view generated by jsdifflib
New patch
1
1
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
2
3
Following the bdrv_activate renaming, change also the name
4
of the respective callers.
5
6
bdrv_invalidate_cache_all -> bdrv_activate_all
7
blk_invalidate_cache -> blk_activate
8
test_sync_op_invalidate_cache -> test_sync_op_activate
9
10
No functional change intended.
11
12
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
13
Reviewed-by: Juan Quintela <quintela@redhat.com>
14
Reviewed-by: Hanna Reitz <hreitz@redhat.com>
15
Message-Id: <20220209105452.1694545-5-eesposit@redhat.com>
16
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
17
---
18
include/block/block.h | 2 +-
19
include/sysemu/block-backend.h | 2 +-
20
block.c | 2 +-
21
block/block-backend.c | 2 +-
22
hw/block/pflash_cfi01.c | 2 +-
23
hw/nvram/spapr_nvram.c | 2 +-
24
migration/block.c | 2 +-
25
migration/migration.c | 14 +++++++-------
26
migration/savevm.c | 6 +++---
27
monitor/qmp-cmds.c | 2 +-
28
tests/unit/test-block-iothread.c | 6 +++---
29
11 files changed, 21 insertions(+), 21 deletions(-)
30
31
diff --git a/include/block/block.h b/include/block/block.h
32
index XXXXXXX..XXXXXXX 100644
33
--- a/include/block/block.h
34
+++ b/include/block/block.h
35
@@ -XXX,XX +XXX,XX @@ int bdrv_co_ioctl(BlockDriverState *bs, int req, void *buf);
36
/* Invalidate any cached metadata used by image formats */
37
int generated_co_wrapper bdrv_invalidate_cache(BlockDriverState *bs,
38
Error **errp);
39
-void bdrv_invalidate_cache_all(Error **errp);
40
int bdrv_activate(BlockDriverState *bs, Error **errp);
41
+void bdrv_activate_all(Error **errp);
42
int bdrv_inactivate_all(void);
43
44
/* Ensure contents are flushed to disk. */
45
diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h
46
index XXXXXXX..XXXXXXX 100644
47
--- a/include/sysemu/block-backend.h
48
+++ b/include/sysemu/block-backend.h
49
@@ -XXX,XX +XXX,XX @@ bool blk_is_writable(BlockBackend *blk);
50
bool blk_is_sg(BlockBackend *blk);
51
bool blk_enable_write_cache(BlockBackend *blk);
52
void blk_set_enable_write_cache(BlockBackend *blk, bool wce);
53
-void blk_invalidate_cache(BlockBackend *blk, Error **errp);
54
+void blk_activate(BlockBackend *blk, Error **errp);
55
bool blk_is_inserted(BlockBackend *blk);
56
bool blk_is_available(BlockBackend *blk);
57
void blk_lock_medium(BlockBackend *blk, bool locked);
58
diff --git a/block.c b/block.c
59
index XXXXXXX..XXXXXXX 100644
60
--- a/block.c
61
+++ b/block.c
62
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_invalidate_cache(BlockDriverState *bs, Error **errp)
63
return 0;
64
}
65
66
-void bdrv_invalidate_cache_all(Error **errp)
67
+void bdrv_activate_all(Error **errp)
68
{
69
BlockDriverState *bs;
70
BdrvNextIterator it;
71
diff --git a/block/block-backend.c b/block/block-backend.c
72
index XXXXXXX..XXXXXXX 100644
73
--- a/block/block-backend.c
74
+++ b/block/block-backend.c
75
@@ -XXX,XX +XXX,XX @@ void blk_set_enable_write_cache(BlockBackend *blk, bool wce)
76
blk->enable_write_cache = wce;
77
}
78
79
-void blk_invalidate_cache(BlockBackend *blk, Error **errp)
80
+void blk_activate(BlockBackend *blk, Error **errp)
81
{
82
BlockDriverState *bs = blk_bs(blk);
83
84
diff --git a/hw/block/pflash_cfi01.c b/hw/block/pflash_cfi01.c
85
index XXXXXXX..XXXXXXX 100644
86
--- a/hw/block/pflash_cfi01.c
87
+++ b/hw/block/pflash_cfi01.c
88
@@ -XXX,XX +XXX,XX @@ static void postload_update_cb(void *opaque, bool running, RunState state)
89
{
90
PFlashCFI01 *pfl = opaque;
91
92
- /* This is called after bdrv_invalidate_cache_all. */
93
+ /* This is called after bdrv_activate_all. */
94
qemu_del_vm_change_state_handler(pfl->vmstate);
95
pfl->vmstate = NULL;
96
97
diff --git a/hw/nvram/spapr_nvram.c b/hw/nvram/spapr_nvram.c
98
index XXXXXXX..XXXXXXX 100644
99
--- a/hw/nvram/spapr_nvram.c
100
+++ b/hw/nvram/spapr_nvram.c
101
@@ -XXX,XX +XXX,XX @@ static void postload_update_cb(void *opaque, bool running, RunState state)
102
{
103
SpaprNvram *nvram = opaque;
104
105
- /* This is called after bdrv_invalidate_cache_all. */
106
+ /* This is called after bdrv_activate_all. */
107
108
qemu_del_vm_change_state_handler(nvram->vmstate);
109
nvram->vmstate = NULL;
110
diff --git a/migration/block.c b/migration/block.c
111
index XXXXXXX..XXXXXXX 100644
112
--- a/migration/block.c
113
+++ b/migration/block.c
114
@@ -XXX,XX +XXX,XX @@ static int block_load(QEMUFile *f, void *opaque, int version_id)
115
return -EINVAL;
116
}
117
118
- blk_invalidate_cache(blk, &local_err);
119
+ blk_activate(blk, &local_err);
120
if (local_err) {
121
error_report_err(local_err);
122
return -EINVAL;
123
diff --git a/migration/migration.c b/migration/migration.c
124
index XXXXXXX..XXXXXXX 100644
125
--- a/migration/migration.c
126
+++ b/migration/migration.c
127
@@ -XXX,XX +XXX,XX @@ static void process_incoming_migration_bh(void *opaque)
128
if (!migrate_late_block_activate() ||
129
(autostart && (!global_state_received() ||
130
global_state_get_runstate() == RUN_STATE_RUNNING))) {
131
- /* Make sure all file formats flush their mutable metadata.
132
+ /* Make sure all file formats throw away their mutable metadata.
133
* If we get an error here, just don't restart the VM yet. */
134
- bdrv_invalidate_cache_all(&local_err);
135
+ bdrv_activate_all(&local_err);
136
if (local_err) {
137
error_report_err(local_err);
138
local_err = NULL;
139
@@ -XXX,XX +XXX,XX @@ static void process_incoming_migration_co(void *opaque)
140
141
/* we get COLO info, and know if we are in COLO mode */
142
if (!ret && migration_incoming_colo_enabled()) {
143
- /* Make sure all file formats flush their mutable metadata */
144
- bdrv_invalidate_cache_all(&local_err);
145
+ /* Make sure all file formats throw away their mutable metadata */
146
+ bdrv_activate_all(&local_err);
147
if (local_err) {
148
error_report_err(local_err);
149
goto fail;
150
@@ -XXX,XX +XXX,XX @@ static void migrate_fd_cancel(MigrationState *s)
151
if (s->state == MIGRATION_STATUS_CANCELLING && s->block_inactive) {
152
Error *local_err = NULL;
153
154
- bdrv_invalidate_cache_all(&local_err);
155
+ bdrv_activate_all(&local_err);
156
if (local_err) {
157
error_report_err(local_err);
158
} else {
159
@@ -XXX,XX +XXX,XX @@ fail:
160
*/
161
Error *local_err = NULL;
162
163
- bdrv_invalidate_cache_all(&local_err);
164
+ bdrv_activate_all(&local_err);
165
if (local_err) {
166
error_report_err(local_err);
167
}
168
@@ -XXX,XX +XXX,XX @@ fail_invalidate:
169
Error *local_err = NULL;
170
171
qemu_mutex_lock_iothread();
172
- bdrv_invalidate_cache_all(&local_err);
173
+ bdrv_activate_all(&local_err);
174
if (local_err) {
175
error_report_err(local_err);
176
} else {
177
diff --git a/migration/savevm.c b/migration/savevm.c
178
index XXXXXXX..XXXXXXX 100644
179
--- a/migration/savevm.c
180
+++ b/migration/savevm.c
181
@@ -XXX,XX +XXX,XX @@ int qemu_savevm_state_complete_precopy_non_iterable(QEMUFile *f,
182
183
if (inactivate_disks) {
184
/* Inactivate before sending QEMU_VM_EOF so that the
185
- * bdrv_invalidate_cache_all() on the other end won't fail. */
186
+ * bdrv_activate_all() on the other end won't fail. */
187
ret = bdrv_inactivate_all();
188
if (ret) {
189
error_report("%s: bdrv_inactivate_all() failed (%d)",
190
@@ -XXX,XX +XXX,XX @@ static void loadvm_postcopy_handle_run_bh(void *opaque)
191
192
trace_loadvm_postcopy_handle_run_bh("after announce");
193
194
- /* Make sure all file formats flush their mutable metadata.
195
+ /* Make sure all file formats throw away their mutable metadata.
196
* If we get an error here, just don't restart the VM yet. */
197
- bdrv_invalidate_cache_all(&local_err);
198
+ bdrv_activate_all(&local_err);
199
if (local_err) {
200
error_report_err(local_err);
201
local_err = NULL;
202
diff --git a/monitor/qmp-cmds.c b/monitor/qmp-cmds.c
203
index XXXXXXX..XXXXXXX 100644
204
--- a/monitor/qmp-cmds.c
205
+++ b/monitor/qmp-cmds.c
206
@@ -XXX,XX +XXX,XX @@ void qmp_cont(Error **errp)
207
* If there are no inactive block nodes (e.g. because the VM was just
208
* paused rather than completing a migration), bdrv_inactivate_all() simply
209
* doesn't do anything. */
210
- bdrv_invalidate_cache_all(&local_err);
211
+ bdrv_activate_all(&local_err);
212
if (local_err) {
213
error_propagate(errp, local_err);
214
return;
215
diff --git a/tests/unit/test-block-iothread.c b/tests/unit/test-block-iothread.c
216
index XXXXXXX..XXXXXXX 100644
217
--- a/tests/unit/test-block-iothread.c
218
+++ b/tests/unit/test-block-iothread.c
219
@@ -XXX,XX +XXX,XX @@ static void test_sync_op_check(BdrvChild *c)
220
g_assert_cmpint(ret, ==, -ENOTSUP);
221
}
222
223
-static void test_sync_op_invalidate_cache(BdrvChild *c)
224
+static void test_sync_op_activate(BdrvChild *c)
225
{
226
/* Early success: Image is not inactive */
227
bdrv_activate(c->bs, NULL);
228
@@ -XXX,XX +XXX,XX @@ const SyncOpTest sync_op_tests[] = {
229
.name = "/sync-op/check",
230
.fn = test_sync_op_check,
231
}, {
232
- .name = "/sync-op/invalidate_cache",
233
- .fn = test_sync_op_invalidate_cache,
234
+ .name = "/sync-op/activate",
235
+ .fn = test_sync_op_activate,
236
},
237
};
238
239
--
240
2.35.1
diff view generated by jsdifflib
1
If BDRV_REQ_ZERO_WRITE is set and we're extending the image, calling
1
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
2
qcow2_cluster_zeroize() with flags=0 does the right thing: It doesn't
3
undo any previous preallocation, but just adds the zero flag to all
4
relevant L2 entries. If an external data file is in use, a write_zeroes
5
request to the data file is made instead.
6
2
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
3
Split bdrv_co_invalidate cache in two: the Global State (under BQL)
8
Message-Id: <20200424125448.63318-5-kwolf@redhat.com>
4
code that takes care of permissions and running GS callbacks,
9
Reviewed-by: Eric Blake <eblake@redhat.com>
5
and leave only the I/O code (->bdrv_co_invalidate_cache) running in
10
Reviewed-by: Max Reitz <mreitz@redhat.com>
6
the I/O coroutine.
7
8
The only side effect is that bdrv_co_invalidate_cache is not
9
recursive anymore, and so is every direct call to
10
bdrv_invalidate_cache().
11
12
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
13
Message-Id: <20220209105452.1694545-6-eesposit@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
---
15
---
13
block/qcow2-cluster.c | 2 +-
16
block.c | 37 +++++++++++++++++++++++--------------
14
block/qcow2.c | 34 ++++++++++++++++++++++++++++++++++
17
1 file changed, 23 insertions(+), 14 deletions(-)
15
2 files changed, 35 insertions(+), 1 deletion(-)
16
18
17
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
19
diff --git a/block.c b/block.c
18
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
19
--- a/block/qcow2-cluster.c
21
--- a/block.c
20
+++ b/block/qcow2-cluster.c
22
+++ b/block.c
21
@@ -XXX,XX +XXX,XX @@ int qcow2_cluster_zeroize(BlockDriverState *bs, uint64_t offset,
23
@@ -XXX,XX +XXX,XX @@ void bdrv_init_with_whitelist(void)
22
/* Caller must pass aligned values, except at image end */
24
}
23
assert(QEMU_IS_ALIGNED(offset, s->cluster_size));
25
24
assert(QEMU_IS_ALIGNED(end_offset, s->cluster_size) ||
26
int bdrv_activate(BlockDriverState *bs, Error **errp)
25
- end_offset == bs->total_sectors << BDRV_SECTOR_BITS);
27
-{
26
+ end_offset >= bs->total_sectors << BDRV_SECTOR_BITS);
28
- return bdrv_invalidate_cache(bs, errp);
27
29
-}
28
/* The zero flag is only supported by version 3 and newer */
30
-
29
if (s->qcow_version < 3) {
31
-int coroutine_fn bdrv_co_invalidate_cache(BlockDriverState *bs, Error **errp)
30
diff --git a/block/qcow2.c b/block/qcow2.c
32
{
31
index XXXXXXX..XXXXXXX 100644
33
BdrvChild *child, *parent;
32
--- a/block/qcow2.c
34
Error *local_err = NULL;
33
+++ b/block/qcow2.c
35
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_invalidate_cache(BlockDriverState *bs, Error **errp)
34
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options,
35
36
bs->supported_zero_flags = header.version >= 3 ?
37
BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK : 0;
38
+ bs->supported_truncate_flags = BDRV_REQ_ZERO_WRITE;
39
40
/* Repair image if dirty */
41
if (!(flags & (BDRV_O_CHECK | BDRV_O_INACTIVE)) && !bs->read_only &&
42
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
43
g_assert_not_reached();
44
}
36
}
45
37
46
+ if ((flags & BDRV_REQ_ZERO_WRITE) && offset > old_length) {
38
QLIST_FOREACH(child, &bs->children, next) {
47
+ uint64_t zero_start = QEMU_ALIGN_UP(old_length, s->cluster_size);
39
- bdrv_co_invalidate_cache(child->bs, &local_err);
40
+ bdrv_activate(child->bs, &local_err);
41
if (local_err) {
42
error_propagate(errp, local_err);
43
return -EINVAL;
44
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_invalidate_cache(BlockDriverState *bs, Error **errp)
45
* Note that the required permissions of inactive images are always a
46
* subset of the permissions required after activating the image. This
47
* allows us to just get the permissions upfront without restricting
48
- * drv->bdrv_invalidate_cache().
49
+ * bdrv_co_invalidate_cache().
50
*
51
* It also means that in error cases, we don't have to try and revert to
52
* the old permissions (which is an operation that could fail, too). We can
53
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_invalidate_cache(BlockDriverState *bs, Error **errp)
54
return ret;
55
}
56
57
- if (bs->drv->bdrv_co_invalidate_cache) {
58
- bs->drv->bdrv_co_invalidate_cache(bs, &local_err);
59
- if (local_err) {
60
- bs->open_flags |= BDRV_O_INACTIVE;
61
- error_propagate(errp, local_err);
62
- return -EINVAL;
63
- }
64
+ ret = bdrv_invalidate_cache(bs, errp);
65
+ if (ret < 0) {
66
+ bs->open_flags |= BDRV_O_INACTIVE;
67
+ return ret;
68
}
69
70
FOR_EACH_DIRTY_BITMAP(bs, bm) {
71
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_invalidate_cache(BlockDriverState *bs, Error **errp)
72
return 0;
73
}
74
75
+int coroutine_fn bdrv_co_invalidate_cache(BlockDriverState *bs, Error **errp)
76
+{
77
+ Error *local_err = NULL;
48
+
78
+
49
+ /*
79
+ assert(!(bs->open_flags & BDRV_O_INACTIVE));
50
+ * Use zero clusters as much as we can. qcow2_cluster_zeroize()
51
+ * requires a cluster-aligned start. The end may be unaligned if it is
52
+ * at the end of the image (which it is here).
53
+ */
54
+ ret = qcow2_cluster_zeroize(bs, zero_start, offset - zero_start, 0);
55
+ if (ret < 0) {
56
+ error_setg_errno(errp, -ret, "Failed to zero out new clusters");
57
+ goto fail;
58
+ }
59
+
80
+
60
+ /* Write explicit zeros for the unaligned head */
81
+ if (bs->drv->bdrv_co_invalidate_cache) {
61
+ if (zero_start > old_length) {
82
+ bs->drv->bdrv_co_invalidate_cache(bs, &local_err);
62
+ uint64_t len = zero_start - old_length;
83
+ if (local_err) {
63
+ uint8_t *buf = qemu_blockalign0(bs, len);
84
+ error_propagate(errp, local_err);
64
+ QEMUIOVector qiov;
85
+ return -EINVAL;
65
+ qemu_iovec_init_buf(&qiov, buf, len);
66
+
67
+ qemu_co_mutex_unlock(&s->lock);
68
+ ret = qcow2_co_pwritev_part(bs, old_length, len, &qiov, 0, 0);
69
+ qemu_co_mutex_lock(&s->lock);
70
+
71
+ qemu_vfree(buf);
72
+ if (ret < 0) {
73
+ error_setg_errno(errp, -ret, "Failed to zero out the new area");
74
+ goto fail;
75
+ }
76
+ }
86
+ }
77
+ }
87
+ }
78
+
88
+
79
if (prealloc != PREALLOC_MODE_OFF) {
89
+ return 0;
80
/* Flush metadata before actually changing the image size */
90
+}
81
ret = qcow2_write_caches(bs);
91
+
92
void bdrv_activate_all(Error **errp)
93
{
94
BlockDriverState *bs;
82
--
95
--
83
2.25.3
96
2.35.1
84
85
diff view generated by jsdifflib
New patch
1
From: Stefan Hajnoczi <stefanha@redhat.com>
1
2
3
Compiler optimizations can cache TLS values across coroutine yield
4
points, resulting in stale values from the previous thread when a
5
coroutine is re-entered by a new thread.
6
7
Serge Guelton developed an __attribute__((noinline)) wrapper and tested
8
it with clang and gcc. I formatted his idea according to QEMU's coding
9
style and wrote documentation.
10
11
The compiler can still optimize based on analyzing noinline code, so an
12
asm volatile barrier with an output constraint is required to prevent
13
unwanted optimizations.
14
15
Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=1952483
16
Suggested-by: Serge Guelton <sguelton@redhat.com>
17
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
18
Message-Id: <20220222140150.27240-2-stefanha@redhat.com>
19
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
20
---
21
include/qemu/coroutine-tls.h | 165 +++++++++++++++++++++++++++++++++++
22
1 file changed, 165 insertions(+)
23
create mode 100644 include/qemu/coroutine-tls.h
24
25
diff --git a/include/qemu/coroutine-tls.h b/include/qemu/coroutine-tls.h
26
new file mode 100644
27
index XXXXXXX..XXXXXXX
28
--- /dev/null
29
+++ b/include/qemu/coroutine-tls.h
30
@@ -XXX,XX +XXX,XX @@
31
+/*
32
+ * QEMU Thread Local Storage for coroutines
33
+ *
34
+ * Copyright Red Hat
35
+ *
36
+ * SPDX-License-Identifier: LGPL-2.1-or-later
37
+ *
38
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
39
+ * See the COPYING.LIB file in the top-level directory.
40
+ *
41
+ * It is forbidden to access Thread Local Storage in coroutines because
42
+ * compiler optimizations may cause values to be cached across coroutine
43
+ * re-entry. Coroutines can run in more than one thread through the course of
44
+ * their life, leading bugs when stale TLS values from the wrong thread are
45
+ * used as a result of compiler optimization.
46
+ *
47
+ * An example is:
48
+ *
49
+ * ..code-block:: c
50
+ * :caption: A coroutine that may see the wrong TLS value
51
+ *
52
+ * static __thread AioContext *current_aio_context;
53
+ * ...
54
+ * static void coroutine_fn foo(void)
55
+ * {
56
+ * aio_notify(current_aio_context);
57
+ * qemu_coroutine_yield();
58
+ * aio_notify(current_aio_context); // <-- may be stale after yielding!
59
+ * }
60
+ *
61
+ * This header provides macros for safely defining variables in Thread Local
62
+ * Storage:
63
+ *
64
+ * ..code-block:: c
65
+ * :caption: A coroutine that safely uses TLS
66
+ *
67
+ * QEMU_DEFINE_STATIC_CO_TLS(AioContext *, current_aio_context)
68
+ * ...
69
+ * static void coroutine_fn foo(void)
70
+ * {
71
+ * aio_notify(get_current_aio_context());
72
+ * qemu_coroutine_yield();
73
+ * aio_notify(get_current_aio_context()); // <-- safe
74
+ * }
75
+ */
76
+
77
+#ifndef QEMU_COROUTINE_TLS_H
78
+#define QEMU_COROUTINE_TLS_H
79
+
80
+/*
81
+ * To stop the compiler from caching TLS values we define accessor functions
82
+ * with __attribute__((noinline)) plus asm volatile("") to prevent
83
+ * optimizations that override noinline.
84
+ *
85
+ * The compiler can still analyze noinline code and make optimizations based on
86
+ * that knowledge, so an inline asm output operand is used to prevent
87
+ * optimizations that make assumptions about the address of the TLS variable.
88
+ *
89
+ * This is fragile and ultimately needs to be solved by a mechanism that is
90
+ * guaranteed to work by the compiler (e.g. stackless coroutines), but for now
91
+ * we use this approach to prevent issues.
92
+ */
93
+
94
+/**
95
+ * QEMU_DECLARE_CO_TLS:
96
+ * @type: the variable's C type
97
+ * @var: the variable name
98
+ *
99
+ * Declare an extern variable in Thread Local Storage from a header file:
100
+ *
101
+ * .. code-block:: c
102
+ * :caption: Declaring an extern variable in Thread Local Storage
103
+ *
104
+ * QEMU_DECLARE_CO_TLS(int, my_count)
105
+ * ...
106
+ * int c = get_my_count();
107
+ * set_my_count(c + 1);
108
+ * *get_ptr_my_count() = 0;
109
+ *
110
+ * This is a coroutine-safe replacement for the __thread keyword and is
111
+ * equivalent to the following code:
112
+ *
113
+ * .. code-block:: c
114
+ * :caption: Declaring a TLS variable using __thread
115
+ *
116
+ * extern __thread int my_count;
117
+ * ...
118
+ * int c = my_count;
119
+ * my_count = c + 1;
120
+ * *(&my_count) = 0;
121
+ */
122
+#define QEMU_DECLARE_CO_TLS(type, var) \
123
+ __attribute__((noinline)) type get_##var(void); \
124
+ __attribute__((noinline)) void set_##var(type v); \
125
+ __attribute__((noinline)) type *get_ptr_##var(void);
126
+
127
+/**
128
+ * QEMU_DEFINE_CO_TLS:
129
+ * @type: the variable's C type
130
+ * @var: the variable name
131
+ *
132
+ * Define a variable in Thread Local Storage that was previously declared from
133
+ * a header file with QEMU_DECLARE_CO_TLS():
134
+ *
135
+ * .. code-block:: c
136
+ * :caption: Defining a variable in Thread Local Storage
137
+ *
138
+ * QEMU_DEFINE_CO_TLS(int, my_count)
139
+ *
140
+ * This is a coroutine-safe replacement for the __thread keyword and is
141
+ * equivalent to the following code:
142
+ *
143
+ * .. code-block:: c
144
+ * :caption: Defining a TLS variable using __thread
145
+ *
146
+ * __thread int my_count;
147
+ */
148
+#define QEMU_DEFINE_CO_TLS(type, var) \
149
+ static __thread type co_tls_##var; \
150
+ type get_##var(void) { asm volatile(""); return co_tls_##var; } \
151
+ void set_##var(type v) { asm volatile(""); co_tls_##var = v; } \
152
+ type *get_ptr_##var(void) \
153
+ { type *ptr = &co_tls_##var; asm volatile("" : "+rm" (ptr)); return ptr; }
154
+
155
+/**
156
+ * QEMU_DEFINE_STATIC_CO_TLS:
157
+ * @type: the variable's C type
158
+ * @var: the variable name
159
+ *
160
+ * Define a static variable in Thread Local Storage:
161
+ *
162
+ * .. code-block:: c
163
+ * :caption: Defining a static variable in Thread Local Storage
164
+ *
165
+ * QEMU_DEFINE_STATIC_CO_TLS(int, my_count)
166
+ * ...
167
+ * int c = get_my_count();
168
+ * set_my_count(c + 1);
169
+ * *get_ptr_my_count() = 0;
170
+ *
171
+ * This is a coroutine-safe replacement for the __thread keyword and is
172
+ * equivalent to the following code:
173
+ *
174
+ * .. code-block:: c
175
+ * :caption: Defining a static TLS variable using __thread
176
+ *
177
+ * static __thread int my_count;
178
+ * ...
179
+ * int c = my_count;
180
+ * my_count = c + 1;
181
+ * *(&my_count) = 0;
182
+ */
183
+#define QEMU_DEFINE_STATIC_CO_TLS(type, var) \
184
+ static __thread type co_tls_##var; \
185
+ static __attribute__((noinline, unused)) \
186
+ type get_##var(void) \
187
+ { asm volatile(""); return co_tls_##var; } \
188
+ static __attribute__((noinline, unused)) \
189
+ void set_##var(type v) \
190
+ { asm volatile(""); co_tls_##var = v; } \
191
+ static __attribute__((noinline, unused)) \
192
+ type *get_ptr_##var(void) \
193
+ { type *ptr = &co_tls_##var; asm volatile("" : "+rm" (ptr)); return ptr; }
194
+
195
+#endif /* QEMU_COROUTINE_TLS_H */
196
--
197
2.35.1
diff view generated by jsdifflib
New patch
1
From: Stefan Hajnoczi <stefanha@redhat.com>
1
2
3
QEMU TLS macros must be used to make TLS variables safe with coroutines.
4
5
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
6
Message-Id: <20220222140150.27240-3-stefanha@redhat.com>
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
---
9
util/async.c | 12 +++++++-----
10
1 file changed, 7 insertions(+), 5 deletions(-)
11
12
diff --git a/util/async.c b/util/async.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/util/async.c
15
+++ b/util/async.c
16
@@ -XXX,XX +XXX,XX @@
17
#include "qemu/rcu_queue.h"
18
#include "block/raw-aio.h"
19
#include "qemu/coroutine_int.h"
20
+#include "qemu/coroutine-tls.h"
21
#include "trace.h"
22
23
/***********************************************************/
24
@@ -XXX,XX +XXX,XX @@ void aio_context_release(AioContext *ctx)
25
qemu_rec_mutex_unlock(&ctx->lock);
26
}
27
28
-static __thread AioContext *my_aiocontext;
29
+QEMU_DEFINE_STATIC_CO_TLS(AioContext *, my_aiocontext)
30
31
AioContext *qemu_get_current_aio_context(void)
32
{
33
- if (my_aiocontext) {
34
- return my_aiocontext;
35
+ AioContext *ctx = get_my_aiocontext();
36
+ if (ctx) {
37
+ return ctx;
38
}
39
if (qemu_mutex_iothread_locked()) {
40
/* Possibly in a vCPU thread. */
41
@@ -XXX,XX +XXX,XX @@ AioContext *qemu_get_current_aio_context(void)
42
43
void qemu_set_current_aio_context(AioContext *ctx)
44
{
45
- assert(!my_aiocontext);
46
- my_aiocontext = ctx;
47
+ assert(!get_my_aiocontext());
48
+ set_my_aiocontext(ctx);
49
}
50
--
51
2.35.1
diff view generated by jsdifflib
New patch
1
From: Stefan Hajnoczi <stefanha@redhat.com>
1
2
3
RCU may be used from coroutines. Standard __thread variables cannot be
4
used by coroutines. Use the coroutine TLS macros instead.
5
6
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
7
Message-Id: <20220222140150.27240-4-stefanha@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
---
10
include/qemu/rcu.h | 7 ++++---
11
tests/unit/rcutorture.c | 10 +++++-----
12
tests/unit/test-rcu-list.c | 4 ++--
13
util/rcu.c | 10 +++++-----
14
4 files changed, 16 insertions(+), 15 deletions(-)
15
16
diff --git a/include/qemu/rcu.h b/include/qemu/rcu.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/include/qemu/rcu.h
19
+++ b/include/qemu/rcu.h
20
@@ -XXX,XX +XXX,XX @@
21
#include "qemu/atomic.h"
22
#include "qemu/notify.h"
23
#include "qemu/sys_membarrier.h"
24
+#include "qemu/coroutine-tls.h"
25
26
#ifdef __cplusplus
27
extern "C" {
28
@@ -XXX,XX +XXX,XX @@ struct rcu_reader_data {
29
NotifierList force_rcu;
30
};
31
32
-extern __thread struct rcu_reader_data rcu_reader;
33
+QEMU_DECLARE_CO_TLS(struct rcu_reader_data, rcu_reader)
34
35
static inline void rcu_read_lock(void)
36
{
37
- struct rcu_reader_data *p_rcu_reader = &rcu_reader;
38
+ struct rcu_reader_data *p_rcu_reader = get_ptr_rcu_reader();
39
unsigned ctr;
40
41
if (p_rcu_reader->depth++ > 0) {
42
@@ -XXX,XX +XXX,XX @@ static inline void rcu_read_lock(void)
43
44
static inline void rcu_read_unlock(void)
45
{
46
- struct rcu_reader_data *p_rcu_reader = &rcu_reader;
47
+ struct rcu_reader_data *p_rcu_reader = get_ptr_rcu_reader();
48
49
assert(p_rcu_reader->depth != 0);
50
if (--p_rcu_reader->depth > 0) {
51
diff --git a/tests/unit/rcutorture.c b/tests/unit/rcutorture.c
52
index XXXXXXX..XXXXXXX 100644
53
--- a/tests/unit/rcutorture.c
54
+++ b/tests/unit/rcutorture.c
55
@@ -XXX,XX +XXX,XX @@ static void *rcu_read_perf_test(void *arg)
56
57
rcu_register_thread();
58
59
- *(struct rcu_reader_data **)arg = &rcu_reader;
60
+ *(struct rcu_reader_data **)arg = get_ptr_rcu_reader();
61
qatomic_inc(&nthreadsrunning);
62
while (goflag == GOFLAG_INIT) {
63
g_usleep(1000);
64
@@ -XXX,XX +XXX,XX @@ static void *rcu_update_perf_test(void *arg)
65
66
rcu_register_thread();
67
68
- *(struct rcu_reader_data **)arg = &rcu_reader;
69
+ *(struct rcu_reader_data **)arg = get_ptr_rcu_reader();
70
qatomic_inc(&nthreadsrunning);
71
while (goflag == GOFLAG_INIT) {
72
g_usleep(1000);
73
@@ -XXX,XX +XXX,XX @@ static void *rcu_read_stress_test(void *arg)
74
75
rcu_register_thread();
76
77
- *(struct rcu_reader_data **)arg = &rcu_reader;
78
+ *(struct rcu_reader_data **)arg = get_ptr_rcu_reader();
79
while (goflag == GOFLAG_INIT) {
80
g_usleep(1000);
81
}
82
@@ -XXX,XX +XXX,XX @@ static void *rcu_update_stress_test(void *arg)
83
struct rcu_stress *cp = qatomic_read(&rcu_stress_current);
84
85
rcu_register_thread();
86
- *(struct rcu_reader_data **)arg = &rcu_reader;
87
+ *(struct rcu_reader_data **)arg = get_ptr_rcu_reader();
88
89
while (goflag == GOFLAG_INIT) {
90
g_usleep(1000);
91
@@ -XXX,XX +XXX,XX @@ static void *rcu_fake_update_stress_test(void *arg)
92
{
93
rcu_register_thread();
94
95
- *(struct rcu_reader_data **)arg = &rcu_reader;
96
+ *(struct rcu_reader_data **)arg = get_ptr_rcu_reader();
97
while (goflag == GOFLAG_INIT) {
98
g_usleep(1000);
99
}
100
diff --git a/tests/unit/test-rcu-list.c b/tests/unit/test-rcu-list.c
101
index XXXXXXX..XXXXXXX 100644
102
--- a/tests/unit/test-rcu-list.c
103
+++ b/tests/unit/test-rcu-list.c
104
@@ -XXX,XX +XXX,XX @@ static void *rcu_q_reader(void *arg)
105
106
rcu_register_thread();
107
108
- *(struct rcu_reader_data **)arg = &rcu_reader;
109
+ *(struct rcu_reader_data **)arg = get_ptr_rcu_reader();
110
qatomic_inc(&nthreadsrunning);
111
while (qatomic_read(&goflag) == GOFLAG_INIT) {
112
g_usleep(1000);
113
@@ -XXX,XX +XXX,XX @@ static void *rcu_q_updater(void *arg)
114
long long n_removed_local = 0;
115
struct list_element *el, *prev_el;
116
117
- *(struct rcu_reader_data **)arg = &rcu_reader;
118
+ *(struct rcu_reader_data **)arg = get_ptr_rcu_reader();
119
qatomic_inc(&nthreadsrunning);
120
while (qatomic_read(&goflag) == GOFLAG_INIT) {
121
g_usleep(1000);
122
diff --git a/util/rcu.c b/util/rcu.c
123
index XXXXXXX..XXXXXXX 100644
124
--- a/util/rcu.c
125
+++ b/util/rcu.c
126
@@ -XXX,XX +XXX,XX @@ static inline int rcu_gp_ongoing(unsigned long *ctr)
127
/* Written to only by each individual reader. Read by both the reader and the
128
* writers.
129
*/
130
-__thread struct rcu_reader_data rcu_reader;
131
+QEMU_DEFINE_CO_TLS(struct rcu_reader_data, rcu_reader)
132
133
/* Protected by rcu_registry_lock. */
134
typedef QLIST_HEAD(, rcu_reader_data) ThreadList;
135
@@ -XXX,XX +XXX,XX @@ void drain_call_rcu(void)
136
137
void rcu_register_thread(void)
138
{
139
- assert(rcu_reader.ctr == 0);
140
+ assert(get_ptr_rcu_reader()->ctr == 0);
141
qemu_mutex_lock(&rcu_registry_lock);
142
- QLIST_INSERT_HEAD(&registry, &rcu_reader, node);
143
+ QLIST_INSERT_HEAD(&registry, get_ptr_rcu_reader(), node);
144
qemu_mutex_unlock(&rcu_registry_lock);
145
}
146
147
void rcu_unregister_thread(void)
148
{
149
qemu_mutex_lock(&rcu_registry_lock);
150
- QLIST_REMOVE(&rcu_reader, node);
151
+ QLIST_REMOVE(get_ptr_rcu_reader(), node);
152
qemu_mutex_unlock(&rcu_registry_lock);
153
}
154
155
void rcu_add_force_rcu_notifier(Notifier *n)
156
{
157
qemu_mutex_lock(&rcu_registry_lock);
158
- notifier_list_add(&rcu_reader.force_rcu, n);
159
+ notifier_list_add(&get_ptr_rcu_reader()->force_rcu, n);
160
qemu_mutex_unlock(&rcu_registry_lock);
161
}
162
163
--
164
2.35.1
diff view generated by jsdifflib
New patch
1
From: Stefan Hajnoczi <stefanha@redhat.com>
1
2
3
qemu_mutex_iothread_locked() may be used from coroutines. Standard
4
__thread variables cannot be used by coroutines. Use the coroutine TLS
5
macros instead.
6
7
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
8
Message-Id: <20220222140150.27240-5-stefanha@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
11
softmmu/cpus.c | 9 +++++----
12
1 file changed, 5 insertions(+), 4 deletions(-)
13
14
diff --git a/softmmu/cpus.c b/softmmu/cpus.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/softmmu/cpus.c
17
+++ b/softmmu/cpus.c
18
@@ -XXX,XX +XXX,XX @@
19
#include "qemu/osdep.h"
20
#include "qemu-common.h"
21
#include "monitor/monitor.h"
22
+#include "qemu/coroutine-tls.h"
23
#include "qapi/error.h"
24
#include "qapi/qapi-commands-machine.h"
25
#include "qapi/qapi-commands-misc.h"
26
@@ -XXX,XX +XXX,XX @@ bool qemu_in_vcpu_thread(void)
27
return current_cpu && qemu_cpu_is_self(current_cpu);
28
}
29
30
-static __thread bool iothread_locked = false;
31
+QEMU_DEFINE_STATIC_CO_TLS(bool, iothread_locked)
32
33
bool qemu_mutex_iothread_locked(void)
34
{
35
- return iothread_locked;
36
+ return get_iothread_locked();
37
}
38
39
/*
40
@@ -XXX,XX +XXX,XX @@ void qemu_mutex_lock_iothread_impl(const char *file, int line)
41
42
g_assert(!qemu_mutex_iothread_locked());
43
bql_lock(&qemu_global_mutex, file, line);
44
- iothread_locked = true;
45
+ set_iothread_locked(true);
46
}
47
48
void qemu_mutex_unlock_iothread(void)
49
{
50
g_assert(qemu_mutex_iothread_locked());
51
- iothread_locked = false;
52
+ set_iothread_locked(false);
53
qemu_mutex_unlock(&qemu_global_mutex);
54
}
55
56
--
57
2.35.1
diff view generated by jsdifflib
New patch
1
From: Hanna Reitz <hreitz@redhat.com>
1
2
3
The daemonizing functions in os-posix (os_daemonize() and
4
os_setup_post()) only daemonize the process if the static `daemonize`
5
variable is set. Right now, it can only be set by os_parse_cmd_args().
6
7
In order to use os_daemonize() and os_setup_post() from the storage
8
daemon to have it be daemonized, we need some other way to set this
9
`daemonize` variable, because I would rather not tap into the system
10
emulator's arg-parsing code. Therefore, this patch adds an
11
os_set_daemonize() function, which will return an error on os-win32
12
(because daemonizing is not supported there).
13
14
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
15
Message-Id: <20220303164814.284974-2-hreitz@redhat.com>
16
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
17
---
18
include/sysemu/os-posix.h | 1 +
19
include/sysemu/os-win32.h | 8 ++++++++
20
os-posix.c | 6 ++++++
21
3 files changed, 15 insertions(+)
22
23
diff --git a/include/sysemu/os-posix.h b/include/sysemu/os-posix.h
24
index XXXXXXX..XXXXXXX 100644
25
--- a/include/sysemu/os-posix.h
26
+++ b/include/sysemu/os-posix.h
27
@@ -XXX,XX +XXX,XX @@ int os_mlock(void);
28
typedef struct timeval qemu_timeval;
29
#define qemu_gettimeofday(tp) gettimeofday(tp, NULL)
30
31
+int os_set_daemonize(bool d);
32
bool is_daemonized(void);
33
34
/**
35
diff --git a/include/sysemu/os-win32.h b/include/sysemu/os-win32.h
36
index XXXXXXX..XXXXXXX 100644
37
--- a/include/sysemu/os-win32.h
38
+++ b/include/sysemu/os-win32.h
39
@@ -XXX,XX +XXX,XX @@ typedef struct {
40
} qemu_timeval;
41
int qemu_gettimeofday(qemu_timeval *tp);
42
43
+static inline int os_set_daemonize(bool d)
44
+{
45
+ if (d) {
46
+ return -ENOTSUP;
47
+ }
48
+ return 0;
49
+}
50
+
51
static inline bool is_daemonized(void)
52
{
53
return false;
54
diff --git a/os-posix.c b/os-posix.c
55
index XXXXXXX..XXXXXXX 100644
56
--- a/os-posix.c
57
+++ b/os-posix.c
58
@@ -XXX,XX +XXX,XX @@ bool is_daemonized(void)
59
return daemonize;
60
}
61
62
+int os_set_daemonize(bool d)
63
+{
64
+ daemonize = d;
65
+ return 0;
66
+}
67
+
68
int os_mlock(void)
69
{
70
#ifdef HAVE_MLOCKALL
71
--
72
2.35.1
diff view generated by jsdifflib
New patch
1
From: Hanna Reitz <hreitz@redhat.com>
1
2
3
In contrast to qemu-nbd (where it is called --fork) and the system
4
emulator, QSD does not have a --daemonize switch yet. Just like them,
5
QSD allows setting up block devices and exports on the command line.
6
When doing so, it is often necessary for whoever invoked the QSD to wait
7
until these exports are fully set up. A --daemonize switch allows
8
precisely this, by virtue of the parent process exiting once everything
9
is set up.
10
11
Note that there are alternative ways of waiting for all exports to be
12
set up, for example:
13
- Passing the --pidfile option and waiting until the respective file
14
exists (but I do not know if there is a way of implementing this
15
without a busy wait loop)
16
- Set up some network server (e.g. on a Unix socket) and have the QSD
17
connect to it after all arguments have been processed by appending
18
corresponding --chardev and --monitor options to the command line,
19
and then wait until the QSD connects
20
21
Having a --daemonize option would make this simpler, though, without
22
having to rely on additional tools (to set up a network server) or busy
23
waiting.
24
25
Implementing a --daemonize switch means having to fork the QSD process.
26
Ideally, we should do this as early as possible: All the parent process
27
has to do is to wait for the child process to signal completion of its
28
set-up phase, and therefore there is basically no initialization that
29
needs to be done before the fork. On the other hand, forking after
30
initialization steps means having to consider how those steps (like
31
setting up the block layer or QMP) interact with a later fork, which is
32
often not trivial.
33
34
In order to fork this early, we must scan the command line for
35
--daemonize long before our current process_options() call. Instead of
36
adding custom new code to do so, just reuse process_options() and give
37
it a @pre_init_pass argument to distinguish the two passes. I believe
38
there are some other switches but --daemonize that deserve parsing in
39
the first pass:
40
41
- --help and --version are supposed to only print some text and then
42
immediately exit (so any initialization we do would be for naught).
43
This changes behavior, because now "--blockdev inv-drv --help" will
44
print a help text instead of complaining about the --blockdev
45
argument.
46
Note that this is similar in behavior to other tools, though: "--help"
47
is generally immediately acted upon when finding it in the argument
48
list, potentially before other arguments (even ones before it) are
49
acted on. For example, "ls /does-not-exist --help" prints a help text
50
and does not complain about ENOENT.
51
52
- --pidfile does not need initialization, and is already exempted from
53
the sequential order that process_options() claims to strictly follow
54
(the PID file is only created after all arguments are processed, not
55
at the time the --pidfile argument appears), so it makes sense to
56
include it in the same category as --daemonize.
57
58
- Invalid arguments should always be reported as soon as possible. (The
59
same caveat with --help applies: That means that "--blockdev inv-drv
60
--inv-arg" will now complain about --inv-arg, not inv-drv.)
61
62
This patch does make some references to --daemonize without having
63
implemented it yet, but that will happen in the next patch.
64
65
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
66
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
67
Message-Id: <20220303164814.284974-3-hreitz@redhat.com>
68
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
69
---
70
storage-daemon/qemu-storage-daemon.c | 43 ++++++++++++++++++++++++----
71
1 file changed, 38 insertions(+), 5 deletions(-)
72
73
diff --git a/storage-daemon/qemu-storage-daemon.c b/storage-daemon/qemu-storage-daemon.c
74
index XXXXXXX..XXXXXXX 100644
75
--- a/storage-daemon/qemu-storage-daemon.c
76
+++ b/storage-daemon/qemu-storage-daemon.c
77
@@ -XXX,XX +XXX,XX @@ static int getopt_set_loc(int argc, char **argv, const char *optstring,
78
return c;
79
}
80
81
-static void process_options(int argc, char *argv[])
82
+/**
83
+ * Process QSD command-line arguments.
84
+ *
85
+ * This is done in two passes:
86
+ *
87
+ * First (@pre_init_pass is true), we do a pass where all global
88
+ * arguments pertaining to the QSD process (like --help or --daemonize)
89
+ * are processed. This pass is done before most of the QEMU-specific
90
+ * initialization steps (e.g. initializing the block layer or QMP), and
91
+ * so must only process arguments that are not really QEMU-specific.
92
+ *
93
+ * Second (@pre_init_pass is false), we (sequentially) process all
94
+ * QEMU/QSD-specific arguments. Many of these arguments are effectively
95
+ * translated to QMP commands (like --blockdev for blockdev-add, or
96
+ * --export for block-export-add).
97
+ */
98
+static void process_options(int argc, char *argv[], bool pre_init_pass)
99
{
100
int c;
101
102
@@ -XXX,XX +XXX,XX @@ static void process_options(int argc, char *argv[])
103
};
104
105
/*
106
- * In contrast to the system emulator, options are processed in the order
107
- * they are given on the command lines. This means that things must be
108
- * defined first before they can be referenced in another option.
109
+ * In contrast to the system emulator, QEMU-specific options are processed
110
+ * in the order they are given on the command lines. This means that things
111
+ * must be defined first before they can be referenced in another option.
112
*/
113
+ optind = 1;
114
while ((c = getopt_set_loc(argc, argv, "-hT:V", long_options)) != -1) {
115
+ bool handle_option_pre_init;
116
+
117
+ /* Should this argument be processed in the pre-init pass? */
118
+ handle_option_pre_init =
119
+ c == '?' ||
120
+ c == 'h' ||
121
+ c == 'V' ||
122
+ c == OPTION_PIDFILE;
123
+
124
+ /* Process every option only in its respective pass */
125
+ if (pre_init_pass != handle_option_pre_init) {
126
+ continue;
127
+ }
128
+
129
switch (c) {
130
case '?':
131
exit(EXIT_FAILURE);
132
@@ -XXX,XX +XXX,XX @@ int main(int argc, char *argv[])
133
qemu_init_exec_dir(argv[0]);
134
os_setup_signal_handling();
135
136
+ process_options(argc, argv, true);
137
+
138
module_call_init(MODULE_INIT_QOM);
139
module_call_init(MODULE_INIT_TRACE);
140
qemu_add_opts(&qemu_trace_opts);
141
@@ -XXX,XX +XXX,XX @@ int main(int argc, char *argv[])
142
qemu_set_log(LOG_TRACE);
143
144
qemu_init_main_loop(&error_fatal);
145
- process_options(argc, argv);
146
+ process_options(argc, argv, false);
147
148
/*
149
* Write the pid file after creating chardevs, exports, and NBD servers but
150
--
151
2.35.1
diff view generated by jsdifflib
New patch
1
From: Hanna Reitz <hreitz@redhat.com>
1
2
3
To implement this, we reuse the existing daemonizing functions from the
4
system emulator, which mainly do the following:
5
- Fork off a child process, and set up a pipe between parent and child
6
- The parent process waits until the child sends a status byte over the
7
pipe (0 means that the child was set up successfully; anything else
8
(including errors or EOF) means that the child was not set up
9
successfully), and then exits with an appropriate exit status
10
- The child process enters a new session (forking off again), changes
11
the umask, and will ignore terminal signals from then on
12
- Once set-up is complete, the child will chdir to /, redirect all
13
standard I/O streams to /dev/null, and tell the parent that set-up has
14
been completed successfully
15
16
In contrast to qemu-nbd's --fork implementation, during the set up
17
phase, error messages are not piped through the parent process.
18
qemu-nbd mainly does this to detect errors, though (while os_daemonize()
19
has the child explicitly signal success after set up); because we do not
20
redirect stderr after forking, error messages continue to appear on
21
whatever the parent's stderr was (until set up is complete).
22
23
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
24
Message-Id: <20220303164814.284974-4-hreitz@redhat.com>
25
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
26
---
27
docs/tools/qemu-storage-daemon.rst | 7 +++++++
28
storage-daemon/qemu-storage-daemon.c | 15 +++++++++++++++
29
2 files changed, 22 insertions(+)
30
31
diff --git a/docs/tools/qemu-storage-daemon.rst b/docs/tools/qemu-storage-daemon.rst
32
index XXXXXXX..XXXXXXX 100644
33
--- a/docs/tools/qemu-storage-daemon.rst
34
+++ b/docs/tools/qemu-storage-daemon.rst
35
@@ -XXX,XX +XXX,XX @@ Standard options:
36
created but before accepting connections. The daemon has started successfully
37
when the pid file is written and clients may begin connecting.
38
39
+.. option:: --daemonize
40
+
41
+ Daemonize the process. The parent process will exit once startup is complete
42
+ (i.e., after the pid file has been or would have been written) or failure
43
+ occurs. Its exit code reflects whether the child has started up successfully
44
+ or failed to do so.
45
+
46
Examples
47
--------
48
Launch the daemon with QMP monitor socket ``qmp.sock`` so clients can execute
49
diff --git a/storage-daemon/qemu-storage-daemon.c b/storage-daemon/qemu-storage-daemon.c
50
index XXXXXXX..XXXXXXX 100644
51
--- a/storage-daemon/qemu-storage-daemon.c
52
+++ b/storage-daemon/qemu-storage-daemon.c
53
@@ -XXX,XX +XXX,XX @@ static void help(void)
54
" --chardev <options> configure a character device backend\n"
55
" (see the qemu(1) man page for possible options)\n"
56
"\n"
57
+" --daemonize daemonize the process, and have the parent exit\n"
58
+" once startup is complete\n"
59
+"\n"
60
" --export [type=]nbd,id=<id>,node-name=<node-name>[,name=<export-name>]\n"
61
" [,writable=on|off][,bitmap=<name>]\n"
62
" export the specified block node over NBD\n"
63
@@ -XXX,XX +XXX,XX @@ QEMU_HELP_BOTTOM "\n",
64
enum {
65
OPTION_BLOCKDEV = 256,
66
OPTION_CHARDEV,
67
+ OPTION_DAEMONIZE,
68
OPTION_EXPORT,
69
OPTION_MONITOR,
70
OPTION_NBD_SERVER,
71
@@ -XXX,XX +XXX,XX @@ static void process_options(int argc, char *argv[], bool pre_init_pass)
72
static const struct option long_options[] = {
73
{"blockdev", required_argument, NULL, OPTION_BLOCKDEV},
74
{"chardev", required_argument, NULL, OPTION_CHARDEV},
75
+ {"daemonize", no_argument, NULL, OPTION_DAEMONIZE},
76
{"export", required_argument, NULL, OPTION_EXPORT},
77
{"help", no_argument, NULL, 'h'},
78
{"monitor", required_argument, NULL, OPTION_MONITOR},
79
@@ -XXX,XX +XXX,XX @@ static void process_options(int argc, char *argv[], bool pre_init_pass)
80
c == '?' ||
81
c == 'h' ||
82
c == 'V' ||
83
+ c == OPTION_DAEMONIZE ||
84
c == OPTION_PIDFILE;
85
86
/* Process every option only in its respective pass */
87
@@ -XXX,XX +XXX,XX @@ static void process_options(int argc, char *argv[], bool pre_init_pass)
88
qemu_opts_del(opts);
89
break;
90
}
91
+ case OPTION_DAEMONIZE:
92
+ if (os_set_daemonize(true) < 0) {
93
+ error_report("--daemonize not supported in this build");
94
+ exit(EXIT_FAILURE);
95
+ }
96
+ break;
97
case OPTION_EXPORT:
98
{
99
Visitor *v;
100
@@ -XXX,XX +XXX,XX @@ int main(int argc, char *argv[])
101
102
process_options(argc, argv, true);
103
104
+ os_daemonize();
105
+
106
module_call_init(MODULE_INIT_QOM);
107
module_call_init(MODULE_INIT_TRACE);
108
qemu_add_opts(&qemu_trace_opts);
109
@@ -XXX,XX +XXX,XX @@ int main(int argc, char *argv[])
110
* it.
111
*/
112
pid_file_init();
113
+ os_setup_post();
114
115
while (!exit_requested) {
116
main_loop_wait(false);
117
--
118
2.35.1
diff view generated by jsdifflib
New patch
1
1
From: Hanna Reitz <hreitz@redhat.com>
2
3
185 tests quitting qemu while a block job is active. It does not
4
specifically test quitting qemu while a mirror or active commit job is
5
in its READY phase.
6
7
Add two test cases for this, where we respectively mirror or commit to
8
an external QSD instance, which provides a throttled block device. qemu
9
is supposed to cancel the job so that it can quit as soon as possible
10
instead of waiting for the job to complete (which it did before 6.2).
11
12
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
13
Message-Id: <20220303164814.284974-5-hreitz@redhat.com>
14
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
15
---
16
tests/qemu-iotests/185 | 190 ++++++++++++++++++++++++++++++++++++-
17
tests/qemu-iotests/185.out | 48 ++++++++++
18
2 files changed, 237 insertions(+), 1 deletion(-)
19
20
diff --git a/tests/qemu-iotests/185 b/tests/qemu-iotests/185
21
index XXXXXXX..XXXXXXX 100755
22
--- a/tests/qemu-iotests/185
23
+++ b/tests/qemu-iotests/185
24
@@ -XXX,XX +XXX,XX @@ _cleanup()
25
_rm_test_img "${TEST_IMG}.copy"
26
_cleanup_test_img
27
_cleanup_qemu
28
+
29
+ if [ -f "$TEST_DIR/qsd.pid" ]; then
30
+ kill -SIGKILL "$(cat "$TEST_DIR/qsd.pid")"
31
+ rm -f "$TEST_DIR/qsd.pid"
32
+ fi
33
+ rm -f "$SOCK_DIR/qsd.sock"
34
}
35
trap "_cleanup; exit \$status" 0 1 2 3 15
36
37
@@ -XXX,XX +XXX,XX @@ _supported_fmt qcow2
38
_supported_proto file
39
_supported_os Linux
40
41
-size=64M
42
+size=$((64 * 1048576))
43
TEST_IMG="${TEST_IMG}.base" _make_test_img $size
44
45
echo
46
@@ -XXX,XX +XXX,XX @@ wait=1 _cleanup_qemu | grep -v 'JOB_STATUS_CHANGE'
47
48
_check_test_img
49
50
+echo
51
+echo === Start mirror to throttled QSD and exit qemu ===
52
+echo
53
+
54
+# Mirror to a throttled QSD instance (so that qemu cannot drain the
55
+# throttling), wait for READY, then write some data to the device,
56
+# and then quit qemu.
57
+# (qemu should force-cancel the job and not wait for the data to be
58
+# written to the target.)
59
+
60
+_make_test_img $size
61
+
62
+# Will be used by this and the next case
63
+set_up_throttled_qsd() {
64
+ $QSD \
65
+ --object throttle-group,id=thrgr,limits.bps-total=1048576 \
66
+ --blockdev null-co,node-name=null,size=$size \
67
+ --blockdev throttle,node-name=throttled,throttle-group=thrgr,file=null \
68
+ --nbd-server addr.type=unix,addr.path="$SOCK_DIR/qsd.sock" \
69
+ --export nbd,id=exp,node-name=throttled,name=target,writable=true \
70
+ --pidfile "$TEST_DIR/qsd.pid" \
71
+ --daemonize
72
+}
73
+
74
+set_up_throttled_qsd
75
+
76
+# Need a virtio-blk device so that qemu-io writes will not block the monitor
77
+_launch_qemu \
78
+ --blockdev file,node-name=source-proto,filename="$TEST_IMG" \
79
+ --blockdev qcow2,node-name=source-fmt,file=source-proto \
80
+ --device virtio-blk,id=vblk,drive=source-fmt \
81
+ --blockdev "{\"driver\": \"nbd\",
82
+ \"node-name\": \"target\",
83
+ \"server\": {
84
+ \"type\": \"unix\",
85
+ \"path\": \"$SOCK_DIR/qsd.sock\"
86
+ },
87
+ \"export\": \"target\"}"
88
+
89
+h=$QEMU_HANDLE
90
+_send_qemu_cmd $h '{"execute": "qmp_capabilities"}' 'return'
91
+
92
+# Use sync=top, so the first pass will not copy the whole image
93
+_send_qemu_cmd $h \
94
+ '{"execute": "blockdev-mirror",
95
+ "arguments": {
96
+ "job-id": "mirror",
97
+ "device": "source-fmt",
98
+ "target": "target",
99
+ "sync": "top"
100
+ }}' \
101
+ 'return' \
102
+ | grep -v JOB_STATUS_CHANGE # Ignore these events during creation
103
+
104
+# This too will be used by this and the next case
105
+# $1: QEMU handle
106
+# $2: Image size
107
+wait_for_job_and_quit() {
108
+ h=$1
109
+ size=$2
110
+
111
+ # List of expected events
112
+ capture_events='BLOCK_JOB_READY JOB_STATUS_CHANGE'
113
+ _wait_event $h 'BLOCK_JOB_READY'
114
+ QEMU_EVENTS= # Ignore all JOB_STATUS_CHANGE events that came before READY
115
+
116
+ # Write something to the device for post-READY mirroring. Write it in
117
+ # blocks matching the cluster size, each spaced one block apart, so
118
+ # that the mirror job will have to spawn one request per cluster.
119
+ # Because the number of concurrent requests is limited (to 16), this
120
+ # limits the number of bytes concurrently in flight, which speeds up
121
+ # cancelling the job (in-flight requests still are waited for).
122
+ # To limit the number of bytes in flight, we could alternatively pass
123
+ # something for blockdev-mirror's @buf-size parameter, but
124
+ # block-commit does not have such a parameter, so we need to figure
125
+ # something out that works for both.
126
+
127
+ cluster_size=65536
128
+ step=$((cluster_size * 2))
129
+
130
+ echo '--- Writing data to the virtio-blk device ---'
131
+
132
+ for ofs in $(seq 0 $step $((size - step))); do
133
+ qemu_io_cmd="qemu-io -d vblk/virtio-backend "
134
+ qemu_io_cmd+="\\\"aio_write $ofs $cluster_size\\\""
135
+
136
+ # Do not include these requests in the reference output
137
+ # (it's just too much)
138
+ silent=yes _send_qemu_cmd $h \
139
+ "{\"execute\": \"human-monitor-command\",
140
+ \"arguments\": {
141
+ \"command-line\": \"$qemu_io_cmd\"
142
+ }}" \
143
+ 'return'
144
+ done
145
+
146
+ # Wait until the job's length is updated to reflect the write requests
147
+
148
+ # We have written to half of the device, so this is the expected job length
149
+ final_len=$((size / 2))
150
+ timeout=100 # unit: 0.1 seconds
151
+ while true; do
152
+ len=$(
153
+ _send_qemu_cmd $h \
154
+ '{"execute": "query-block-jobs"}' \
155
+ 'return.*"len": [0-9]\+' \
156
+ | grep 'return.*"len": [0-9]\+' \
157
+ | sed -e 's/.*"len": \([0-9]\+\).*/\1/'
158
+ )
159
+ if [ "$len" -eq "$final_len" ]; then
160
+ break
161
+ fi
162
+ timeout=$((timeout - 1))
163
+ if [ "$timeout" -eq 0 ]; then
164
+ echo "ERROR: Timeout waiting for job to reach len=$final_len"
165
+ break
166
+ fi
167
+ sleep 0.1
168
+ done
169
+
170
+ sleep 1
171
+
172
+ _send_qemu_cmd $h \
173
+ '{"execute": "quit"}' \
174
+ 'return'
175
+
176
+ # List of expected events
177
+ capture_events='BLOCK_JOB_CANCELLED JOB_STATUS_CHANGE SHUTDOWN'
178
+ _wait_event $h 'SHUTDOWN'
179
+ QEMU_EVENTS= # Ignore all JOB_STATUS_CHANGE events that came before SHUTDOWN
180
+ _wait_event $h 'JOB_STATUS_CHANGE' # standby
181
+ _wait_event $h 'JOB_STATUS_CHANGE' # ready
182
+ _wait_event $h 'JOB_STATUS_CHANGE' # aborting
183
+ # Filter the offset (depends on when exactly `quit` was issued)
184
+ _wait_event $h 'BLOCK_JOB_CANCELLED' \
185
+ | sed -e 's/"offset": [0-9]\+/"offset": (filtered)/'
186
+ _wait_event $h 'JOB_STATUS_CHANGE' # concluded
187
+ _wait_event $h 'JOB_STATUS_CHANGE' # null
188
+
189
+ wait=yes _cleanup_qemu
190
+
191
+ kill -SIGTERM "$(cat "$TEST_DIR/qsd.pid")"
192
+}
193
+
194
+wait_for_job_and_quit $h $size
195
+
196
+echo
197
+echo === Start active commit to throttled QSD and exit qemu ===
198
+echo
199
+
200
+# Same as the above, but instead of mirroring, do an active commit
201
+
202
+_make_test_img $size
203
+
204
+set_up_throttled_qsd
205
+
206
+_launch_qemu \
207
+ --blockdev "{\"driver\": \"nbd\",
208
+ \"node-name\": \"target\",
209
+ \"server\": {
210
+ \"type\": \"unix\",
211
+ \"path\": \"$SOCK_DIR/qsd.sock\"
212
+ },
213
+ \"export\": \"target\"}" \
214
+ --blockdev file,node-name=source-proto,filename="$TEST_IMG" \
215
+ --blockdev qcow2,node-name=source-fmt,file=source-proto,backing=target \
216
+ --device virtio-blk,id=vblk,drive=source-fmt
217
+
218
+h=$QEMU_HANDLE
219
+_send_qemu_cmd $h '{"execute": "qmp_capabilities"}' 'return'
220
+
221
+_send_qemu_cmd $h \
222
+ '{"execute": "block-commit",
223
+ "arguments": {
224
+ "job-id": "commit",
225
+ "device": "source-fmt"
226
+ }}' \
227
+ 'return' \
228
+ | grep -v JOB_STATUS_CHANGE # Ignore these events during creation
229
+
230
+wait_for_job_and_quit $h $size
231
+
232
# success, all done
233
echo "*** done"
234
rm -f $seq.full
235
diff --git a/tests/qemu-iotests/185.out b/tests/qemu-iotests/185.out
236
index XXXXXXX..XXXXXXX 100644
237
--- a/tests/qemu-iotests/185.out
238
+++ b/tests/qemu-iotests/185.out
239
@@ -XXX,XX +XXX,XX @@ Formatting 'TEST_DIR/t.qcow2.copy', fmt=qcow2 cluster_size=65536 extended_l2=off
240
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
241
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "disk", "len": 67108864, "offset": 524288, "speed": 65536, "type": "stream"}}
242
No errors were found on the image.
243
+
244
+=== Start mirror to throttled QSD and exit qemu ===
245
+
246
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
247
+{"execute": "qmp_capabilities"}
248
+{"return": {}}
249
+{"execute": "blockdev-mirror",
250
+ "arguments": {
251
+ "job-id": "mirror",
252
+ "device": "source-fmt",
253
+ "target": "target",
254
+ "sync": "top"
255
+ }}
256
+{"return": {}}
257
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "mirror", "len": 0, "offset": 0, "speed": 0, "type": "mirror"}}
258
+--- Writing data to the virtio-blk device ---
259
+{"execute": "quit"}
260
+{"return": {}}
261
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
262
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "standby", "id": "mirror"}}
263
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "mirror"}}
264
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "aborting", "id": "mirror"}}
265
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "mirror", "len": 33554432, "offset": (filtered), "speed": 0, "type": "mirror"}}
266
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "mirror"}}
267
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "mirror"}}
268
+
269
+=== Start active commit to throttled QSD and exit qemu ===
270
+
271
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
272
+{"execute": "qmp_capabilities"}
273
+{"return": {}}
274
+{"execute": "block-commit",
275
+ "arguments": {
276
+ "job-id": "commit",
277
+ "device": "source-fmt"
278
+ }}
279
+{"return": {}}
280
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "commit", "len": 0, "offset": 0, "speed": 0, "type": "commit"}}
281
+--- Writing data to the virtio-blk device ---
282
+{"execute": "quit"}
283
+{"return": {}}
284
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false, "reason": "host-qmp-quit"}}
285
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "standby", "id": "commit"}}
286
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "commit"}}
287
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "aborting", "id": "commit"}}
288
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "commit", "len": 33554432, "offset": (filtered), "speed": 0, "type": "commit"}}
289
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "commit"}}
290
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "commit"}}
291
*** done
292
--
293
2.35.1
diff view generated by jsdifflib
New patch
1
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
1
2
3
When invoked from the main loop, this function is the same
4
as qemu_mutex_iothread_locked, and returns true if the BQL is held.
5
When invoked from iothreads or tests, it returns true only
6
if the current AioContext is the Main Loop.
7
8
This essentially just extends qemu_mutex_iothread_locked to work
9
also in unit tests or other users like storage-daemon, that run
10
in the Main Loop but end up using the implementation in
11
stubs/iothread-lock.c.
12
13
Using qemu_mutex_iothread_locked in unit tests defaults to false
14
because they use the implementation in stubs/iothread-lock,
15
making all assertions added in next patches fail despite the
16
AioContext is still the main loop.
17
18
See the comment in the function header for more information.
19
20
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
21
Message-Id: <20220303151616.325444-2-eesposit@redhat.com>
22
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
23
---
24
include/qemu/main-loop.h | 24 ++++++++++++++++++++++++
25
softmmu/cpus.c | 5 +++++
26
stubs/iothread-lock.c | 5 +++++
27
3 files changed, 34 insertions(+)
28
29
diff --git a/include/qemu/main-loop.h b/include/qemu/main-loop.h
30
index XXXXXXX..XXXXXXX 100644
31
--- a/include/qemu/main-loop.h
32
+++ b/include/qemu/main-loop.h
33
@@ -XXX,XX +XXX,XX @@ AioContext *iohandler_get_aio_context(void);
34
* must always be taken outside other locks. This function helps
35
* functions take different paths depending on whether the current
36
* thread is running within the main loop mutex.
37
+ *
38
+ * This function should never be used in the block layer, because
39
+ * unit tests, block layer tools and qemu-storage-daemon do not
40
+ * have a BQL.
41
+ * Please instead refer to qemu_in_main_thread().
42
*/
43
bool qemu_mutex_iothread_locked(void);
44
45
+/**
46
+ * qemu_in_main_thread: return whether it's possible to safely access
47
+ * the global state of the block layer.
48
+ *
49
+ * Global state of the block layer is not accessible from I/O threads
50
+ * or worker threads; only from threads that "own" the default
51
+ * AioContext that qemu_get_aio_context() returns. For tests, block
52
+ * layer tools and qemu-storage-daemon there is a designated thread that
53
+ * runs the event loop for qemu_get_aio_context(), and that is the
54
+ * main thread.
55
+ *
56
+ * For emulators, however, any thread that holds the BQL can act
57
+ * as the block layer main thread; this will be any of the actual
58
+ * main thread, the vCPU threads or the RCU thread.
59
+ *
60
+ * For clarity, do not use this function outside the block layer.
61
+ */
62
+bool qemu_in_main_thread(void);
63
+
64
/**
65
* qemu_mutex_lock_iothread: Lock the main loop mutex.
66
*
67
diff --git a/softmmu/cpus.c b/softmmu/cpus.c
68
index XXXXXXX..XXXXXXX 100644
69
--- a/softmmu/cpus.c
70
+++ b/softmmu/cpus.c
71
@@ -XXX,XX +XXX,XX @@ bool qemu_mutex_iothread_locked(void)
72
return get_iothread_locked();
73
}
74
75
+bool qemu_in_main_thread(void)
76
+{
77
+ return qemu_mutex_iothread_locked();
78
+}
79
+
80
/*
81
* The BQL is taken from so many places that it is worth profiling the
82
* callers directly, instead of funneling them all through a single function.
83
diff --git a/stubs/iothread-lock.c b/stubs/iothread-lock.c
84
index XXXXXXX..XXXXXXX 100644
85
--- a/stubs/iothread-lock.c
86
+++ b/stubs/iothread-lock.c
87
@@ -XXX,XX +XXX,XX @@ bool qemu_mutex_iothread_locked(void)
88
return false;
89
}
90
91
+bool qemu_in_main_thread(void)
92
+{
93
+ return qemu_get_current_aio_context() == qemu_get_aio_context();
94
+}
95
+
96
void qemu_mutex_lock_iothread_impl(const char *file, int line)
97
{
98
}
99
--
100
2.35.1
diff view generated by jsdifflib
New patch
1
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
1
2
3
Righ now, IO_CODE and IO_OR_GS_CODE are nop, as there isn't
4
really a way to check that a function is only called in I/O.
5
On the other side, we can use qemu_in_main_thread() to check if
6
we are in the main loop.
7
8
The usage of macros makes easy to extend them in the future without
9
making changes in all callers. They will also visually help understanding
10
in which category each function is, without looking at the header.
11
12
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
13
Message-Id: <20220303151616.325444-3-eesposit@redhat.com>
14
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
15
---
16
include/qemu/main-loop.h | 18 ++++++++++++++++++
17
1 file changed, 18 insertions(+)
18
19
diff --git a/include/qemu/main-loop.h b/include/qemu/main-loop.h
20
index XXXXXXX..XXXXXXX 100644
21
--- a/include/qemu/main-loop.h
22
+++ b/include/qemu/main-loop.h
23
@@ -XXX,XX +XXX,XX @@ bool qemu_mutex_iothread_locked(void);
24
*/
25
bool qemu_in_main_thread(void);
26
27
+/* Mark and check that the function is part of the global state API. */
28
+#define GLOBAL_STATE_CODE() \
29
+ do { \
30
+ assert(qemu_in_main_thread()); \
31
+ } while (0)
32
+
33
+/* Mark and check that the function is part of the I/O API. */
34
+#define IO_CODE() \
35
+ do { \
36
+ /* nop */ \
37
+ } while (0)
38
+
39
+/* Mark and check that the function is part of the "I/O OR GS" API. */
40
+#define IO_OR_GS_CODE() \
41
+ do { \
42
+ /* nop */ \
43
+ } while (0)
44
+
45
/**
46
* qemu_mutex_lock_iothread: Lock the main loop mutex.
47
*
48
--
49
2.35.1
diff view generated by jsdifflib
New patch
1
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
1
2
3
block.h currently contains a mix of functions:
4
some of them run under the BQL and modify the block layer graph,
5
others are instead thread-safe and perform I/O in iothreads.
6
Some others can only be called by either the main loop or the
7
iothread running the AioContext (and not other iothreads),
8
and using them in another thread would cause deadlocks, and therefore
9
it is not ideal to define them as I/O.
10
11
It is not easy to understand which function is part of which
12
group (I/O vs GS vs "I/O or GS"), and this patch aims to clarify it.
13
14
The "GS" functions need the BQL, and often use
15
aio_context_acquire/release and/or drain to be sure they
16
can modify the graph safely.
17
The I/O function are instead thread safe, and can run in
18
any AioContext.
19
"I/O or GS" functions run instead in the main loop or in
20
a single iothread, and use BDRV_POLL_WHILE().
21
22
By splitting the header in two files, block-io.h
23
and block-global-state.h we have a clearer view on what
24
needs what kind of protection. block-common.h
25
contains common structures shared by both headers.
26
27
block.h is left there for legacy and to avoid changing
28
all includes in all c files that use the block APIs.
29
30
Assertions are added in the next patch.
31
32
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
33
Message-Id: <20220303151616.325444-4-eesposit@redhat.com>
34
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
35
---
36
include/block/block-common.h | 418 ++++++++++++++
37
include/block/block-global-state.h | 253 +++++++++
38
include/block/block-io.h | 367 ++++++++++++
39
include/block/block.h | 879 +----------------------------
40
block.c | 3 +
41
block/meson.build | 7 +-
42
6 files changed, 1069 insertions(+), 858 deletions(-)
43
create mode 100644 include/block/block-common.h
44
create mode 100644 include/block/block-global-state.h
45
create mode 100644 include/block/block-io.h
46
47
diff --git a/include/block/block-common.h b/include/block/block-common.h
48
new file mode 100644
49
index XXXXXXX..XXXXXXX
50
--- /dev/null
51
+++ b/include/block/block-common.h
52
@@ -XXX,XX +XXX,XX @@
53
+/*
54
+ * QEMU System Emulator block driver
55
+ *
56
+ * Copyright (c) 2003 Fabrice Bellard
57
+ *
58
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
59
+ * of this software and associated documentation files (the "Software"), to deal
60
+ * in the Software without restriction, including without limitation the rights
61
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
62
+ * copies of the Software, and to permit persons to whom the Software is
63
+ * furnished to do so, subject to the following conditions:
64
+ *
65
+ * The above copyright notice and this permission notice shall be included in
66
+ * all copies or substantial portions of the Software.
67
+ *
68
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
69
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
70
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
71
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
72
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
73
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
74
+ * THE SOFTWARE.
75
+ */
76
+#ifndef BLOCK_COMMON_H
77
+#define BLOCK_COMMON_H
78
+
79
+#include "block/aio.h"
80
+#include "block/aio-wait.h"
81
+#include "qemu/iov.h"
82
+#include "qemu/coroutine.h"
83
+#include "block/accounting.h"
84
+#include "block/dirty-bitmap.h"
85
+#include "block/blockjob.h"
86
+#include "qemu/hbitmap.h"
87
+#include "qemu/transactions.h"
88
+
89
+/*
90
+ * generated_co_wrapper
91
+ *
92
+ * Function specifier, which does nothing but mark functions to be
93
+ * generated by scripts/block-coroutine-wrapper.py
94
+ *
95
+ * Read more in docs/devel/block-coroutine-wrapper.rst
96
+ */
97
+#define generated_co_wrapper
98
+
99
+/* block.c */
100
+typedef struct BlockDriver BlockDriver;
101
+typedef struct BdrvChild BdrvChild;
102
+typedef struct BdrvChildClass BdrvChildClass;
103
+
104
+typedef struct BlockDriverInfo {
105
+ /* in bytes, 0 if irrelevant */
106
+ int cluster_size;
107
+ /* offset at which the VM state can be saved (0 if not possible) */
108
+ int64_t vm_state_offset;
109
+ bool is_dirty;
110
+ /*
111
+ * True if this block driver only supports compressed writes
112
+ */
113
+ bool needs_compressed_writes;
114
+} BlockDriverInfo;
115
+
116
+typedef struct BlockFragInfo {
117
+ uint64_t allocated_clusters;
118
+ uint64_t total_clusters;
119
+ uint64_t fragmented_clusters;
120
+ uint64_t compressed_clusters;
121
+} BlockFragInfo;
122
+
123
+typedef enum {
124
+ BDRV_REQ_COPY_ON_READ = 0x1,
125
+ BDRV_REQ_ZERO_WRITE = 0x2,
126
+
127
+ /*
128
+ * The BDRV_REQ_MAY_UNMAP flag is used in write_zeroes requests to indicate
129
+ * that the block driver should unmap (discard) blocks if it is guaranteed
130
+ * that the result will read back as zeroes. The flag is only passed to the
131
+ * driver if the block device is opened with BDRV_O_UNMAP.
132
+ */
133
+ BDRV_REQ_MAY_UNMAP = 0x4,
134
+
135
+ BDRV_REQ_FUA = 0x10,
136
+ BDRV_REQ_WRITE_COMPRESSED = 0x20,
137
+
138
+ /*
139
+ * Signifies that this write request will not change the visible disk
140
+ * content.
141
+ */
142
+ BDRV_REQ_WRITE_UNCHANGED = 0x40,
143
+
144
+ /*
145
+ * Forces request serialisation. Use only with write requests.
146
+ */
147
+ BDRV_REQ_SERIALISING = 0x80,
148
+
149
+ /*
150
+ * Execute the request only if the operation can be offloaded or otherwise
151
+ * be executed efficiently, but return an error instead of using a slow
152
+ * fallback.
153
+ */
154
+ BDRV_REQ_NO_FALLBACK = 0x100,
155
+
156
+ /*
157
+ * BDRV_REQ_PREFETCH makes sense only in the context of copy-on-read
158
+ * (i.e., together with the BDRV_REQ_COPY_ON_READ flag or when a COR
159
+ * filter is involved), in which case it signals that the COR operation
160
+ * need not read the data into memory (qiov) but only ensure they are
161
+ * copied to the top layer (i.e., that COR operation is done).
162
+ */
163
+ BDRV_REQ_PREFETCH = 0x200,
164
+
165
+ /*
166
+ * If we need to wait for other requests, just fail immediately. Used
167
+ * only together with BDRV_REQ_SERIALISING.
168
+ */
169
+ BDRV_REQ_NO_WAIT = 0x400,
170
+
171
+ /* Mask of valid flags */
172
+ BDRV_REQ_MASK = 0x7ff,
173
+} BdrvRequestFlags;
174
+
175
+#define BDRV_O_NO_SHARE 0x0001 /* don't share permissions */
176
+#define BDRV_O_RDWR 0x0002
177
+#define BDRV_O_RESIZE 0x0004 /* request permission for resizing the node */
178
+#define BDRV_O_SNAPSHOT 0x0008 /* open the file read only and save
179
+ writes in a snapshot */
180
+#define BDRV_O_TEMPORARY 0x0010 /* delete the file after use */
181
+#define BDRV_O_NOCACHE 0x0020 /* do not use the host page cache */
182
+#define BDRV_O_NATIVE_AIO 0x0080 /* use native AIO instead of the
183
+ thread pool */
184
+#define BDRV_O_NO_BACKING 0x0100 /* don't open the backing file */
185
+#define BDRV_O_NO_FLUSH 0x0200 /* disable flushing on this disk */
186
+#define BDRV_O_COPY_ON_READ 0x0400 /* copy read backing sectors into image */
187
+#define BDRV_O_INACTIVE 0x0800 /* consistency hint for migration handoff */
188
+#define BDRV_O_CHECK 0x1000 /* open solely for consistency check */
189
+#define BDRV_O_ALLOW_RDWR 0x2000 /* allow reopen to change from r/o to r/w */
190
+#define BDRV_O_UNMAP 0x4000 /* execute guest UNMAP/TRIM operations */
191
+#define BDRV_O_PROTOCOL 0x8000 /* if no block driver is explicitly given:
192
+ select an appropriate protocol driver,
193
+ ignoring the format layer */
194
+#define BDRV_O_NO_IO 0x10000 /* don't initialize for I/O */
195
+#define BDRV_O_AUTO_RDONLY 0x20000 /* degrade to read-only if opening
196
+ read-write fails */
197
+#define BDRV_O_IO_URING 0x40000 /* use io_uring instead of the thread pool */
198
+
199
+#define BDRV_O_CACHE_MASK (BDRV_O_NOCACHE | BDRV_O_NO_FLUSH)
200
+
201
+
202
+/* Option names of options parsed by the block layer */
203
+
204
+#define BDRV_OPT_CACHE_WB "cache.writeback"
205
+#define BDRV_OPT_CACHE_DIRECT "cache.direct"
206
+#define BDRV_OPT_CACHE_NO_FLUSH "cache.no-flush"
207
+#define BDRV_OPT_READ_ONLY "read-only"
208
+#define BDRV_OPT_AUTO_READ_ONLY "auto-read-only"
209
+#define BDRV_OPT_DISCARD "discard"
210
+#define BDRV_OPT_FORCE_SHARE "force-share"
211
+
212
+
213
+#define BDRV_SECTOR_BITS 9
214
+#define BDRV_SECTOR_SIZE (1ULL << BDRV_SECTOR_BITS)
215
+
216
+#define BDRV_REQUEST_MAX_SECTORS MIN_CONST(SIZE_MAX >> BDRV_SECTOR_BITS, \
217
+ INT_MAX >> BDRV_SECTOR_BITS)
218
+#define BDRV_REQUEST_MAX_BYTES (BDRV_REQUEST_MAX_SECTORS << BDRV_SECTOR_BITS)
219
+
220
+/*
221
+ * We want allow aligning requests and disk length up to any 32bit alignment
222
+ * and don't afraid of overflow.
223
+ * To achieve it, and in the same time use some pretty number as maximum disk
224
+ * size, let's define maximum "length" (a limit for any offset/bytes request and
225
+ * for disk size) to be the greatest power of 2 less than INT64_MAX.
226
+ */
227
+#define BDRV_MAX_ALIGNMENT (1L << 30)
228
+#define BDRV_MAX_LENGTH (QEMU_ALIGN_DOWN(INT64_MAX, BDRV_MAX_ALIGNMENT))
229
+
230
+/*
231
+ * Allocation status flags for bdrv_block_status() and friends.
232
+ *
233
+ * Public flags:
234
+ * BDRV_BLOCK_DATA: allocation for data at offset is tied to this layer
235
+ * BDRV_BLOCK_ZERO: offset reads as zero
236
+ * BDRV_BLOCK_OFFSET_VALID: an associated offset exists for accessing raw data
237
+ * BDRV_BLOCK_ALLOCATED: the content of the block is determined by this
238
+ * layer rather than any backing, set by block layer
239
+ * BDRV_BLOCK_EOF: the returned pnum covers through end of file for this
240
+ * layer, set by block layer
241
+ *
242
+ * Internal flags:
243
+ * BDRV_BLOCK_RAW: for use by passthrough drivers, such as raw, to request
244
+ * that the block layer recompute the answer from the returned
245
+ * BDS; must be accompanied by just BDRV_BLOCK_OFFSET_VALID.
246
+ * BDRV_BLOCK_RECURSE: request that the block layer will recursively search for
247
+ * zeroes in file child of current block node inside
248
+ * returned region. Only valid together with both
249
+ * BDRV_BLOCK_DATA and BDRV_BLOCK_OFFSET_VALID. Should not
250
+ * appear with BDRV_BLOCK_ZERO.
251
+ *
252
+ * If BDRV_BLOCK_OFFSET_VALID is set, the map parameter represents the
253
+ * host offset within the returned BDS that is allocated for the
254
+ * corresponding raw guest data. However, whether that offset
255
+ * actually contains data also depends on BDRV_BLOCK_DATA, as follows:
256
+ *
257
+ * DATA ZERO OFFSET_VALID
258
+ * t t t sectors read as zero, returned file is zero at offset
259
+ * t f t sectors read as valid from file at offset
260
+ * f t t sectors preallocated, read as zero, returned file not
261
+ * necessarily zero at offset
262
+ * f f t sectors preallocated but read from backing_hd,
263
+ * returned file contains garbage at offset
264
+ * t t f sectors preallocated, read as zero, unknown offset
265
+ * t f f sectors read from unknown file or offset
266
+ * f t f not allocated or unknown offset, read as zero
267
+ * f f f not allocated or unknown offset, read from backing_hd
268
+ */
269
+#define BDRV_BLOCK_DATA 0x01
270
+#define BDRV_BLOCK_ZERO 0x02
271
+#define BDRV_BLOCK_OFFSET_VALID 0x04
272
+#define BDRV_BLOCK_RAW 0x08
273
+#define BDRV_BLOCK_ALLOCATED 0x10
274
+#define BDRV_BLOCK_EOF 0x20
275
+#define BDRV_BLOCK_RECURSE 0x40
276
+
277
+typedef QTAILQ_HEAD(BlockReopenQueue, BlockReopenQueueEntry) BlockReopenQueue;
278
+
279
+typedef struct BDRVReopenState {
280
+ BlockDriverState *bs;
281
+ int flags;
282
+ BlockdevDetectZeroesOptions detect_zeroes;
283
+ bool backing_missing;
284
+ BlockDriverState *old_backing_bs; /* keep pointer for permissions update */
285
+ BlockDriverState *old_file_bs; /* keep pointer for permissions update */
286
+ QDict *options;
287
+ QDict *explicit_options;
288
+ void *opaque;
289
+} BDRVReopenState;
290
+
291
+/*
292
+ * Block operation types
293
+ */
294
+typedef enum BlockOpType {
295
+ BLOCK_OP_TYPE_BACKUP_SOURCE,
296
+ BLOCK_OP_TYPE_BACKUP_TARGET,
297
+ BLOCK_OP_TYPE_CHANGE,
298
+ BLOCK_OP_TYPE_COMMIT_SOURCE,
299
+ BLOCK_OP_TYPE_COMMIT_TARGET,
300
+ BLOCK_OP_TYPE_DATAPLANE,
301
+ BLOCK_OP_TYPE_DRIVE_DEL,
302
+ BLOCK_OP_TYPE_EJECT,
303
+ BLOCK_OP_TYPE_EXTERNAL_SNAPSHOT,
304
+ BLOCK_OP_TYPE_INTERNAL_SNAPSHOT,
305
+ BLOCK_OP_TYPE_INTERNAL_SNAPSHOT_DELETE,
306
+ BLOCK_OP_TYPE_MIRROR_SOURCE,
307
+ BLOCK_OP_TYPE_MIRROR_TARGET,
308
+ BLOCK_OP_TYPE_RESIZE,
309
+ BLOCK_OP_TYPE_STREAM,
310
+ BLOCK_OP_TYPE_REPLACE,
311
+ BLOCK_OP_TYPE_MAX,
312
+} BlockOpType;
313
+
314
+/* Block node permission constants */
315
+enum {
316
+ /**
317
+ * A user that has the "permission" of consistent reads is guaranteed that
318
+ * their view of the contents of the block device is complete and
319
+ * self-consistent, representing the contents of a disk at a specific
320
+ * point.
321
+ *
322
+ * For most block devices (including their backing files) this is true, but
323
+ * the property cannot be maintained in a few situations like for
324
+ * intermediate nodes of a commit block job.
325
+ */
326
+ BLK_PERM_CONSISTENT_READ = 0x01,
327
+
328
+ /** This permission is required to change the visible disk contents. */
329
+ BLK_PERM_WRITE = 0x02,
330
+
331
+ /**
332
+ * This permission (which is weaker than BLK_PERM_WRITE) is both enough and
333
+ * required for writes to the block node when the caller promises that
334
+ * the visible disk content doesn't change.
335
+ *
336
+ * As the BLK_PERM_WRITE permission is strictly stronger, either is
337
+ * sufficient to perform an unchanging write.
338
+ */
339
+ BLK_PERM_WRITE_UNCHANGED = 0x04,
340
+
341
+ /** This permission is required to change the size of a block node. */
342
+ BLK_PERM_RESIZE = 0x08,
343
+
344
+ /**
345
+ * There was a now-removed bit BLK_PERM_GRAPH_MOD, with value of 0x10. QEMU
346
+ * 6.1 and earlier may still lock the corresponding byte in block/file-posix
347
+ * locking. So, implementing some new permission should be very careful to
348
+ * not interfere with this old unused thing.
349
+ */
350
+
351
+ BLK_PERM_ALL = 0x0f,
352
+
353
+ DEFAULT_PERM_PASSTHROUGH = BLK_PERM_CONSISTENT_READ
354
+ | BLK_PERM_WRITE
355
+ | BLK_PERM_WRITE_UNCHANGED
356
+ | BLK_PERM_RESIZE,
357
+
358
+ DEFAULT_PERM_UNCHANGED = BLK_PERM_ALL & ~DEFAULT_PERM_PASSTHROUGH,
359
+};
360
+
361
+/*
362
+ * Flags that parent nodes assign to child nodes to specify what kind of
363
+ * role(s) they take.
364
+ *
365
+ * At least one of DATA, METADATA, FILTERED, or COW must be set for
366
+ * every child.
367
+ */
368
+enum BdrvChildRoleBits {
369
+ /*
370
+ * This child stores data.
371
+ * Any node may have an arbitrary number of such children.
372
+ */
373
+ BDRV_CHILD_DATA = (1 << 0),
374
+
375
+ /*
376
+ * This child stores metadata.
377
+ * Any node may have an arbitrary number of metadata-storing
378
+ * children.
379
+ */
380
+ BDRV_CHILD_METADATA = (1 << 1),
381
+
382
+ /*
383
+ * A child that always presents exactly the same visible data as
384
+ * the parent, e.g. by virtue of the parent forwarding all reads
385
+ * and writes.
386
+ * This flag is mutually exclusive with DATA, METADATA, and COW.
387
+ * Any node may have at most one filtered child at a time.
388
+ */
389
+ BDRV_CHILD_FILTERED = (1 << 2),
390
+
391
+ /*
392
+ * Child from which to read all data that isn't allocated in the
393
+ * parent (i.e., the backing child); such data is copied to the
394
+ * parent through COW (and optionally COR).
395
+ * This field is mutually exclusive with DATA, METADATA, and
396
+ * FILTERED.
397
+ * Any node may have at most one such backing child at a time.
398
+ */
399
+ BDRV_CHILD_COW = (1 << 3),
400
+
401
+ /*
402
+ * The primary child. For most drivers, this is the child whose
403
+ * filename applies best to the parent node.
404
+ * Any node may have at most one primary child at a time.
405
+ */
406
+ BDRV_CHILD_PRIMARY = (1 << 4),
407
+
408
+ /* Useful combination of flags */
409
+ BDRV_CHILD_IMAGE = BDRV_CHILD_DATA
410
+ | BDRV_CHILD_METADATA
411
+ | BDRV_CHILD_PRIMARY,
412
+};
413
+
414
+/* Mask of BdrvChildRoleBits values */
415
+typedef unsigned int BdrvChildRole;
416
+
417
+typedef struct BdrvCheckResult {
418
+ int corruptions;
419
+ int leaks;
420
+ int check_errors;
421
+ int corruptions_fixed;
422
+ int leaks_fixed;
423
+ int64_t image_end_offset;
424
+ BlockFragInfo bfi;
425
+} BdrvCheckResult;
426
+
427
+typedef enum {
428
+ BDRV_FIX_LEAKS = 1,
429
+ BDRV_FIX_ERRORS = 2,
430
+} BdrvCheckMode;
431
+
432
+typedef struct BlockSizes {
433
+ uint32_t phys;
434
+ uint32_t log;
435
+} BlockSizes;
436
+
437
+typedef struct HDGeometry {
438
+ uint32_t heads;
439
+ uint32_t sectors;
440
+ uint32_t cylinders;
441
+} HDGeometry;
442
+
443
+/*
444
+ * Common functions that are neither I/O nor Global State.
445
+ *
446
+ * These functions must never call any function from other categories
447
+ * (I/O, "I/O or GS", Global State) except this one, but can be invoked by
448
+ * all of them.
449
+ */
450
+
451
+char *bdrv_perm_names(uint64_t perm);
452
+uint64_t bdrv_qapi_perm_to_blk_perm(BlockPermission qapi_perm);
453
+
454
+void bdrv_init_with_whitelist(void);
455
+bool bdrv_uses_whitelist(void);
456
+int bdrv_is_whitelisted(BlockDriver *drv, bool read_only);
457
+
458
+int bdrv_parse_aio(const char *mode, int *flags);
459
+int bdrv_parse_cache_mode(const char *mode, int *flags, bool *writethrough);
460
+int bdrv_parse_discard_flags(const char *mode, int *flags);
461
+
462
+int path_has_protocol(const char *path);
463
+int path_is_absolute(const char *path);
464
+char *path_combine(const char *base_path, const char *filename);
465
+
466
+char *bdrv_get_full_backing_filename_from_filename(const char *backed,
467
+ const char *backing,
468
+ Error **errp);
469
+
470
+#endif /* BLOCK_COMMON_H */
471
diff --git a/include/block/block-global-state.h b/include/block/block-global-state.h
472
new file mode 100644
473
index XXXXXXX..XXXXXXX
474
--- /dev/null
475
+++ b/include/block/block-global-state.h
476
@@ -XXX,XX +XXX,XX @@
477
+/*
478
+ * QEMU System Emulator block driver
479
+ *
480
+ * Copyright (c) 2003 Fabrice Bellard
481
+ *
482
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
483
+ * of this software and associated documentation files (the "Software"), to deal
484
+ * in the Software without restriction, including without limitation the rights
485
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
486
+ * copies of the Software, and to permit persons to whom the Software is
487
+ * furnished to do so, subject to the following conditions:
488
+ *
489
+ * The above copyright notice and this permission notice shall be included in
490
+ * all copies or substantial portions of the Software.
491
+ *
492
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
493
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
494
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
495
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
496
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
497
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
498
+ * THE SOFTWARE.
499
+ */
500
+#ifndef BLOCK_GLOBAL_STATE_H
501
+#define BLOCK_GLOBAL_STATE_H
502
+
503
+#include "block-common.h"
504
+
505
+/*
506
+ * Global state (GS) API. These functions run under the BQL.
507
+ *
508
+ * If a function modifies the graph, it also uses drain and/or
509
+ * aio_context_acquire/release to be sure it has unique access.
510
+ * aio_context locking is needed together with BQL because of
511
+ * the thread-safe I/O API that concurrently runs and accesses
512
+ * the graph without the BQL.
513
+ *
514
+ * It is important to note that not all of these functions are
515
+ * necessarily limited to running under the BQL, but they would
516
+ * require additional auditing and many small thread-safety changes
517
+ * to move them into the I/O API. Often it's not worth doing that
518
+ * work since the APIs are only used with the BQL held at the
519
+ * moment, so they have been placed in the GS API (for now).
520
+ *
521
+ * These functions can call any function from this and other categories
522
+ * (I/O, "I/O or GS", Common), but must be invoked only by other GS APIs.
523
+ *
524
+ * All functions in this header must use the macro
525
+ * GLOBAL_STATE_CODE();
526
+ * to catch when they are accidentally called without the BQL.
527
+ */
528
+
529
+void bdrv_init(void);
530
+BlockDriver *bdrv_find_protocol(const char *filename,
531
+ bool allow_protocol_prefix,
532
+ Error **errp);
533
+BlockDriver *bdrv_find_format(const char *format_name);
534
+int bdrv_create(BlockDriver *drv, const char* filename,
535
+ QemuOpts *opts, Error **errp);
536
+int bdrv_create_file(const char *filename, QemuOpts *opts, Error **errp);
537
+
538
+BlockDriverState *bdrv_new(void);
539
+int bdrv_append(BlockDriverState *bs_new, BlockDriverState *bs_top,
540
+ Error **errp);
541
+int bdrv_replace_node(BlockDriverState *from, BlockDriverState *to,
542
+ Error **errp);
543
+int bdrv_replace_child_bs(BdrvChild *child, BlockDriverState *new_bs,
544
+ Error **errp);
545
+BlockDriverState *bdrv_insert_node(BlockDriverState *bs, QDict *node_options,
546
+ int flags, Error **errp);
547
+int bdrv_drop_filter(BlockDriverState *bs, Error **errp);
548
+
549
+BdrvChild *bdrv_open_child(const char *filename,
550
+ QDict *options, const char *bdref_key,
551
+ BlockDriverState *parent,
552
+ const BdrvChildClass *child_class,
553
+ BdrvChildRole child_role,
554
+ bool allow_none, Error **errp);
555
+BlockDriverState *bdrv_open_blockdev_ref(BlockdevRef *ref, Error **errp);
556
+int bdrv_set_backing_hd(BlockDriverState *bs, BlockDriverState *backing_hd,
557
+ Error **errp);
558
+int bdrv_open_backing_file(BlockDriverState *bs, QDict *parent_options,
559
+ const char *bdref_key, Error **errp);
560
+BlockDriverState *bdrv_open(const char *filename, const char *reference,
561
+ QDict *options, int flags, Error **errp);
562
+BlockDriverState *bdrv_new_open_driver_opts(BlockDriver *drv,
563
+ const char *node_name,
564
+ QDict *options, int flags,
565
+ Error **errp);
566
+BlockDriverState *bdrv_new_open_driver(BlockDriver *drv, const char *node_name,
567
+ int flags, Error **errp);
568
+BlockReopenQueue *bdrv_reopen_queue(BlockReopenQueue *bs_queue,
569
+ BlockDriverState *bs, QDict *options,
570
+ bool keep_old_opts);
571
+void bdrv_reopen_queue_free(BlockReopenQueue *bs_queue);
572
+int bdrv_reopen_multiple(BlockReopenQueue *bs_queue, Error **errp);
573
+int bdrv_reopen(BlockDriverState *bs, QDict *opts, bool keep_old_opts,
574
+ Error **errp);
575
+int bdrv_reopen_set_read_only(BlockDriverState *bs, bool read_only,
576
+ Error **errp);
577
+BlockDriverState *bdrv_find_backing_image(BlockDriverState *bs,
578
+ const char *backing_file);
579
+void bdrv_refresh_filename(BlockDriverState *bs);
580
+void bdrv_refresh_limits(BlockDriverState *bs, Transaction *tran, Error **errp);
581
+int bdrv_commit(BlockDriverState *bs);
582
+int bdrv_make_empty(BdrvChild *c, Error **errp);
583
+int bdrv_change_backing_file(BlockDriverState *bs, const char *backing_file,
584
+ const char *backing_fmt, bool warn);
585
+void bdrv_register(BlockDriver *bdrv);
586
+int bdrv_drop_intermediate(BlockDriverState *top, BlockDriverState *base,
587
+ const char *backing_file_str);
588
+BlockDriverState *bdrv_find_overlay(BlockDriverState *active,
589
+ BlockDriverState *bs);
590
+BlockDriverState *bdrv_find_base(BlockDriverState *bs);
591
+bool bdrv_is_backing_chain_frozen(BlockDriverState *bs, BlockDriverState *base,
592
+ Error **errp);
593
+int bdrv_freeze_backing_chain(BlockDriverState *bs, BlockDriverState *base,
594
+ Error **errp);
595
+void bdrv_unfreeze_backing_chain(BlockDriverState *bs, BlockDriverState *base);
596
+
597
+/*
598
+ * The units of offset and total_work_size may be chosen arbitrarily by the
599
+ * block driver; total_work_size may change during the course of the amendment
600
+ * operation
601
+ */
602
+typedef void BlockDriverAmendStatusCB(BlockDriverState *bs, int64_t offset,
603
+ int64_t total_work_size, void *opaque);
604
+int bdrv_amend_options(BlockDriverState *bs_new, QemuOpts *opts,
605
+ BlockDriverAmendStatusCB *status_cb, void *cb_opaque,
606
+ bool force,
607
+ Error **errp);
608
+
609
+/* check if a named node can be replaced when doing drive-mirror */
610
+BlockDriverState *check_to_replace_node(BlockDriverState *parent_bs,
611
+ const char *node_name, Error **errp);
612
+
613
+int bdrv_activate(BlockDriverState *bs, Error **errp);
614
+void bdrv_activate_all(Error **errp);
615
+int bdrv_inactivate_all(void);
616
+
617
+int bdrv_flush_all(void);
618
+void bdrv_close_all(void);
619
+void bdrv_drain_all_begin(void);
620
+void bdrv_drain_all_end(void);
621
+void bdrv_drain_all(void);
622
+
623
+int bdrv_has_zero_init_1(BlockDriverState *bs);
624
+int bdrv_has_zero_init(BlockDriverState *bs);
625
+BlockDriverState *bdrv_find_node(const char *node_name);
626
+BlockDeviceInfoList *bdrv_named_nodes_list(bool flat, Error **errp);
627
+XDbgBlockGraph *bdrv_get_xdbg_block_graph(Error **errp);
628
+BlockDriverState *bdrv_lookup_bs(const char *device,
629
+ const char *node_name,
630
+ Error **errp);
631
+bool bdrv_chain_contains(BlockDriverState *top, BlockDriverState *base);
632
+BlockDriverState *bdrv_next_node(BlockDriverState *bs);
633
+BlockDriverState *bdrv_next_all_states(BlockDriverState *bs);
634
+
635
+typedef struct BdrvNextIterator {
636
+ enum {
637
+ BDRV_NEXT_BACKEND_ROOTS,
638
+ BDRV_NEXT_MONITOR_OWNED,
639
+ } phase;
640
+ BlockBackend *blk;
641
+ BlockDriverState *bs;
642
+} BdrvNextIterator;
643
+
644
+BlockDriverState *bdrv_first(BdrvNextIterator *it);
645
+BlockDriverState *bdrv_next(BdrvNextIterator *it);
646
+void bdrv_next_cleanup(BdrvNextIterator *it);
647
+
648
+BlockDriverState *bdrv_next_monitor_owned(BlockDriverState *bs);
649
+void bdrv_iterate_format(void (*it)(void *opaque, const char *name),
650
+ void *opaque, bool read_only);
651
+int bdrv_get_flags(BlockDriverState *bs);
652
+char *bdrv_get_full_backing_filename(BlockDriverState *bs, Error **errp);
653
+char *bdrv_dirname(BlockDriverState *bs, Error **errp);
654
+
655
+void bdrv_img_create(const char *filename, const char *fmt,
656
+ const char *base_filename, const char *base_fmt,
657
+ char *options, uint64_t img_size, int flags,
658
+ bool quiet, Error **errp);
659
+
660
+void bdrv_ref(BlockDriverState *bs);
661
+void bdrv_unref(BlockDriverState *bs);
662
+void bdrv_unref_child(BlockDriverState *parent, BdrvChild *child);
663
+BdrvChild *bdrv_attach_child(BlockDriverState *parent_bs,
664
+ BlockDriverState *child_bs,
665
+ const char *child_name,
666
+ const BdrvChildClass *child_class,
667
+ BdrvChildRole child_role,
668
+ Error **errp);
669
+
670
+bool bdrv_op_is_blocked(BlockDriverState *bs, BlockOpType op, Error **errp);
671
+void bdrv_op_block(BlockDriverState *bs, BlockOpType op, Error *reason);
672
+void bdrv_op_unblock(BlockDriverState *bs, BlockOpType op, Error *reason);
673
+void bdrv_op_block_all(BlockDriverState *bs, Error *reason);
674
+void bdrv_op_unblock_all(BlockDriverState *bs, Error *reason);
675
+bool bdrv_op_blocker_is_empty(BlockDriverState *bs);
676
+
677
+int bdrv_debug_breakpoint(BlockDriverState *bs, const char *event,
678
+ const char *tag);
679
+int bdrv_debug_remove_breakpoint(BlockDriverState *bs, const char *tag);
680
+int bdrv_debug_resume(BlockDriverState *bs, const char *tag);
681
+bool bdrv_debug_is_suspended(BlockDriverState *bs, const char *tag);
682
+
683
+/**
684
+ * Locks the AioContext of @bs if it's not the current AioContext. This avoids
685
+ * double locking which could lead to deadlocks: This is a coroutine_fn, so we
686
+ * know we already own the lock of the current AioContext.
687
+ *
688
+ * May only be called in the main thread.
689
+ */
690
+void coroutine_fn bdrv_co_lock(BlockDriverState *bs);
691
+
692
+/**
693
+ * Unlocks the AioContext of @bs if it's not the current AioContext.
694
+ */
695
+void coroutine_fn bdrv_co_unlock(BlockDriverState *bs);
696
+
697
+void bdrv_set_aio_context_ignore(BlockDriverState *bs,
698
+ AioContext *new_context, GSList **ignore);
699
+int bdrv_try_set_aio_context(BlockDriverState *bs, AioContext *ctx,
700
+ Error **errp);
701
+int bdrv_child_try_set_aio_context(BlockDriverState *bs, AioContext *ctx,
702
+ BdrvChild *ignore_child, Error **errp);
703
+bool bdrv_child_can_set_aio_context(BdrvChild *c, AioContext *ctx,
704
+ GSList **ignore, Error **errp);
705
+bool bdrv_can_set_aio_context(BlockDriverState *bs, AioContext *ctx,
706
+ GSList **ignore, Error **errp);
707
+AioContext *bdrv_child_get_parent_aio_context(BdrvChild *c);
708
+
709
+int bdrv_probe_blocksizes(BlockDriverState *bs, BlockSizes *bsz);
710
+int bdrv_probe_geometry(BlockDriverState *bs, HDGeometry *geo);
711
+
712
+void bdrv_add_child(BlockDriverState *parent, BlockDriverState *child,
713
+ Error **errp);
714
+void bdrv_del_child(BlockDriverState *parent, BdrvChild *child, Error **errp);
715
+
716
+/**
717
+ *
718
+ * bdrv_register_buf/bdrv_unregister_buf:
719
+ *
720
+ * Register/unregister a buffer for I/O. For example, VFIO drivers are
721
+ * interested to know the memory areas that would later be used for I/O, so
722
+ * that they can prepare IOMMU mapping etc., to get better performance.
723
+ */
724
+void bdrv_register_buf(BlockDriverState *bs, void *host, size_t size);
725
+void bdrv_unregister_buf(BlockDriverState *bs, void *host);
726
+
727
+void bdrv_cancel_in_flight(BlockDriverState *bs);
728
+
729
+#endif /* BLOCK_GLOBAL_STATE_H */
730
diff --git a/include/block/block-io.h b/include/block/block-io.h
731
new file mode 100644
732
index XXXXXXX..XXXXXXX
733
--- /dev/null
734
+++ b/include/block/block-io.h
735
@@ -XXX,XX +XXX,XX @@
736
+/*
737
+ * QEMU System Emulator block driver
738
+ *
739
+ * Copyright (c) 2003 Fabrice Bellard
740
+ *
741
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
742
+ * of this software and associated documentation files (the "Software"), to deal
743
+ * in the Software without restriction, including without limitation the rights
744
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
745
+ * copies of the Software, and to permit persons to whom the Software is
746
+ * furnished to do so, subject to the following conditions:
747
+ *
748
+ * The above copyright notice and this permission notice shall be included in
749
+ * all copies or substantial portions of the Software.
750
+ *
751
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
752
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
753
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
754
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
755
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
756
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
757
+ * THE SOFTWARE.
758
+ */
759
+#ifndef BLOCK_IO_H
760
+#define BLOCK_IO_H
761
+
762
+#include "block-common.h"
763
+
764
+/*
765
+ * I/O API functions. These functions are thread-safe, and therefore
766
+ * can run in any thread as long as the thread has called
767
+ * aio_context_acquire/release().
768
+ *
769
+ * These functions can only call functions from I/O and Common categories,
770
+ * but can be invoked by GS, "I/O or GS" and I/O APIs.
771
+ *
772
+ * All functions in this category must use the macro
773
+ * IO_CODE();
774
+ * to catch when they are accidentally called by the wrong API.
775
+ */
776
+
777
+int bdrv_pwrite_zeroes(BdrvChild *child, int64_t offset,
778
+ int64_t bytes, BdrvRequestFlags flags);
779
+int bdrv_make_zero(BdrvChild *child, BdrvRequestFlags flags);
780
+int bdrv_pread(BdrvChild *child, int64_t offset, void *buf, int64_t bytes);
781
+int bdrv_pwrite(BdrvChild *child, int64_t offset, const void *buf,
782
+ int64_t bytes);
783
+int bdrv_pwrite_sync(BdrvChild *child, int64_t offset,
784
+ const void *buf, int64_t bytes);
785
+/*
786
+ * Efficiently zero a region of the disk image. Note that this is a regular
787
+ * I/O request like read or write and should have a reasonable size. This
788
+ * function is not suitable for zeroing the entire image in a single request
789
+ * because it may allocate memory for the entire region.
790
+ */
791
+int coroutine_fn bdrv_co_pwrite_zeroes(BdrvChild *child, int64_t offset,
792
+ int64_t bytes, BdrvRequestFlags flags);
793
+
794
+int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact,
795
+ PreallocMode prealloc, BdrvRequestFlags flags,
796
+ Error **errp);
797
+
798
+int64_t bdrv_nb_sectors(BlockDriverState *bs);
799
+int64_t bdrv_getlength(BlockDriverState *bs);
800
+int64_t bdrv_get_allocated_file_size(BlockDriverState *bs);
801
+BlockMeasureInfo *bdrv_measure(BlockDriver *drv, QemuOpts *opts,
802
+ BlockDriverState *in_bs, Error **errp);
803
+void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr);
804
+int coroutine_fn bdrv_co_delete_file(BlockDriverState *bs, Error **errp);
805
+void coroutine_fn bdrv_co_delete_file_noerr(BlockDriverState *bs);
806
+
807
+
808
+/* async block I/O */
809
+void bdrv_aio_cancel(BlockAIOCB *acb);
810
+void bdrv_aio_cancel_async(BlockAIOCB *acb);
811
+
812
+/* sg packet commands */
813
+int bdrv_co_ioctl(BlockDriverState *bs, int req, void *buf);
814
+
815
+/* Ensure contents are flushed to disk. */
816
+int coroutine_fn bdrv_co_flush(BlockDriverState *bs);
817
+
818
+int bdrv_co_pdiscard(BdrvChild *child, int64_t offset, int64_t bytes);
819
+bool bdrv_can_write_zeroes_with_unmap(BlockDriverState *bs);
820
+int bdrv_block_status(BlockDriverState *bs, int64_t offset,
821
+ int64_t bytes, int64_t *pnum, int64_t *map,
822
+ BlockDriverState **file);
823
+int bdrv_block_status_above(BlockDriverState *bs, BlockDriverState *base,
824
+ int64_t offset, int64_t bytes, int64_t *pnum,
825
+ int64_t *map, BlockDriverState **file);
826
+int bdrv_is_allocated(BlockDriverState *bs, int64_t offset, int64_t bytes,
827
+ int64_t *pnum);
828
+int bdrv_is_allocated_above(BlockDriverState *top, BlockDriverState *base,
829
+ bool include_base, int64_t offset, int64_t bytes,
830
+ int64_t *pnum);
831
+int coroutine_fn bdrv_co_is_zero_fast(BlockDriverState *bs, int64_t offset,
832
+ int64_t bytes);
833
+
834
+int bdrv_can_set_read_only(BlockDriverState *bs, bool read_only,
835
+ bool ignore_allow_rdw, Error **errp);
836
+int bdrv_apply_auto_read_only(BlockDriverState *bs, const char *errmsg,
837
+ Error **errp);
838
+bool bdrv_is_read_only(BlockDriverState *bs);
839
+bool bdrv_is_writable(BlockDriverState *bs);
840
+bool bdrv_is_sg(BlockDriverState *bs);
841
+bool bdrv_is_inserted(BlockDriverState *bs);
842
+void bdrv_lock_medium(BlockDriverState *bs, bool locked);
843
+void bdrv_eject(BlockDriverState *bs, bool eject_flag);
844
+const char *bdrv_get_format_name(BlockDriverState *bs);
845
+
846
+bool bdrv_supports_compressed_writes(BlockDriverState *bs);
847
+const char *bdrv_get_node_name(const BlockDriverState *bs);
848
+const char *bdrv_get_device_name(const BlockDriverState *bs);
849
+const char *bdrv_get_device_or_node_name(const BlockDriverState *bs);
850
+int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi);
851
+ImageInfoSpecific *bdrv_get_specific_info(BlockDriverState *bs,
852
+ Error **errp);
853
+BlockStatsSpecific *bdrv_get_specific_stats(BlockDriverState *bs);
854
+void bdrv_round_to_clusters(BlockDriverState *bs,
855
+ int64_t offset, int64_t bytes,
856
+ int64_t *cluster_offset,
857
+ int64_t *cluster_bytes);
858
+
859
+void bdrv_get_backing_filename(BlockDriverState *bs,
860
+ char *filename, int filename_size);
861
+
862
+int bdrv_save_vmstate(BlockDriverState *bs, const uint8_t *buf,
863
+ int64_t pos, int size);
864
+
865
+int bdrv_load_vmstate(BlockDriverState *bs, uint8_t *buf,
866
+ int64_t pos, int size);
867
+
868
+/*
869
+ * Returns the alignment in bytes that is required so that no bounce buffer
870
+ * is required throughout the stack
871
+ */
872
+size_t bdrv_min_mem_align(BlockDriverState *bs);
873
+/* Returns optimal alignment in bytes for bounce buffer */
874
+size_t bdrv_opt_mem_align(BlockDriverState *bs);
875
+void *qemu_blockalign(BlockDriverState *bs, size_t size);
876
+void *qemu_blockalign0(BlockDriverState *bs, size_t size);
877
+void *qemu_try_blockalign(BlockDriverState *bs, size_t size);
878
+void *qemu_try_blockalign0(BlockDriverState *bs, size_t size);
879
+bool bdrv_qiov_is_aligned(BlockDriverState *bs, QEMUIOVector *qiov);
880
+
881
+void bdrv_enable_copy_on_read(BlockDriverState *bs);
882
+void bdrv_disable_copy_on_read(BlockDriverState *bs);
883
+
884
+void bdrv_debug_event(BlockDriverState *bs, BlkdebugEvent event);
885
+
886
+#define BLKDBG_EVENT(child, evt) \
887
+ do { \
888
+ if (child) { \
889
+ bdrv_debug_event(child->bs, evt); \
890
+ } \
891
+ } while (0)
892
+
893
+/**
894
+ * bdrv_get_aio_context:
895
+ *
896
+ * Returns: the currently bound #AioContext
897
+ */
898
+AioContext *bdrv_get_aio_context(BlockDriverState *bs);
899
+
900
+/**
901
+ * Move the current coroutine to the AioContext of @bs and return the old
902
+ * AioContext of the coroutine. Increase bs->in_flight so that draining @bs
903
+ * will wait for the operation to proceed until the corresponding
904
+ * bdrv_co_leave().
905
+ *
906
+ * Consequently, you can't call drain inside a bdrv_co_enter/leave() section as
907
+ * this will deadlock.
908
+ */
909
+AioContext *coroutine_fn bdrv_co_enter(BlockDriverState *bs);
910
+
911
+/**
912
+ * Ends a section started by bdrv_co_enter(). Move the current coroutine back
913
+ * to old_ctx and decrease bs->in_flight again.
914
+ */
915
+void coroutine_fn bdrv_co_leave(BlockDriverState *bs, AioContext *old_ctx);
916
+
917
+/**
918
+ * Transfer control to @co in the aio context of @bs
919
+ */
920
+void bdrv_coroutine_enter(BlockDriverState *bs, Coroutine *co);
921
+
922
+AioContext *child_of_bds_get_parent_aio_context(BdrvChild *c);
923
+
924
+void bdrv_io_plug(BlockDriverState *bs);
925
+void bdrv_io_unplug(BlockDriverState *bs);
926
+
927
+bool bdrv_can_store_new_dirty_bitmap(BlockDriverState *bs, const char *name,
928
+ uint32_t granularity, Error **errp);
929
+
930
+/**
931
+ *
932
+ * bdrv_co_copy_range:
933
+ *
934
+ * Do offloaded copy between two children. If the operation is not implemented
935
+ * by the driver, or if the backend storage doesn't support it, a negative
936
+ * error code will be returned.
937
+ *
938
+ * Note: block layer doesn't emulate or fallback to a bounce buffer approach
939
+ * because usually the caller shouldn't attempt offloaded copy any more (e.g.
940
+ * calling copy_file_range(2)) after the first error, thus it should fall back
941
+ * to a read+write path in the caller level.
942
+ *
943
+ * @src: Source child to copy data from
944
+ * @src_offset: offset in @src image to read data
945
+ * @dst: Destination child to copy data to
946
+ * @dst_offset: offset in @dst image to write data
947
+ * @bytes: number of bytes to copy
948
+ * @flags: request flags. Supported flags:
949
+ * BDRV_REQ_ZERO_WRITE - treat the @src range as zero data and do zero
950
+ * write on @dst as if bdrv_co_pwrite_zeroes is
951
+ * called. Used to simplify caller code, or
952
+ * during BlockDriver.bdrv_co_copy_range_from()
953
+ * recursion.
954
+ * BDRV_REQ_NO_SERIALISING - do not serialize with other overlapping
955
+ * requests currently in flight.
956
+ *
957
+ * Returns: 0 if succeeded; negative error code if failed.
958
+ **/
959
+int coroutine_fn bdrv_co_copy_range(BdrvChild *src, int64_t src_offset,
960
+ BdrvChild *dst, int64_t dst_offset,
961
+ int64_t bytes, BdrvRequestFlags read_flags,
962
+ BdrvRequestFlags write_flags);
963
+
964
+/**
965
+ * bdrv_drained_end_no_poll:
966
+ *
967
+ * Same as bdrv_drained_end(), but do not poll for the subgraph to
968
+ * actually become unquiesced. Therefore, no graph changes will occur
969
+ * with this function.
970
+ *
971
+ * *drained_end_counter is incremented for every background operation
972
+ * that is scheduled, and will be decremented for every operation once
973
+ * it settles. The caller must poll until it reaches 0. The counter
974
+ * should be accessed using atomic operations only.
975
+ */
976
+void bdrv_drained_end_no_poll(BlockDriverState *bs, int *drained_end_counter);
977
+
978
+
979
+/*
980
+ * "I/O or GS" API functions. These functions can run without
981
+ * the BQL, but only in one specific iothread/main loop.
982
+ *
983
+ * More specifically, these functions use BDRV_POLL_WHILE(bs), which
984
+ * requires the caller to be either in the main thread and hold
985
+ * the BlockdriverState (bs) AioContext lock, or directly in the
986
+ * home thread that runs the bs AioContext. Calling them from
987
+ * another thread in another AioContext would cause deadlocks.
988
+ *
989
+ * Therefore, these functions are not proper I/O, because they
990
+ * can't run in *any* iothreads, but only in a specific one.
991
+ *
992
+ * These functions can call any function from I/O, Common and this
993
+ * categories, but must be invoked only by other "I/O or GS" and GS APIs.
994
+ *
995
+ * All functions in this category must use the macro
996
+ * IO_OR_GS_CODE();
997
+ * to catch when they are accidentally called by the wrong API.
998
+ */
999
+
1000
+#define BDRV_POLL_WHILE(bs, cond) ({ \
1001
+ BlockDriverState *bs_ = (bs); \
1002
+ AIO_WAIT_WHILE(bdrv_get_aio_context(bs_), \
1003
+ cond); })
1004
+
1005
+void bdrv_drain(BlockDriverState *bs);
1006
+void coroutine_fn bdrv_co_drain(BlockDriverState *bs);
1007
+
1008
+int generated_co_wrapper
1009
+bdrv_truncate(BdrvChild *child, int64_t offset, bool exact,
1010
+ PreallocMode prealloc, BdrvRequestFlags flags, Error **errp);
1011
+
1012
+int generated_co_wrapper bdrv_check(BlockDriverState *bs, BdrvCheckResult *res,
1013
+ BdrvCheckMode fix);
1014
+
1015
+/* Invalidate any cached metadata used by image formats */
1016
+int generated_co_wrapper bdrv_invalidate_cache(BlockDriverState *bs,
1017
+ Error **errp);
1018
+int generated_co_wrapper bdrv_flush(BlockDriverState *bs);
1019
+int generated_co_wrapper bdrv_pdiscard(BdrvChild *child, int64_t offset,
1020
+ int64_t bytes);
1021
+int generated_co_wrapper
1022
+bdrv_readv_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos);
1023
+int generated_co_wrapper
1024
+bdrv_writev_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos);
1025
+
1026
+/**
1027
+ * bdrv_parent_drained_begin_single:
1028
+ *
1029
+ * Begin a quiesced section for the parent of @c. If @poll is true, wait for
1030
+ * any pending activity to cease.
1031
+ */
1032
+void bdrv_parent_drained_begin_single(BdrvChild *c, bool poll);
1033
+
1034
+/**
1035
+ * bdrv_parent_drained_end_single:
1036
+ *
1037
+ * End a quiesced section for the parent of @c.
1038
+ *
1039
+ * This polls @bs's AioContext until all scheduled sub-drained_ends
1040
+ * have settled, which may result in graph changes.
1041
+ */
1042
+void bdrv_parent_drained_end_single(BdrvChild *c);
1043
+
1044
+/**
1045
+ * bdrv_drain_poll:
1046
+ *
1047
+ * Poll for pending requests in @bs, its parents (except for @ignore_parent),
1048
+ * and if @recursive is true its children as well (used for subtree drain).
1049
+ *
1050
+ * If @ignore_bds_parents is true, parents that are BlockDriverStates must
1051
+ * ignore the drain request because they will be drained separately (used for
1052
+ * drain_all).
1053
+ *
1054
+ * This is part of bdrv_drained_begin.
1055
+ */
1056
+bool bdrv_drain_poll(BlockDriverState *bs, bool recursive,
1057
+ BdrvChild *ignore_parent, bool ignore_bds_parents);
1058
+
1059
+/**
1060
+ * bdrv_drained_begin:
1061
+ *
1062
+ * Begin a quiesced section for exclusive access to the BDS, by disabling
1063
+ * external request sources including NBD server, block jobs, and device model.
1064
+ *
1065
+ * This function can be recursive.
1066
+ */
1067
+void bdrv_drained_begin(BlockDriverState *bs);
1068
+
1069
+/**
1070
+ * bdrv_do_drained_begin_quiesce:
1071
+ *
1072
+ * Quiesces a BDS like bdrv_drained_begin(), but does not wait for already
1073
+ * running requests to complete.
1074
+ */
1075
+void bdrv_do_drained_begin_quiesce(BlockDriverState *bs,
1076
+ BdrvChild *parent, bool ignore_bds_parents);
1077
+
1078
+/**
1079
+ * Like bdrv_drained_begin, but recursively begins a quiesced section for
1080
+ * exclusive access to all child nodes as well.
1081
+ */
1082
+void bdrv_subtree_drained_begin(BlockDriverState *bs);
1083
+
1084
+/**
1085
+ * bdrv_drained_end:
1086
+ *
1087
+ * End a quiescent section started by bdrv_drained_begin().
1088
+ *
1089
+ * This polls @bs's AioContext until all scheduled sub-drained_ends
1090
+ * have settled. On one hand, that may result in graph changes. On
1091
+ * the other, this requires that the caller either runs in the main
1092
+ * loop; or that all involved nodes (@bs and all of its parents) are
1093
+ * in the caller's AioContext.
1094
+ */
1095
+void bdrv_drained_end(BlockDriverState *bs);
1096
+
1097
+/**
1098
+ * End a quiescent section started by bdrv_subtree_drained_begin().
1099
+ */
1100
+void bdrv_subtree_drained_end(BlockDriverState *bs);
1101
+
1102
+#endif /* BLOCK_IO_H */
1103
diff --git a/include/block/block.h b/include/block/block.h
1104
index XXXXXXX..XXXXXXX 100644
1105
--- a/include/block/block.h
1106
+++ b/include/block/block.h
1107
@@ -XXX,XX +XXX,XX @@
1108
-#ifndef BLOCK_H
1109
-#define BLOCK_H
1110
-
1111
-#include "block/aio.h"
1112
-#include "block/aio-wait.h"
1113
-#include "qemu/iov.h"
1114
-#include "qemu/coroutine.h"
1115
-#include "block/accounting.h"
1116
-#include "block/dirty-bitmap.h"
1117
-#include "block/blockjob.h"
1118
-#include "qemu/hbitmap.h"
1119
-#include "qemu/transactions.h"
1120
-
1121
/*
1122
- * generated_co_wrapper
1123
- *
1124
- * Function specifier, which does nothing but mark functions to be
1125
- * generated by scripts/block-coroutine-wrapper.py
1126
- *
1127
- * Read more in docs/devel/block-coroutine-wrapper.rst
1128
- */
1129
-#define generated_co_wrapper
1130
-
1131
-/* block.c */
1132
-typedef struct BlockDriver BlockDriver;
1133
-typedef struct BdrvChild BdrvChild;
1134
-typedef struct BdrvChildClass BdrvChildClass;
1135
-
1136
-typedef struct BlockDriverInfo {
1137
- /* in bytes, 0 if irrelevant */
1138
- int cluster_size;
1139
- /* offset at which the VM state can be saved (0 if not possible) */
1140
- int64_t vm_state_offset;
1141
- bool is_dirty;
1142
- /*
1143
- * True if this block driver only supports compressed writes
1144
- */
1145
- bool needs_compressed_writes;
1146
-} BlockDriverInfo;
1147
-
1148
-typedef struct BlockFragInfo {
1149
- uint64_t allocated_clusters;
1150
- uint64_t total_clusters;
1151
- uint64_t fragmented_clusters;
1152
- uint64_t compressed_clusters;
1153
-} BlockFragInfo;
1154
-
1155
-typedef enum {
1156
- BDRV_REQ_COPY_ON_READ = 0x1,
1157
- BDRV_REQ_ZERO_WRITE = 0x2,
1158
-
1159
- /*
1160
- * The BDRV_REQ_MAY_UNMAP flag is used in write_zeroes requests to indicate
1161
- * that the block driver should unmap (discard) blocks if it is guaranteed
1162
- * that the result will read back as zeroes. The flag is only passed to the
1163
- * driver if the block device is opened with BDRV_O_UNMAP.
1164
- */
1165
- BDRV_REQ_MAY_UNMAP = 0x4,
1166
-
1167
- BDRV_REQ_FUA = 0x10,
1168
- BDRV_REQ_WRITE_COMPRESSED = 0x20,
1169
-
1170
- /* Signifies that this write request will not change the visible disk
1171
- * content. */
1172
- BDRV_REQ_WRITE_UNCHANGED = 0x40,
1173
-
1174
- /* Forces request serialisation. Use only with write requests. */
1175
- BDRV_REQ_SERIALISING = 0x80,
1176
-
1177
- /* Execute the request only if the operation can be offloaded or otherwise
1178
- * be executed efficiently, but return an error instead of using a slow
1179
- * fallback. */
1180
- BDRV_REQ_NO_FALLBACK = 0x100,
1181
-
1182
- /*
1183
- * BDRV_REQ_PREFETCH makes sense only in the context of copy-on-read
1184
- * (i.e., together with the BDRV_REQ_COPY_ON_READ flag or when a COR
1185
- * filter is involved), in which case it signals that the COR operation
1186
- * need not read the data into memory (qiov) but only ensure they are
1187
- * copied to the top layer (i.e., that COR operation is done).
1188
- */
1189
- BDRV_REQ_PREFETCH = 0x200,
1190
-
1191
- /*
1192
- * If we need to wait for other requests, just fail immediately. Used
1193
- * only together with BDRV_REQ_SERIALISING.
1194
- */
1195
- BDRV_REQ_NO_WAIT = 0x400,
1196
-
1197
- /* Mask of valid flags */
1198
- BDRV_REQ_MASK = 0x7ff,
1199
-} BdrvRequestFlags;
1200
-
1201
-typedef struct BlockSizes {
1202
- uint32_t phys;
1203
- uint32_t log;
1204
-} BlockSizes;
1205
-
1206
-typedef struct HDGeometry {
1207
- uint32_t heads;
1208
- uint32_t sectors;
1209
- uint32_t cylinders;
1210
-} HDGeometry;
1211
-
1212
-#define BDRV_O_NO_SHARE 0x0001 /* don't share permissions */
1213
-#define BDRV_O_RDWR 0x0002
1214
-#define BDRV_O_RESIZE 0x0004 /* request permission for resizing the node */
1215
-#define BDRV_O_SNAPSHOT 0x0008 /* open the file read only and save writes in a snapshot */
1216
-#define BDRV_O_TEMPORARY 0x0010 /* delete the file after use */
1217
-#define BDRV_O_NOCACHE 0x0020 /* do not use the host page cache */
1218
-#define BDRV_O_NATIVE_AIO 0x0080 /* use native AIO instead of the thread pool */
1219
-#define BDRV_O_NO_BACKING 0x0100 /* don't open the backing file */
1220
-#define BDRV_O_NO_FLUSH 0x0200 /* disable flushing on this disk */
1221
-#define BDRV_O_COPY_ON_READ 0x0400 /* copy read backing sectors into image */
1222
-#define BDRV_O_INACTIVE 0x0800 /* consistency hint for migration handoff */
1223
-#define BDRV_O_CHECK 0x1000 /* open solely for consistency check */
1224
-#define BDRV_O_ALLOW_RDWR 0x2000 /* allow reopen to change from r/o to r/w */
1225
-#define BDRV_O_UNMAP 0x4000 /* execute guest UNMAP/TRIM operations */
1226
-#define BDRV_O_PROTOCOL 0x8000 /* if no block driver is explicitly given:
1227
- select an appropriate protocol driver,
1228
- ignoring the format layer */
1229
-#define BDRV_O_NO_IO 0x10000 /* don't initialize for I/O */
1230
-#define BDRV_O_AUTO_RDONLY 0x20000 /* degrade to read-only if opening read-write fails */
1231
-#define BDRV_O_IO_URING 0x40000 /* use io_uring instead of the thread pool */
1232
-
1233
-#define BDRV_O_CACHE_MASK (BDRV_O_NOCACHE | BDRV_O_NO_FLUSH)
1234
-
1235
-
1236
-/* Option names of options parsed by the block layer */
1237
-
1238
-#define BDRV_OPT_CACHE_WB "cache.writeback"
1239
-#define BDRV_OPT_CACHE_DIRECT "cache.direct"
1240
-#define BDRV_OPT_CACHE_NO_FLUSH "cache.no-flush"
1241
-#define BDRV_OPT_READ_ONLY "read-only"
1242
-#define BDRV_OPT_AUTO_READ_ONLY "auto-read-only"
1243
-#define BDRV_OPT_DISCARD "discard"
1244
-#define BDRV_OPT_FORCE_SHARE "force-share"
1245
-
1246
-
1247
-#define BDRV_SECTOR_BITS 9
1248
-#define BDRV_SECTOR_SIZE (1ULL << BDRV_SECTOR_BITS)
1249
-
1250
-#define BDRV_REQUEST_MAX_SECTORS MIN_CONST(SIZE_MAX >> BDRV_SECTOR_BITS, \
1251
- INT_MAX >> BDRV_SECTOR_BITS)
1252
-#define BDRV_REQUEST_MAX_BYTES (BDRV_REQUEST_MAX_SECTORS << BDRV_SECTOR_BITS)
1253
-
1254
-/*
1255
- * We want allow aligning requests and disk length up to any 32bit alignment
1256
- * and don't afraid of overflow.
1257
- * To achieve it, and in the same time use some pretty number as maximum disk
1258
- * size, let's define maximum "length" (a limit for any offset/bytes request and
1259
- * for disk size) to be the greatest power of 2 less than INT64_MAX.
1260
- */
1261
-#define BDRV_MAX_ALIGNMENT (1L << 30)
1262
-#define BDRV_MAX_LENGTH (QEMU_ALIGN_DOWN(INT64_MAX, BDRV_MAX_ALIGNMENT))
1263
-
1264
-/*
1265
- * Allocation status flags for bdrv_block_status() and friends.
1266
- *
1267
- * Public flags:
1268
- * BDRV_BLOCK_DATA: allocation for data at offset is tied to this layer
1269
- * BDRV_BLOCK_ZERO: offset reads as zero
1270
- * BDRV_BLOCK_OFFSET_VALID: an associated offset exists for accessing raw data
1271
- * BDRV_BLOCK_ALLOCATED: the content of the block is determined by this
1272
- * layer rather than any backing, set by block layer
1273
- * BDRV_BLOCK_EOF: the returned pnum covers through end of file for this
1274
- * layer, set by block layer
1275
- *
1276
- * Internal flags:
1277
- * BDRV_BLOCK_RAW: for use by passthrough drivers, such as raw, to request
1278
- * that the block layer recompute the answer from the returned
1279
- * BDS; must be accompanied by just BDRV_BLOCK_OFFSET_VALID.
1280
- * BDRV_BLOCK_RECURSE: request that the block layer will recursively search for
1281
- * zeroes in file child of current block node inside
1282
- * returned region. Only valid together with both
1283
- * BDRV_BLOCK_DATA and BDRV_BLOCK_OFFSET_VALID. Should not
1284
- * appear with BDRV_BLOCK_ZERO.
1285
- *
1286
- * If BDRV_BLOCK_OFFSET_VALID is set, the map parameter represents the
1287
- * host offset within the returned BDS that is allocated for the
1288
- * corresponding raw guest data. However, whether that offset
1289
- * actually contains data also depends on BDRV_BLOCK_DATA, as follows:
1290
- *
1291
- * DATA ZERO OFFSET_VALID
1292
- * t t t sectors read as zero, returned file is zero at offset
1293
- * t f t sectors read as valid from file at offset
1294
- * f t t sectors preallocated, read as zero, returned file not
1295
- * necessarily zero at offset
1296
- * f f t sectors preallocated but read from backing_hd,
1297
- * returned file contains garbage at offset
1298
- * t t f sectors preallocated, read as zero, unknown offset
1299
- * t f f sectors read from unknown file or offset
1300
- * f t f not allocated or unknown offset, read as zero
1301
- * f f f not allocated or unknown offset, read from backing_hd
1302
- */
1303
-#define BDRV_BLOCK_DATA 0x01
1304
-#define BDRV_BLOCK_ZERO 0x02
1305
-#define BDRV_BLOCK_OFFSET_VALID 0x04
1306
-#define BDRV_BLOCK_RAW 0x08
1307
-#define BDRV_BLOCK_ALLOCATED 0x10
1308
-#define BDRV_BLOCK_EOF 0x20
1309
-#define BDRV_BLOCK_RECURSE 0x40
1310
-
1311
-typedef QTAILQ_HEAD(BlockReopenQueue, BlockReopenQueueEntry) BlockReopenQueue;
1312
-
1313
-typedef struct BDRVReopenState {
1314
- BlockDriverState *bs;
1315
- int flags;
1316
- BlockdevDetectZeroesOptions detect_zeroes;
1317
- bool backing_missing;
1318
- BlockDriverState *old_backing_bs; /* keep pointer for permissions update */
1319
- BlockDriverState *old_file_bs; /* keep pointer for permissions update */
1320
- QDict *options;
1321
- QDict *explicit_options;
1322
- void *opaque;
1323
-} BDRVReopenState;
1324
-
1325
-/*
1326
- * Block operation types
1327
- */
1328
-typedef enum BlockOpType {
1329
- BLOCK_OP_TYPE_BACKUP_SOURCE,
1330
- BLOCK_OP_TYPE_BACKUP_TARGET,
1331
- BLOCK_OP_TYPE_CHANGE,
1332
- BLOCK_OP_TYPE_COMMIT_SOURCE,
1333
- BLOCK_OP_TYPE_COMMIT_TARGET,
1334
- BLOCK_OP_TYPE_DATAPLANE,
1335
- BLOCK_OP_TYPE_DRIVE_DEL,
1336
- BLOCK_OP_TYPE_EJECT,
1337
- BLOCK_OP_TYPE_EXTERNAL_SNAPSHOT,
1338
- BLOCK_OP_TYPE_INTERNAL_SNAPSHOT,
1339
- BLOCK_OP_TYPE_INTERNAL_SNAPSHOT_DELETE,
1340
- BLOCK_OP_TYPE_MIRROR_SOURCE,
1341
- BLOCK_OP_TYPE_MIRROR_TARGET,
1342
- BLOCK_OP_TYPE_RESIZE,
1343
- BLOCK_OP_TYPE_STREAM,
1344
- BLOCK_OP_TYPE_REPLACE,
1345
- BLOCK_OP_TYPE_MAX,
1346
-} BlockOpType;
1347
-
1348
-/* Block node permission constants */
1349
-enum {
1350
- /**
1351
- * A user that has the "permission" of consistent reads is guaranteed that
1352
- * their view of the contents of the block device is complete and
1353
- * self-consistent, representing the contents of a disk at a specific
1354
- * point.
1355
- *
1356
- * For most block devices (including their backing files) this is true, but
1357
- * the property cannot be maintained in a few situations like for
1358
- * intermediate nodes of a commit block job.
1359
- */
1360
- BLK_PERM_CONSISTENT_READ = 0x01,
1361
-
1362
- /** This permission is required to change the visible disk contents. */
1363
- BLK_PERM_WRITE = 0x02,
1364
-
1365
- /**
1366
- * This permission (which is weaker than BLK_PERM_WRITE) is both enough and
1367
- * required for writes to the block node when the caller promises that
1368
- * the visible disk content doesn't change.
1369
- *
1370
- * As the BLK_PERM_WRITE permission is strictly stronger, either is
1371
- * sufficient to perform an unchanging write.
1372
- */
1373
- BLK_PERM_WRITE_UNCHANGED = 0x04,
1374
-
1375
- /** This permission is required to change the size of a block node. */
1376
- BLK_PERM_RESIZE = 0x08,
1377
-
1378
- /**
1379
- * There was a now-removed bit BLK_PERM_GRAPH_MOD, with value of 0x10. QEMU
1380
- * 6.1 and earlier may still lock the corresponding byte in block/file-posix
1381
- * locking. So, implementing some new permission should be very careful to
1382
- * not interfere with this old unused thing.
1383
- */
1384
-
1385
- BLK_PERM_ALL = 0x0f,
1386
-
1387
- DEFAULT_PERM_PASSTHROUGH = BLK_PERM_CONSISTENT_READ
1388
- | BLK_PERM_WRITE
1389
- | BLK_PERM_WRITE_UNCHANGED
1390
- | BLK_PERM_RESIZE,
1391
-
1392
- DEFAULT_PERM_UNCHANGED = BLK_PERM_ALL & ~DEFAULT_PERM_PASSTHROUGH,
1393
-};
1394
-
1395
-/*
1396
- * Flags that parent nodes assign to child nodes to specify what kind of
1397
- * role(s) they take.
1398
- *
1399
- * At least one of DATA, METADATA, FILTERED, or COW must be set for
1400
- * every child.
1401
- */
1402
-enum BdrvChildRoleBits {
1403
- /*
1404
- * This child stores data.
1405
- * Any node may have an arbitrary number of such children.
1406
- */
1407
- BDRV_CHILD_DATA = (1 << 0),
1408
-
1409
- /*
1410
- * This child stores metadata.
1411
- * Any node may have an arbitrary number of metadata-storing
1412
- * children.
1413
- */
1414
- BDRV_CHILD_METADATA = (1 << 1),
1415
-
1416
- /*
1417
- * A child that always presents exactly the same visible data as
1418
- * the parent, e.g. by virtue of the parent forwarding all reads
1419
- * and writes.
1420
- * This flag is mutually exclusive with DATA, METADATA, and COW.
1421
- * Any node may have at most one filtered child at a time.
1422
- */
1423
- BDRV_CHILD_FILTERED = (1 << 2),
1424
-
1425
- /*
1426
- * Child from which to read all data that isn't allocated in the
1427
- * parent (i.e., the backing child); such data is copied to the
1428
- * parent through COW (and optionally COR).
1429
- * This field is mutually exclusive with DATA, METADATA, and
1430
- * FILTERED.
1431
- * Any node may have at most one such backing child at a time.
1432
- */
1433
- BDRV_CHILD_COW = (1 << 3),
1434
-
1435
- /*
1436
- * The primary child. For most drivers, this is the child whose
1437
- * filename applies best to the parent node.
1438
- * Any node may have at most one primary child at a time.
1439
- */
1440
- BDRV_CHILD_PRIMARY = (1 << 4),
1441
-
1442
- /* Useful combination of flags */
1443
- BDRV_CHILD_IMAGE = BDRV_CHILD_DATA
1444
- | BDRV_CHILD_METADATA
1445
- | BDRV_CHILD_PRIMARY,
1446
-};
1447
-
1448
-/* Mask of BdrvChildRoleBits values */
1449
-typedef unsigned int BdrvChildRole;
1450
-
1451
-char *bdrv_perm_names(uint64_t perm);
1452
-uint64_t bdrv_qapi_perm_to_blk_perm(BlockPermission qapi_perm);
1453
-
1454
-void bdrv_init(void);
1455
-void bdrv_init_with_whitelist(void);
1456
-bool bdrv_uses_whitelist(void);
1457
-int bdrv_is_whitelisted(BlockDriver *drv, bool read_only);
1458
-BlockDriver *bdrv_find_protocol(const char *filename,
1459
- bool allow_protocol_prefix,
1460
- Error **errp);
1461
-BlockDriver *bdrv_find_format(const char *format_name);
1462
-int bdrv_create(BlockDriver *drv, const char* filename,
1463
- QemuOpts *opts, Error **errp);
1464
-int bdrv_create_file(const char *filename, QemuOpts *opts, Error **errp);
1465
-
1466
-BlockDriverState *bdrv_new(void);
1467
-int bdrv_append(BlockDriverState *bs_new, BlockDriverState *bs_top,
1468
- Error **errp);
1469
-int bdrv_replace_node(BlockDriverState *from, BlockDriverState *to,
1470
- Error **errp);
1471
-int bdrv_replace_child_bs(BdrvChild *child, BlockDriverState *new_bs,
1472
- Error **errp);
1473
-BlockDriverState *bdrv_insert_node(BlockDriverState *bs, QDict *node_options,
1474
- int flags, Error **errp);
1475
-int bdrv_drop_filter(BlockDriverState *bs, Error **errp);
1476
-
1477
-int bdrv_parse_aio(const char *mode, int *flags);
1478
-int bdrv_parse_cache_mode(const char *mode, int *flags, bool *writethrough);
1479
-int bdrv_parse_discard_flags(const char *mode, int *flags);
1480
-BdrvChild *bdrv_open_child(const char *filename,
1481
- QDict *options, const char *bdref_key,
1482
- BlockDriverState* parent,
1483
- const BdrvChildClass *child_class,
1484
- BdrvChildRole child_role,
1485
- bool allow_none, Error **errp);
1486
-BlockDriverState *bdrv_open_blockdev_ref(BlockdevRef *ref, Error **errp);
1487
-int bdrv_set_backing_hd(BlockDriverState *bs, BlockDriverState *backing_hd,
1488
- Error **errp);
1489
-int bdrv_open_backing_file(BlockDriverState *bs, QDict *parent_options,
1490
- const char *bdref_key, Error **errp);
1491
-BlockDriverState *bdrv_open(const char *filename, const char *reference,
1492
- QDict *options, int flags, Error **errp);
1493
-BlockDriverState *bdrv_new_open_driver_opts(BlockDriver *drv,
1494
- const char *node_name,
1495
- QDict *options, int flags,
1496
- Error **errp);
1497
-BlockDriverState *bdrv_new_open_driver(BlockDriver *drv, const char *node_name,
1498
- int flags, Error **errp);
1499
-BlockReopenQueue *bdrv_reopen_queue(BlockReopenQueue *bs_queue,
1500
- BlockDriverState *bs, QDict *options,
1501
- bool keep_old_opts);
1502
-void bdrv_reopen_queue_free(BlockReopenQueue *bs_queue);
1503
-int bdrv_reopen_multiple(BlockReopenQueue *bs_queue, Error **errp);
1504
-int bdrv_reopen(BlockDriverState *bs, QDict *opts, bool keep_old_opts,
1505
- Error **errp);
1506
-int bdrv_reopen_set_read_only(BlockDriverState *bs, bool read_only,
1507
- Error **errp);
1508
-int bdrv_pwrite_zeroes(BdrvChild *child, int64_t offset,
1509
- int64_t bytes, BdrvRequestFlags flags);
1510
-int bdrv_make_zero(BdrvChild *child, BdrvRequestFlags flags);
1511
-int bdrv_pread(BdrvChild *child, int64_t offset, void *buf, int64_t bytes);
1512
-int bdrv_pwrite(BdrvChild *child, int64_t offset, const void *buf,
1513
- int64_t bytes);
1514
-int bdrv_pwrite_sync(BdrvChild *child, int64_t offset,
1515
- const void *buf, int64_t bytes);
1516
-/*
1517
- * Efficiently zero a region of the disk image. Note that this is a regular
1518
- * I/O request like read or write and should have a reasonable size. This
1519
- * function is not suitable for zeroing the entire image in a single request
1520
- * because it may allocate memory for the entire region.
1521
- */
1522
-int coroutine_fn bdrv_co_pwrite_zeroes(BdrvChild *child, int64_t offset,
1523
- int64_t bytes, BdrvRequestFlags flags);
1524
-BlockDriverState *bdrv_find_backing_image(BlockDriverState *bs,
1525
- const char *backing_file);
1526
-void bdrv_refresh_filename(BlockDriverState *bs);
1527
-
1528
-int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact,
1529
- PreallocMode prealloc, BdrvRequestFlags flags,
1530
- Error **errp);
1531
-int generated_co_wrapper
1532
-bdrv_truncate(BdrvChild *child, int64_t offset, bool exact,
1533
- PreallocMode prealloc, BdrvRequestFlags flags, Error **errp);
1534
-
1535
-int64_t bdrv_nb_sectors(BlockDriverState *bs);
1536
-int64_t bdrv_getlength(BlockDriverState *bs);
1537
-int64_t bdrv_get_allocated_file_size(BlockDriverState *bs);
1538
-BlockMeasureInfo *bdrv_measure(BlockDriver *drv, QemuOpts *opts,
1539
- BlockDriverState *in_bs, Error **errp);
1540
-void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr);
1541
-void bdrv_refresh_limits(BlockDriverState *bs, Transaction *tran, Error **errp);
1542
-int bdrv_commit(BlockDriverState *bs);
1543
-int bdrv_make_empty(BdrvChild *c, Error **errp);
1544
-int bdrv_change_backing_file(BlockDriverState *bs, const char *backing_file,
1545
- const char *backing_fmt, bool warn);
1546
-void bdrv_register(BlockDriver *bdrv);
1547
-int bdrv_drop_intermediate(BlockDriverState *top, BlockDriverState *base,
1548
- const char *backing_file_str);
1549
-BlockDriverState *bdrv_find_overlay(BlockDriverState *active,
1550
- BlockDriverState *bs);
1551
-BlockDriverState *bdrv_find_base(BlockDriverState *bs);
1552
-bool bdrv_is_backing_chain_frozen(BlockDriverState *bs, BlockDriverState *base,
1553
- Error **errp);
1554
-int bdrv_freeze_backing_chain(BlockDriverState *bs, BlockDriverState *base,
1555
- Error **errp);
1556
-void bdrv_unfreeze_backing_chain(BlockDriverState *bs, BlockDriverState *base);
1557
-int coroutine_fn bdrv_co_delete_file(BlockDriverState *bs, Error **errp);
1558
-void coroutine_fn bdrv_co_delete_file_noerr(BlockDriverState *bs);
1559
-
1560
-
1561
-typedef struct BdrvCheckResult {
1562
- int corruptions;
1563
- int leaks;
1564
- int check_errors;
1565
- int corruptions_fixed;
1566
- int leaks_fixed;
1567
- int64_t image_end_offset;
1568
- BlockFragInfo bfi;
1569
-} BdrvCheckResult;
1570
-
1571
-typedef enum {
1572
- BDRV_FIX_LEAKS = 1,
1573
- BDRV_FIX_ERRORS = 2,
1574
-} BdrvCheckMode;
1575
-
1576
-int generated_co_wrapper bdrv_check(BlockDriverState *bs, BdrvCheckResult *res,
1577
- BdrvCheckMode fix);
1578
-
1579
-/* The units of offset and total_work_size may be chosen arbitrarily by the
1580
- * block driver; total_work_size may change during the course of the amendment
1581
- * operation */
1582
-typedef void BlockDriverAmendStatusCB(BlockDriverState *bs, int64_t offset,
1583
- int64_t total_work_size, void *opaque);
1584
-int bdrv_amend_options(BlockDriverState *bs_new, QemuOpts *opts,
1585
- BlockDriverAmendStatusCB *status_cb, void *cb_opaque,
1586
- bool force,
1587
- Error **errp);
1588
-
1589
-/* check if a named node can be replaced when doing drive-mirror */
1590
-BlockDriverState *check_to_replace_node(BlockDriverState *parent_bs,
1591
- const char *node_name, Error **errp);
1592
-
1593
-/* async block I/O */
1594
-void bdrv_aio_cancel(BlockAIOCB *acb);
1595
-void bdrv_aio_cancel_async(BlockAIOCB *acb);
1596
-
1597
-/* sg packet commands */
1598
-int bdrv_co_ioctl(BlockDriverState *bs, int req, void *buf);
1599
-
1600
-/* Invalidate any cached metadata used by image formats */
1601
-int generated_co_wrapper bdrv_invalidate_cache(BlockDriverState *bs,
1602
- Error **errp);
1603
-int bdrv_activate(BlockDriverState *bs, Error **errp);
1604
-void bdrv_activate_all(Error **errp);
1605
-int bdrv_inactivate_all(void);
1606
-
1607
-/* Ensure contents are flushed to disk. */
1608
-int generated_co_wrapper bdrv_flush(BlockDriverState *bs);
1609
-int coroutine_fn bdrv_co_flush(BlockDriverState *bs);
1610
-int bdrv_flush_all(void);
1611
-void bdrv_close_all(void);
1612
-void bdrv_drain(BlockDriverState *bs);
1613
-void coroutine_fn bdrv_co_drain(BlockDriverState *bs);
1614
-void bdrv_drain_all_begin(void);
1615
-void bdrv_drain_all_end(void);
1616
-void bdrv_drain_all(void);
1617
-
1618
-#define BDRV_POLL_WHILE(bs, cond) ({ \
1619
- BlockDriverState *bs_ = (bs); \
1620
- AIO_WAIT_WHILE(bdrv_get_aio_context(bs_), \
1621
- cond); })
1622
-
1623
-int generated_co_wrapper bdrv_pdiscard(BdrvChild *child, int64_t offset,
1624
- int64_t bytes);
1625
-int bdrv_co_pdiscard(BdrvChild *child, int64_t offset, int64_t bytes);
1626
-int bdrv_has_zero_init_1(BlockDriverState *bs);
1627
-int bdrv_has_zero_init(BlockDriverState *bs);
1628
-bool bdrv_can_write_zeroes_with_unmap(BlockDriverState *bs);
1629
-int bdrv_block_status(BlockDriverState *bs, int64_t offset,
1630
- int64_t bytes, int64_t *pnum, int64_t *map,
1631
- BlockDriverState **file);
1632
-int bdrv_block_status_above(BlockDriverState *bs, BlockDriverState *base,
1633
- int64_t offset, int64_t bytes, int64_t *pnum,
1634
- int64_t *map, BlockDriverState **file);
1635
-int bdrv_is_allocated(BlockDriverState *bs, int64_t offset, int64_t bytes,
1636
- int64_t *pnum);
1637
-int bdrv_is_allocated_above(BlockDriverState *top, BlockDriverState *base,
1638
- bool include_base, int64_t offset, int64_t bytes,
1639
- int64_t *pnum);
1640
-int coroutine_fn bdrv_co_is_zero_fast(BlockDriverState *bs, int64_t offset,
1641
- int64_t bytes);
1642
-
1643
-bool bdrv_is_read_only(BlockDriverState *bs);
1644
-int bdrv_can_set_read_only(BlockDriverState *bs, bool read_only,
1645
- bool ignore_allow_rdw, Error **errp);
1646
-int bdrv_apply_auto_read_only(BlockDriverState *bs, const char *errmsg,
1647
- Error **errp);
1648
-bool bdrv_is_writable(BlockDriverState *bs);
1649
-bool bdrv_is_sg(BlockDriverState *bs);
1650
-bool bdrv_is_inserted(BlockDriverState *bs);
1651
-void bdrv_lock_medium(BlockDriverState *bs, bool locked);
1652
-void bdrv_eject(BlockDriverState *bs, bool eject_flag);
1653
-const char *bdrv_get_format_name(BlockDriverState *bs);
1654
-BlockDriverState *bdrv_find_node(const char *node_name);
1655
-BlockDeviceInfoList *bdrv_named_nodes_list(bool flat, Error **errp);
1656
-XDbgBlockGraph *bdrv_get_xdbg_block_graph(Error **errp);
1657
-BlockDriverState *bdrv_lookup_bs(const char *device,
1658
- const char *node_name,
1659
- Error **errp);
1660
-bool bdrv_chain_contains(BlockDriverState *top, BlockDriverState *base);
1661
-BlockDriverState *bdrv_next_node(BlockDriverState *bs);
1662
-BlockDriverState *bdrv_next_all_states(BlockDriverState *bs);
1663
-
1664
-typedef struct BdrvNextIterator {
1665
- enum {
1666
- BDRV_NEXT_BACKEND_ROOTS,
1667
- BDRV_NEXT_MONITOR_OWNED,
1668
- } phase;
1669
- BlockBackend *blk;
1670
- BlockDriverState *bs;
1671
-} BdrvNextIterator;
1672
-
1673
-BlockDriverState *bdrv_first(BdrvNextIterator *it);
1674
-BlockDriverState *bdrv_next(BdrvNextIterator *it);
1675
-void bdrv_next_cleanup(BdrvNextIterator *it);
1676
-
1677
-BlockDriverState *bdrv_next_monitor_owned(BlockDriverState *bs);
1678
-bool bdrv_supports_compressed_writes(BlockDriverState *bs);
1679
-void bdrv_iterate_format(void (*it)(void *opaque, const char *name),
1680
- void *opaque, bool read_only);
1681
-const char *bdrv_get_node_name(const BlockDriverState *bs);
1682
-const char *bdrv_get_device_name(const BlockDriverState *bs);
1683
-const char *bdrv_get_device_or_node_name(const BlockDriverState *bs);
1684
-int bdrv_get_flags(BlockDriverState *bs);
1685
-int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi);
1686
-ImageInfoSpecific *bdrv_get_specific_info(BlockDriverState *bs,
1687
- Error **errp);
1688
-BlockStatsSpecific *bdrv_get_specific_stats(BlockDriverState *bs);
1689
-void bdrv_round_to_clusters(BlockDriverState *bs,
1690
- int64_t offset, int64_t bytes,
1691
- int64_t *cluster_offset,
1692
- int64_t *cluster_bytes);
1693
-
1694
-void bdrv_get_backing_filename(BlockDriverState *bs,
1695
- char *filename, int filename_size);
1696
-char *bdrv_get_full_backing_filename(BlockDriverState *bs, Error **errp);
1697
-char *bdrv_get_full_backing_filename_from_filename(const char *backed,
1698
- const char *backing,
1699
- Error **errp);
1700
-char *bdrv_dirname(BlockDriverState *bs, Error **errp);
1701
-
1702
-int path_has_protocol(const char *path);
1703
-int path_is_absolute(const char *path);
1704
-char *path_combine(const char *base_path, const char *filename);
1705
-
1706
-int generated_co_wrapper
1707
-bdrv_readv_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos);
1708
-int generated_co_wrapper
1709
-bdrv_writev_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos);
1710
-int bdrv_save_vmstate(BlockDriverState *bs, const uint8_t *buf,
1711
- int64_t pos, int size);
1712
-
1713
-int bdrv_load_vmstate(BlockDriverState *bs, uint8_t *buf,
1714
- int64_t pos, int size);
1715
-
1716
-void bdrv_img_create(const char *filename, const char *fmt,
1717
- const char *base_filename, const char *base_fmt,
1718
- char *options, uint64_t img_size, int flags,
1719
- bool quiet, Error **errp);
1720
-
1721
-/* Returns the alignment in bytes that is required so that no bounce buffer
1722
- * is required throughout the stack */
1723
-size_t bdrv_min_mem_align(BlockDriverState *bs);
1724
-/* Returns optimal alignment in bytes for bounce buffer */
1725
-size_t bdrv_opt_mem_align(BlockDriverState *bs);
1726
-void *qemu_blockalign(BlockDriverState *bs, size_t size);
1727
-void *qemu_blockalign0(BlockDriverState *bs, size_t size);
1728
-void *qemu_try_blockalign(BlockDriverState *bs, size_t size);
1729
-void *qemu_try_blockalign0(BlockDriverState *bs, size_t size);
1730
-bool bdrv_qiov_is_aligned(BlockDriverState *bs, QEMUIOVector *qiov);
1731
-
1732
-void bdrv_enable_copy_on_read(BlockDriverState *bs);
1733
-void bdrv_disable_copy_on_read(BlockDriverState *bs);
1734
-
1735
-void bdrv_ref(BlockDriverState *bs);
1736
-void bdrv_unref(BlockDriverState *bs);
1737
-void bdrv_unref_child(BlockDriverState *parent, BdrvChild *child);
1738
-BdrvChild *bdrv_attach_child(BlockDriverState *parent_bs,
1739
- BlockDriverState *child_bs,
1740
- const char *child_name,
1741
- const BdrvChildClass *child_class,
1742
- BdrvChildRole child_role,
1743
- Error **errp);
1744
-
1745
-bool bdrv_op_is_blocked(BlockDriverState *bs, BlockOpType op, Error **errp);
1746
-void bdrv_op_block(BlockDriverState *bs, BlockOpType op, Error *reason);
1747
-void bdrv_op_unblock(BlockDriverState *bs, BlockOpType op, Error *reason);
1748
-void bdrv_op_block_all(BlockDriverState *bs, Error *reason);
1749
-void bdrv_op_unblock_all(BlockDriverState *bs, Error *reason);
1750
-bool bdrv_op_blocker_is_empty(BlockDriverState *bs);
1751
-
1752
-#define BLKDBG_EVENT(child, evt) \
1753
- do { \
1754
- if (child) { \
1755
- bdrv_debug_event(child->bs, evt); \
1756
- } \
1757
- } while (0)
1758
-
1759
-void bdrv_debug_event(BlockDriverState *bs, BlkdebugEvent event);
1760
-
1761
-int bdrv_debug_breakpoint(BlockDriverState *bs, const char *event,
1762
- const char *tag);
1763
-int bdrv_debug_remove_breakpoint(BlockDriverState *bs, const char *tag);
1764
-int bdrv_debug_resume(BlockDriverState *bs, const char *tag);
1765
-bool bdrv_debug_is_suspended(BlockDriverState *bs, const char *tag);
1766
-
1767
-/**
1768
- * bdrv_get_aio_context:
1769
+ * QEMU System Emulator block driver
1770
*
1771
- * Returns: the currently bound #AioContext
1772
- */
1773
-AioContext *bdrv_get_aio_context(BlockDriverState *bs);
1774
-
1775
-/**
1776
- * Move the current coroutine to the AioContext of @bs and return the old
1777
- * AioContext of the coroutine. Increase bs->in_flight so that draining @bs
1778
- * will wait for the operation to proceed until the corresponding
1779
- * bdrv_co_leave().
1780
+ * Copyright (c) 2003 Fabrice Bellard
1781
*
1782
- * Consequently, you can't call drain inside a bdrv_co_enter/leave() section as
1783
- * this will deadlock.
1784
- */
1785
-AioContext *coroutine_fn bdrv_co_enter(BlockDriverState *bs);
1786
-
1787
-/**
1788
- * Ends a section started by bdrv_co_enter(). Move the current coroutine back
1789
- * to old_ctx and decrease bs->in_flight again.
1790
- */
1791
-void coroutine_fn bdrv_co_leave(BlockDriverState *bs, AioContext *old_ctx);
1792
-
1793
-/**
1794
- * Locks the AioContext of @bs if it's not the current AioContext. This avoids
1795
- * double locking which could lead to deadlocks: This is a coroutine_fn, so we
1796
- * know we already own the lock of the current AioContext.
1797
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
1798
+ * of this software and associated documentation files (the "Software"), to deal
1799
+ * in the Software without restriction, including without limitation the rights
1800
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
1801
+ * copies of the Software, and to permit persons to whom the Software is
1802
+ * furnished to do so, subject to the following conditions:
1803
*
1804
- * May only be called in the main thread.
1805
- */
1806
-void coroutine_fn bdrv_co_lock(BlockDriverState *bs);
1807
-
1808
-/**
1809
- * Unlocks the AioContext of @bs if it's not the current AioContext.
1810
- */
1811
-void coroutine_fn bdrv_co_unlock(BlockDriverState *bs);
1812
-
1813
-/**
1814
- * Transfer control to @co in the aio context of @bs
1815
- */
1816
-void bdrv_coroutine_enter(BlockDriverState *bs, Coroutine *co);
1817
-
1818
-void bdrv_set_aio_context_ignore(BlockDriverState *bs,
1819
- AioContext *new_context, GSList **ignore);
1820
-int bdrv_try_set_aio_context(BlockDriverState *bs, AioContext *ctx,
1821
- Error **errp);
1822
-int bdrv_child_try_set_aio_context(BlockDriverState *bs, AioContext *ctx,
1823
- BdrvChild *ignore_child, Error **errp);
1824
-bool bdrv_child_can_set_aio_context(BdrvChild *c, AioContext *ctx,
1825
- GSList **ignore, Error **errp);
1826
-bool bdrv_can_set_aio_context(BlockDriverState *bs, AioContext *ctx,
1827
- GSList **ignore, Error **errp);
1828
-AioContext *bdrv_child_get_parent_aio_context(BdrvChild *c);
1829
-AioContext *child_of_bds_get_parent_aio_context(BdrvChild *c);
1830
-
1831
-int bdrv_probe_blocksizes(BlockDriverState *bs, BlockSizes *bsz);
1832
-int bdrv_probe_geometry(BlockDriverState *bs, HDGeometry *geo);
1833
-
1834
-void bdrv_io_plug(BlockDriverState *bs);
1835
-void bdrv_io_unplug(BlockDriverState *bs);
1836
-
1837
-/**
1838
- * bdrv_parent_drained_begin_single:
1839
+ * The above copyright notice and this permission notice shall be included in
1840
+ * all copies or substantial portions of the Software.
1841
*
1842
- * Begin a quiesced section for the parent of @c. If @poll is true, wait for
1843
- * any pending activity to cease.
1844
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1845
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1846
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
1847
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1848
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
1849
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
1850
+ * THE SOFTWARE.
1851
*/
1852
-void bdrv_parent_drained_begin_single(BdrvChild *c, bool poll);
1853
-
1854
-/**
1855
- * bdrv_parent_drained_end_single:
1856
- *
1857
- * End a quiesced section for the parent of @c.
1858
- *
1859
- * This polls @bs's AioContext until all scheduled sub-drained_ends
1860
- * have settled, which may result in graph changes.
1861
- */
1862
-void bdrv_parent_drained_end_single(BdrvChild *c);
1863
-
1864
-/**
1865
- * bdrv_drain_poll:
1866
- *
1867
- * Poll for pending requests in @bs, its parents (except for @ignore_parent),
1868
- * and if @recursive is true its children as well (used for subtree drain).
1869
- *
1870
- * If @ignore_bds_parents is true, parents that are BlockDriverStates must
1871
- * ignore the drain request because they will be drained separately (used for
1872
- * drain_all).
1873
- *
1874
- * This is part of bdrv_drained_begin.
1875
- */
1876
-bool bdrv_drain_poll(BlockDriverState *bs, bool recursive,
1877
- BdrvChild *ignore_parent, bool ignore_bds_parents);
1878
-
1879
-/**
1880
- * bdrv_drained_begin:
1881
- *
1882
- * Begin a quiesced section for exclusive access to the BDS, by disabling
1883
- * external request sources including NBD server, block jobs, and device model.
1884
- *
1885
- * This function can be recursive.
1886
- */
1887
-void bdrv_drained_begin(BlockDriverState *bs);
1888
-
1889
-/**
1890
- * bdrv_do_drained_begin_quiesce:
1891
- *
1892
- * Quiesces a BDS like bdrv_drained_begin(), but does not wait for already
1893
- * running requests to complete.
1894
- */
1895
-void bdrv_do_drained_begin_quiesce(BlockDriverState *bs,
1896
- BdrvChild *parent, bool ignore_bds_parents);
1897
-
1898
-/**
1899
- * Like bdrv_drained_begin, but recursively begins a quiesced section for
1900
- * exclusive access to all child nodes as well.
1901
- */
1902
-void bdrv_subtree_drained_begin(BlockDriverState *bs);
1903
-
1904
-/**
1905
- * bdrv_drained_end:
1906
- *
1907
- * End a quiescent section started by bdrv_drained_begin().
1908
- *
1909
- * This polls @bs's AioContext until all scheduled sub-drained_ends
1910
- * have settled. On one hand, that may result in graph changes. On
1911
- * the other, this requires that the caller either runs in the main
1912
- * loop; or that all involved nodes (@bs and all of its parents) are
1913
- * in the caller's AioContext.
1914
- */
1915
-void bdrv_drained_end(BlockDriverState *bs);
1916
-
1917
-/**
1918
- * bdrv_drained_end_no_poll:
1919
- *
1920
- * Same as bdrv_drained_end(), but do not poll for the subgraph to
1921
- * actually become unquiesced. Therefore, no graph changes will occur
1922
- * with this function.
1923
- *
1924
- * *drained_end_counter is incremented for every background operation
1925
- * that is scheduled, and will be decremented for every operation once
1926
- * it settles. The caller must poll until it reaches 0. The counter
1927
- * should be accessed using atomic operations only.
1928
- */
1929
-void bdrv_drained_end_no_poll(BlockDriverState *bs, int *drained_end_counter);
1930
-
1931
-/**
1932
- * End a quiescent section started by bdrv_subtree_drained_begin().
1933
- */
1934
-void bdrv_subtree_drained_end(BlockDriverState *bs);
1935
-
1936
-void bdrv_add_child(BlockDriverState *parent, BlockDriverState *child,
1937
- Error **errp);
1938
-void bdrv_del_child(BlockDriverState *parent, BdrvChild *child, Error **errp);
1939
-
1940
-bool bdrv_can_store_new_dirty_bitmap(BlockDriverState *bs, const char *name,
1941
- uint32_t granularity, Error **errp);
1942
-/**
1943
- *
1944
- * bdrv_register_buf/bdrv_unregister_buf:
1945
- *
1946
- * Register/unregister a buffer for I/O. For example, VFIO drivers are
1947
- * interested to know the memory areas that would later be used for I/O, so
1948
- * that they can prepare IOMMU mapping etc., to get better performance.
1949
- */
1950
-void bdrv_register_buf(BlockDriverState *bs, void *host, size_t size);
1951
-void bdrv_unregister_buf(BlockDriverState *bs, void *host);
1952
+#ifndef BLOCK_H
1953
+#define BLOCK_H
1954
1955
-/**
1956
- *
1957
- * bdrv_co_copy_range:
1958
- *
1959
- * Do offloaded copy between two children. If the operation is not implemented
1960
- * by the driver, or if the backend storage doesn't support it, a negative
1961
- * error code will be returned.
1962
- *
1963
- * Note: block layer doesn't emulate or fallback to a bounce buffer approach
1964
- * because usually the caller shouldn't attempt offloaded copy any more (e.g.
1965
- * calling copy_file_range(2)) after the first error, thus it should fall back
1966
- * to a read+write path in the caller level.
1967
- *
1968
- * @src: Source child to copy data from
1969
- * @src_offset: offset in @src image to read data
1970
- * @dst: Destination child to copy data to
1971
- * @dst_offset: offset in @dst image to write data
1972
- * @bytes: number of bytes to copy
1973
- * @flags: request flags. Supported flags:
1974
- * BDRV_REQ_ZERO_WRITE - treat the @src range as zero data and do zero
1975
- * write on @dst as if bdrv_co_pwrite_zeroes is
1976
- * called. Used to simplify caller code, or
1977
- * during BlockDriver.bdrv_co_copy_range_from()
1978
- * recursion.
1979
- * BDRV_REQ_NO_SERIALISING - do not serialize with other overlapping
1980
- * requests currently in flight.
1981
- *
1982
- * Returns: 0 if succeeded; negative error code if failed.
1983
- **/
1984
-int coroutine_fn bdrv_co_copy_range(BdrvChild *src, int64_t src_offset,
1985
- BdrvChild *dst, int64_t dst_offset,
1986
- int64_t bytes, BdrvRequestFlags read_flags,
1987
- BdrvRequestFlags write_flags);
1988
+#include "block-global-state.h"
1989
+#include "block-io.h"
1990
1991
-void bdrv_cancel_in_flight(BlockDriverState *bs);
1992
+/* DO NOT ADD ANYTHING IN HERE. USE ONE OF THE HEADERS INCLUDED ABOVE */
1993
1994
-#endif
1995
+#endif /* BLOCK_H */
1996
diff --git a/block.c b/block.c
1997
index XXXXXXX..XXXXXXX 100644
1998
--- a/block.c
1999
+++ b/block.c
2000
@@ -XXX,XX +XXX,XX @@
2001
2002
#define NOT_DONE 0x7fffffff /* used while emulated sync operation in progress */
2003
2004
+/* Protected by BQL */
2005
static QTAILQ_HEAD(, BlockDriverState) graph_bdrv_states =
2006
QTAILQ_HEAD_INITIALIZER(graph_bdrv_states);
2007
2008
+/* Protected by BQL */
2009
static QTAILQ_HEAD(, BlockDriverState) all_bdrv_states =
2010
QTAILQ_HEAD_INITIALIZER(all_bdrv_states);
2011
2012
+/* Protected by BQL */
2013
static QLIST_HEAD(, BlockDriver) bdrv_drivers =
2014
QLIST_HEAD_INITIALIZER(bdrv_drivers);
2015
2016
diff --git a/block/meson.build b/block/meson.build
2017
index XXXXXXX..XXXXXXX 100644
2018
--- a/block/meson.build
2019
+++ b/block/meson.build
2020
@@ -XXX,XX +XXX,XX @@ block_ss.add(module_block_h)
2021
wrapper_py = find_program('../scripts/block-coroutine-wrapper.py')
2022
block_gen_c = custom_target('block-gen.c',
2023
output: 'block-gen.c',
2024
- input: files('../include/block/block.h',
2025
- 'coroutines.h'),
2026
+ input: files(
2027
+ '../include/block/block-io.h',
2028
+ '../include/block/block-global-state.h',
2029
+ 'coroutines.h'
2030
+ ),
2031
command: [wrapper_py, '@OUTPUT@', '@INPUT@'])
2032
block_ss.add(block_gen_c)
2033
2034
--
2035
2.35.1
diff view generated by jsdifflib
New patch
1
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
1
2
3
All the global state (GS) API functions will check that
4
qemu_in_main_thread() returns true. If not, it means
5
that the safety of BQL cannot be guaranteed, and
6
they need to be moved to I/O.
7
8
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
9
Message-Id: <20220303151616.325444-5-eesposit@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
---
12
block.c | 125 ++++++++++++++++++++++++++++++++++++++++++++++++-
13
block/commit.c | 2 +
14
block/io.c | 11 +++++
15
blockdev.c | 1 +
16
4 files changed, 137 insertions(+), 2 deletions(-)
17
18
diff --git a/block.c b/block.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/block.c
21
+++ b/block.c
22
@@ -XXX,XX +XXX,XX @@ static char *bdrv_make_absolute_filename(BlockDriverState *relative_to,
23
24
char *bdrv_get_full_backing_filename(BlockDriverState *bs, Error **errp)
25
{
26
+ GLOBAL_STATE_CODE();
27
return bdrv_make_absolute_filename(bs, bs->backing_file, errp);
28
}
29
30
void bdrv_register(BlockDriver *bdrv)
31
{
32
assert(bdrv->format_name);
33
+ GLOBAL_STATE_CODE();
34
QLIST_INSERT_HEAD(&bdrv_drivers, bdrv, list);
35
}
36
37
@@ -XXX,XX +XXX,XX @@ BlockDriverState *bdrv_new(void)
38
BlockDriverState *bs;
39
int i;
40
41
+ GLOBAL_STATE_CODE();
42
+
43
bs = g_new0(BlockDriverState, 1);
44
QLIST_INIT(&bs->dirty_bitmaps);
45
for (i = 0; i < BLOCK_OP_TYPE_MAX; i++) {
46
@@ -XXX,XX +XXX,XX @@ BlockDriver *bdrv_find_format(const char *format_name)
47
BlockDriver *drv1;
48
int i;
49
50
+ GLOBAL_STATE_CODE();
51
+
52
drv1 = bdrv_do_find_format(format_name);
53
if (drv1) {
54
return drv1;
55
@@ -XXX,XX +XXX,XX @@ static int bdrv_format_is_whitelisted(const char *format_name, bool read_only)
56
57
int bdrv_is_whitelisted(BlockDriver *drv, bool read_only)
58
{
59
+ GLOBAL_STATE_CODE();
60
return bdrv_format_is_whitelisted(drv->format_name, read_only);
61
}
62
63
@@ -XXX,XX +XXX,XX @@ int bdrv_create(BlockDriver *drv, const char* filename,
64
{
65
int ret;
66
67
+ GLOBAL_STATE_CODE();
68
+
69
Coroutine *co;
70
CreateCo cco = {
71
.drv = drv,
72
@@ -XXX,XX +XXX,XX @@ int bdrv_create_file(const char *filename, QemuOpts *opts, Error **errp)
73
QDict *qdict;
74
int ret;
75
76
+ GLOBAL_STATE_CODE();
77
+
78
drv = bdrv_find_protocol(filename, true, errp);
79
if (drv == NULL) {
80
return -ENOENT;
81
@@ -XXX,XX +XXX,XX @@ int bdrv_probe_blocksizes(BlockDriverState *bs, BlockSizes *bsz)
82
{
83
BlockDriver *drv = bs->drv;
84
BlockDriverState *filtered = bdrv_filter_bs(bs);
85
+ GLOBAL_STATE_CODE();
86
87
if (drv && drv->bdrv_probe_blocksizes) {
88
return drv->bdrv_probe_blocksizes(bs, bsz);
89
@@ -XXX,XX +XXX,XX @@ int bdrv_probe_geometry(BlockDriverState *bs, HDGeometry *geo)
90
{
91
BlockDriver *drv = bs->drv;
92
BlockDriverState *filtered = bdrv_filter_bs(bs);
93
+ GLOBAL_STATE_CODE();
94
95
if (drv && drv->bdrv_probe_geometry) {
96
return drv->bdrv_probe_geometry(bs, geo);
97
@@ -XXX,XX +XXX,XX @@ BlockDriver *bdrv_find_protocol(const char *filename,
98
const char *p;
99
int i;
100
101
+ GLOBAL_STATE_CODE();
102
/* TODO Drivers without bdrv_file_open must be specified explicitly */
103
104
/*
105
@@ -XXX,XX +XXX,XX @@ BlockDriverState *bdrv_new_open_driver_opts(BlockDriver *drv,
106
BlockDriverState *bs;
107
int ret;
108
109
+ GLOBAL_STATE_CODE();
110
+
111
bs = bdrv_new();
112
bs->open_flags = flags;
113
bs->options = options ?: qdict_new();
114
@@ -XXX,XX +XXX,XX @@ BlockDriverState *bdrv_new_open_driver_opts(BlockDriver *drv,
115
BlockDriverState *bdrv_new_open_driver(BlockDriver *drv, const char *node_name,
116
int flags, Error **errp)
117
{
118
+ GLOBAL_STATE_CODE();
119
return bdrv_new_open_driver_opts(drv, node_name, NULL, flags, errp);
120
}
121
122
@@ -XXX,XX +XXX,XX @@ BdrvChild *bdrv_attach_child(BlockDriverState *parent_bs,
123
BdrvChild *child = NULL;
124
Transaction *tran = tran_new();
125
126
+ GLOBAL_STATE_CODE();
127
+
128
ret = bdrv_attach_child_noperm(parent_bs, child_bs, child_name, child_class,
129
child_role, &child, tran, errp);
130
if (ret < 0) {
131
@@ -XXX,XX +XXX,XX @@ void bdrv_root_unref_child(BdrvChild *child)
132
{
133
BlockDriverState *child_bs;
134
135
+ GLOBAL_STATE_CODE();
136
+
137
child_bs = child->bs;
138
bdrv_detach_child(&child);
139
bdrv_unref(child_bs);
140
@@ -XXX,XX +XXX,XX @@ static void bdrv_unset_inherits_from(BlockDriverState *root, BdrvChild *child,
141
/* Callers must ensure that child->frozen is false. */
142
void bdrv_unref_child(BlockDriverState *parent, BdrvChild *child)
143
{
144
+ GLOBAL_STATE_CODE();
145
if (child == NULL) {
146
return;
147
}
148
@@ -XXX,XX +XXX,XX @@ int bdrv_set_backing_hd(BlockDriverState *bs, BlockDriverState *backing_hd,
149
int ret;
150
Transaction *tran = tran_new();
151
152
+ GLOBAL_STATE_CODE();
153
bdrv_drained_begin(bs);
154
155
ret = bdrv_set_backing_noperm(bs, backing_hd, tran, errp);
156
@@ -XXX,XX +XXX,XX @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *parent_options,
157
QDict *tmp_parent_options = NULL;
158
Error *local_err = NULL;
159
160
+ GLOBAL_STATE_CODE();
161
+
162
if (bs->backing != NULL) {
163
goto free_exit;
164
}
165
@@ -XXX,XX +XXX,XX @@ BdrvChild *bdrv_open_child(const char *filename,
166
{
167
BlockDriverState *bs;
168
169
+ GLOBAL_STATE_CODE();
170
+
171
bs = bdrv_open_child_bs(filename, options, bdref_key, parent, child_class,
172
child_role, allow_none, errp);
173
if (bs == NULL) {
174
@@ -XXX,XX +XXX,XX @@ BlockDriverState *bdrv_open_blockdev_ref(BlockdevRef *ref, Error **errp)
175
const char *reference = NULL;
176
Visitor *v = NULL;
177
178
+ GLOBAL_STATE_CODE();
179
+
180
if (ref->type == QTYPE_QSTRING) {
181
reference = ref->u.reference;
182
} else {
183
@@ -XXX,XX +XXX,XX @@ close_and_fail:
184
BlockDriverState *bdrv_open(const char *filename, const char *reference,
185
QDict *options, int flags, Error **errp)
186
{
187
+ GLOBAL_STATE_CODE();
188
+
189
return bdrv_open_inherit(filename, reference, options, flags, NULL,
190
NULL, 0, errp);
191
}
192
@@ -XXX,XX +XXX,XX @@ BlockReopenQueue *bdrv_reopen_queue(BlockReopenQueue *bs_queue,
193
BlockDriverState *bs,
194
QDict *options, bool keep_old_opts)
195
{
196
+ GLOBAL_STATE_CODE();
197
+
198
return bdrv_reopen_queue_child(bs_queue, bs, options, NULL, 0, false,
199
NULL, 0, keep_old_opts);
200
}
201
202
void bdrv_reopen_queue_free(BlockReopenQueue *bs_queue)
203
{
204
+ GLOBAL_STATE_CODE();
205
if (bs_queue) {
206
BlockReopenQueueEntry *bs_entry, *next;
207
QTAILQ_FOREACH_SAFE(bs_entry, bs_queue, entry, next) {
208
@@ -XXX,XX +XXX,XX @@ int bdrv_reopen(BlockDriverState *bs, QDict *opts, bool keep_old_opts,
209
BlockReopenQueue *queue;
210
int ret;
211
212
+ GLOBAL_STATE_CODE();
213
+
214
bdrv_subtree_drained_begin(bs);
215
if (ctx != qemu_get_aio_context()) {
216
aio_context_release(ctx);
217
@@ -XXX,XX +XXX,XX @@ int bdrv_reopen_set_read_only(BlockDriverState *bs, bool read_only,
218
{
219
QDict *opts = qdict_new();
220
221
+ GLOBAL_STATE_CODE();
222
+
223
qdict_put_bool(opts, BDRV_OPT_READ_ONLY, read_only);
224
225
return bdrv_reopen(bs, opts, true, errp);
226
@@ -XXX,XX +XXX,XX @@ static void bdrv_close(BlockDriverState *bs)
227
BdrvAioNotifier *ban, *ban_next;
228
BdrvChild *child, *next;
229
230
+ GLOBAL_STATE_CODE();
231
assert(!bs->refcnt);
232
233
bdrv_drained_begin(bs); /* complete I/O */
234
@@ -XXX,XX +XXX,XX @@ static void bdrv_close(BlockDriverState *bs)
235
void bdrv_close_all(void)
236
{
237
assert(job_next(NULL) == NULL);
238
+ GLOBAL_STATE_CODE();
239
240
/* Drop references from requests still in flight, such as canceled block
241
* jobs whose AIO context has not been polled yet */
242
@@ -XXX,XX +XXX,XX @@ out:
243
int bdrv_replace_node(BlockDriverState *from, BlockDriverState *to,
244
Error **errp)
245
{
246
+ GLOBAL_STATE_CODE();
247
+
248
return bdrv_replace_node_common(from, to, true, false, errp);
249
}
250
251
int bdrv_drop_filter(BlockDriverState *bs, Error **errp)
252
{
253
+ GLOBAL_STATE_CODE();
254
+
255
return bdrv_replace_node_common(bs, bdrv_filter_or_cow_bs(bs), true, true,
256
errp);
257
}
258
@@ -XXX,XX +XXX,XX @@ int bdrv_append(BlockDriverState *bs_new, BlockDriverState *bs_top,
259
int ret;
260
Transaction *tran = tran_new();
261
262
+ GLOBAL_STATE_CODE();
263
+
264
assert(!bs_new->backing);
265
266
ret = bdrv_attach_child_noperm(bs_new, bs_top, "backing",
267
@@ -XXX,XX +XXX,XX @@ int bdrv_replace_child_bs(BdrvChild *child, BlockDriverState *new_bs,
268
g_autoptr(GSList) refresh_list = NULL;
269
BlockDriverState *old_bs = child->bs;
270
271
+ GLOBAL_STATE_CODE();
272
+
273
bdrv_ref(old_bs);
274
bdrv_drained_begin(old_bs);
275
bdrv_drained_begin(new_bs);
276
@@ -XXX,XX +XXX,XX @@ static void bdrv_delete(BlockDriverState *bs)
277
{
278
assert(bdrv_op_blocker_is_empty(bs));
279
assert(!bs->refcnt);
280
+ GLOBAL_STATE_CODE();
281
282
/* remove from list, if necessary */
283
if (bs->node_name[0] != '\0') {
284
@@ -XXX,XX +XXX,XX @@ BlockDriverState *bdrv_insert_node(BlockDriverState *bs, QDict *options,
285
286
node_name = qdict_get_try_str(options, "node-name");
287
288
+ GLOBAL_STATE_CODE();
289
+
290
new_node_bs = bdrv_new_open_driver_opts(drv, node_name, options, flags,
291
errp);
292
options = NULL; /* bdrv_new_open_driver() eats options */
293
@@ -XXX,XX +XXX,XX @@ int bdrv_change_backing_file(BlockDriverState *bs, const char *backing_file,
294
BlockDriver *drv = bs->drv;
295
int ret;
296
297
+ GLOBAL_STATE_CODE();
298
+
299
if (!drv) {
300
return -ENOMEDIUM;
301
}
302
@@ -XXX,XX +XXX,XX @@ int bdrv_change_backing_file(BlockDriverState *bs, const char *backing_file,
303
BlockDriverState *bdrv_find_overlay(BlockDriverState *active,
304
BlockDriverState *bs)
305
{
306
+
307
+ GLOBAL_STATE_CODE();
308
+
309
bs = bdrv_skip_filters(bs);
310
active = bdrv_skip_filters(active);
311
312
@@ -XXX,XX +XXX,XX @@ BlockDriverState *bdrv_find_overlay(BlockDriverState *active,
313
/* Given a BDS, searches for the base layer. */
314
BlockDriverState *bdrv_find_base(BlockDriverState *bs)
315
{
316
+ GLOBAL_STATE_CODE();
317
+
318
return bdrv_find_overlay(bs, NULL);
319
}
320
321
@@ -XXX,XX +XXX,XX @@ bool bdrv_is_backing_chain_frozen(BlockDriverState *bs, BlockDriverState *base,
322
BlockDriverState *i;
323
BdrvChild *child;
324
325
+ GLOBAL_STATE_CODE();
326
+
327
for (i = bs; i != base; i = child_bs(child)) {
328
child = bdrv_filter_or_cow_child(i);
329
330
@@ -XXX,XX +XXX,XX @@ int bdrv_freeze_backing_chain(BlockDriverState *bs, BlockDriverState *base,
331
BlockDriverState *i;
332
BdrvChild *child;
333
334
+ GLOBAL_STATE_CODE();
335
+
336
if (bdrv_is_backing_chain_frozen(bs, base, errp)) {
337
return -EPERM;
338
}
339
@@ -XXX,XX +XXX,XX @@ void bdrv_unfreeze_backing_chain(BlockDriverState *bs, BlockDriverState *base)
340
BlockDriverState *i;
341
BdrvChild *child;
342
343
+ GLOBAL_STATE_CODE();
344
+
345
for (i = bs; i != base; i = child_bs(child)) {
346
child = bdrv_filter_or_cow_child(i);
347
if (child) {
348
@@ -XXX,XX +XXX,XX @@ int bdrv_drop_intermediate(BlockDriverState *top, BlockDriverState *base,
349
g_autoptr(GSList) updated_children = NULL;
350
GSList *p;
351
352
+ GLOBAL_STATE_CODE();
353
+
354
bdrv_ref(top);
355
bdrv_subtree_drained_begin(top);
356
357
@@ -XXX,XX +XXX,XX @@ void bdrv_iterate_format(void (*it)(void *opaque, const char *name),
358
int i;
359
const char **formats = NULL;
360
361
+ GLOBAL_STATE_CODE();
362
+
363
QLIST_FOREACH(drv, &bdrv_drivers, list) {
364
if (drv->format_name) {
365
bool found = false;
366
@@ -XXX,XX +XXX,XX @@ BlockDriverState *bdrv_find_node(const char *node_name)
367
BlockDriverState *bs;
368
369
assert(node_name);
370
+ GLOBAL_STATE_CODE();
371
372
QTAILQ_FOREACH(bs, &graph_bdrv_states, node_list) {
373
if (!strcmp(node_name, bs->node_name)) {
374
@@ -XXX,XX +XXX,XX @@ BlockDeviceInfoList *bdrv_named_nodes_list(bool flat,
375
BlockDeviceInfoList *list;
376
BlockDriverState *bs;
377
378
+ GLOBAL_STATE_CODE();
379
+
380
list = NULL;
381
QTAILQ_FOREACH(bs, &graph_bdrv_states, node_list) {
382
BlockDeviceInfo *info = bdrv_block_device_info(NULL, bs, flat, errp);
383
@@ -XXX,XX +XXX,XX @@ XDbgBlockGraph *bdrv_get_xdbg_block_graph(Error **errp)
384
BdrvChild *child;
385
XDbgBlockGraphConstructor *gr = xdbg_graph_new();
386
387
+ GLOBAL_STATE_CODE();
388
+
389
for (blk = blk_all_next(NULL); blk; blk = blk_all_next(blk)) {
390
char *allocated_name = NULL;
391
const char *name = blk_name(blk);
392
@@ -XXX,XX +XXX,XX @@ BlockDriverState *bdrv_lookup_bs(const char *device,
393
BlockBackend *blk;
394
BlockDriverState *bs;
395
396
+ GLOBAL_STATE_CODE();
397
+
398
if (device) {
399
blk = blk_by_name(device);
400
401
@@ -XXX,XX +XXX,XX @@ BlockDriverState *bdrv_lookup_bs(const char *device,
402
* return false. If either argument is NULL, return false. */
403
bool bdrv_chain_contains(BlockDriverState *top, BlockDriverState *base)
404
{
405
+
406
+ GLOBAL_STATE_CODE();
407
+
408
while (top && top != base) {
409
top = bdrv_filter_or_cow_bs(top);
410
}
411
@@ -XXX,XX +XXX,XX @@ bool bdrv_chain_contains(BlockDriverState *top, BlockDriverState *base)
412
413
BlockDriverState *bdrv_next_node(BlockDriverState *bs)
414
{
415
+ GLOBAL_STATE_CODE();
416
if (!bs) {
417
return QTAILQ_FIRST(&graph_bdrv_states);
418
}
419
@@ -XXX,XX +XXX,XX @@ BlockDriverState *bdrv_next_node(BlockDriverState *bs)
420
421
BlockDriverState *bdrv_next_all_states(BlockDriverState *bs)
422
{
423
+ GLOBAL_STATE_CODE();
424
if (!bs) {
425
return QTAILQ_FIRST(&all_bdrv_states);
426
}
427
@@ -XXX,XX +XXX,XX @@ const char *bdrv_get_device_or_node_name(const BlockDriverState *bs)
428
429
int bdrv_get_flags(BlockDriverState *bs)
430
{
431
+ GLOBAL_STATE_CODE();
432
return bs->open_flags;
433
}
434
435
int bdrv_has_zero_init_1(BlockDriverState *bs)
436
{
437
+ GLOBAL_STATE_CODE();
438
return 1;
439
}
440
441
int bdrv_has_zero_init(BlockDriverState *bs)
442
{
443
BlockDriverState *filtered;
444
+ GLOBAL_STATE_CODE();
445
446
if (!bs->drv) {
447
return 0;
448
@@ -XXX,XX +XXX,XX @@ static BlockDriverState *bdrv_find_debug_node(BlockDriverState *bs)
449
int bdrv_debug_breakpoint(BlockDriverState *bs, const char *event,
450
const char *tag)
451
{
452
+ GLOBAL_STATE_CODE();
453
bs = bdrv_find_debug_node(bs);
454
if (bs) {
455
return bs->drv->bdrv_debug_breakpoint(bs, event, tag);
456
@@ -XXX,XX +XXX,XX @@ int bdrv_debug_breakpoint(BlockDriverState *bs, const char *event,
457
458
int bdrv_debug_remove_breakpoint(BlockDriverState *bs, const char *tag)
459
{
460
+ GLOBAL_STATE_CODE();
461
bs = bdrv_find_debug_node(bs);
462
if (bs) {
463
return bs->drv->bdrv_debug_remove_breakpoint(bs, tag);
464
@@ -XXX,XX +XXX,XX @@ int bdrv_debug_remove_breakpoint(BlockDriverState *bs, const char *tag)
465
466
int bdrv_debug_resume(BlockDriverState *bs, const char *tag)
467
{
468
+ GLOBAL_STATE_CODE();
469
while (bs && (!bs->drv || !bs->drv->bdrv_debug_resume)) {
470
bs = bdrv_primary_bs(bs);
471
}
472
@@ -XXX,XX +XXX,XX @@ int bdrv_debug_resume(BlockDriverState *bs, const char *tag)
473
474
bool bdrv_debug_is_suspended(BlockDriverState *bs, const char *tag)
475
{
476
+ GLOBAL_STATE_CODE();
477
while (bs && bs->drv && !bs->drv->bdrv_debug_is_suspended) {
478
bs = bdrv_primary_bs(bs);
479
}
480
@@ -XXX,XX +XXX,XX @@ BlockDriverState *bdrv_find_backing_image(BlockDriverState *bs,
481
BlockDriverState *retval = NULL;
482
BlockDriverState *bs_below;
483
484
+ GLOBAL_STATE_CODE();
485
+
486
if (!bs || !bs->drv || !backing_file) {
487
return NULL;
488
}
489
@@ -XXX,XX +XXX,XX @@ int bdrv_activate(BlockDriverState *bs, Error **errp)
490
int ret;
491
BdrvDirtyBitmap *bm;
492
493
+ GLOBAL_STATE_CODE();
494
+
495
if (!bs->drv) {
496
return -ENOMEDIUM;
497
}
498
@@ -XXX,XX +XXX,XX @@ void bdrv_activate_all(Error **errp)
499
BlockDriverState *bs;
500
BdrvNextIterator it;
501
502
+ GLOBAL_STATE_CODE();
503
+
504
for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
505
AioContext *aio_context = bdrv_get_aio_context(bs);
506
int ret;
507
@@ -XXX,XX +XXX,XX @@ int bdrv_inactivate_all(void)
508
int ret = 0;
509
GSList *aio_ctxs = NULL, *ctx;
510
511
+ GLOBAL_STATE_CODE();
512
+
513
for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
514
AioContext *aio_context = bdrv_get_aio_context(bs);
515
516
@@ -XXX,XX +XXX,XX @@ void bdrv_lock_medium(BlockDriverState *bs, bool locked)
517
/* Get a reference to bs */
518
void bdrv_ref(BlockDriverState *bs)
519
{
520
+ GLOBAL_STATE_CODE();
521
bs->refcnt++;
522
}
523
524
@@ -XXX,XX +XXX,XX @@ void bdrv_ref(BlockDriverState *bs)
525
* deleted. */
526
void bdrv_unref(BlockDriverState *bs)
527
{
528
+ GLOBAL_STATE_CODE();
529
if (!bs) {
530
return;
531
}
532
@@ -XXX,XX +XXX,XX @@ struct BdrvOpBlocker {
533
bool bdrv_op_is_blocked(BlockDriverState *bs, BlockOpType op, Error **errp)
534
{
535
BdrvOpBlocker *blocker;
536
+ GLOBAL_STATE_CODE();
537
assert((int) op >= 0 && op < BLOCK_OP_TYPE_MAX);
538
if (!QLIST_EMPTY(&bs->op_blockers[op])) {
539
blocker = QLIST_FIRST(&bs->op_blockers[op]);
540
@@ -XXX,XX +XXX,XX @@ bool bdrv_op_is_blocked(BlockDriverState *bs, BlockOpType op, Error **errp)
541
void bdrv_op_block(BlockDriverState *bs, BlockOpType op, Error *reason)
542
{
543
BdrvOpBlocker *blocker;
544
+ GLOBAL_STATE_CODE();
545
assert((int) op >= 0 && op < BLOCK_OP_TYPE_MAX);
546
547
blocker = g_new0(BdrvOpBlocker, 1);
548
@@ -XXX,XX +XXX,XX @@ void bdrv_op_block(BlockDriverState *bs, BlockOpType op, Error *reason)
549
void bdrv_op_unblock(BlockDriverState *bs, BlockOpType op, Error *reason)
550
{
551
BdrvOpBlocker *blocker, *next;
552
+ GLOBAL_STATE_CODE();
553
assert((int) op >= 0 && op < BLOCK_OP_TYPE_MAX);
554
QLIST_FOREACH_SAFE(blocker, &bs->op_blockers[op], list, next) {
555
if (blocker->reason == reason) {
556
@@ -XXX,XX +XXX,XX @@ void bdrv_op_unblock(BlockDriverState *bs, BlockOpType op, Error *reason)
557
void bdrv_op_block_all(BlockDriverState *bs, Error *reason)
558
{
559
int i;
560
+ GLOBAL_STATE_CODE();
561
for (i = 0; i < BLOCK_OP_TYPE_MAX; i++) {
562
bdrv_op_block(bs, i, reason);
563
}
564
@@ -XXX,XX +XXX,XX @@ void bdrv_op_block_all(BlockDriverState *bs, Error *reason)
565
void bdrv_op_unblock_all(BlockDriverState *bs, Error *reason)
566
{
567
int i;
568
+ GLOBAL_STATE_CODE();
569
for (i = 0; i < BLOCK_OP_TYPE_MAX; i++) {
570
bdrv_op_unblock(bs, i, reason);
571
}
572
@@ -XXX,XX +XXX,XX @@ void bdrv_op_unblock_all(BlockDriverState *bs, Error *reason)
573
bool bdrv_op_blocker_is_empty(BlockDriverState *bs)
574
{
575
int i;
576
-
577
+ GLOBAL_STATE_CODE();
578
for (i = 0; i < BLOCK_OP_TYPE_MAX; i++) {
579
if (!QLIST_EMPTY(&bs->op_blockers[i])) {
580
return false;
581
@@ -XXX,XX +XXX,XX @@ void bdrv_img_create(const char *filename, const char *fmt,
582
Error *local_err = NULL;
583
int ret = 0;
584
585
+ GLOBAL_STATE_CODE();
586
+
587
/* Find driver and parse its options */
588
drv = bdrv_find_format(fmt);
589
if (!drv) {
590
@@ -XXX,XX +XXX,XX @@ static bool bdrv_parent_can_set_aio_context(BdrvChild *c, AioContext *ctx,
591
bool bdrv_child_can_set_aio_context(BdrvChild *c, AioContext *ctx,
592
GSList **ignore, Error **errp)
593
{
594
+ GLOBAL_STATE_CODE();
595
if (g_slist_find(*ignore, c)) {
596
return true;
597
}
598
@@ -XXX,XX +XXX,XX @@ bool bdrv_can_set_aio_context(BlockDriverState *bs, AioContext *ctx,
599
return true;
600
}
601
602
+ GLOBAL_STATE_CODE();
603
+
604
QLIST_FOREACH(c, &bs->parents, next_parent) {
605
if (!bdrv_parent_can_set_aio_context(c, ctx, ignore, errp)) {
606
return false;
607
@@ -XXX,XX +XXX,XX @@ int bdrv_child_try_set_aio_context(BlockDriverState *bs, AioContext *ctx,
608
GSList *ignore;
609
bool ret;
610
611
+ GLOBAL_STATE_CODE();
612
+
613
ignore = ignore_child ? g_slist_prepend(NULL, ignore_child) : NULL;
614
ret = bdrv_can_set_aio_context(bs, ctx, &ignore, errp);
615
g_slist_free(ignore);
616
@@ -XXX,XX +XXX,XX @@ int bdrv_child_try_set_aio_context(BlockDriverState *bs, AioContext *ctx,
617
int bdrv_try_set_aio_context(BlockDriverState *bs, AioContext *ctx,
618
Error **errp)
619
{
620
+ GLOBAL_STATE_CODE();
621
return bdrv_child_try_set_aio_context(bs, ctx, NULL, errp);
622
}
623
624
@@ -XXX,XX +XXX,XX @@ void bdrv_add_aio_context_notifier(BlockDriverState *bs,
625
.detach_aio_context = detach_aio_context,
626
.opaque = opaque
627
};
628
+ GLOBAL_STATE_CODE();
629
630
QLIST_INSERT_HEAD(&bs->aio_notifiers, ban, list);
631
}
632
@@ -XXX,XX +XXX,XX @@ void bdrv_remove_aio_context_notifier(BlockDriverState *bs,
633
void *opaque)
634
{
635
BdrvAioNotifier *ban, *ban_next;
636
+ GLOBAL_STATE_CODE();
637
638
QLIST_FOREACH_SAFE(ban, &bs->aio_notifiers, list, ban_next) {
639
if (ban->attached_aio_context == attached_aio_context &&
640
@@ -XXX,XX +XXX,XX @@ int bdrv_amend_options(BlockDriverState *bs, QemuOpts *opts,
641
bool force,
642
Error **errp)
643
{
644
+ GLOBAL_STATE_CODE();
645
if (!bs->drv) {
646
error_setg(errp, "Node is ejected");
647
return -ENOMEDIUM;
648
@@ -XXX,XX +XXX,XX @@ BlockDriverState *check_to_replace_node(BlockDriverState *parent_bs,
649
BlockDriverState *to_replace_bs = bdrv_find_node(node_name);
650
AioContext *aio_context;
651
652
+ GLOBAL_STATE_CODE();
653
+
654
if (!to_replace_bs) {
655
error_setg(errp, "Failed to find node with node-name='%s'", node_name);
656
return NULL;
657
@@ -XXX,XX +XXX,XX @@ void bdrv_refresh_filename(BlockDriverState *bs)
658
bool generate_json_filename; /* Whether our default implementation should
659
fill exact_filename (false) or not (true) */
660
661
+ GLOBAL_STATE_CODE();
662
+
663
if (!drv) {
664
return;
665
}
666
@@ -XXX,XX +XXX,XX @@ char *bdrv_dirname(BlockDriverState *bs, Error **errp)
667
BlockDriver *drv = bs->drv;
668
BlockDriverState *child_bs;
669
670
+ GLOBAL_STATE_CODE();
671
+
672
if (!drv) {
673
error_setg(errp, "Node '%s' is ejected", bs->node_name);
674
return NULL;
675
@@ -XXX,XX +XXX,XX @@ char *bdrv_dirname(BlockDriverState *bs, Error **errp)
676
void bdrv_add_child(BlockDriverState *parent_bs, BlockDriverState *child_bs,
677
Error **errp)
678
{
679
-
680
+ GLOBAL_STATE_CODE();
681
if (!parent_bs->drv || !parent_bs->drv->bdrv_add_child) {
682
error_setg(errp, "The node %s does not support adding a child",
683
bdrv_get_device_or_node_name(parent_bs));
684
@@ -XXX,XX +XXX,XX @@ void bdrv_del_child(BlockDriverState *parent_bs, BdrvChild *child, Error **errp)
685
{
686
BdrvChild *tmp;
687
688
+ GLOBAL_STATE_CODE();
689
if (!parent_bs->drv || !parent_bs->drv->bdrv_del_child) {
690
error_setg(errp, "The node %s does not support removing a child",
691
bdrv_get_device_or_node_name(parent_bs));
692
@@ -XXX,XX +XXX,XX @@ int bdrv_make_empty(BdrvChild *c, Error **errp)
693
BlockDriver *drv = c->bs->drv;
694
int ret;
695
696
+ GLOBAL_STATE_CODE();
697
assert(c->perm & (BLK_PERM_WRITE | BLK_PERM_WRITE_UNCHANGED));
698
699
if (!drv->bdrv_make_empty) {
700
diff --git a/block/commit.c b/block/commit.c
701
index XXXXXXX..XXXXXXX 100644
702
--- a/block/commit.c
703
+++ b/block/commit.c
704
@@ -XXX,XX +XXX,XX @@ int bdrv_commit(BlockDriverState *bs)
705
QEMU_AUTO_VFREE uint8_t *buf = NULL;
706
Error *local_err = NULL;
707
708
+ GLOBAL_STATE_CODE();
709
+
710
if (!drv)
711
return -ENOMEDIUM;
712
713
diff --git a/block/io.c b/block/io.c
714
index XXXXXXX..XXXXXXX 100644
715
--- a/block/io.c
716
+++ b/block/io.c
717
@@ -XXX,XX +XXX,XX @@ void bdrv_refresh_limits(BlockDriverState *bs, Transaction *tran, Error **errp)
718
BdrvChild *c;
719
bool have_limits;
720
721
+ GLOBAL_STATE_CODE();
722
+
723
if (tran) {
724
BdrvRefreshLimitsState *s = g_new(BdrvRefreshLimitsState, 1);
725
*s = (BdrvRefreshLimitsState) {
726
@@ -XXX,XX +XXX,XX @@ static bool bdrv_drain_all_poll(void)
727
{
728
BlockDriverState *bs = NULL;
729
bool result = false;
730
+ GLOBAL_STATE_CODE();
731
732
/* bdrv_drain_poll() can't make changes to the graph and we are holding the
733
* main AioContext lock, so iterating bdrv_next_all_states() is safe. */
734
@@ -XXX,XX +XXX,XX @@ static bool bdrv_drain_all_poll(void)
735
void bdrv_drain_all_begin(void)
736
{
737
BlockDriverState *bs = NULL;
738
+ GLOBAL_STATE_CODE();
739
740
if (qemu_in_coroutine()) {
741
bdrv_co_yield_to_drain(NULL, true, false, NULL, true, true, NULL);
742
@@ -XXX,XX +XXX,XX @@ void bdrv_drain_all_end(void)
743
{
744
BlockDriverState *bs = NULL;
745
int drained_end_counter = 0;
746
+ GLOBAL_STATE_CODE();
747
748
/*
749
* bdrv queue is managed by record/replay,
750
@@ -XXX,XX +XXX,XX @@ void bdrv_drain_all_end(void)
751
752
void bdrv_drain_all(void)
753
{
754
+ GLOBAL_STATE_CODE();
755
bdrv_drain_all_begin();
756
bdrv_drain_all_end();
757
}
758
@@ -XXX,XX +XXX,XX @@ int bdrv_flush_all(void)
759
BlockDriverState *bs = NULL;
760
int result = 0;
761
762
+ GLOBAL_STATE_CODE();
763
+
764
/*
765
* bdrv queue is managed by record/replay,
766
* creating new flush request for stopping
767
@@ -XXX,XX +XXX,XX @@ void bdrv_register_buf(BlockDriverState *bs, void *host, size_t size)
768
{
769
BdrvChild *child;
770
771
+ GLOBAL_STATE_CODE();
772
if (bs->drv && bs->drv->bdrv_register_buf) {
773
bs->drv->bdrv_register_buf(bs, host, size);
774
}
775
@@ -XXX,XX +XXX,XX @@ void bdrv_unregister_buf(BlockDriverState *bs, void *host)
776
{
777
BdrvChild *child;
778
779
+ GLOBAL_STATE_CODE();
780
if (bs->drv && bs->drv->bdrv_unregister_buf) {
781
bs->drv->bdrv_unregister_buf(bs, host);
782
}
783
@@ -XXX,XX +XXX,XX @@ out:
784
785
void bdrv_cancel_in_flight(BlockDriverState *bs)
786
{
787
+ GLOBAL_STATE_CODE();
788
if (!bs || !bs->drv) {
789
return;
790
}
791
diff --git a/blockdev.c b/blockdev.c
792
index XXXXXXX..XXXXXXX 100644
793
--- a/blockdev.c
794
+++ b/blockdev.c
795
@@ -XXX,XX +XXX,XX @@ void blockdev_close_all_bdrv_states(void)
796
/* Iterates over the list of monitor-owned BlockDriverStates */
797
BlockDriverState *bdrv_next_monitor_owned(BlockDriverState *bs)
798
{
799
+ GLOBAL_STATE_CODE();
800
return bs ? QTAILQ_NEXT(bs, monitor_list)
801
: QTAILQ_FIRST(&monitor_bdrv_states);
802
}
803
--
804
2.35.1
diff view generated by jsdifflib
New patch
1
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
1
2
3
Mark all I/O functions with IO_CODE, and all "I/O OR GS" with
4
IO_OR_GS_CODE.
5
6
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
7
Message-Id: <20220303151616.325444-6-eesposit@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
---
10
include/block/block-io.h | 1 +
11
block.c | 37 +++++++++++++++++++++++++++++++++-
12
block/dirty-bitmap.c | 1 +
13
block/io.c | 43 ++++++++++++++++++++++++++++++++++++++--
14
4 files changed, 79 insertions(+), 3 deletions(-)
15
16
diff --git a/include/block/block-io.h b/include/block/block-io.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/include/block/block-io.h
19
+++ b/include/block/block-io.h
20
@@ -XXX,XX +XXX,XX @@ void bdrv_drained_end_no_poll(BlockDriverState *bs, int *drained_end_counter);
21
22
#define BDRV_POLL_WHILE(bs, cond) ({ \
23
BlockDriverState *bs_ = (bs); \
24
+ IO_OR_GS_CODE(); \
25
AIO_WAIT_WHILE(bdrv_get_aio_context(bs_), \
26
cond); })
27
28
diff --git a/block.c b/block.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/block.c
31
+++ b/block.c
32
@@ -XXX,XX +XXX,XX @@ size_t bdrv_opt_mem_align(BlockDriverState *bs)
33
/* page size or 4k (hdd sector size) should be on the safe side */
34
return MAX(4096, qemu_real_host_page_size);
35
}
36
+ IO_CODE();
37
38
return bs->bl.opt_mem_alignment;
39
}
40
@@ -XXX,XX +XXX,XX @@ size_t bdrv_min_mem_align(BlockDriverState *bs)
41
/* page size or 4k (hdd sector size) should be on the safe side */
42
return MAX(4096, qemu_real_host_page_size);
43
}
44
+ IO_CODE();
45
46
return bs->bl.min_mem_alignment;
47
}
48
@@ -XXX,XX +XXX,XX @@ void bdrv_parse_filename_strip_prefix(const char *filename, const char *prefix,
49
* image is inactivated. */
50
bool bdrv_is_read_only(BlockDriverState *bs)
51
{
52
+ IO_CODE();
53
return !(bs->open_flags & BDRV_O_RDWR);
54
}
55
56
int bdrv_can_set_read_only(BlockDriverState *bs, bool read_only,
57
bool ignore_allow_rdw, Error **errp)
58
{
59
+ IO_CODE();
60
+
61
/* Do not set read_only if copy_on_read is enabled */
62
if (bs->copy_on_read && read_only) {
63
error_setg(errp, "Can't set node '%s' to r/o with copy-on-read enabled",
64
@@ -XXX,XX +XXX,XX @@ int bdrv_apply_auto_read_only(BlockDriverState *bs, const char *errmsg,
65
Error **errp)
66
{
67
int ret = 0;
68
+ IO_CODE();
69
70
if (!(bs->open_flags & BDRV_O_RDWR)) {
71
return 0;
72
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_delete_file(BlockDriverState *bs, Error **errp)
73
Error *local_err = NULL;
74
int ret;
75
76
+ IO_CODE();
77
assert(bs != NULL);
78
79
if (!bs->drv) {
80
@@ -XXX,XX +XXX,XX @@ void coroutine_fn bdrv_co_delete_file_noerr(BlockDriverState *bs)
81
{
82
Error *local_err = NULL;
83
int ret;
84
+ IO_CODE();
85
86
if (!bs) {
87
return;
88
@@ -XXX,XX +XXX,XX @@ static int bdrv_child_cb_update_filename(BdrvChild *c, BlockDriverState *base,
89
AioContext *child_of_bds_get_parent_aio_context(BdrvChild *c)
90
{
91
BlockDriverState *bs = c->opaque;
92
+ IO_CODE();
93
94
return bdrv_get_aio_context(bs);
95
}
96
@@ -XXX,XX +XXX,XX @@ const BdrvChildClass child_of_bds = {
97
98
AioContext *bdrv_child_get_parent_aio_context(BdrvChild *c)
99
{
100
+ IO_CODE();
101
return c->klass->get_parent_aio_context(c);
102
}
103
104
@@ -XXX,XX +XXX,XX @@ static bool bdrv_is_writable_after_reopen(BlockDriverState *bs,
105
*/
106
bool bdrv_is_writable(BlockDriverState *bs)
107
{
108
+ IO_CODE();
109
return bdrv_is_writable_after_reopen(bs, NULL);
110
}
111
112
@@ -XXX,XX +XXX,XX @@ static int64_t bdrv_sum_allocated_file_size(BlockDriverState *bs)
113
int64_t bdrv_get_allocated_file_size(BlockDriverState *bs)
114
{
115
BlockDriver *drv = bs->drv;
116
+ IO_CODE();
117
+
118
if (!drv) {
119
return -ENOMEDIUM;
120
}
121
@@ -XXX,XX +XXX,XX @@ int64_t bdrv_get_allocated_file_size(BlockDriverState *bs)
122
BlockMeasureInfo *bdrv_measure(BlockDriver *drv, QemuOpts *opts,
123
BlockDriverState *in_bs, Error **errp)
124
{
125
+ IO_CODE();
126
if (!drv->bdrv_measure) {
127
error_setg(errp, "Block driver '%s' does not support size measurement",
128
drv->format_name);
129
@@ -XXX,XX +XXX,XX @@ BlockMeasureInfo *bdrv_measure(BlockDriver *drv, QemuOpts *opts,
130
int64_t bdrv_nb_sectors(BlockDriverState *bs)
131
{
132
BlockDriver *drv = bs->drv;
133
+ IO_CODE();
134
135
if (!drv)
136
return -ENOMEDIUM;
137
@@ -XXX,XX +XXX,XX @@ int64_t bdrv_nb_sectors(BlockDriverState *bs)
138
int64_t bdrv_getlength(BlockDriverState *bs)
139
{
140
int64_t ret = bdrv_nb_sectors(bs);
141
+ IO_CODE();
142
143
if (ret < 0) {
144
return ret;
145
@@ -XXX,XX +XXX,XX @@ int64_t bdrv_getlength(BlockDriverState *bs)
146
void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr)
147
{
148
int64_t nb_sectors = bdrv_nb_sectors(bs);
149
+ IO_CODE();
150
151
*nb_sectors_ptr = nb_sectors < 0 ? 0 : nb_sectors;
152
}
153
154
bool bdrv_is_sg(BlockDriverState *bs)
155
{
156
+ IO_CODE();
157
return bs->sg;
158
}
159
160
@@ -XXX,XX +XXX,XX @@ bool bdrv_is_sg(BlockDriverState *bs)
161
bool bdrv_supports_compressed_writes(BlockDriverState *bs)
162
{
163
BlockDriverState *filtered;
164
+ IO_CODE();
165
166
if (!bs->drv || !block_driver_can_compress(bs->drv)) {
167
return false;
168
@@ -XXX,XX +XXX,XX @@ bool bdrv_supports_compressed_writes(BlockDriverState *bs)
169
170
const char *bdrv_get_format_name(BlockDriverState *bs)
171
{
172
+ IO_CODE();
173
return bs->drv ? bs->drv->format_name : NULL;
174
}
175
176
@@ -XXX,XX +XXX,XX @@ BlockDriverState *bdrv_next_all_states(BlockDriverState *bs)
177
178
const char *bdrv_get_node_name(const BlockDriverState *bs)
179
{
180
+ IO_CODE();
181
return bs->node_name;
182
}
183
184
@@ -XXX,XX +XXX,XX @@ const char *bdrv_get_parent_name(const BlockDriverState *bs)
185
/* TODO check what callers really want: bs->node_name or blk_name() */
186
const char *bdrv_get_device_name(const BlockDriverState *bs)
187
{
188
+ IO_CODE();
189
return bdrv_get_parent_name(bs) ?: "";
190
}
191
192
@@ -XXX,XX +XXX,XX @@ const char *bdrv_get_device_name(const BlockDriverState *bs)
193
* absent, then this returns an empty (non-null) string. */
194
const char *bdrv_get_device_or_node_name(const BlockDriverState *bs)
195
{
196
+ IO_CODE();
197
return bdrv_get_parent_name(bs) ?: bs->node_name;
198
}
199
200
@@ -XXX,XX +XXX,XX @@ int bdrv_has_zero_init(BlockDriverState *bs)
201
202
bool bdrv_can_write_zeroes_with_unmap(BlockDriverState *bs)
203
{
204
+ IO_CODE();
205
if (!(bs->open_flags & BDRV_O_UNMAP)) {
206
return false;
207
}
208
@@ -XXX,XX +XXX,XX @@ bool bdrv_can_write_zeroes_with_unmap(BlockDriverState *bs)
209
void bdrv_get_backing_filename(BlockDriverState *bs,
210
char *filename, int filename_size)
211
{
212
+ IO_CODE();
213
pstrcpy(filename, filename_size, bs->backing_file);
214
}
215
216
@@ -XXX,XX +XXX,XX @@ int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
217
{
218
int ret;
219
BlockDriver *drv = bs->drv;
220
+ IO_CODE();
221
/* if bs->drv == NULL, bs is closed, so there's nothing to do here */
222
if (!drv) {
223
return -ENOMEDIUM;
224
@@ -XXX,XX +XXX,XX @@ ImageInfoSpecific *bdrv_get_specific_info(BlockDriverState *bs,
225
Error **errp)
226
{
227
BlockDriver *drv = bs->drv;
228
+ IO_CODE();
229
if (drv && drv->bdrv_get_specific_info) {
230
return drv->bdrv_get_specific_info(bs, errp);
231
}
232
@@ -XXX,XX +XXX,XX @@ ImageInfoSpecific *bdrv_get_specific_info(BlockDriverState *bs,
233
BlockStatsSpecific *bdrv_get_specific_stats(BlockDriverState *bs)
234
{
235
BlockDriver *drv = bs->drv;
236
+ IO_CODE();
237
if (!drv || !drv->bdrv_get_specific_stats) {
238
return NULL;
239
}
240
@@ -XXX,XX +XXX,XX @@ BlockStatsSpecific *bdrv_get_specific_stats(BlockDriverState *bs)
241
242
void bdrv_debug_event(BlockDriverState *bs, BlkdebugEvent event)
243
{
244
+ IO_CODE();
245
if (!bs || !bs->drv || !bs->drv->bdrv_debug_event) {
246
return;
247
}
248
@@ -XXX,XX +XXX,XX @@ bool bdrv_is_inserted(BlockDriverState *bs)
249
{
250
BlockDriver *drv = bs->drv;
251
BdrvChild *child;
252
+ IO_CODE();
253
254
if (!drv) {
255
return false;
256
@@ -XXX,XX +XXX,XX @@ bool bdrv_is_inserted(BlockDriverState *bs)
257
void bdrv_eject(BlockDriverState *bs, bool eject_flag)
258
{
259
BlockDriver *drv = bs->drv;
260
+ IO_CODE();
261
262
if (drv && drv->bdrv_eject) {
263
drv->bdrv_eject(bs, eject_flag);
264
@@ -XXX,XX +XXX,XX @@ void bdrv_eject(BlockDriverState *bs, bool eject_flag)
265
void bdrv_lock_medium(BlockDriverState *bs, bool locked)
266
{
267
BlockDriver *drv = bs->drv;
268
-
269
+ IO_CODE();
270
trace_bdrv_lock_medium(bs, locked);
271
272
if (drv && drv->bdrv_lock_medium) {
273
@@ -XXX,XX +XXX,XX @@ out:
274
275
AioContext *bdrv_get_aio_context(BlockDriverState *bs)
276
{
277
+ IO_CODE();
278
return bs ? bs->aio_context : qemu_get_aio_context();
279
}
280
281
@@ -XXX,XX +XXX,XX @@ AioContext *coroutine_fn bdrv_co_enter(BlockDriverState *bs)
282
Coroutine *self = qemu_coroutine_self();
283
AioContext *old_ctx = qemu_coroutine_get_aio_context(self);
284
AioContext *new_ctx;
285
+ IO_CODE();
286
287
/*
288
* Increase bs->in_flight to ensure that this operation is completed before
289
@@ -XXX,XX +XXX,XX @@ AioContext *coroutine_fn bdrv_co_enter(BlockDriverState *bs)
290
291
void coroutine_fn bdrv_co_leave(BlockDriverState *bs, AioContext *old_ctx)
292
{
293
+ IO_CODE();
294
aio_co_reschedule_self(old_ctx);
295
bdrv_dec_in_flight(bs);
296
}
297
@@ -XXX,XX +XXX,XX @@ void coroutine_fn bdrv_co_unlock(BlockDriverState *bs)
298
299
void bdrv_coroutine_enter(BlockDriverState *bs, Coroutine *co)
300
{
301
+ IO_CODE();
302
aio_co_enter(bdrv_get_aio_context(bs), co);
303
}
304
305
diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c
306
index XXXXXXX..XXXXXXX 100644
307
--- a/block/dirty-bitmap.c
308
+++ b/block/dirty-bitmap.c
309
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn bdrv_co_can_store_new_dirty_bitmap_entry(void *opaque)
310
bool bdrv_can_store_new_dirty_bitmap(BlockDriverState *bs, const char *name,
311
uint32_t granularity, Error **errp)
312
{
313
+ IO_CODE();
314
if (qemu_in_coroutine()) {
315
return bdrv_co_can_store_new_dirty_bitmap(bs, name, granularity, errp);
316
} else {
317
diff --git a/block/io.c b/block/io.c
318
index XXXXXXX..XXXXXXX 100644
319
--- a/block/io.c
320
+++ b/block/io.c
321
@@ -XXX,XX +XXX,XX @@ static void bdrv_parent_drained_end_single_no_poll(BdrvChild *c,
322
void bdrv_parent_drained_end_single(BdrvChild *c)
323
{
324
int drained_end_counter = 0;
325
+ IO_OR_GS_CODE();
326
bdrv_parent_drained_end_single_no_poll(c, &drained_end_counter);
327
BDRV_POLL_WHILE(c->bs, qatomic_read(&drained_end_counter) > 0);
328
}
329
@@ -XXX,XX +XXX,XX @@ static bool bdrv_parent_drained_poll(BlockDriverState *bs, BdrvChild *ignore,
330
331
void bdrv_parent_drained_begin_single(BdrvChild *c, bool poll)
332
{
333
+ IO_OR_GS_CODE();
334
c->parent_quiesce_counter++;
335
if (c->klass->drained_begin) {
336
c->klass->drained_begin(c);
337
@@ -XXX,XX +XXX,XX @@ void bdrv_refresh_limits(BlockDriverState *bs, Transaction *tran, Error **errp)
338
*/
339
void bdrv_enable_copy_on_read(BlockDriverState *bs)
340
{
341
+ IO_CODE();
342
qatomic_inc(&bs->copy_on_read);
343
}
344
345
void bdrv_disable_copy_on_read(BlockDriverState *bs)
346
{
347
int old = qatomic_fetch_dec(&bs->copy_on_read);
348
+ IO_CODE();
349
assert(old >= 1);
350
}
351
352
@@ -XXX,XX +XXX,XX @@ bool bdrv_drain_poll(BlockDriverState *bs, bool recursive,
353
BdrvChild *ignore_parent, bool ignore_bds_parents)
354
{
355
BdrvChild *child, *next;
356
+ IO_OR_GS_CODE();
357
358
if (bdrv_parent_drained_poll(bs, ignore_parent, ignore_bds_parents)) {
359
return true;
360
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn bdrv_co_yield_to_drain(BlockDriverState *bs,
361
void bdrv_do_drained_begin_quiesce(BlockDriverState *bs,
362
BdrvChild *parent, bool ignore_bds_parents)
363
{
364
+ IO_OR_GS_CODE();
365
assert(!qemu_in_coroutine());
366
367
/* Stop things in parent-to-child order */
368
@@ -XXX,XX +XXX,XX @@ static void bdrv_do_drained_begin(BlockDriverState *bs, bool recursive,
369
370
void bdrv_drained_begin(BlockDriverState *bs)
371
{
372
+ IO_OR_GS_CODE();
373
bdrv_do_drained_begin(bs, false, NULL, false, true);
374
}
375
376
void bdrv_subtree_drained_begin(BlockDriverState *bs)
377
{
378
+ IO_OR_GS_CODE();
379
bdrv_do_drained_begin(bs, true, NULL, false, true);
380
}
381
382
@@ -XXX,XX +XXX,XX @@ static void bdrv_do_drained_end(BlockDriverState *bs, bool recursive,
383
void bdrv_drained_end(BlockDriverState *bs)
384
{
385
int drained_end_counter = 0;
386
+ IO_OR_GS_CODE();
387
bdrv_do_drained_end(bs, false, NULL, false, &drained_end_counter);
388
BDRV_POLL_WHILE(bs, qatomic_read(&drained_end_counter) > 0);
389
}
390
391
void bdrv_drained_end_no_poll(BlockDriverState *bs, int *drained_end_counter)
392
{
393
+ IO_CODE();
394
bdrv_do_drained_end(bs, false, NULL, false, drained_end_counter);
395
}
396
397
void bdrv_subtree_drained_end(BlockDriverState *bs)
398
{
399
int drained_end_counter = 0;
400
+ IO_OR_GS_CODE();
401
bdrv_do_drained_end(bs, true, NULL, false, &drained_end_counter);
402
BDRV_POLL_WHILE(bs, qatomic_read(&drained_end_counter) > 0);
403
}
404
@@ -XXX,XX +XXX,XX @@ void bdrv_unapply_subtree_drain(BdrvChild *child, BlockDriverState *old_parent)
405
*/
406
void coroutine_fn bdrv_co_drain(BlockDriverState *bs)
407
{
408
+ IO_OR_GS_CODE();
409
assert(qemu_in_coroutine());
410
bdrv_drained_begin(bs);
411
bdrv_drained_end(bs);
412
@@ -XXX,XX +XXX,XX @@ void coroutine_fn bdrv_co_drain(BlockDriverState *bs)
413
414
void bdrv_drain(BlockDriverState *bs)
415
{
416
+ IO_OR_GS_CODE();
417
bdrv_drained_begin(bs);
418
bdrv_drained_end(bs);
419
}
420
@@ -XXX,XX +XXX,XX @@ void bdrv_round_to_clusters(BlockDriverState *bs,
421
int64_t *cluster_bytes)
422
{
423
BlockDriverInfo bdi;
424
-
425
+ IO_CODE();
426
if (bdrv_get_info(bs, &bdi) < 0 || bdi.cluster_size == 0) {
427
*cluster_offset = offset;
428
*cluster_bytes = bytes;
429
@@ -XXX,XX +XXX,XX @@ static int bdrv_check_request32(int64_t offset, int64_t bytes,
430
int bdrv_pwrite_zeroes(BdrvChild *child, int64_t offset,
431
int64_t bytes, BdrvRequestFlags flags)
432
{
433
+ IO_CODE();
434
return bdrv_pwritev(child, offset, bytes, NULL,
435
BDRV_REQ_ZERO_WRITE | flags);
436
}
437
@@ -XXX,XX +XXX,XX @@ int bdrv_make_zero(BdrvChild *child, BdrvRequestFlags flags)
438
int ret;
439
int64_t target_size, bytes, offset = 0;
440
BlockDriverState *bs = child->bs;
441
+ IO_CODE();
442
443
target_size = bdrv_getlength(bs);
444
if (target_size < 0) {
445
@@ -XXX,XX +XXX,XX @@ int bdrv_pread(BdrvChild *child, int64_t offset, void *buf, int64_t bytes)
446
{
447
int ret;
448
QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, bytes);
449
+ IO_CODE();
450
451
if (bytes < 0) {
452
return -EINVAL;
453
@@ -XXX,XX +XXX,XX @@ int bdrv_pwrite(BdrvChild *child, int64_t offset, const void *buf,
454
{
455
int ret;
456
QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, bytes);
457
+ IO_CODE();
458
459
if (bytes < 0) {
460
return -EINVAL;
461
@@ -XXX,XX +XXX,XX @@ int bdrv_pwrite_sync(BdrvChild *child, int64_t offset,
462
const void *buf, int64_t count)
463
{
464
int ret;
465
+ IO_CODE();
466
467
ret = bdrv_pwrite(child, offset, buf, count);
468
if (ret < 0) {
469
@@ -XXX,XX +XXX,XX @@ out:
470
int coroutine_fn bdrv_co_pwrite_zeroes(BdrvChild *child, int64_t offset,
471
int64_t bytes, BdrvRequestFlags flags)
472
{
473
+ IO_CODE();
474
trace_bdrv_co_pwrite_zeroes(child->bs, offset, bytes, flags);
475
476
if (!(child->bs->open_flags & BDRV_O_UNMAP)) {
477
@@ -XXX,XX +XXX,XX @@ int bdrv_block_status_above(BlockDriverState *bs, BlockDriverState *base,
478
int64_t offset, int64_t bytes, int64_t *pnum,
479
int64_t *map, BlockDriverState **file)
480
{
481
+ IO_CODE();
482
return bdrv_common_block_status_above(bs, base, false, true, offset, bytes,
483
pnum, map, file, NULL);
484
}
485
@@ -XXX,XX +XXX,XX @@ int bdrv_block_status_above(BlockDriverState *bs, BlockDriverState *base,
486
int bdrv_block_status(BlockDriverState *bs, int64_t offset, int64_t bytes,
487
int64_t *pnum, int64_t *map, BlockDriverState **file)
488
{
489
+ IO_CODE();
490
return bdrv_block_status_above(bs, bdrv_filter_or_cow_bs(bs),
491
offset, bytes, pnum, map, file);
492
}
493
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_is_zero_fast(BlockDriverState *bs, int64_t offset,
494
{
495
int ret;
496
int64_t pnum = bytes;
497
+ IO_CODE();
498
499
if (!bytes) {
500
return 1;
501
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_is_allocated(BlockDriverState *bs, int64_t offset,
502
{
503
int ret;
504
int64_t dummy;
505
+ IO_CODE();
506
507
ret = bdrv_common_block_status_above(bs, bs, true, false, offset,
508
bytes, pnum ? pnum : &dummy, NULL,
509
@@ -XXX,XX +XXX,XX @@ int bdrv_is_allocated_above(BlockDriverState *top,
510
int ret = bdrv_common_block_status_above(top, base, include_base, false,
511
offset, bytes, pnum, NULL, NULL,
512
&depth);
513
+ IO_CODE();
514
if (ret < 0) {
515
return ret;
516
}
517
@@ -XXX,XX +XXX,XX @@ int bdrv_save_vmstate(BlockDriverState *bs, const uint8_t *buf,
518
{
519
QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, size);
520
int ret = bdrv_writev_vmstate(bs, &qiov, pos);
521
+ IO_CODE();
522
523
return ret < 0 ? ret : size;
524
}
525
@@ -XXX,XX +XXX,XX @@ int bdrv_load_vmstate(BlockDriverState *bs, uint8_t *buf,
526
{
527
QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, size);
528
int ret = bdrv_readv_vmstate(bs, &qiov, pos);
529
+ IO_CODE();
530
531
return ret < 0 ? ret : size;
532
}
533
@@ -XXX,XX +XXX,XX @@ int bdrv_load_vmstate(BlockDriverState *bs, uint8_t *buf,
534
535
void bdrv_aio_cancel(BlockAIOCB *acb)
536
{
537
+ IO_CODE();
538
qemu_aio_ref(acb);
539
bdrv_aio_cancel_async(acb);
540
while (acb->refcnt > 1) {
541
@@ -XXX,XX +XXX,XX @@ void bdrv_aio_cancel(BlockAIOCB *acb)
542
* In either case the completion callback must be called. */
543
void bdrv_aio_cancel_async(BlockAIOCB *acb)
544
{
545
+ IO_CODE();
546
if (acb->aiocb_info->cancel_async) {
547
acb->aiocb_info->cancel_async(acb);
548
}
549
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_flush(BlockDriverState *bs)
550
BdrvChild *child;
551
int current_gen;
552
int ret = 0;
553
+ IO_CODE();
554
555
bdrv_inc_in_flight(bs);
556
557
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_pdiscard(BdrvChild *child, int64_t offset,
558
int64_t max_pdiscard;
559
int head, tail, align;
560
BlockDriverState *bs = child->bs;
561
+ IO_CODE();
562
563
if (!bs || !bs->drv || !bdrv_is_inserted(bs)) {
564
return -ENOMEDIUM;
565
@@ -XXX,XX +XXX,XX @@ int bdrv_co_ioctl(BlockDriverState *bs, int req, void *buf)
566
.coroutine = qemu_coroutine_self(),
567
};
568
BlockAIOCB *acb;
569
+ IO_CODE();
570
571
bdrv_inc_in_flight(bs);
572
if (!drv || (!drv->bdrv_aio_ioctl && !drv->bdrv_co_ioctl)) {
573
@@ -XXX,XX +XXX,XX @@ out:
574
575
void *qemu_blockalign(BlockDriverState *bs, size_t size)
576
{
577
+ IO_CODE();
578
return qemu_memalign(bdrv_opt_mem_align(bs), size);
579
}
580
581
void *qemu_blockalign0(BlockDriverState *bs, size_t size)
582
{
583
+ IO_CODE();
584
return memset(qemu_blockalign(bs, size), 0, size);
585
}
586
587
void *qemu_try_blockalign(BlockDriverState *bs, size_t size)
588
{
589
size_t align = bdrv_opt_mem_align(bs);
590
+ IO_CODE();
591
592
/* Ensure that NULL is never returned on success */
593
assert(align > 0);
594
@@ -XXX,XX +XXX,XX @@ void *qemu_try_blockalign(BlockDriverState *bs, size_t size)
595
void *qemu_try_blockalign0(BlockDriverState *bs, size_t size)
596
{
597
void *mem = qemu_try_blockalign(bs, size);
598
+ IO_CODE();
599
600
if (mem) {
601
memset(mem, 0, size);
602
@@ -XXX,XX +XXX,XX @@ bool bdrv_qiov_is_aligned(BlockDriverState *bs, QEMUIOVector *qiov)
603
{
604
int i;
605
size_t alignment = bdrv_min_mem_align(bs);
606
+ IO_CODE();
607
608
for (i = 0; i < qiov->niov; i++) {
609
if ((uintptr_t) qiov->iov[i].iov_base % alignment) {
610
@@ -XXX,XX +XXX,XX @@ bool bdrv_qiov_is_aligned(BlockDriverState *bs, QEMUIOVector *qiov)
611
void bdrv_io_plug(BlockDriverState *bs)
612
{
613
BdrvChild *child;
614
+ IO_CODE();
615
616
QLIST_FOREACH(child, &bs->children, next) {
617
bdrv_io_plug(child->bs);
618
@@ -XXX,XX +XXX,XX @@ void bdrv_io_plug(BlockDriverState *bs)
619
void bdrv_io_unplug(BlockDriverState *bs)
620
{
621
BdrvChild *child;
622
+ IO_CODE();
623
624
assert(bs->io_plugged);
625
if (qatomic_fetch_dec(&bs->io_plugged) == 1) {
626
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_copy_range(BdrvChild *src, int64_t src_offset,
627
int64_t bytes, BdrvRequestFlags read_flags,
628
BdrvRequestFlags write_flags)
629
{
630
+ IO_CODE();
631
return bdrv_co_copy_range_from(src, src_offset,
632
dst, dst_offset,
633
bytes, read_flags, write_flags);
634
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact,
635
BdrvTrackedRequest req;
636
int64_t old_size, new_bytes;
637
int ret;
638
-
639
+ IO_CODE();
640
641
/* if bs->drv == NULL, bs is closed, so there's nothing to do here */
642
if (!drv) {
643
--
644
2.35.1
diff view generated by jsdifflib
1
From: Andrzej Jakowski <andrzej.jakowski@linux.intel.com>
1
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
2
2
3
This patch introduces support for PMR that has been defined as part of NVMe 1.4
3
Allow writable exports to get BLK_PERM_RESIZE permission
4
spec. User can now specify a pmrdev option that should point to HostMemoryBackend.
4
from creation, in fuse_export_create().
5
pmrdev memory region will subsequently be exposed as PCI BAR 2 in emulated NVMe
5
In this way, there is no need to give the permission in
6
device. Guest OS can perform mmio read and writes to the PMR region that will stay
6
fuse_do_truncate(), which might be run in an iothread.
7
persistent across system reboot.
8
7
9
Signed-off-by: Andrzej Jakowski <andrzej.jakowski@linux.intel.com>
8
Permissions should be set only in the main thread, so
10
Reviewed-by: Klaus Jensen <k.jensen@samsung.com>
9
in any case if an iothread tries to set RESIZE, it will
11
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
10
be blocked.
12
Message-Id: <20200330164656.9348-1-andrzej.jakowski@linux.intel.com>
11
13
Reviewed-by: Keith Busch <kbusch@kernel.org>
12
Also assert in fuse_do_truncate that if we give the
13
RESIZE permission we can then restore the original ones.
14
15
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
16
Reviewed-by: Hanna Reitz <hreitz@redhat.com>
17
Message-Id: <20220303151616.325444-7-eesposit@redhat.com>
14
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
18
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
15
---
19
---
16
hw/block/nvme.h | 2 +
20
block/export/fuse.c | 25 ++++++++++++++++++-------
17
include/block/nvme.h | 172 +++++++++++++++++++++++++++++++++++++++++
21
1 file changed, 18 insertions(+), 7 deletions(-)
18
hw/block/nvme.c | 109 ++++++++++++++++++++++++++
19
hw/block/Makefile.objs | 2 +-
20
hw/block/trace-events | 4 +
21
5 files changed, 288 insertions(+), 1 deletion(-)
22
22
23
diff --git a/hw/block/nvme.h b/hw/block/nvme.h
23
diff --git a/block/export/fuse.c b/block/export/fuse.c
24
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
25
--- a/hw/block/nvme.h
25
--- a/block/export/fuse.c
26
+++ b/hw/block/nvme.h
26
+++ b/block/export/fuse.c
27
@@ -XXX,XX +XXX,XX @@ typedef struct NvmeCtrl {
27
@@ -XXX,XX +XXX,XX @@ static int fuse_export_create(BlockExport *blk_exp,
28
uint64_t timestamp_set_qemu_clock_ms; /* QEMU clock time */
28
29
29
assert(blk_exp_args->type == BLOCK_EXPORT_TYPE_FUSE);
30
char *serial;
30
31
+ HostMemoryBackend *pmrdev;
31
- /* For growable exports, take the RESIZE permission */
32
- if (args->growable) {
33
+ /* For growable and writable exports, take the RESIZE permission */
34
+ if (args->growable || blk_exp_args->writable) {
35
uint64_t blk_perm, blk_shared_perm;
36
37
blk_get_perm(exp->common.blk, &blk_perm, &blk_shared_perm);
38
@@ -XXX,XX +XXX,XX @@ static int fuse_do_truncate(const FuseExport *exp, int64_t size,
39
{
40
uint64_t blk_perm, blk_shared_perm;
41
BdrvRequestFlags truncate_flags = 0;
42
- int ret;
43
+ bool add_resize_perm;
44
+ int ret, ret_check;
32
+
45
+
33
NvmeNamespace *namespaces;
46
+ /* Growable and writable exports have a permanent RESIZE permission */
34
NvmeSQueue **sq;
47
+ add_resize_perm = !exp->growable && !exp->writable;
35
NvmeCQueue **cq;
48
36
diff --git a/include/block/nvme.h b/include/block/nvme.h
49
if (req_zero_write) {
37
index XXXXXXX..XXXXXXX 100644
50
truncate_flags |= BDRV_REQ_ZERO_WRITE;
38
--- a/include/block/nvme.h
51
}
39
+++ b/include/block/nvme.h
52
40
@@ -XXX,XX +XXX,XX @@ typedef struct NvmeBar {
53
- /* Growable exports have a permanent RESIZE permission */
41
uint64_t acq;
54
- if (!exp->growable) {
42
uint32_t cmbloc;
55
+ if (add_resize_perm) {
43
uint32_t cmbsz;
44
+ uint8_t padding[3520]; /* not used by QEMU */
45
+ uint32_t pmrcap;
46
+ uint32_t pmrctl;
47
+ uint32_t pmrsts;
48
+ uint32_t pmrebs;
49
+ uint32_t pmrswtp;
50
+ uint32_t pmrmsc;
51
} NvmeBar;
52
53
enum NvmeCapShift {
54
@@ -XXX,XX +XXX,XX @@ enum NvmeCapShift {
55
CAP_CSS_SHIFT = 37,
56
CAP_MPSMIN_SHIFT = 48,
57
CAP_MPSMAX_SHIFT = 52,
58
+ CAP_PMR_SHIFT = 56,
59
};
60
61
enum NvmeCapMask {
62
@@ -XXX,XX +XXX,XX @@ enum NvmeCapMask {
63
CAP_CSS_MASK = 0xff,
64
CAP_MPSMIN_MASK = 0xf,
65
CAP_MPSMAX_MASK = 0xf,
66
+ CAP_PMR_MASK = 0x1,
67
};
68
69
#define NVME_CAP_MQES(cap) (((cap) >> CAP_MQES_SHIFT) & CAP_MQES_MASK)
70
@@ -XXX,XX +XXX,XX @@ enum NvmeCapMask {
71
<< CAP_MPSMIN_SHIFT)
72
#define NVME_CAP_SET_MPSMAX(cap, val) (cap |= (uint64_t)(val & CAP_MPSMAX_MASK)\
73
<< CAP_MPSMAX_SHIFT)
74
+#define NVME_CAP_SET_PMRS(cap, val) (cap |= (uint64_t)(val & CAP_PMR_MASK)\
75
+ << CAP_PMR_SHIFT)
76
77
enum NvmeCcShift {
78
CC_EN_SHIFT = 0,
79
@@ -XXX,XX +XXX,XX @@ enum NvmeCmbszMask {
80
#define NVME_CMBSZ_GETSIZE(cmbsz) \
81
(NVME_CMBSZ_SZ(cmbsz) * (1 << (12 + 4 * NVME_CMBSZ_SZU(cmbsz))))
82
83
+enum NvmePmrcapShift {
84
+ PMRCAP_RDS_SHIFT = 3,
85
+ PMRCAP_WDS_SHIFT = 4,
86
+ PMRCAP_BIR_SHIFT = 5,
87
+ PMRCAP_PMRTU_SHIFT = 8,
88
+ PMRCAP_PMRWBM_SHIFT = 10,
89
+ PMRCAP_PMRTO_SHIFT = 16,
90
+ PMRCAP_CMSS_SHIFT = 24,
91
+};
92
+
56
+
93
+enum NvmePmrcapMask {
57
+ if (!qemu_in_main_thread()) {
94
+ PMRCAP_RDS_MASK = 0x1,
58
+ /* Changing permissions like below only works in the main thread */
95
+ PMRCAP_WDS_MASK = 0x1,
59
+ return -EPERM;
96
+ PMRCAP_BIR_MASK = 0x7,
97
+ PMRCAP_PMRTU_MASK = 0x3,
98
+ PMRCAP_PMRWBM_MASK = 0xf,
99
+ PMRCAP_PMRTO_MASK = 0xff,
100
+ PMRCAP_CMSS_MASK = 0x1,
101
+};
102
+
103
+#define NVME_PMRCAP_RDS(pmrcap) \
104
+ ((pmrcap >> PMRCAP_RDS_SHIFT) & PMRCAP_RDS_MASK)
105
+#define NVME_PMRCAP_WDS(pmrcap) \
106
+ ((pmrcap >> PMRCAP_WDS_SHIFT) & PMRCAP_WDS_MASK)
107
+#define NVME_PMRCAP_BIR(pmrcap) \
108
+ ((pmrcap >> PMRCAP_BIR_SHIFT) & PMRCAP_BIR_MASK)
109
+#define NVME_PMRCAP_PMRTU(pmrcap) \
110
+ ((pmrcap >> PMRCAP_PMRTU_SHIFT) & PMRCAP_PMRTU_MASK)
111
+#define NVME_PMRCAP_PMRWBM(pmrcap) \
112
+ ((pmrcap >> PMRCAP_PMRWBM_SHIFT) & PMRCAP_PMRWBM_MASK)
113
+#define NVME_PMRCAP_PMRTO(pmrcap) \
114
+ ((pmrcap >> PMRCAP_PMRTO_SHIFT) & PMRCAP_PMRTO_MASK)
115
+#define NVME_PMRCAP_CMSS(pmrcap) \
116
+ ((pmrcap >> PMRCAP_CMSS_SHIFT) & PMRCAP_CMSS_MASK)
117
+
118
+#define NVME_PMRCAP_SET_RDS(pmrcap, val) \
119
+ (pmrcap |= (uint64_t)(val & PMRCAP_RDS_MASK) << PMRCAP_RDS_SHIFT)
120
+#define NVME_PMRCAP_SET_WDS(pmrcap, val) \
121
+ (pmrcap |= (uint64_t)(val & PMRCAP_WDS_MASK) << PMRCAP_WDS_SHIFT)
122
+#define NVME_PMRCAP_SET_BIR(pmrcap, val) \
123
+ (pmrcap |= (uint64_t)(val & PMRCAP_BIR_MASK) << PMRCAP_BIR_SHIFT)
124
+#define NVME_PMRCAP_SET_PMRTU(pmrcap, val) \
125
+ (pmrcap |= (uint64_t)(val & PMRCAP_PMRTU_MASK) << PMRCAP_PMRTU_SHIFT)
126
+#define NVME_PMRCAP_SET_PMRWBM(pmrcap, val) \
127
+ (pmrcap |= (uint64_t)(val & PMRCAP_PMRWBM_MASK) << PMRCAP_PMRWBM_SHIFT)
128
+#define NVME_PMRCAP_SET_PMRTO(pmrcap, val) \
129
+ (pmrcap |= (uint64_t)(val & PMRCAP_PMRTO_MASK) << PMRCAP_PMRTO_SHIFT)
130
+#define NVME_PMRCAP_SET_CMSS(pmrcap, val) \
131
+ (pmrcap |= (uint64_t)(val & PMRCAP_CMSS_MASK) << PMRCAP_CMSS_SHIFT)
132
+
133
+enum NvmePmrctlShift {
134
+ PMRCTL_EN_SHIFT = 0,
135
+};
136
+
137
+enum NvmePmrctlMask {
138
+ PMRCTL_EN_MASK = 0x1,
139
+};
140
+
141
+#define NVME_PMRCTL_EN(pmrctl) ((pmrctl >> PMRCTL_EN_SHIFT) & PMRCTL_EN_MASK)
142
+
143
+#define NVME_PMRCTL_SET_EN(pmrctl, val) \
144
+ (pmrctl |= (uint64_t)(val & PMRCTL_EN_MASK) << PMRCTL_EN_SHIFT)
145
+
146
+enum NvmePmrstsShift {
147
+ PMRSTS_ERR_SHIFT = 0,
148
+ PMRSTS_NRDY_SHIFT = 8,
149
+ PMRSTS_HSTS_SHIFT = 9,
150
+ PMRSTS_CBAI_SHIFT = 12,
151
+};
152
+
153
+enum NvmePmrstsMask {
154
+ PMRSTS_ERR_MASK = 0xff,
155
+ PMRSTS_NRDY_MASK = 0x1,
156
+ PMRSTS_HSTS_MASK = 0x7,
157
+ PMRSTS_CBAI_MASK = 0x1,
158
+};
159
+
160
+#define NVME_PMRSTS_ERR(pmrsts) \
161
+ ((pmrsts >> PMRSTS_ERR_SHIFT) & PMRSTS_ERR_MASK)
162
+#define NVME_PMRSTS_NRDY(pmrsts) \
163
+ ((pmrsts >> PMRSTS_NRDY_SHIFT) & PMRSTS_NRDY_MASK)
164
+#define NVME_PMRSTS_HSTS(pmrsts) \
165
+ ((pmrsts >> PMRSTS_HSTS_SHIFT) & PMRSTS_HSTS_MASK)
166
+#define NVME_PMRSTS_CBAI(pmrsts) \
167
+ ((pmrsts >> PMRSTS_CBAI_SHIFT) & PMRSTS_CBAI_MASK)
168
+
169
+#define NVME_PMRSTS_SET_ERR(pmrsts, val) \
170
+ (pmrsts |= (uint64_t)(val & PMRSTS_ERR_MASK) << PMRSTS_ERR_SHIFT)
171
+#define NVME_PMRSTS_SET_NRDY(pmrsts, val) \
172
+ (pmrsts |= (uint64_t)(val & PMRSTS_NRDY_MASK) << PMRSTS_NRDY_SHIFT)
173
+#define NVME_PMRSTS_SET_HSTS(pmrsts, val) \
174
+ (pmrsts |= (uint64_t)(val & PMRSTS_HSTS_MASK) << PMRSTS_HSTS_SHIFT)
175
+#define NVME_PMRSTS_SET_CBAI(pmrsts, val) \
176
+ (pmrsts |= (uint64_t)(val & PMRSTS_CBAI_MASK) << PMRSTS_CBAI_SHIFT)
177
+
178
+enum NvmePmrebsShift {
179
+ PMREBS_PMRSZU_SHIFT = 0,
180
+ PMREBS_RBB_SHIFT = 4,
181
+ PMREBS_PMRWBZ_SHIFT = 8,
182
+};
183
+
184
+enum NvmePmrebsMask {
185
+ PMREBS_PMRSZU_MASK = 0xf,
186
+ PMREBS_RBB_MASK = 0x1,
187
+ PMREBS_PMRWBZ_MASK = 0xffffff,
188
+};
189
+
190
+#define NVME_PMREBS_PMRSZU(pmrebs) \
191
+ ((pmrebs >> PMREBS_PMRSZU_SHIFT) & PMREBS_PMRSZU_MASK)
192
+#define NVME_PMREBS_RBB(pmrebs) \
193
+ ((pmrebs >> PMREBS_RBB_SHIFT) & PMREBS_RBB_MASK)
194
+#define NVME_PMREBS_PMRWBZ(pmrebs) \
195
+ ((pmrebs >> PMREBS_PMRWBZ_SHIFT) & PMREBS_PMRWBZ_MASK)
196
+
197
+#define NVME_PMREBS_SET_PMRSZU(pmrebs, val) \
198
+ (pmrebs |= (uint64_t)(val & PMREBS_PMRSZU_MASK) << PMREBS_PMRSZU_SHIFT)
199
+#define NVME_PMREBS_SET_RBB(pmrebs, val) \
200
+ (pmrebs |= (uint64_t)(val & PMREBS_RBB_MASK) << PMREBS_RBB_SHIFT)
201
+#define NVME_PMREBS_SET_PMRWBZ(pmrebs, val) \
202
+ (pmrebs |= (uint64_t)(val & PMREBS_PMRWBZ_MASK) << PMREBS_PMRWBZ_SHIFT)
203
+
204
+enum NvmePmrswtpShift {
205
+ PMRSWTP_PMRSWTU_SHIFT = 0,
206
+ PMRSWTP_PMRSWTV_SHIFT = 8,
207
+};
208
+
209
+enum NvmePmrswtpMask {
210
+ PMRSWTP_PMRSWTU_MASK = 0xf,
211
+ PMRSWTP_PMRSWTV_MASK = 0xffffff,
212
+};
213
+
214
+#define NVME_PMRSWTP_PMRSWTU(pmrswtp) \
215
+ ((pmrswtp >> PMRSWTP_PMRSWTU_SHIFT) & PMRSWTP_PMRSWTU_MASK)
216
+#define NVME_PMRSWTP_PMRSWTV(pmrswtp) \
217
+ ((pmrswtp >> PMRSWTP_PMRSWTV_SHIFT) & PMRSWTP_PMRSWTV_MASK)
218
+
219
+#define NVME_PMRSWTP_SET_PMRSWTU(pmrswtp, val) \
220
+ (pmrswtp |= (uint64_t)(val & PMRSWTP_PMRSWTU_MASK) << PMRSWTP_PMRSWTU_SHIFT)
221
+#define NVME_PMRSWTP_SET_PMRSWTV(pmrswtp, val) \
222
+ (pmrswtp |= (uint64_t)(val & PMRSWTP_PMRSWTV_MASK) << PMRSWTP_PMRSWTV_SHIFT)
223
+
224
+enum NvmePmrmscShift {
225
+ PMRMSC_CMSE_SHIFT = 1,
226
+ PMRMSC_CBA_SHIFT = 12,
227
+};
228
+
229
+enum NvmePmrmscMask {
230
+ PMRMSC_CMSE_MASK = 0x1,
231
+ PMRMSC_CBA_MASK = 0xfffffffffffff,
232
+};
233
+
234
+#define NVME_PMRMSC_CMSE(pmrmsc) \
235
+ ((pmrmsc >> PMRMSC_CMSE_SHIFT) & PMRMSC_CMSE_MASK)
236
+#define NVME_PMRMSC_CBA(pmrmsc) \
237
+ ((pmrmsc >> PMRMSC_CBA_SHIFT) & PMRMSC_CBA_MASK)
238
+
239
+#define NVME_PMRMSC_SET_CMSE(pmrmsc, val) \
240
+ (pmrmsc |= (uint64_t)(val & PMRMSC_CMSE_MASK) << PMRMSC_CMSE_SHIFT)
241
+#define NVME_PMRMSC_SET_CBA(pmrmsc, val) \
242
+ (pmrmsc |= (uint64_t)(val & PMRMSC_CBA_MASK) << PMRMSC_CBA_SHIFT)
243
+
244
typedef struct NvmeCmd {
245
uint8_t opcode;
246
uint8_t fuse;
247
diff --git a/hw/block/nvme.c b/hw/block/nvme.c
248
index XXXXXXX..XXXXXXX 100644
249
--- a/hw/block/nvme.c
250
+++ b/hw/block/nvme.c
251
@@ -XXX,XX +XXX,XX @@
252
* -drive file=<file>,if=none,id=<drive_id>
253
* -device nvme,drive=<drive_id>,serial=<serial>,id=<id[optional]>, \
254
* cmb_size_mb=<cmb_size_mb[optional]>, \
255
+ * [pmrdev=<mem_backend_file_id>,] \
256
* num_queues=<N[optional]>
257
*
258
* Note cmb_size_mb denotes size of CMB in MB. CMB is assumed to be at
259
* offset 0 in BAR2 and supports only WDS, RDS and SQS for now.
260
+ *
261
+ * cmb_size_mb= and pmrdev= options are mutually exclusive due to limitation
262
+ * in available BAR's. cmb_size_mb= will take precedence over pmrdev= when
263
+ * both provided.
264
+ * Enabling pmr emulation can be achieved by pointing to memory-backend-file.
265
+ * For example:
266
+ * -object memory-backend-file,id=<mem_id>,share=on,mem-path=<file_path>, \
267
+ * size=<size> .... -device nvme,...,pmrdev=<mem_id>
268
*/
269
270
#include "qemu/osdep.h"
271
@@ -XXX,XX +XXX,XX @@
272
#include "sysemu/sysemu.h"
273
#include "qapi/error.h"
274
#include "qapi/visitor.h"
275
+#include "sysemu/hostmem.h"
276
#include "sysemu/block-backend.h"
277
+#include "exec/ram_addr.h"
278
279
#include "qemu/log.h"
280
#include "qemu/module.h"
281
@@ -XXX,XX +XXX,XX @@ static void nvme_write_bar(NvmeCtrl *n, hwaddr offset, uint64_t data,
282
NVME_GUEST_ERR(nvme_ub_mmiowr_cmbsz_readonly,
283
"invalid write to read only CMBSZ, ignored");
284
return;
285
+ case 0xE00: /* PMRCAP */
286
+ NVME_GUEST_ERR(nvme_ub_mmiowr_pmrcap_readonly,
287
+ "invalid write to PMRCAP register, ignored");
288
+ return;
289
+ case 0xE04: /* TODO PMRCTL */
290
+ break;
291
+ case 0xE08: /* PMRSTS */
292
+ NVME_GUEST_ERR(nvme_ub_mmiowr_pmrsts_readonly,
293
+ "invalid write to PMRSTS register, ignored");
294
+ return;
295
+ case 0xE0C: /* PMREBS */
296
+ NVME_GUEST_ERR(nvme_ub_mmiowr_pmrebs_readonly,
297
+ "invalid write to PMREBS register, ignored");
298
+ return;
299
+ case 0xE10: /* PMRSWTP */
300
+ NVME_GUEST_ERR(nvme_ub_mmiowr_pmrswtp_readonly,
301
+ "invalid write to PMRSWTP register, ignored");
302
+ return;
303
+ case 0xE14: /* TODO PMRMSC */
304
+ break;
305
default:
306
NVME_GUEST_ERR(nvme_ub_mmiowr_invalid,
307
"invalid MMIO write,"
308
@@ -XXX,XX +XXX,XX @@ static uint64_t nvme_mmio_read(void *opaque, hwaddr addr, unsigned size)
309
}
310
311
if (addr < sizeof(n->bar)) {
312
+ /*
313
+ * When PMRWBM bit 1 is set then read from
314
+ * from PMRSTS should ensure prior writes
315
+ * made it to persistent media
316
+ */
317
+ if (addr == 0xE08 &&
318
+ (NVME_PMRCAP_PMRWBM(n->bar.pmrcap) & 0x02)) {
319
+ qemu_ram_writeback(n->pmrdev->mr.ram_block,
320
+ 0, n->pmrdev->size);
321
+ }
322
memcpy(&val, ptr + addr, size);
323
} else {
324
NVME_GUEST_ERR(nvme_ub_mmiord_invalid_ofs,
325
@@ -XXX,XX +XXX,XX @@ static void nvme_realize(PCIDevice *pci_dev, Error **errp)
326
error_setg(errp, "serial property not set");
327
return;
328
}
329
+
330
+ if (!n->cmb_size_mb && n->pmrdev) {
331
+ if (host_memory_backend_is_mapped(n->pmrdev)) {
332
+ char *path = object_get_canonical_path_component(OBJECT(n->pmrdev));
333
+ error_setg(errp, "can't use already busy memdev: %s", path);
334
+ g_free(path);
335
+ return;
336
+ }
60
+ }
337
+
61
+
338
+ if (!is_power_of_2(n->pmrdev->size)) {
62
blk_get_perm(exp->common.blk, &blk_perm, &blk_shared_perm);
339
+ error_setg(errp, "pmr backend size needs to be power of 2 in size");
63
340
+ return;
64
ret = blk_set_perm(exp->common.blk, blk_perm | BLK_PERM_RESIZE,
341
+ }
65
@@ -XXX,XX +XXX,XX @@ static int fuse_do_truncate(const FuseExport *exp, int64_t size,
342
+
66
ret = blk_truncate(exp->common.blk, size, true, prealloc,
343
+ host_memory_backend_set_mapped(n->pmrdev, true);
67
truncate_flags, NULL);
344
+ }
68
345
+
69
- if (!exp->growable) {
346
blkconf_blocksizes(&n->conf);
70
+ if (add_resize_perm) {
347
if (!blkconf_apply_backend_options(&n->conf, blk_is_read_only(n->conf.blk),
71
/* Must succeed, because we are only giving up the RESIZE permission */
348
false, errp)) {
72
- blk_set_perm(exp->common.blk, blk_perm, blk_shared_perm, &error_abort);
349
@@ -XXX,XX +XXX,XX @@ static void nvme_realize(PCIDevice *pci_dev, Error **errp)
73
+ ret_check = blk_set_perm(exp->common.blk, blk_perm,
350
PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_TYPE_64 |
74
+ blk_shared_perm, &error_abort);
351
PCI_BASE_ADDRESS_MEM_PREFETCH, &n->ctrl_mem);
75
+ assert(ret_check == 0);
352
353
+ } else if (n->pmrdev) {
354
+ /* Controller Capabilities register */
355
+ NVME_CAP_SET_PMRS(n->bar.cap, 1);
356
+
357
+ /* PMR Capabities register */
358
+ n->bar.pmrcap = 0;
359
+ NVME_PMRCAP_SET_RDS(n->bar.pmrcap, 0);
360
+ NVME_PMRCAP_SET_WDS(n->bar.pmrcap, 0);
361
+ NVME_PMRCAP_SET_BIR(n->bar.pmrcap, 2);
362
+ NVME_PMRCAP_SET_PMRTU(n->bar.pmrcap, 0);
363
+ /* Turn on bit 1 support */
364
+ NVME_PMRCAP_SET_PMRWBM(n->bar.pmrcap, 0x02);
365
+ NVME_PMRCAP_SET_PMRTO(n->bar.pmrcap, 0);
366
+ NVME_PMRCAP_SET_CMSS(n->bar.pmrcap, 0);
367
+
368
+ /* PMR Control register */
369
+ n->bar.pmrctl = 0;
370
+ NVME_PMRCTL_SET_EN(n->bar.pmrctl, 0);
371
+
372
+ /* PMR Status register */
373
+ n->bar.pmrsts = 0;
374
+ NVME_PMRSTS_SET_ERR(n->bar.pmrsts, 0);
375
+ NVME_PMRSTS_SET_NRDY(n->bar.pmrsts, 0);
376
+ NVME_PMRSTS_SET_HSTS(n->bar.pmrsts, 0);
377
+ NVME_PMRSTS_SET_CBAI(n->bar.pmrsts, 0);
378
+
379
+ /* PMR Elasticity Buffer Size register */
380
+ n->bar.pmrebs = 0;
381
+ NVME_PMREBS_SET_PMRSZU(n->bar.pmrebs, 0);
382
+ NVME_PMREBS_SET_RBB(n->bar.pmrebs, 0);
383
+ NVME_PMREBS_SET_PMRWBZ(n->bar.pmrebs, 0);
384
+
385
+ /* PMR Sustained Write Throughput register */
386
+ n->bar.pmrswtp = 0;
387
+ NVME_PMRSWTP_SET_PMRSWTU(n->bar.pmrswtp, 0);
388
+ NVME_PMRSWTP_SET_PMRSWTV(n->bar.pmrswtp, 0);
389
+
390
+ /* PMR Memory Space Control register */
391
+ n->bar.pmrmsc = 0;
392
+ NVME_PMRMSC_SET_CMSE(n->bar.pmrmsc, 0);
393
+ NVME_PMRMSC_SET_CBA(n->bar.pmrmsc, 0);
394
+
395
+ pci_register_bar(pci_dev, NVME_PMRCAP_BIR(n->bar.pmrcap),
396
+ PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_TYPE_64 |
397
+ PCI_BASE_ADDRESS_MEM_PREFETCH, &n->pmrdev->mr);
398
}
76
}
399
77
400
for (i = 0; i < n->num_namespaces; i++) {
78
return ret;
401
@@ -XXX,XX +XXX,XX @@ static void nvme_exit(PCIDevice *pci_dev)
402
if (n->cmb_size_mb) {
403
g_free(n->cmbuf);
404
}
405
+
406
+ if (n->pmrdev) {
407
+ host_memory_backend_set_mapped(n->pmrdev, false);
408
+ }
409
msix_uninit_exclusive_bar(pci_dev);
410
}
411
412
static Property nvme_props[] = {
413
DEFINE_BLOCK_PROPERTIES(NvmeCtrl, conf),
414
+ DEFINE_PROP_LINK("pmrdev", NvmeCtrl, pmrdev, TYPE_MEMORY_BACKEND,
415
+ HostMemoryBackend *),
416
DEFINE_PROP_STRING("serial", NvmeCtrl, serial),
417
DEFINE_PROP_UINT32("cmb_size_mb", NvmeCtrl, cmb_size_mb, 0),
418
DEFINE_PROP_UINT32("num_queues", NvmeCtrl, num_queues, 64),
419
diff --git a/hw/block/Makefile.objs b/hw/block/Makefile.objs
420
index XXXXXXX..XXXXXXX 100644
421
--- a/hw/block/Makefile.objs
422
+++ b/hw/block/Makefile.objs
423
@@ -XXX,XX +XXX,XX @@ common-obj-$(CONFIG_PFLASH_CFI02) += pflash_cfi02.o
424
common-obj-$(CONFIG_XEN) += xen-block.o
425
common-obj-$(CONFIG_ECC) += ecc.o
426
common-obj-$(CONFIG_ONENAND) += onenand.o
427
-common-obj-$(CONFIG_NVME_PCI) += nvme.o
428
common-obj-$(CONFIG_SWIM) += swim.o
429
430
common-obj-$(CONFIG_SH4) += tc58128.o
431
432
obj-$(CONFIG_VIRTIO_BLK) += virtio-blk.o
433
obj-$(CONFIG_VHOST_USER_BLK) += vhost-user-blk.o
434
+obj-$(CONFIG_NVME_PCI) += nvme.o
435
436
obj-y += dataplane/
437
diff --git a/hw/block/trace-events b/hw/block/trace-events
438
index XXXXXXX..XXXXXXX 100644
439
--- a/hw/block/trace-events
440
+++ b/hw/block/trace-events
441
@@ -XXX,XX +XXX,XX @@ nvme_ub_mmiowr_ssreset_w1c_unsupported(void) "attempted to W1C CSTS.NSSRO but CA
442
nvme_ub_mmiowr_ssreset_unsupported(void) "attempted NVM subsystem reset but CAP.NSSRS is zero (not supported)"
443
nvme_ub_mmiowr_cmbloc_reserved(void) "invalid write to reserved CMBLOC when CMBSZ is zero, ignored"
444
nvme_ub_mmiowr_cmbsz_readonly(void) "invalid write to read only CMBSZ, ignored"
445
+nvme_ub_mmiowr_pmrcap_readonly(void) "invalid write to read only PMRCAP, ignored"
446
+nvme_ub_mmiowr_pmrsts_readonly(void) "invalid write to read only PMRSTS, ignored"
447
+nvme_ub_mmiowr_pmrebs_readonly(void) "invalid write to read only PMREBS, ignored"
448
+nvme_ub_mmiowr_pmrswtp_readonly(void) "invalid write to read only PMRSWTP, ignored"
449
nvme_ub_mmiowr_invalid(uint64_t offset, uint64_t data) "invalid MMIO write, offset=0x%"PRIx64", data=0x%"PRIx64""
450
nvme_ub_mmiord_misaligned32(uint64_t offset) "MMIO read not 32-bit aligned, offset=0x%"PRIx64""
451
nvme_ub_mmiord_toosmall(uint64_t offset) "MMIO read smaller than 32-bits, offset=0x%"PRIx64""
452
--
79
--
453
2.25.3
80
2.35.1
454
455
diff view generated by jsdifflib
New patch
1
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
1
2
3
Similarly to the previous patches, split block-backend.h
4
in block-backend-io.h and block-backend-global-state.h
5
6
In addition, remove "block/block.h" include as it seems
7
it is not necessary anymore, together with "qemu/iov.h"
8
9
block-backend-common.h contains the structures shared between
10
the two headers, and the functions that can't be categorized as
11
I/O or global state.
12
13
Assertions are added in the next patch.
14
15
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
16
Message-Id: <20220303151616.325444-8-eesposit@redhat.com>
17
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
18
---
19
include/sysemu/block-backend-common.h | 84 ++++++
20
include/sysemu/block-backend-global-state.h | 116 +++++++++
21
include/sysemu/block-backend-io.h | 159 ++++++++++++
22
include/sysemu/block-backend.h | 269 +-------------------
23
block/block-backend.c | 9 +-
24
5 files changed, 368 insertions(+), 269 deletions(-)
25
create mode 100644 include/sysemu/block-backend-common.h
26
create mode 100644 include/sysemu/block-backend-global-state.h
27
create mode 100644 include/sysemu/block-backend-io.h
28
29
diff --git a/include/sysemu/block-backend-common.h b/include/sysemu/block-backend-common.h
30
new file mode 100644
31
index XXXXXXX..XXXXXXX
32
--- /dev/null
33
+++ b/include/sysemu/block-backend-common.h
34
@@ -XXX,XX +XXX,XX @@
35
+/*
36
+ * QEMU Block backends
37
+ *
38
+ * Copyright (C) 2014-2016 Red Hat, Inc.
39
+ *
40
+ * Authors:
41
+ * Markus Armbruster <armbru@redhat.com>,
42
+ *
43
+ * This work is licensed under the terms of the GNU LGPL, version 2.1
44
+ * or later. See the COPYING.LIB file in the top-level directory.
45
+ */
46
+
47
+#ifndef BLOCK_BACKEND_COMMON_H
48
+#define BLOCK_BACKEND_COMMON_H
49
+
50
+#include "qemu/iov.h"
51
+#include "block/throttle-groups.h"
52
+
53
+/*
54
+ * TODO Have to include block/block.h for a bunch of block layer
55
+ * types. Unfortunately, this pulls in the whole BlockDriverState
56
+ * API, which we don't want used by many BlockBackend users. Some of
57
+ * the types belong here, and the rest should be split into a common
58
+ * header and one for the BlockDriverState API.
59
+ */
60
+#include "block/block.h"
61
+
62
+/* Callbacks for block device models */
63
+typedef struct BlockDevOps {
64
+ /*
65
+ * Runs when virtual media changed (monitor commands eject, change)
66
+ * Argument load is true on load and false on eject.
67
+ * Beware: doesn't run when a host device's physical media
68
+ * changes. Sure would be useful if it did.
69
+ * Device models with removable media must implement this callback.
70
+ */
71
+ void (*change_media_cb)(void *opaque, bool load, Error **errp);
72
+ /*
73
+ * Runs when an eject request is issued from the monitor, the tray
74
+ * is closed, and the medium is locked.
75
+ * Device models that do not implement is_medium_locked will not need
76
+ * this callback. Device models that can lock the medium or tray might
77
+ * want to implement the callback and unlock the tray when "force" is
78
+ * true, even if they do not support eject requests.
79
+ */
80
+ void (*eject_request_cb)(void *opaque, bool force);
81
+ /*
82
+ * Is the virtual tray open?
83
+ * Device models implement this only when the device has a tray.
84
+ */
85
+ bool (*is_tray_open)(void *opaque);
86
+ /*
87
+ * Is the virtual medium locked into the device?
88
+ * Device models implement this only when device has such a lock.
89
+ */
90
+ bool (*is_medium_locked)(void *opaque);
91
+ /*
92
+ * Runs when the size changed (e.g. monitor command block_resize)
93
+ */
94
+ void (*resize_cb)(void *opaque);
95
+ /*
96
+ * Runs when the backend receives a drain request.
97
+ */
98
+ void (*drained_begin)(void *opaque);
99
+ /*
100
+ * Runs when the backend's last drain request ends.
101
+ */
102
+ void (*drained_end)(void *opaque);
103
+ /*
104
+ * Is the device still busy?
105
+ */
106
+ bool (*drained_poll)(void *opaque);
107
+} BlockDevOps;
108
+
109
+/*
110
+ * This struct is embedded in (the private) BlockBackend struct and contains
111
+ * fields that must be public. This is in particular for QLIST_ENTRY() and
112
+ * friends so that BlockBackends can be kept in lists outside block-backend.c
113
+ */
114
+typedef struct BlockBackendPublic {
115
+ ThrottleGroupMember throttle_group_member;
116
+} BlockBackendPublic;
117
+
118
+#endif /* BLOCK_BACKEND_COMMON_H */
119
diff --git a/include/sysemu/block-backend-global-state.h b/include/sysemu/block-backend-global-state.h
120
new file mode 100644
121
index XXXXXXX..XXXXXXX
122
--- /dev/null
123
+++ b/include/sysemu/block-backend-global-state.h
124
@@ -XXX,XX +XXX,XX @@
125
+/*
126
+ * QEMU Block backends
127
+ *
128
+ * Copyright (C) 2014-2016 Red Hat, Inc.
129
+ *
130
+ * Authors:
131
+ * Markus Armbruster <armbru@redhat.com>,
132
+ *
133
+ * This work is licensed under the terms of the GNU LGPL, version 2.1
134
+ * or later. See the COPYING.LIB file in the top-level directory.
135
+ */
136
+
137
+#ifndef BLOCK_BACKEND_GS_H
138
+#define BLOCK_BACKEND_GS_H
139
+
140
+#include "block-backend-common.h"
141
+
142
+/*
143
+ * Global state (GS) API. These functions run under the BQL.
144
+ *
145
+ * See include/block/block-global-state.h for more information about
146
+ * the GS API.
147
+ */
148
+
149
+BlockBackend *blk_new(AioContext *ctx, uint64_t perm, uint64_t shared_perm);
150
+BlockBackend *blk_new_with_bs(BlockDriverState *bs, uint64_t perm,
151
+ uint64_t shared_perm, Error **errp);
152
+BlockBackend *blk_new_open(const char *filename, const char *reference,
153
+ QDict *options, int flags, Error **errp);
154
+int blk_get_refcnt(BlockBackend *blk);
155
+void blk_ref(BlockBackend *blk);
156
+void blk_unref(BlockBackend *blk);
157
+void blk_remove_all_bs(void);
158
+BlockBackend *blk_by_name(const char *name);
159
+BlockBackend *blk_next(BlockBackend *blk);
160
+BlockBackend *blk_all_next(BlockBackend *blk);
161
+bool monitor_add_blk(BlockBackend *blk, const char *name, Error **errp);
162
+void monitor_remove_blk(BlockBackend *blk);
163
+
164
+BlockBackendPublic *blk_get_public(BlockBackend *blk);
165
+BlockBackend *blk_by_public(BlockBackendPublic *public);
166
+
167
+void blk_remove_bs(BlockBackend *blk);
168
+int blk_insert_bs(BlockBackend *blk, BlockDriverState *bs, Error **errp);
169
+int blk_replace_bs(BlockBackend *blk, BlockDriverState *new_bs, Error **errp);
170
+bool bdrv_has_blk(BlockDriverState *bs);
171
+bool bdrv_is_root_node(BlockDriverState *bs);
172
+int blk_set_perm(BlockBackend *blk, uint64_t perm, uint64_t shared_perm,
173
+ Error **errp);
174
+void blk_get_perm(BlockBackend *blk, uint64_t *perm, uint64_t *shared_perm);
175
+
176
+void blk_iostatus_enable(BlockBackend *blk);
177
+BlockDeviceIoStatus blk_iostatus(const BlockBackend *blk);
178
+void blk_iostatus_disable(BlockBackend *blk);
179
+void blk_iostatus_reset(BlockBackend *blk);
180
+int blk_attach_dev(BlockBackend *blk, DeviceState *dev);
181
+void blk_detach_dev(BlockBackend *blk, DeviceState *dev);
182
+DeviceState *blk_get_attached_dev(BlockBackend *blk);
183
+BlockBackend *blk_by_dev(void *dev);
184
+BlockBackend *blk_by_qdev_id(const char *id, Error **errp);
185
+void blk_set_dev_ops(BlockBackend *blk, const BlockDevOps *ops, void *opaque);
186
+
187
+void blk_activate(BlockBackend *blk, Error **errp);
188
+
189
+int blk_make_zero(BlockBackend *blk, BdrvRequestFlags flags);
190
+void blk_aio_cancel(BlockAIOCB *acb);
191
+int blk_commit_all(void);
192
+void blk_drain(BlockBackend *blk);
193
+void blk_drain_all(void);
194
+void blk_set_on_error(BlockBackend *blk, BlockdevOnError on_read_error,
195
+ BlockdevOnError on_write_error);
196
+bool blk_supports_write_perm(BlockBackend *blk);
197
+bool blk_is_sg(BlockBackend *blk);
198
+void blk_set_enable_write_cache(BlockBackend *blk, bool wce);
199
+int blk_get_flags(BlockBackend *blk);
200
+bool blk_op_is_blocked(BlockBackend *blk, BlockOpType op, Error **errp);
201
+void blk_op_unblock(BlockBackend *blk, BlockOpType op, Error *reason);
202
+void blk_op_block_all(BlockBackend *blk, Error *reason);
203
+void blk_op_unblock_all(BlockBackend *blk, Error *reason);
204
+int blk_set_aio_context(BlockBackend *blk, AioContext *new_context,
205
+ Error **errp);
206
+void blk_add_aio_context_notifier(BlockBackend *blk,
207
+ void (*attached_aio_context)(AioContext *new_context, void *opaque),
208
+ void (*detach_aio_context)(void *opaque), void *opaque);
209
+void blk_remove_aio_context_notifier(BlockBackend *blk,
210
+ void (*attached_aio_context)(AioContext *,
211
+ void *),
212
+ void (*detach_aio_context)(void *),
213
+ void *opaque);
214
+void blk_add_remove_bs_notifier(BlockBackend *blk, Notifier *notify);
215
+void blk_add_insert_bs_notifier(BlockBackend *blk, Notifier *notify);
216
+BlockBackendRootState *blk_get_root_state(BlockBackend *blk);
217
+void blk_update_root_state(BlockBackend *blk);
218
+bool blk_get_detect_zeroes_from_root_state(BlockBackend *blk);
219
+int blk_get_open_flags_from_root_state(BlockBackend *blk);
220
+
221
+int blk_save_vmstate(BlockBackend *blk, const uint8_t *buf,
222
+ int64_t pos, int size);
223
+int blk_load_vmstate(BlockBackend *blk, uint8_t *buf, int64_t pos, int size);
224
+int blk_probe_blocksizes(BlockBackend *blk, BlockSizes *bsz);
225
+int blk_probe_geometry(BlockBackend *blk, HDGeometry *geo);
226
+
227
+void blk_set_io_limits(BlockBackend *blk, ThrottleConfig *cfg);
228
+void blk_io_limits_disable(BlockBackend *blk);
229
+void blk_io_limits_enable(BlockBackend *blk, const char *group);
230
+void blk_io_limits_update_group(BlockBackend *blk, const char *group);
231
+void blk_set_force_allow_inactivate(BlockBackend *blk);
232
+
233
+void blk_register_buf(BlockBackend *blk, void *host, size_t size);
234
+void blk_unregister_buf(BlockBackend *blk, void *host);
235
+
236
+const BdrvChild *blk_root(BlockBackend *blk);
237
+
238
+int blk_make_empty(BlockBackend *blk, Error **errp);
239
+
240
+#endif /* BLOCK_BACKEND_GS_H */
241
diff --git a/include/sysemu/block-backend-io.h b/include/sysemu/block-backend-io.h
242
new file mode 100644
243
index XXXXXXX..XXXXXXX
244
--- /dev/null
245
+++ b/include/sysemu/block-backend-io.h
246
@@ -XXX,XX +XXX,XX @@
247
+/*
248
+ * QEMU Block backends
249
+ *
250
+ * Copyright (C) 2014-2016 Red Hat, Inc.
251
+ *
252
+ * Authors:
253
+ * Markus Armbruster <armbru@redhat.com>,
254
+ *
255
+ * This work is licensed under the terms of the GNU LGPL, version 2.1
256
+ * or later. See the COPYING.LIB file in the top-level directory.
257
+ */
258
+
259
+#ifndef BLOCK_BACKEND_IO_H
260
+#define BLOCK_BACKEND_IO_H
261
+
262
+#include "block-backend-common.h"
263
+
264
+/*
265
+ * I/O API functions. These functions are thread-safe.
266
+ *
267
+ * See include/block/block-io.h for more information about
268
+ * the I/O API.
269
+ */
270
+
271
+const char *blk_name(const BlockBackend *blk);
272
+
273
+BlockDriverState *blk_bs(BlockBackend *blk);
274
+
275
+void blk_set_allow_write_beyond_eof(BlockBackend *blk, bool allow);
276
+void blk_set_allow_aio_context_change(BlockBackend *blk, bool allow);
277
+void blk_set_disable_request_queuing(BlockBackend *blk, bool disable);
278
+bool blk_iostatus_is_enabled(const BlockBackend *blk);
279
+
280
+char *blk_get_attached_dev_id(BlockBackend *blk);
281
+
282
+BlockAIOCB *blk_aio_pwrite_zeroes(BlockBackend *blk, int64_t offset,
283
+ int64_t bytes, BdrvRequestFlags flags,
284
+ BlockCompletionFunc *cb, void *opaque);
285
+
286
+BlockAIOCB *blk_aio_preadv(BlockBackend *blk, int64_t offset,
287
+ QEMUIOVector *qiov, BdrvRequestFlags flags,
288
+ BlockCompletionFunc *cb, void *opaque);
289
+BlockAIOCB *blk_aio_pwritev(BlockBackend *blk, int64_t offset,
290
+ QEMUIOVector *qiov, BdrvRequestFlags flags,
291
+ BlockCompletionFunc *cb, void *opaque);
292
+BlockAIOCB *blk_aio_flush(BlockBackend *blk,
293
+ BlockCompletionFunc *cb, void *opaque);
294
+BlockAIOCB *blk_aio_pdiscard(BlockBackend *blk, int64_t offset, int64_t bytes,
295
+ BlockCompletionFunc *cb, void *opaque);
296
+void blk_aio_cancel_async(BlockAIOCB *acb);
297
+BlockAIOCB *blk_aio_ioctl(BlockBackend *blk, unsigned long int req, void *buf,
298
+ BlockCompletionFunc *cb, void *opaque);
299
+
300
+void blk_inc_in_flight(BlockBackend *blk);
301
+void blk_dec_in_flight(BlockBackend *blk);
302
+bool blk_is_inserted(BlockBackend *blk);
303
+bool blk_is_available(BlockBackend *blk);
304
+void blk_lock_medium(BlockBackend *blk, bool locked);
305
+void blk_eject(BlockBackend *blk, bool eject_flag);
306
+int64_t blk_getlength(BlockBackend *blk);
307
+void blk_get_geometry(BlockBackend *blk, uint64_t *nb_sectors_ptr);
308
+int64_t blk_nb_sectors(BlockBackend *blk);
309
+void *blk_try_blockalign(BlockBackend *blk, size_t size);
310
+void *blk_blockalign(BlockBackend *blk, size_t size);
311
+bool blk_is_writable(BlockBackend *blk);
312
+bool blk_enable_write_cache(BlockBackend *blk);
313
+BlockdevOnError blk_get_on_error(BlockBackend *blk, bool is_read);
314
+BlockErrorAction blk_get_error_action(BlockBackend *blk, bool is_read,
315
+ int error);
316
+void blk_error_action(BlockBackend *blk, BlockErrorAction action,
317
+ bool is_read, int error);
318
+void blk_iostatus_set_err(BlockBackend *blk, int error);
319
+int blk_get_max_iov(BlockBackend *blk);
320
+int blk_get_max_hw_iov(BlockBackend *blk);
321
+void blk_set_guest_block_size(BlockBackend *blk, int align);
322
+
323
+void blk_io_plug(BlockBackend *blk);
324
+void blk_io_unplug(BlockBackend *blk);
325
+AioContext *blk_get_aio_context(BlockBackend *blk);
326
+BlockAcctStats *blk_get_stats(BlockBackend *blk);
327
+void *blk_aio_get(const AIOCBInfo *aiocb_info, BlockBackend *blk,
328
+ BlockCompletionFunc *cb, void *opaque);
329
+BlockAIOCB *blk_abort_aio_request(BlockBackend *blk,
330
+ BlockCompletionFunc *cb,
331
+ void *opaque, int ret);
332
+
333
+uint32_t blk_get_request_alignment(BlockBackend *blk);
334
+uint32_t blk_get_max_transfer(BlockBackend *blk);
335
+uint64_t blk_get_max_hw_transfer(BlockBackend *blk);
336
+
337
+int coroutine_fn blk_co_copy_range(BlockBackend *blk_in, int64_t off_in,
338
+ BlockBackend *blk_out, int64_t off_out,
339
+ int64_t bytes, BdrvRequestFlags read_flags,
340
+ BdrvRequestFlags write_flags);
341
+
342
+
343
+/*
344
+ * "I/O or GS" API functions. These functions can run without
345
+ * the BQL, but only in one specific iothread/main loop.
346
+ *
347
+ * See include/block/block-io.h for more information about
348
+ * the "I/O or GS" API.
349
+ */
350
+
351
+int blk_pread(BlockBackend *blk, int64_t offset, void *buf, int bytes);
352
+int blk_pwrite(BlockBackend *blk, int64_t offset, const void *buf, int bytes,
353
+ BdrvRequestFlags flags);
354
+int coroutine_fn blk_co_preadv(BlockBackend *blk, int64_t offset,
355
+ int64_t bytes, QEMUIOVector *qiov,
356
+ BdrvRequestFlags flags);
357
+int coroutine_fn blk_co_pwritev_part(BlockBackend *blk, int64_t offset,
358
+ int64_t bytes,
359
+ QEMUIOVector *qiov, size_t qiov_offset,
360
+ BdrvRequestFlags flags);
361
+int coroutine_fn blk_co_pwritev(BlockBackend *blk, int64_t offset,
362
+ int64_t bytes, QEMUIOVector *qiov,
363
+ BdrvRequestFlags flags);
364
+
365
+static inline int coroutine_fn blk_co_pread(BlockBackend *blk, int64_t offset,
366
+ int64_t bytes, void *buf,
367
+ BdrvRequestFlags flags)
368
+{
369
+ QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, bytes);
370
+
371
+ assert(bytes <= SIZE_MAX);
372
+
373
+ return blk_co_preadv(blk, offset, bytes, &qiov, flags);
374
+}
375
+
376
+static inline int coroutine_fn blk_co_pwrite(BlockBackend *blk, int64_t offset,
377
+ int64_t bytes, void *buf,
378
+ BdrvRequestFlags flags)
379
+{
380
+ QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, bytes);
381
+
382
+ assert(bytes <= SIZE_MAX);
383
+
384
+ return blk_co_pwritev(blk, offset, bytes, &qiov, flags);
385
+}
386
+
387
+int coroutine_fn blk_co_pdiscard(BlockBackend *blk, int64_t offset,
388
+ int64_t bytes);
389
+
390
+int coroutine_fn blk_co_flush(BlockBackend *blk);
391
+int blk_flush(BlockBackend *blk);
392
+
393
+int blk_ioctl(BlockBackend *blk, unsigned long int req, void *buf);
394
+
395
+int blk_pwrite_compressed(BlockBackend *blk, int64_t offset, const void *buf,
396
+ int64_t bytes);
397
+int blk_pdiscard(BlockBackend *blk, int64_t offset, int64_t bytes);
398
+int blk_pwrite_zeroes(BlockBackend *blk, int64_t offset,
399
+ int64_t bytes, BdrvRequestFlags flags);
400
+int coroutine_fn blk_co_pwrite_zeroes(BlockBackend *blk, int64_t offset,
401
+ int64_t bytes, BdrvRequestFlags flags);
402
+int blk_truncate(BlockBackend *blk, int64_t offset, bool exact,
403
+ PreallocMode prealloc, BdrvRequestFlags flags, Error **errp);
404
+
405
+#endif /* BLOCK_BACKEND_IO_H */
406
diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h
407
index XXXXXXX..XXXXXXX 100644
408
--- a/include/sysemu/block-backend.h
409
+++ b/include/sysemu/block-backend.h
410
@@ -XXX,XX +XXX,XX @@
411
#ifndef BLOCK_BACKEND_H
412
#define BLOCK_BACKEND_H
413
414
-#include "qemu/iov.h"
415
-#include "block/throttle-groups.h"
416
+#include "block-backend-global-state.h"
417
+#include "block-backend-io.h"
418
419
-/*
420
- * TODO Have to include block/block.h for a bunch of block layer
421
- * types. Unfortunately, this pulls in the whole BlockDriverState
422
- * API, which we don't want used by many BlockBackend users. Some of
423
- * the types belong here, and the rest should be split into a common
424
- * header and one for the BlockDriverState API.
425
- */
426
-#include "block/block.h"
427
-
428
-/* Callbacks for block device models */
429
-typedef struct BlockDevOps {
430
- /*
431
- * Runs when virtual media changed (monitor commands eject, change)
432
- * Argument load is true on load and false on eject.
433
- * Beware: doesn't run when a host device's physical media
434
- * changes. Sure would be useful if it did.
435
- * Device models with removable media must implement this callback.
436
- */
437
- void (*change_media_cb)(void *opaque, bool load, Error **errp);
438
- /*
439
- * Runs when an eject request is issued from the monitor, the tray
440
- * is closed, and the medium is locked.
441
- * Device models that do not implement is_medium_locked will not need
442
- * this callback. Device models that can lock the medium or tray might
443
- * want to implement the callback and unlock the tray when "force" is
444
- * true, even if they do not support eject requests.
445
- */
446
- void (*eject_request_cb)(void *opaque, bool force);
447
- /*
448
- * Is the virtual tray open?
449
- * Device models implement this only when the device has a tray.
450
- */
451
- bool (*is_tray_open)(void *opaque);
452
- /*
453
- * Is the virtual medium locked into the device?
454
- * Device models implement this only when device has such a lock.
455
- */
456
- bool (*is_medium_locked)(void *opaque);
457
- /*
458
- * Runs when the size changed (e.g. monitor command block_resize)
459
- */
460
- void (*resize_cb)(void *opaque);
461
- /*
462
- * Runs when the backend receives a drain request.
463
- */
464
- void (*drained_begin)(void *opaque);
465
- /*
466
- * Runs when the backend's last drain request ends.
467
- */
468
- void (*drained_end)(void *opaque);
469
- /*
470
- * Is the device still busy?
471
- */
472
- bool (*drained_poll)(void *opaque);
473
-} BlockDevOps;
474
-
475
-/* This struct is embedded in (the private) BlockBackend struct and contains
476
- * fields that must be public. This is in particular for QLIST_ENTRY() and
477
- * friends so that BlockBackends can be kept in lists outside block-backend.c
478
- * */
479
-typedef struct BlockBackendPublic {
480
- ThrottleGroupMember throttle_group_member;
481
-} BlockBackendPublic;
482
-
483
-BlockBackend *blk_new(AioContext *ctx, uint64_t perm, uint64_t shared_perm);
484
-BlockBackend *blk_new_with_bs(BlockDriverState *bs, uint64_t perm,
485
- uint64_t shared_perm, Error **errp);
486
-BlockBackend *blk_new_open(const char *filename, const char *reference,
487
- QDict *options, int flags, Error **errp);
488
-int blk_get_refcnt(BlockBackend *blk);
489
-void blk_ref(BlockBackend *blk);
490
-void blk_unref(BlockBackend *blk);
491
-void blk_remove_all_bs(void);
492
-const char *blk_name(const BlockBackend *blk);
493
-BlockBackend *blk_by_name(const char *name);
494
-BlockBackend *blk_next(BlockBackend *blk);
495
-BlockBackend *blk_all_next(BlockBackend *blk);
496
-bool monitor_add_blk(BlockBackend *blk, const char *name, Error **errp);
497
-void monitor_remove_blk(BlockBackend *blk);
498
-
499
-BlockBackendPublic *blk_get_public(BlockBackend *blk);
500
-BlockBackend *blk_by_public(BlockBackendPublic *public);
501
-
502
-BlockDriverState *blk_bs(BlockBackend *blk);
503
-void blk_remove_bs(BlockBackend *blk);
504
-int blk_insert_bs(BlockBackend *blk, BlockDriverState *bs, Error **errp);
505
-int blk_replace_bs(BlockBackend *blk, BlockDriverState *new_bs, Error **errp);
506
-bool bdrv_has_blk(BlockDriverState *bs);
507
-bool bdrv_is_root_node(BlockDriverState *bs);
508
-int blk_set_perm(BlockBackend *blk, uint64_t perm, uint64_t shared_perm,
509
- Error **errp);
510
-void blk_get_perm(BlockBackend *blk, uint64_t *perm, uint64_t *shared_perm);
511
-
512
-void blk_set_allow_write_beyond_eof(BlockBackend *blk, bool allow);
513
-void blk_set_allow_aio_context_change(BlockBackend *blk, bool allow);
514
-void blk_set_disable_request_queuing(BlockBackend *blk, bool disable);
515
-void blk_iostatus_enable(BlockBackend *blk);
516
-bool blk_iostatus_is_enabled(const BlockBackend *blk);
517
-BlockDeviceIoStatus blk_iostatus(const BlockBackend *blk);
518
-void blk_iostatus_disable(BlockBackend *blk);
519
-void blk_iostatus_reset(BlockBackend *blk);
520
-void blk_iostatus_set_err(BlockBackend *blk, int error);
521
-int blk_attach_dev(BlockBackend *blk, DeviceState *dev);
522
-void blk_detach_dev(BlockBackend *blk, DeviceState *dev);
523
-DeviceState *blk_get_attached_dev(BlockBackend *blk);
524
-char *blk_get_attached_dev_id(BlockBackend *blk);
525
-BlockBackend *blk_by_dev(void *dev);
526
-BlockBackend *blk_by_qdev_id(const char *id, Error **errp);
527
-void blk_set_dev_ops(BlockBackend *blk, const BlockDevOps *ops, void *opaque);
528
-int coroutine_fn blk_co_preadv(BlockBackend *blk, int64_t offset,
529
- int64_t bytes, QEMUIOVector *qiov,
530
- BdrvRequestFlags flags);
531
-int coroutine_fn blk_co_pwritev_part(BlockBackend *blk, int64_t offset,
532
- int64_t bytes,
533
- QEMUIOVector *qiov, size_t qiov_offset,
534
- BdrvRequestFlags flags);
535
-int coroutine_fn blk_co_pwritev(BlockBackend *blk, int64_t offset,
536
- int64_t bytes, QEMUIOVector *qiov,
537
- BdrvRequestFlags flags);
538
-
539
-static inline int coroutine_fn blk_co_pread(BlockBackend *blk, int64_t offset,
540
- int64_t bytes, void *buf,
541
- BdrvRequestFlags flags)
542
-{
543
- QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, bytes);
544
-
545
- assert(bytes <= SIZE_MAX);
546
-
547
- return blk_co_preadv(blk, offset, bytes, &qiov, flags);
548
-}
549
-
550
-static inline int coroutine_fn blk_co_pwrite(BlockBackend *blk, int64_t offset,
551
- int64_t bytes, void *buf,
552
- BdrvRequestFlags flags)
553
-{
554
- QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, bytes);
555
-
556
- assert(bytes <= SIZE_MAX);
557
-
558
- return blk_co_pwritev(blk, offset, bytes, &qiov, flags);
559
-}
560
-
561
-int blk_pwrite_zeroes(BlockBackend *blk, int64_t offset,
562
- int64_t bytes, BdrvRequestFlags flags);
563
-BlockAIOCB *blk_aio_pwrite_zeroes(BlockBackend *blk, int64_t offset,
564
- int64_t bytes, BdrvRequestFlags flags,
565
- BlockCompletionFunc *cb, void *opaque);
566
-int blk_make_zero(BlockBackend *blk, BdrvRequestFlags flags);
567
-int blk_pread(BlockBackend *blk, int64_t offset, void *buf, int bytes);
568
-int blk_pwrite(BlockBackend *blk, int64_t offset, const void *buf, int bytes,
569
- BdrvRequestFlags flags);
570
-int64_t blk_getlength(BlockBackend *blk);
571
-void blk_get_geometry(BlockBackend *blk, uint64_t *nb_sectors_ptr);
572
-int64_t blk_nb_sectors(BlockBackend *blk);
573
-BlockAIOCB *blk_aio_preadv(BlockBackend *blk, int64_t offset,
574
- QEMUIOVector *qiov, BdrvRequestFlags flags,
575
- BlockCompletionFunc *cb, void *opaque);
576
-BlockAIOCB *blk_aio_pwritev(BlockBackend *blk, int64_t offset,
577
- QEMUIOVector *qiov, BdrvRequestFlags flags,
578
- BlockCompletionFunc *cb, void *opaque);
579
-BlockAIOCB *blk_aio_flush(BlockBackend *blk,
580
- BlockCompletionFunc *cb, void *opaque);
581
-BlockAIOCB *blk_aio_pdiscard(BlockBackend *blk, int64_t offset, int64_t bytes,
582
- BlockCompletionFunc *cb, void *opaque);
583
-void blk_aio_cancel(BlockAIOCB *acb);
584
-void blk_aio_cancel_async(BlockAIOCB *acb);
585
-int blk_ioctl(BlockBackend *blk, unsigned long int req, void *buf);
586
-BlockAIOCB *blk_aio_ioctl(BlockBackend *blk, unsigned long int req, void *buf,
587
- BlockCompletionFunc *cb, void *opaque);
588
-int coroutine_fn blk_co_pdiscard(BlockBackend *blk, int64_t offset,
589
- int64_t bytes);
590
-int coroutine_fn blk_co_flush(BlockBackend *blk);
591
-int blk_flush(BlockBackend *blk);
592
-int blk_commit_all(void);
593
-void blk_inc_in_flight(BlockBackend *blk);
594
-void blk_dec_in_flight(BlockBackend *blk);
595
-void blk_drain(BlockBackend *blk);
596
-void blk_drain_all(void);
597
-void blk_set_on_error(BlockBackend *blk, BlockdevOnError on_read_error,
598
- BlockdevOnError on_write_error);
599
-BlockdevOnError blk_get_on_error(BlockBackend *blk, bool is_read);
600
-BlockErrorAction blk_get_error_action(BlockBackend *blk, bool is_read,
601
- int error);
602
-void blk_error_action(BlockBackend *blk, BlockErrorAction action,
603
- bool is_read, int error);
604
-bool blk_supports_write_perm(BlockBackend *blk);
605
-bool blk_is_writable(BlockBackend *blk);
606
-bool blk_is_sg(BlockBackend *blk);
607
-bool blk_enable_write_cache(BlockBackend *blk);
608
-void blk_set_enable_write_cache(BlockBackend *blk, bool wce);
609
-void blk_activate(BlockBackend *blk, Error **errp);
610
-bool blk_is_inserted(BlockBackend *blk);
611
-bool blk_is_available(BlockBackend *blk);
612
-void blk_lock_medium(BlockBackend *blk, bool locked);
613
-void blk_eject(BlockBackend *blk, bool eject_flag);
614
-int blk_get_flags(BlockBackend *blk);
615
-uint32_t blk_get_request_alignment(BlockBackend *blk);
616
-uint32_t blk_get_max_transfer(BlockBackend *blk);
617
-uint64_t blk_get_max_hw_transfer(BlockBackend *blk);
618
-int blk_get_max_iov(BlockBackend *blk);
619
-int blk_get_max_hw_iov(BlockBackend *blk);
620
-void blk_set_guest_block_size(BlockBackend *blk, int align);
621
-void *blk_try_blockalign(BlockBackend *blk, size_t size);
622
-void *blk_blockalign(BlockBackend *blk, size_t size);
623
-bool blk_op_is_blocked(BlockBackend *blk, BlockOpType op, Error **errp);
624
-void blk_op_unblock(BlockBackend *blk, BlockOpType op, Error *reason);
625
-void blk_op_block_all(BlockBackend *blk, Error *reason);
626
-void blk_op_unblock_all(BlockBackend *blk, Error *reason);
627
-AioContext *blk_get_aio_context(BlockBackend *blk);
628
-int blk_set_aio_context(BlockBackend *blk, AioContext *new_context,
629
- Error **errp);
630
-void blk_add_aio_context_notifier(BlockBackend *blk,
631
- void (*attached_aio_context)(AioContext *new_context, void *opaque),
632
- void (*detach_aio_context)(void *opaque), void *opaque);
633
-void blk_remove_aio_context_notifier(BlockBackend *blk,
634
- void (*attached_aio_context)(AioContext *,
635
- void *),
636
- void (*detach_aio_context)(void *),
637
- void *opaque);
638
-void blk_add_remove_bs_notifier(BlockBackend *blk, Notifier *notify);
639
-void blk_add_insert_bs_notifier(BlockBackend *blk, Notifier *notify);
640
-void blk_io_plug(BlockBackend *blk);
641
-void blk_io_unplug(BlockBackend *blk);
642
-BlockAcctStats *blk_get_stats(BlockBackend *blk);
643
-BlockBackendRootState *blk_get_root_state(BlockBackend *blk);
644
-void blk_update_root_state(BlockBackend *blk);
645
-bool blk_get_detect_zeroes_from_root_state(BlockBackend *blk);
646
-int blk_get_open_flags_from_root_state(BlockBackend *blk);
647
-
648
-void *blk_aio_get(const AIOCBInfo *aiocb_info, BlockBackend *blk,
649
- BlockCompletionFunc *cb, void *opaque);
650
-int coroutine_fn blk_co_pwrite_zeroes(BlockBackend *blk, int64_t offset,
651
- int64_t bytes, BdrvRequestFlags flags);
652
-int blk_pwrite_compressed(BlockBackend *blk, int64_t offset, const void *buf,
653
- int64_t bytes);
654
-int blk_truncate(BlockBackend *blk, int64_t offset, bool exact,
655
- PreallocMode prealloc, BdrvRequestFlags flags, Error **errp);
656
-int blk_pdiscard(BlockBackend *blk, int64_t offset, int64_t bytes);
657
-int blk_save_vmstate(BlockBackend *blk, const uint8_t *buf,
658
- int64_t pos, int size);
659
-int blk_load_vmstate(BlockBackend *blk, uint8_t *buf, int64_t pos, int size);
660
-int blk_probe_blocksizes(BlockBackend *blk, BlockSizes *bsz);
661
-int blk_probe_geometry(BlockBackend *blk, HDGeometry *geo);
662
-BlockAIOCB *blk_abort_aio_request(BlockBackend *blk,
663
- BlockCompletionFunc *cb,
664
- void *opaque, int ret);
665
-
666
-void blk_set_io_limits(BlockBackend *blk, ThrottleConfig *cfg);
667
-void blk_io_limits_disable(BlockBackend *blk);
668
-void blk_io_limits_enable(BlockBackend *blk, const char *group);
669
-void blk_io_limits_update_group(BlockBackend *blk, const char *group);
670
-void blk_set_force_allow_inactivate(BlockBackend *blk);
671
-
672
-void blk_register_buf(BlockBackend *blk, void *host, size_t size);
673
-void blk_unregister_buf(BlockBackend *blk, void *host);
674
-
675
-int coroutine_fn blk_co_copy_range(BlockBackend *blk_in, int64_t off_in,
676
- BlockBackend *blk_out, int64_t off_out,
677
- int64_t bytes, BdrvRequestFlags read_flags,
678
- BdrvRequestFlags write_flags);
679
-
680
-const BdrvChild *blk_root(BlockBackend *blk);
681
-
682
-int blk_make_empty(BlockBackend *blk, Error **errp);
683
+/* DO NOT ADD ANYTHING IN HERE. USE ONE OF THE HEADERS INCLUDED ABOVE */
684
685
#endif
686
diff --git a/block/block-backend.c b/block/block-backend.c
687
index XXXXXXX..XXXXXXX 100644
688
--- a/block/block-backend.c
689
+++ b/block/block-backend.c
690
@@ -XXX,XX +XXX,XX @@ struct BlockBackend {
691
bool allow_aio_context_change;
692
bool allow_write_beyond_eof;
693
694
+ /* Protected by BQL */
695
NotifierList remove_bs_notifiers, insert_bs_notifiers;
696
QLIST_HEAD(, BlockBackendAioNotifier) aio_notifiers;
697
698
@@ -XXX,XX +XXX,XX @@ static const AIOCBInfo block_backend_aiocb_info = {
699
static void drive_info_del(DriveInfo *dinfo);
700
static BlockBackend *bdrv_first_blk(BlockDriverState *bs);
701
702
-/* All BlockBackends */
703
+/* All BlockBackends. Protected by BQL. */
704
static QTAILQ_HEAD(, BlockBackend) block_backends =
705
QTAILQ_HEAD_INITIALIZER(block_backends);
706
707
-/* All BlockBackends referenced by the monitor and which are iterated through by
708
- * blk_next() */
709
+/*
710
+ * All BlockBackends referenced by the monitor and which are iterated through by
711
+ * blk_next(). Protected by BQL.
712
+ */
713
static QTAILQ_HEAD(, BlockBackend) monitor_block_backends =
714
QTAILQ_HEAD_INITIALIZER(monitor_block_backends);
715
716
--
717
2.35.1
diff view generated by jsdifflib
New patch
1
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
1
2
3
All the global state (GS) API functions will check that
4
qemu_in_main_thread() returns true. If not, it means
5
that the safety of BQL cannot be guaranteed, and
6
they need to be moved to I/O.
7
8
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
9
Message-Id: <20220303151616.325444-9-eesposit@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
---
12
block/block-backend.c | 78 ++++++++++++++++++++++++++++++++++++++++++
13
softmmu/qdev-monitor.c | 2 ++
14
2 files changed, 80 insertions(+)
15
16
diff --git a/block/block-backend.c b/block/block-backend.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/block/block-backend.c
19
+++ b/block/block-backend.c
20
@@ -XXX,XX +XXX,XX @@ static void blk_root_activate(BdrvChild *child, Error **errp)
21
22
void blk_set_force_allow_inactivate(BlockBackend *blk)
23
{
24
+ GLOBAL_STATE_CODE();
25
blk->force_allow_inactivate = true;
26
}
27
28
@@ -XXX,XX +XXX,XX @@ BlockBackend *blk_new(AioContext *ctx, uint64_t perm, uint64_t shared_perm)
29
{
30
BlockBackend *blk;
31
32
+ GLOBAL_STATE_CODE();
33
+
34
blk = g_new0(BlockBackend, 1);
35
blk->refcnt = 1;
36
blk->ctx = ctx;
37
@@ -XXX,XX +XXX,XX @@ BlockBackend *blk_new_with_bs(BlockDriverState *bs, uint64_t perm,
38
{
39
BlockBackend *blk = blk_new(bdrv_get_aio_context(bs), perm, shared_perm);
40
41
+ GLOBAL_STATE_CODE();
42
+
43
if (blk_insert_bs(blk, bs, errp) < 0) {
44
blk_unref(blk);
45
return NULL;
46
@@ -XXX,XX +XXX,XX @@ BlockBackend *blk_new_open(const char *filename, const char *reference,
47
uint64_t perm = 0;
48
uint64_t shared = BLK_PERM_ALL;
49
50
+ GLOBAL_STATE_CODE();
51
+
52
/*
53
* blk_new_open() is mainly used in .bdrv_create implementations and the
54
* tools where sharing isn't a major concern because the BDS stays private
55
@@ -XXX,XX +XXX,XX @@ static void drive_info_del(DriveInfo *dinfo)
56
57
int blk_get_refcnt(BlockBackend *blk)
58
{
59
+ GLOBAL_STATE_CODE();
60
return blk ? blk->refcnt : 0;
61
}
62
63
@@ -XXX,XX +XXX,XX @@ int blk_get_refcnt(BlockBackend *blk)
64
void blk_ref(BlockBackend *blk)
65
{
66
assert(blk->refcnt > 0);
67
+ GLOBAL_STATE_CODE();
68
blk->refcnt++;
69
}
70
71
@@ -XXX,XX +XXX,XX @@ void blk_ref(BlockBackend *blk)
72
*/
73
void blk_unref(BlockBackend *blk)
74
{
75
+ GLOBAL_STATE_CODE();
76
if (blk) {
77
assert(blk->refcnt > 0);
78
if (blk->refcnt > 1) {
79
@@ -XXX,XX +XXX,XX @@ void blk_unref(BlockBackend *blk)
80
*/
81
BlockBackend *blk_all_next(BlockBackend *blk)
82
{
83
+ GLOBAL_STATE_CODE();
84
return blk ? QTAILQ_NEXT(blk, link)
85
: QTAILQ_FIRST(&block_backends);
86
}
87
@@ -XXX,XX +XXX,XX @@ void blk_remove_all_bs(void)
88
{
89
BlockBackend *blk = NULL;
90
91
+ GLOBAL_STATE_CODE();
92
+
93
while ((blk = blk_all_next(blk)) != NULL) {
94
AioContext *ctx = blk_get_aio_context(blk);
95
96
@@ -XXX,XX +XXX,XX @@ void blk_remove_all_bs(void)
97
*/
98
BlockBackend *blk_next(BlockBackend *blk)
99
{
100
+ GLOBAL_STATE_CODE();
101
return blk ? QTAILQ_NEXT(blk, monitor_link)
102
: QTAILQ_FIRST(&monitor_block_backends);
103
}
104
@@ -XXX,XX +XXX,XX @@ static void bdrv_next_reset(BdrvNextIterator *it)
105
106
BlockDriverState *bdrv_first(BdrvNextIterator *it)
107
{
108
+ GLOBAL_STATE_CODE();
109
bdrv_next_reset(it);
110
return bdrv_next(it);
111
}
112
@@ -XXX,XX +XXX,XX @@ bool monitor_add_blk(BlockBackend *blk, const char *name, Error **errp)
113
{
114
assert(!blk->name);
115
assert(name && name[0]);
116
+ GLOBAL_STATE_CODE();
117
118
if (!id_wellformed(name)) {
119
error_setg(errp, "Invalid device name");
120
@@ -XXX,XX +XXX,XX @@ bool monitor_add_blk(BlockBackend *blk, const char *name, Error **errp)
121
*/
122
void monitor_remove_blk(BlockBackend *blk)
123
{
124
+ GLOBAL_STATE_CODE();
125
+
126
if (!blk->name) {
127
return;
128
}
129
@@ -XXX,XX +XXX,XX @@ BlockBackend *blk_by_name(const char *name)
130
{
131
BlockBackend *blk = NULL;
132
133
+ GLOBAL_STATE_CODE();
134
assert(name);
135
while ((blk = blk_next(blk)) != NULL) {
136
if (!strcmp(name, blk->name)) {
137
@@ -XXX,XX +XXX,XX @@ static BlockBackend *bdrv_first_blk(BlockDriverState *bs)
138
*/
139
bool bdrv_has_blk(BlockDriverState *bs)
140
{
141
+ GLOBAL_STATE_CODE();
142
return bdrv_first_blk(bs) != NULL;
143
}
144
145
@@ -XXX,XX +XXX,XX @@ bool bdrv_is_root_node(BlockDriverState *bs)
146
{
147
BdrvChild *c;
148
149
+ GLOBAL_STATE_CODE();
150
QLIST_FOREACH(c, &bs->parents, next_parent) {
151
if (c->klass != &child_root) {
152
return false;
153
@@ -XXX,XX +XXX,XX @@ BlockBackend *blk_by_legacy_dinfo(DriveInfo *dinfo)
154
*/
155
BlockBackendPublic *blk_get_public(BlockBackend *blk)
156
{
157
+ GLOBAL_STATE_CODE();
158
return &blk->public;
159
}
160
161
@@ -XXX,XX +XXX,XX @@ BlockBackendPublic *blk_get_public(BlockBackend *blk)
162
*/
163
BlockBackend *blk_by_public(BlockBackendPublic *public)
164
{
165
+ GLOBAL_STATE_CODE();
166
return container_of(public, BlockBackend, public);
167
}
168
169
@@ -XXX,XX +XXX,XX @@ void blk_remove_bs(BlockBackend *blk)
170
ThrottleGroupMember *tgm = &blk->public.throttle_group_member;
171
BdrvChild *root;
172
173
+ GLOBAL_STATE_CODE();
174
+
175
notifier_list_notify(&blk->remove_bs_notifiers, blk);
176
if (tgm->throttle_state) {
177
BlockDriverState *bs = blk_bs(blk);
178
@@ -XXX,XX +XXX,XX @@ void blk_remove_bs(BlockBackend *blk)
179
int blk_insert_bs(BlockBackend *blk, BlockDriverState *bs, Error **errp)
180
{
181
ThrottleGroupMember *tgm = &blk->public.throttle_group_member;
182
+ GLOBAL_STATE_CODE();
183
bdrv_ref(bs);
184
blk->root = bdrv_root_attach_child(bs, "root", &child_root,
185
BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY,
186
@@ -XXX,XX +XXX,XX @@ int blk_insert_bs(BlockBackend *blk, BlockDriverState *bs, Error **errp)
187
*/
188
int blk_replace_bs(BlockBackend *blk, BlockDriverState *new_bs, Error **errp)
189
{
190
+ GLOBAL_STATE_CODE();
191
return bdrv_replace_child_bs(blk->root, new_bs, errp);
192
}
193
194
@@ -XXX,XX +XXX,XX @@ int blk_set_perm(BlockBackend *blk, uint64_t perm, uint64_t shared_perm,
195
Error **errp)
196
{
197
int ret;
198
+ GLOBAL_STATE_CODE();
199
200
if (blk->root && !blk->disable_perm) {
201
ret = bdrv_child_try_set_perm(blk->root, perm, shared_perm, errp);
202
@@ -XXX,XX +XXX,XX @@ int blk_set_perm(BlockBackend *blk, uint64_t perm, uint64_t shared_perm,
203
204
void blk_get_perm(BlockBackend *blk, uint64_t *perm, uint64_t *shared_perm)
205
{
206
+ GLOBAL_STATE_CODE();
207
*perm = blk->perm;
208
*shared_perm = blk->shared_perm;
209
}
210
@@ -XXX,XX +XXX,XX @@ void blk_get_perm(BlockBackend *blk, uint64_t *perm, uint64_t *shared_perm)
211
*/
212
int blk_attach_dev(BlockBackend *blk, DeviceState *dev)
213
{
214
+ GLOBAL_STATE_CODE();
215
if (blk->dev) {
216
return -EBUSY;
217
}
218
@@ -XXX,XX +XXX,XX @@ int blk_attach_dev(BlockBackend *blk, DeviceState *dev)
219
void blk_detach_dev(BlockBackend *blk, DeviceState *dev)
220
{
221
assert(blk->dev == dev);
222
+ GLOBAL_STATE_CODE();
223
blk->dev = NULL;
224
blk->dev_ops = NULL;
225
blk->dev_opaque = NULL;
226
@@ -XXX,XX +XXX,XX @@ void blk_detach_dev(BlockBackend *blk, DeviceState *dev)
227
*/
228
DeviceState *blk_get_attached_dev(BlockBackend *blk)
229
{
230
+ GLOBAL_STATE_CODE();
231
return blk->dev;
232
}
233
234
@@ -XXX,XX +XXX,XX @@ BlockBackend *blk_by_dev(void *dev)
235
{
236
BlockBackend *blk = NULL;
237
238
+ GLOBAL_STATE_CODE();
239
+
240
assert(dev != NULL);
241
while ((blk = blk_all_next(blk)) != NULL) {
242
if (blk->dev == dev) {
243
@@ -XXX,XX +XXX,XX @@ BlockBackend *blk_by_dev(void *dev)
244
void blk_set_dev_ops(BlockBackend *blk, const BlockDevOps *ops,
245
void *opaque)
246
{
247
+ GLOBAL_STATE_CODE();
248
blk->dev_ops = ops;
249
blk->dev_opaque = opaque;
250
251
@@ -XXX,XX +XXX,XX @@ void blk_set_dev_ops(BlockBackend *blk, const BlockDevOps *ops,
252
*/
253
void blk_dev_change_media_cb(BlockBackend *blk, bool load, Error **errp)
254
{
255
+ GLOBAL_STATE_CODE();
256
if (blk->dev_ops && blk->dev_ops->change_media_cb) {
257
bool tray_was_open, tray_is_open;
258
Error *local_err = NULL;
259
@@ -XXX,XX +XXX,XX @@ static void blk_root_resize(BdrvChild *child)
260
261
void blk_iostatus_enable(BlockBackend *blk)
262
{
263
+ GLOBAL_STATE_CODE();
264
blk->iostatus_enabled = true;
265
blk->iostatus = BLOCK_DEVICE_IO_STATUS_OK;
266
}
267
@@ -XXX,XX +XXX,XX @@ bool blk_iostatus_is_enabled(const BlockBackend *blk)
268
269
BlockDeviceIoStatus blk_iostatus(const BlockBackend *blk)
270
{
271
+ GLOBAL_STATE_CODE();
272
return blk->iostatus;
273
}
274
275
void blk_iostatus_disable(BlockBackend *blk)
276
{
277
+ GLOBAL_STATE_CODE();
278
blk->iostatus_enabled = false;
279
}
280
281
void blk_iostatus_reset(BlockBackend *blk)
282
{
283
+ GLOBAL_STATE_CODE();
284
if (blk_iostatus_is_enabled(blk)) {
285
blk->iostatus = BLOCK_DEVICE_IO_STATUS_OK;
286
}
287
@@ -XXX,XX +XXX,XX @@ int blk_pwrite_zeroes(BlockBackend *blk, int64_t offset,
288
289
int blk_make_zero(BlockBackend *blk, BdrvRequestFlags flags)
290
{
291
+ GLOBAL_STATE_CODE();
292
return bdrv_make_zero(blk->root, flags);
293
}
294
295
@@ -XXX,XX +XXX,XX @@ BlockAIOCB *blk_aio_pwritev(BlockBackend *blk, int64_t offset,
296
297
void blk_aio_cancel(BlockAIOCB *acb)
298
{
299
+ GLOBAL_STATE_CODE();
300
bdrv_aio_cancel(acb);
301
}
302
303
@@ -XXX,XX +XXX,XX @@ int blk_flush(BlockBackend *blk)
304
void blk_drain(BlockBackend *blk)
305
{
306
BlockDriverState *bs = blk_bs(blk);
307
+ GLOBAL_STATE_CODE();
308
309
if (bs) {
310
bdrv_ref(bs);
311
@@ -XXX,XX +XXX,XX @@ void blk_drain_all(void)
312
{
313
BlockBackend *blk = NULL;
314
315
+ GLOBAL_STATE_CODE();
316
+
317
bdrv_drain_all_begin();
318
319
while ((blk = blk_all_next(blk)) != NULL) {
320
@@ -XXX,XX +XXX,XX @@ void blk_drain_all(void)
321
void blk_set_on_error(BlockBackend *blk, BlockdevOnError on_read_error,
322
BlockdevOnError on_write_error)
323
{
324
+ GLOBAL_STATE_CODE();
325
blk->on_read_error = on_read_error;
326
blk->on_write_error = on_write_error;
327
}
328
@@ -XXX,XX +XXX,XX @@ void blk_error_action(BlockBackend *blk, BlockErrorAction action,
329
bool blk_supports_write_perm(BlockBackend *blk)
330
{
331
BlockDriverState *bs = blk_bs(blk);
332
+ GLOBAL_STATE_CODE();
333
334
if (bs) {
335
return !bdrv_is_read_only(bs);
336
@@ -XXX,XX +XXX,XX @@ bool blk_is_writable(BlockBackend *blk)
337
bool blk_is_sg(BlockBackend *blk)
338
{
339
BlockDriverState *bs = blk_bs(blk);
340
+ GLOBAL_STATE_CODE();
341
342
if (!bs) {
343
return false;
344
@@ -XXX,XX +XXX,XX @@ bool blk_enable_write_cache(BlockBackend *blk)
345
346
void blk_set_enable_write_cache(BlockBackend *blk, bool wce)
347
{
348
+ GLOBAL_STATE_CODE();
349
blk->enable_write_cache = wce;
350
}
351
352
void blk_activate(BlockBackend *blk, Error **errp)
353
{
354
BlockDriverState *bs = blk_bs(blk);
355
+ GLOBAL_STATE_CODE();
356
357
if (!bs) {
358
error_setg(errp, "Device '%s' has no medium", blk->name);
359
@@ -XXX,XX +XXX,XX @@ void blk_eject(BlockBackend *blk, bool eject_flag)
360
int blk_get_flags(BlockBackend *blk)
361
{
362
BlockDriverState *bs = blk_bs(blk);
363
+ GLOBAL_STATE_CODE();
364
365
if (bs) {
366
return bdrv_get_flags(bs);
367
@@ -XXX,XX +XXX,XX @@ void *blk_blockalign(BlockBackend *blk, size_t size)
368
bool blk_op_is_blocked(BlockBackend *blk, BlockOpType op, Error **errp)
369
{
370
BlockDriverState *bs = blk_bs(blk);
371
+ GLOBAL_STATE_CODE();
372
373
if (!bs) {
374
return false;
375
@@ -XXX,XX +XXX,XX @@ bool blk_op_is_blocked(BlockBackend *blk, BlockOpType op, Error **errp)
376
void blk_op_unblock(BlockBackend *blk, BlockOpType op, Error *reason)
377
{
378
BlockDriverState *bs = blk_bs(blk);
379
+ GLOBAL_STATE_CODE();
380
381
if (bs) {
382
bdrv_op_unblock(bs, op, reason);
383
@@ -XXX,XX +XXX,XX @@ void blk_op_unblock(BlockBackend *blk, BlockOpType op, Error *reason)
384
void blk_op_block_all(BlockBackend *blk, Error *reason)
385
{
386
BlockDriverState *bs = blk_bs(blk);
387
+ GLOBAL_STATE_CODE();
388
389
if (bs) {
390
bdrv_op_block_all(bs, reason);
391
@@ -XXX,XX +XXX,XX @@ void blk_op_block_all(BlockBackend *blk, Error *reason)
392
void blk_op_unblock_all(BlockBackend *blk, Error *reason)
393
{
394
BlockDriverState *bs = blk_bs(blk);
395
+ GLOBAL_STATE_CODE();
396
397
if (bs) {
398
bdrv_op_unblock_all(bs, reason);
399
@@ -XXX,XX +XXX,XX @@ static int blk_do_set_aio_context(BlockBackend *blk, AioContext *new_context,
400
int blk_set_aio_context(BlockBackend *blk, AioContext *new_context,
401
Error **errp)
402
{
403
+ GLOBAL_STATE_CODE();
404
return blk_do_set_aio_context(blk, new_context, true, errp);
405
}
406
407
@@ -XXX,XX +XXX,XX @@ void blk_add_aio_context_notifier(BlockBackend *blk,
408
{
409
BlockBackendAioNotifier *notifier;
410
BlockDriverState *bs = blk_bs(blk);
411
+ GLOBAL_STATE_CODE();
412
413
notifier = g_new(BlockBackendAioNotifier, 1);
414
notifier->attached_aio_context = attached_aio_context;
415
@@ -XXX,XX +XXX,XX @@ void blk_remove_aio_context_notifier(BlockBackend *blk,
416
BlockBackendAioNotifier *notifier;
417
BlockDriverState *bs = blk_bs(blk);
418
419
+ GLOBAL_STATE_CODE();
420
+
421
if (bs) {
422
bdrv_remove_aio_context_notifier(bs, attached_aio_context,
423
detach_aio_context, opaque);
424
@@ -XXX,XX +XXX,XX @@ void blk_remove_aio_context_notifier(BlockBackend *blk,
425
426
void blk_add_remove_bs_notifier(BlockBackend *blk, Notifier *notify)
427
{
428
+ GLOBAL_STATE_CODE();
429
notifier_list_add(&blk->remove_bs_notifiers, notify);
430
}
431
432
void blk_add_insert_bs_notifier(BlockBackend *blk, Notifier *notify)
433
{
434
+ GLOBAL_STATE_CODE();
435
notifier_list_add(&blk->insert_bs_notifiers, notify);
436
}
437
438
@@ -XXX,XX +XXX,XX @@ int blk_save_vmstate(BlockBackend *blk, const uint8_t *buf,
439
int64_t pos, int size)
440
{
441
int ret;
442
+ GLOBAL_STATE_CODE();
443
444
if (!blk_is_available(blk)) {
445
return -ENOMEDIUM;
446
@@ -XXX,XX +XXX,XX @@ int blk_save_vmstate(BlockBackend *blk, const uint8_t *buf,
447
448
int blk_load_vmstate(BlockBackend *blk, uint8_t *buf, int64_t pos, int size)
449
{
450
+ GLOBAL_STATE_CODE();
451
if (!blk_is_available(blk)) {
452
return -ENOMEDIUM;
453
}
454
@@ -XXX,XX +XXX,XX @@ int blk_load_vmstate(BlockBackend *blk, uint8_t *buf, int64_t pos, int size)
455
456
int blk_probe_blocksizes(BlockBackend *blk, BlockSizes *bsz)
457
{
458
+ GLOBAL_STATE_CODE();
459
if (!blk_is_available(blk)) {
460
return -ENOMEDIUM;
461
}
462
@@ -XXX,XX +XXX,XX @@ int blk_probe_blocksizes(BlockBackend *blk, BlockSizes *bsz)
463
464
int blk_probe_geometry(BlockBackend *blk, HDGeometry *geo)
465
{
466
+ GLOBAL_STATE_CODE();
467
if (!blk_is_available(blk)) {
468
return -ENOMEDIUM;
469
}
470
@@ -XXX,XX +XXX,XX @@ int blk_probe_geometry(BlockBackend *blk, HDGeometry *geo)
471
*/
472
void blk_update_root_state(BlockBackend *blk)
473
{
474
+ GLOBAL_STATE_CODE();
475
assert(blk->root);
476
477
blk->root_state.open_flags = blk->root->bs->open_flags;
478
@@ -XXX,XX +XXX,XX @@ void blk_update_root_state(BlockBackend *blk)
479
*/
480
bool blk_get_detect_zeroes_from_root_state(BlockBackend *blk)
481
{
482
+ GLOBAL_STATE_CODE();
483
return blk->root_state.detect_zeroes;
484
}
485
486
@@ -XXX,XX +XXX,XX @@ bool blk_get_detect_zeroes_from_root_state(BlockBackend *blk)
487
*/
488
int blk_get_open_flags_from_root_state(BlockBackend *blk)
489
{
490
+ GLOBAL_STATE_CODE();
491
return blk->root_state.open_flags;
492
}
493
494
BlockBackendRootState *blk_get_root_state(BlockBackend *blk)
495
{
496
+ GLOBAL_STATE_CODE();
497
return &blk->root_state;
498
}
499
500
int blk_commit_all(void)
501
{
502
BlockBackend *blk = NULL;
503
+ GLOBAL_STATE_CODE();
504
505
while ((blk = blk_all_next(blk)) != NULL) {
506
AioContext *aio_context = blk_get_aio_context(blk);
507
@@ -XXX,XX +XXX,XX @@ int blk_commit_all(void)
508
/* throttling disk I/O limits */
509
void blk_set_io_limits(BlockBackend *blk, ThrottleConfig *cfg)
510
{
511
+ GLOBAL_STATE_CODE();
512
throttle_group_config(&blk->public.throttle_group_member, cfg);
513
}
514
515
@@ -XXX,XX +XXX,XX @@ void blk_io_limits_disable(BlockBackend *blk)
516
BlockDriverState *bs = blk_bs(blk);
517
ThrottleGroupMember *tgm = &blk->public.throttle_group_member;
518
assert(tgm->throttle_state);
519
+ GLOBAL_STATE_CODE();
520
if (bs) {
521
bdrv_ref(bs);
522
bdrv_drained_begin(bs);
523
@@ -XXX,XX +XXX,XX @@ void blk_io_limits_disable(BlockBackend *blk)
524
void blk_io_limits_enable(BlockBackend *blk, const char *group)
525
{
526
assert(!blk->public.throttle_group_member.throttle_state);
527
+ GLOBAL_STATE_CODE();
528
throttle_group_register_tgm(&blk->public.throttle_group_member,
529
group, blk_get_aio_context(blk));
530
}
531
532
void blk_io_limits_update_group(BlockBackend *blk, const char *group)
533
{
534
+ GLOBAL_STATE_CODE();
535
/* this BB is not part of any group */
536
if (!blk->public.throttle_group_member.throttle_state) {
537
return;
538
@@ -XXX,XX +XXX,XX @@ static void blk_root_drained_end(BdrvChild *child, int *drained_end_counter)
539
540
void blk_register_buf(BlockBackend *blk, void *host, size_t size)
541
{
542
+ GLOBAL_STATE_CODE();
543
bdrv_register_buf(blk_bs(blk), host, size);
544
}
545
546
void blk_unregister_buf(BlockBackend *blk, void *host)
547
{
548
+ GLOBAL_STATE_CODE();
549
bdrv_unregister_buf(blk_bs(blk), host);
550
}
551
552
@@ -XXX,XX +XXX,XX @@ int coroutine_fn blk_co_copy_range(BlockBackend *blk_in, int64_t off_in,
553
554
const BdrvChild *blk_root(BlockBackend *blk)
555
{
556
+ GLOBAL_STATE_CODE();
557
return blk->root;
558
}
559
560
int blk_make_empty(BlockBackend *blk, Error **errp)
561
{
562
+ GLOBAL_STATE_CODE();
563
if (!blk_is_available(blk)) {
564
error_setg(errp, "No medium inserted");
565
return -ENOMEDIUM;
566
diff --git a/softmmu/qdev-monitor.c b/softmmu/qdev-monitor.c
567
index XXXXXXX..XXXXXXX 100644
568
--- a/softmmu/qdev-monitor.c
569
+++ b/softmmu/qdev-monitor.c
570
@@ -XXX,XX +XXX,XX @@ BlockBackend *blk_by_qdev_id(const char *id, Error **errp)
571
DeviceState *dev;
572
BlockBackend *blk;
573
574
+ GLOBAL_STATE_CODE();
575
+
576
dev = find_device_state(id, errp);
577
if (dev == NULL) {
578
return NULL;
579
--
580
2.35.1
diff view generated by jsdifflib
New patch
1
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
1
2
3
Mark all I/O functions with IO_CODE, and all "I/O OR GS" with
4
IO_OR_GS_CODE.
5
6
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
7
Message-Id: <20220303151616.325444-10-eesposit@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
---
10
include/sysemu/block-backend-io.h | 2 ++
11
block/block-backend.c | 58 +++++++++++++++++++++++++++++++
12
2 files changed, 60 insertions(+)
13
14
diff --git a/include/sysemu/block-backend-io.h b/include/sysemu/block-backend-io.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/include/sysemu/block-backend-io.h
17
+++ b/include/sysemu/block-backend-io.h
18
@@ -XXX,XX +XXX,XX @@ static inline int coroutine_fn blk_co_pread(BlockBackend *blk, int64_t offset,
19
BdrvRequestFlags flags)
20
{
21
QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, bytes);
22
+ IO_OR_GS_CODE();
23
24
assert(bytes <= SIZE_MAX);
25
26
@@ -XXX,XX +XXX,XX @@ static inline int coroutine_fn blk_co_pwrite(BlockBackend *blk, int64_t offset,
27
BdrvRequestFlags flags)
28
{
29
QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, bytes);
30
+ IO_OR_GS_CODE();
31
32
assert(bytes <= SIZE_MAX);
33
34
diff --git a/block/block-backend.c b/block/block-backend.c
35
index XXXXXXX..XXXXXXX 100644
36
--- a/block/block-backend.c
37
+++ b/block/block-backend.c
38
@@ -XXX,XX +XXX,XX @@ void monitor_remove_blk(BlockBackend *blk)
39
*/
40
const char *blk_name(const BlockBackend *blk)
41
{
42
+ IO_CODE();
43
return blk->name ?: "";
44
}
45
46
@@ -XXX,XX +XXX,XX @@ BlockBackend *blk_by_name(const char *name)
47
*/
48
BlockDriverState *blk_bs(BlockBackend *blk)
49
{
50
+ IO_CODE();
51
return blk->root ? blk->root->bs : NULL;
52
}
53
54
@@ -XXX,XX +XXX,XX @@ DeviceState *blk_get_attached_dev(BlockBackend *blk)
55
char *blk_get_attached_dev_id(BlockBackend *blk)
56
{
57
DeviceState *dev = blk->dev;
58
+ IO_CODE();
59
60
if (!dev) {
61
return g_strdup("");
62
@@ -XXX,XX +XXX,XX @@ void blk_iostatus_enable(BlockBackend *blk)
63
* enables it _and_ the VM is configured to stop on errors */
64
bool blk_iostatus_is_enabled(const BlockBackend *blk)
65
{
66
+ IO_CODE();
67
return (blk->iostatus_enabled &&
68
(blk->on_write_error == BLOCKDEV_ON_ERROR_ENOSPC ||
69
blk->on_write_error == BLOCKDEV_ON_ERROR_STOP ||
70
@@ -XXX,XX +XXX,XX @@ void blk_iostatus_reset(BlockBackend *blk)
71
72
void blk_iostatus_set_err(BlockBackend *blk, int error)
73
{
74
+ IO_CODE();
75
assert(blk_iostatus_is_enabled(blk));
76
if (blk->iostatus == BLOCK_DEVICE_IO_STATUS_OK) {
77
blk->iostatus = error == ENOSPC ? BLOCK_DEVICE_IO_STATUS_NOSPACE :
78
@@ -XXX,XX +XXX,XX @@ void blk_iostatus_set_err(BlockBackend *blk, int error)
79
80
void blk_set_allow_write_beyond_eof(BlockBackend *blk, bool allow)
81
{
82
+ IO_CODE();
83
blk->allow_write_beyond_eof = allow;
84
}
85
86
void blk_set_allow_aio_context_change(BlockBackend *blk, bool allow)
87
{
88
+ IO_CODE();
89
blk->allow_aio_context_change = allow;
90
}
91
92
void blk_set_disable_request_queuing(BlockBackend *blk, bool disable)
93
{
94
+ IO_CODE();
95
blk->disable_request_queuing = disable;
96
}
97
98
@@ -XXX,XX +XXX,XX @@ int coroutine_fn blk_co_preadv(BlockBackend *blk, int64_t offset,
99
BdrvRequestFlags flags)
100
{
101
int ret;
102
+ IO_OR_GS_CODE();
103
104
blk_inc_in_flight(blk);
105
ret = blk_co_do_preadv(blk, offset, bytes, qiov, flags);
106
@@ -XXX,XX +XXX,XX @@ int coroutine_fn blk_co_pwritev_part(BlockBackend *blk, int64_t offset,
107
BdrvRequestFlags flags)
108
{
109
int ret;
110
+ IO_OR_GS_CODE();
111
112
blk_inc_in_flight(blk);
113
ret = blk_co_do_pwritev_part(blk, offset, bytes, qiov, qiov_offset, flags);
114
@@ -XXX,XX +XXX,XX @@ int coroutine_fn blk_co_pwritev(BlockBackend *blk, int64_t offset,
115
int64_t bytes, QEMUIOVector *qiov,
116
BdrvRequestFlags flags)
117
{
118
+ IO_OR_GS_CODE();
119
return blk_co_pwritev_part(blk, offset, bytes, qiov, 0, flags);
120
}
121
122
@@ -XXX,XX +XXX,XX @@ typedef struct BlkRwCo {
123
int blk_pwrite_zeroes(BlockBackend *blk, int64_t offset,
124
int64_t bytes, BdrvRequestFlags flags)
125
{
126
+ IO_OR_GS_CODE();
127
return blk_pwritev_part(blk, offset, bytes, NULL, 0,
128
flags | BDRV_REQ_ZERO_WRITE);
129
}
130
@@ -XXX,XX +XXX,XX @@ int blk_make_zero(BlockBackend *blk, BdrvRequestFlags flags)
131
132
void blk_inc_in_flight(BlockBackend *blk)
133
{
134
+ IO_CODE();
135
qatomic_inc(&blk->in_flight);
136
}
137
138
void blk_dec_in_flight(BlockBackend *blk)
139
{
140
+ IO_CODE();
141
qatomic_dec(&blk->in_flight);
142
aio_wait_kick();
143
}
144
@@ -XXX,XX +XXX,XX @@ BlockAIOCB *blk_abort_aio_request(BlockBackend *blk,
145
void *opaque, int ret)
146
{
147
struct BlockBackendAIOCB *acb;
148
+ IO_CODE();
149
150
blk_inc_in_flight(blk);
151
acb = blk_aio_get(&block_backend_aiocb_info, blk, cb, opaque);
152
@@ -XXX,XX +XXX,XX @@ BlockAIOCB *blk_aio_pwrite_zeroes(BlockBackend *blk, int64_t offset,
153
int64_t bytes, BdrvRequestFlags flags,
154
BlockCompletionFunc *cb, void *opaque)
155
{
156
+ IO_CODE();
157
return blk_aio_prwv(blk, offset, bytes, NULL, blk_aio_write_entry,
158
flags | BDRV_REQ_ZERO_WRITE, cb, opaque);
159
}
160
@@ -XXX,XX +XXX,XX @@ int blk_pread(BlockBackend *blk, int64_t offset, void *buf, int bytes)
161
{
162
int ret;
163
QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, bytes);
164
+ IO_OR_GS_CODE();
165
166
blk_inc_in_flight(blk);
167
ret = blk_do_preadv(blk, offset, bytes, &qiov, 0);
168
@@ -XXX,XX +XXX,XX @@ int blk_pwrite(BlockBackend *blk, int64_t offset, const void *buf, int bytes,
169
{
170
int ret;
171
QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, bytes);
172
+ IO_OR_GS_CODE();
173
174
ret = blk_pwritev_part(blk, offset, bytes, &qiov, 0, flags);
175
176
@@ -XXX,XX +XXX,XX @@ int blk_pwrite(BlockBackend *blk, int64_t offset, const void *buf, int bytes,
177
178
int64_t blk_getlength(BlockBackend *blk)
179
{
180
+ IO_CODE();
181
if (!blk_is_available(blk)) {
182
return -ENOMEDIUM;
183
}
184
@@ -XXX,XX +XXX,XX @@ int64_t blk_getlength(BlockBackend *blk)
185
186
void blk_get_geometry(BlockBackend *blk, uint64_t *nb_sectors_ptr)
187
{
188
+ IO_CODE();
189
if (!blk_bs(blk)) {
190
*nb_sectors_ptr = 0;
191
} else {
192
@@ -XXX,XX +XXX,XX @@ void blk_get_geometry(BlockBackend *blk, uint64_t *nb_sectors_ptr)
193
194
int64_t blk_nb_sectors(BlockBackend *blk)
195
{
196
+ IO_CODE();
197
if (!blk_is_available(blk)) {
198
return -ENOMEDIUM;
199
}
200
@@ -XXX,XX +XXX,XX @@ BlockAIOCB *blk_aio_preadv(BlockBackend *blk, int64_t offset,
201
QEMUIOVector *qiov, BdrvRequestFlags flags,
202
BlockCompletionFunc *cb, void *opaque)
203
{
204
+ IO_CODE();
205
assert((uint64_t)qiov->size <= INT64_MAX);
206
return blk_aio_prwv(blk, offset, qiov->size, qiov,
207
blk_aio_read_entry, flags, cb, opaque);
208
@@ -XXX,XX +XXX,XX @@ BlockAIOCB *blk_aio_pwritev(BlockBackend *blk, int64_t offset,
209
QEMUIOVector *qiov, BdrvRequestFlags flags,
210
BlockCompletionFunc *cb, void *opaque)
211
{
212
+ IO_CODE();
213
assert((uint64_t)qiov->size <= INT64_MAX);
214
return blk_aio_prwv(blk, offset, qiov->size, qiov,
215
blk_aio_write_entry, flags, cb, opaque);
216
@@ -XXX,XX +XXX,XX @@ void blk_aio_cancel(BlockAIOCB *acb)
217
218
void blk_aio_cancel_async(BlockAIOCB *acb)
219
{
220
+ IO_CODE();
221
bdrv_aio_cancel_async(acb);
222
}
223
224
@@ -XXX,XX +XXX,XX @@ blk_co_do_ioctl(BlockBackend *blk, unsigned long int req, void *buf)
225
int blk_ioctl(BlockBackend *blk, unsigned long int req, void *buf)
226
{
227
int ret;
228
+ IO_OR_GS_CODE();
229
230
blk_inc_in_flight(blk);
231
ret = blk_do_ioctl(blk, req, buf);
232
@@ -XXX,XX +XXX,XX @@ static void blk_aio_ioctl_entry(void *opaque)
233
BlockAIOCB *blk_aio_ioctl(BlockBackend *blk, unsigned long int req, void *buf,
234
BlockCompletionFunc *cb, void *opaque)
235
{
236
+ IO_CODE();
237
return blk_aio_prwv(blk, req, 0, buf, blk_aio_ioctl_entry, 0, cb, opaque);
238
}
239
240
@@ -XXX,XX +XXX,XX @@ BlockAIOCB *blk_aio_pdiscard(BlockBackend *blk,
241
int64_t offset, int64_t bytes,
242
BlockCompletionFunc *cb, void *opaque)
243
{
244
+ IO_CODE();
245
return blk_aio_prwv(blk, offset, bytes, NULL, blk_aio_pdiscard_entry, 0,
246
cb, opaque);
247
}
248
@@ -XXX,XX +XXX,XX @@ int coroutine_fn blk_co_pdiscard(BlockBackend *blk, int64_t offset,
249
int64_t bytes)
250
{
251
int ret;
252
+ IO_OR_GS_CODE();
253
254
blk_inc_in_flight(blk);
255
ret = blk_co_do_pdiscard(blk, offset, bytes);
256
@@ -XXX,XX +XXX,XX @@ int coroutine_fn blk_co_pdiscard(BlockBackend *blk, int64_t offset,
257
int blk_pdiscard(BlockBackend *blk, int64_t offset, int64_t bytes)
258
{
259
int ret;
260
+ IO_OR_GS_CODE();
261
262
blk_inc_in_flight(blk);
263
ret = blk_do_pdiscard(blk, offset, bytes);
264
@@ -XXX,XX +XXX,XX @@ static void blk_aio_flush_entry(void *opaque)
265
BlockAIOCB *blk_aio_flush(BlockBackend *blk,
266
BlockCompletionFunc *cb, void *opaque)
267
{
268
+ IO_CODE();
269
return blk_aio_prwv(blk, 0, 0, NULL, blk_aio_flush_entry, 0, cb, opaque);
270
}
271
272
int coroutine_fn blk_co_flush(BlockBackend *blk)
273
{
274
int ret;
275
+ IO_OR_GS_CODE();
276
277
blk_inc_in_flight(blk);
278
ret = blk_co_do_flush(blk);
279
@@ -XXX,XX +XXX,XX @@ void blk_set_on_error(BlockBackend *blk, BlockdevOnError on_read_error,
280
281
BlockdevOnError blk_get_on_error(BlockBackend *blk, bool is_read)
282
{
283
+ IO_CODE();
284
return is_read ? blk->on_read_error : blk->on_write_error;
285
}
286
287
@@ -XXX,XX +XXX,XX @@ BlockErrorAction blk_get_error_action(BlockBackend *blk, bool is_read,
288
int error)
289
{
290
BlockdevOnError on_err = blk_get_on_error(blk, is_read);
291
+ IO_CODE();
292
293
switch (on_err) {
294
case BLOCKDEV_ON_ERROR_ENOSPC:
295
@@ -XXX,XX +XXX,XX @@ void blk_error_action(BlockBackend *blk, BlockErrorAction action,
296
bool is_read, int error)
297
{
298
assert(error >= 0);
299
+ IO_CODE();
300
301
if (action == BLOCK_ERROR_ACTION_STOP) {
302
/* First set the iostatus, so that "info block" returns an iostatus
303
@@ -XXX,XX +XXX,XX @@ bool blk_supports_write_perm(BlockBackend *blk)
304
*/
305
bool blk_is_writable(BlockBackend *blk)
306
{
307
+ IO_CODE();
308
return blk->perm & BLK_PERM_WRITE;
309
}
310
311
@@ -XXX,XX +XXX,XX @@ bool blk_is_sg(BlockBackend *blk)
312
313
bool blk_enable_write_cache(BlockBackend *blk)
314
{
315
+ IO_CODE();
316
return blk->enable_write_cache;
317
}
318
319
@@ -XXX,XX +XXX,XX @@ void blk_activate(BlockBackend *blk, Error **errp)
320
bool blk_is_inserted(BlockBackend *blk)
321
{
322
BlockDriverState *bs = blk_bs(blk);
323
+ IO_CODE();
324
325
return bs && bdrv_is_inserted(bs);
326
}
327
328
bool blk_is_available(BlockBackend *blk)
329
{
330
+ IO_CODE();
331
return blk_is_inserted(blk) && !blk_dev_is_tray_open(blk);
332
}
333
334
void blk_lock_medium(BlockBackend *blk, bool locked)
335
{
336
BlockDriverState *bs = blk_bs(blk);
337
+ IO_CODE();
338
339
if (bs) {
340
bdrv_lock_medium(bs, locked);
341
@@ -XXX,XX +XXX,XX @@ void blk_eject(BlockBackend *blk, bool eject_flag)
342
{
343
BlockDriverState *bs = blk_bs(blk);
344
char *id;
345
+ IO_CODE();
346
347
if (bs) {
348
bdrv_eject(bs, eject_flag);
349
@@ -XXX,XX +XXX,XX @@ int blk_get_flags(BlockBackend *blk)
350
uint32_t blk_get_request_alignment(BlockBackend *blk)
351
{
352
BlockDriverState *bs = blk_bs(blk);
353
+ IO_CODE();
354
return bs ? bs->bl.request_alignment : BDRV_SECTOR_SIZE;
355
}
356
357
@@ -XXX,XX +XXX,XX @@ uint64_t blk_get_max_hw_transfer(BlockBackend *blk)
358
{
359
BlockDriverState *bs = blk_bs(blk);
360
uint64_t max = INT_MAX;
361
+ IO_CODE();
362
363
if (bs) {
364
max = MIN_NON_ZERO(max, bs->bl.max_hw_transfer);
365
@@ -XXX,XX +XXX,XX @@ uint32_t blk_get_max_transfer(BlockBackend *blk)
366
{
367
BlockDriverState *bs = blk_bs(blk);
368
uint32_t max = INT_MAX;
369
+ IO_CODE();
370
371
if (bs) {
372
max = MIN_NON_ZERO(max, bs->bl.max_transfer);
373
@@ -XXX,XX +XXX,XX @@ uint32_t blk_get_max_transfer(BlockBackend *blk)
374
375
int blk_get_max_hw_iov(BlockBackend *blk)
376
{
377
+ IO_CODE();
378
return MIN_NON_ZERO(blk->root->bs->bl.max_hw_iov,
379
blk->root->bs->bl.max_iov);
380
}
381
382
int blk_get_max_iov(BlockBackend *blk)
383
{
384
+ IO_CODE();
385
return blk->root->bs->bl.max_iov;
386
}
387
388
void blk_set_guest_block_size(BlockBackend *blk, int align)
389
{
390
+ IO_CODE();
391
blk->guest_block_size = align;
392
}
393
394
void *blk_try_blockalign(BlockBackend *blk, size_t size)
395
{
396
+ IO_CODE();
397
return qemu_try_blockalign(blk ? blk_bs(blk) : NULL, size);
398
}
399
400
void *blk_blockalign(BlockBackend *blk, size_t size)
401
{
402
+ IO_CODE();
403
return qemu_blockalign(blk ? blk_bs(blk) : NULL, size);
404
}
405
406
@@ -XXX,XX +XXX,XX @@ void blk_op_unblock_all(BlockBackend *blk, Error *reason)
407
AioContext *blk_get_aio_context(BlockBackend *blk)
408
{
409
BlockDriverState *bs = blk_bs(blk);
410
+ IO_CODE();
411
412
if (bs) {
413
AioContext *ctx = bdrv_get_aio_context(blk_bs(blk));
414
@@ -XXX,XX +XXX,XX @@ void blk_add_insert_bs_notifier(BlockBackend *blk, Notifier *notify)
415
void blk_io_plug(BlockBackend *blk)
416
{
417
BlockDriverState *bs = blk_bs(blk);
418
+ IO_CODE();
419
420
if (bs) {
421
bdrv_io_plug(bs);
422
@@ -XXX,XX +XXX,XX @@ void blk_io_plug(BlockBackend *blk)
423
void blk_io_unplug(BlockBackend *blk)
424
{
425
BlockDriverState *bs = blk_bs(blk);
426
+ IO_CODE();
427
428
if (bs) {
429
bdrv_io_unplug(bs);
430
@@ -XXX,XX +XXX,XX @@ void blk_io_unplug(BlockBackend *blk)
431
432
BlockAcctStats *blk_get_stats(BlockBackend *blk)
433
{
434
+ IO_CODE();
435
return &blk->stats;
436
}
437
438
void *blk_aio_get(const AIOCBInfo *aiocb_info, BlockBackend *blk,
439
BlockCompletionFunc *cb, void *opaque)
440
{
441
+ IO_CODE();
442
return qemu_aio_get(aiocb_info, blk_bs(blk), cb, opaque);
443
}
444
445
int coroutine_fn blk_co_pwrite_zeroes(BlockBackend *blk, int64_t offset,
446
int64_t bytes, BdrvRequestFlags flags)
447
{
448
+ IO_OR_GS_CODE();
449
return blk_co_pwritev(blk, offset, bytes, NULL,
450
flags | BDRV_REQ_ZERO_WRITE);
451
}
452
@@ -XXX,XX +XXX,XX @@ int blk_pwrite_compressed(BlockBackend *blk, int64_t offset, const void *buf,
453
int64_t bytes)
454
{
455
QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, bytes);
456
+ IO_OR_GS_CODE();
457
return blk_pwritev_part(blk, offset, bytes, &qiov, 0,
458
BDRV_REQ_WRITE_COMPRESSED);
459
}
460
@@ -XXX,XX +XXX,XX @@ int blk_pwrite_compressed(BlockBackend *blk, int64_t offset, const void *buf,
461
int blk_truncate(BlockBackend *blk, int64_t offset, bool exact,
462
PreallocMode prealloc, BdrvRequestFlags flags, Error **errp)
463
{
464
+ IO_OR_GS_CODE();
465
if (!blk_is_available(blk)) {
466
error_setg(errp, "No medium inserted");
467
return -ENOMEDIUM;
468
@@ -XXX,XX +XXX,XX @@ int coroutine_fn blk_co_copy_range(BlockBackend *blk_in, int64_t off_in,
469
BdrvRequestFlags write_flags)
470
{
471
int r;
472
+ IO_CODE();
473
+
474
r = blk_check_byte_request(blk_in, off_in, bytes);
475
if (r) {
476
return r;
477
--
478
2.35.1
diff view generated by jsdifflib
New patch
1
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
1
2
3
Now that we "covered" the three main cases where the
4
permission API was being used under BQL (fuse,
5
amend and invalidate_cache), we can safely assert for
6
the permission functions implemented in block.c
7
8
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
9
Message-Id: <20220303151616.325444-11-eesposit@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
---
12
block.c | 12 ++++++++++++
13
1 file changed, 12 insertions(+)
14
15
diff --git a/block.c b/block.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/block.c
18
+++ b/block.c
19
@@ -XXX,XX +XXX,XX @@ static bool bdrv_a_allow_b(BdrvChild *a, BdrvChild *b, Error **errp)
20
21
assert(a->bs);
22
assert(a->bs == b->bs);
23
+ GLOBAL_STATE_CODE();
24
25
if ((b->perm & a->shared_perm) == b->perm) {
26
return true;
27
@@ -XXX,XX +XXX,XX @@ static bool bdrv_a_allow_b(BdrvChild *a, BdrvChild *b, Error **errp)
28
static bool bdrv_parent_perms_conflict(BlockDriverState *bs, Error **errp)
29
{
30
BdrvChild *a, *b;
31
+ GLOBAL_STATE_CODE();
32
33
/*
34
* During the loop we'll look at each pair twice. That's correct because
35
@@ -XXX,XX +XXX,XX @@ static void bdrv_child_set_perm_abort(void *opaque)
36
{
37
BdrvChildSetPermState *s = opaque;
38
39
+ GLOBAL_STATE_CODE();
40
+
41
s->child->perm = s->old_perm;
42
s->child->shared_perm = s->old_shared_perm;
43
}
44
@@ -XXX,XX +XXX,XX @@ static void bdrv_child_set_perm(BdrvChild *c, uint64_t perm,
45
uint64_t shared, Transaction *tran)
46
{
47
BdrvChildSetPermState *s = g_new(BdrvChildSetPermState, 1);
48
+ GLOBAL_STATE_CODE();
49
50
*s = (BdrvChildSetPermState) {
51
.child = c,
52
@@ -XXX,XX +XXX,XX @@ static int bdrv_node_refresh_perm(BlockDriverState *bs, BlockReopenQueue *q,
53
BdrvChild *c;
54
int ret;
55
uint64_t cumulative_perms, cumulative_shared_perms;
56
+ GLOBAL_STATE_CODE();
57
58
bdrv_get_cumulative_perm(bs, &cumulative_perms, &cumulative_shared_perms);
59
60
@@ -XXX,XX +XXX,XX @@ static int bdrv_list_refresh_perms(GSList *list, BlockReopenQueue *q,
61
{
62
int ret;
63
BlockDriverState *bs;
64
+ GLOBAL_STATE_CODE();
65
66
for ( ; list; list = list->next) {
67
bs = list->data;
68
@@ -XXX,XX +XXX,XX @@ static int bdrv_refresh_perms(BlockDriverState *bs, Error **errp)
69
int ret;
70
Transaction *tran = tran_new();
71
g_autoptr(GSList) list = bdrv_topological_dfs(NULL, NULL, bs);
72
+ GLOBAL_STATE_CODE();
73
74
ret = bdrv_list_refresh_perms(list, NULL, tran, errp);
75
tran_finalize(tran, ret);
76
@@ -XXX,XX +XXX,XX @@ static void bdrv_filter_default_perms(BlockDriverState *bs, BdrvChild *c,
77
uint64_t perm, uint64_t shared,
78
uint64_t *nperm, uint64_t *nshared)
79
{
80
+ GLOBAL_STATE_CODE();
81
*nperm = perm & DEFAULT_PERM_PASSTHROUGH;
82
*nshared = (shared & DEFAULT_PERM_PASSTHROUGH) | DEFAULT_PERM_UNCHANGED;
83
}
84
@@ -XXX,XX +XXX,XX @@ static void bdrv_default_perms_for_cow(BlockDriverState *bs, BdrvChild *c,
85
uint64_t *nperm, uint64_t *nshared)
86
{
87
assert(role & BDRV_CHILD_COW);
88
+ GLOBAL_STATE_CODE();
89
90
/*
91
* We want consistent read from backing files if the parent needs it.
92
@@ -XXX,XX +XXX,XX @@ static void bdrv_default_perms_for_storage(BlockDriverState *bs, BdrvChild *c,
93
{
94
int flags;
95
96
+ GLOBAL_STATE_CODE();
97
assert(role & (BDRV_CHILD_METADATA | BDRV_CHILD_DATA));
98
99
flags = bdrv_reopen_get_flags(reopen_queue, bs);
100
@@ -XXX,XX +XXX,XX @@ static void xdbg_graph_add_edge(XDbgBlockGraphConstructor *gr, void *parent,
101
{
102
BlockPermission qapi_perm;
103
XDbgBlockGraphEdge *edge;
104
+ GLOBAL_STATE_CODE();
105
106
edge = g_new0(XDbgBlockGraphEdge, 1);
107
108
--
109
2.35.1
diff view generated by jsdifflib
New patch
1
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
1
2
3
Similarly to the previous patch, split block_int.h
4
in block_int-io.h and block_int-global-state.h
5
6
block_int-common.h contains the structures shared between
7
the two headers, and the functions that can't be categorized as
8
I/O or global state.
9
10
Assertions are added in the next patch.
11
12
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
13
Message-Id: <20220303151616.325444-12-eesposit@redhat.com>
14
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
15
---
16
include/block/block_int-common.h | 1180 +++++++++++++++++++
17
include/block/block_int-global-state.h | 312 +++++
18
include/block/block_int-io.h | 179 +++
19
include/block/block_int.h | 1489 +-----------------------
20
blockdev.c | 5 +
21
5 files changed, 1679 insertions(+), 1486 deletions(-)
22
create mode 100644 include/block/block_int-common.h
23
create mode 100644 include/block/block_int-global-state.h
24
create mode 100644 include/block/block_int-io.h
25
26
diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h
27
new file mode 100644
28
index XXXXXXX..XXXXXXX
29
--- /dev/null
30
+++ b/include/block/block_int-common.h
31
@@ -XXX,XX +XXX,XX @@
32
+/*
33
+ * QEMU System Emulator block driver
34
+ *
35
+ * Copyright (c) 2003 Fabrice Bellard
36
+ *
37
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
38
+ * of this software and associated documentation files (the "Software"), to deal
39
+ * in the Software without restriction, including without limitation the rights
40
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
41
+ * copies of the Software, and to permit persons to whom the Software is
42
+ * furnished to do so, subject to the following conditions:
43
+ *
44
+ * The above copyright notice and this permission notice shall be included in
45
+ * all copies or substantial portions of the Software.
46
+ *
47
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
48
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
49
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
50
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
51
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
52
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
53
+ * THE SOFTWARE.
54
+ */
55
+#ifndef BLOCK_INT_COMMON_H
56
+#define BLOCK_INT_COMMON_H
57
+
58
+#include "block/accounting.h"
59
+#include "block/block.h"
60
+#include "block/aio-wait.h"
61
+#include "qemu/queue.h"
62
+#include "qemu/coroutine.h"
63
+#include "qemu/stats64.h"
64
+#include "qemu/timer.h"
65
+#include "qemu/hbitmap.h"
66
+#include "block/snapshot.h"
67
+#include "qemu/throttle.h"
68
+#include "qemu/rcu.h"
69
+
70
+#define BLOCK_FLAG_LAZY_REFCOUNTS 8
71
+
72
+#define BLOCK_OPT_SIZE "size"
73
+#define BLOCK_OPT_ENCRYPT "encryption"
74
+#define BLOCK_OPT_ENCRYPT_FORMAT "encrypt.format"
75
+#define BLOCK_OPT_COMPAT6 "compat6"
76
+#define BLOCK_OPT_HWVERSION "hwversion"
77
+#define BLOCK_OPT_BACKING_FILE "backing_file"
78
+#define BLOCK_OPT_BACKING_FMT "backing_fmt"
79
+#define BLOCK_OPT_CLUSTER_SIZE "cluster_size"
80
+#define BLOCK_OPT_TABLE_SIZE "table_size"
81
+#define BLOCK_OPT_PREALLOC "preallocation"
82
+#define BLOCK_OPT_SUBFMT "subformat"
83
+#define BLOCK_OPT_COMPAT_LEVEL "compat"
84
+#define BLOCK_OPT_LAZY_REFCOUNTS "lazy_refcounts"
85
+#define BLOCK_OPT_ADAPTER_TYPE "adapter_type"
86
+#define BLOCK_OPT_REDUNDANCY "redundancy"
87
+#define BLOCK_OPT_NOCOW "nocow"
88
+#define BLOCK_OPT_EXTENT_SIZE_HINT "extent_size_hint"
89
+#define BLOCK_OPT_OBJECT_SIZE "object_size"
90
+#define BLOCK_OPT_REFCOUNT_BITS "refcount_bits"
91
+#define BLOCK_OPT_DATA_FILE "data_file"
92
+#define BLOCK_OPT_DATA_FILE_RAW "data_file_raw"
93
+#define BLOCK_OPT_COMPRESSION_TYPE "compression_type"
94
+#define BLOCK_OPT_EXTL2 "extended_l2"
95
+
96
+#define BLOCK_PROBE_BUF_SIZE 512
97
+
98
+enum BdrvTrackedRequestType {
99
+ BDRV_TRACKED_READ,
100
+ BDRV_TRACKED_WRITE,
101
+ BDRV_TRACKED_DISCARD,
102
+ BDRV_TRACKED_TRUNCATE,
103
+};
104
+
105
+/*
106
+ * That is not quite good that BdrvTrackedRequest structure is public,
107
+ * as block/io.c is very careful about incoming offset/bytes being
108
+ * correct. Be sure to assert bdrv_check_request() succeeded after any
109
+ * modification of BdrvTrackedRequest object out of block/io.c
110
+ */
111
+typedef struct BdrvTrackedRequest {
112
+ BlockDriverState *bs;
113
+ int64_t offset;
114
+ int64_t bytes;
115
+ enum BdrvTrackedRequestType type;
116
+
117
+ bool serialising;
118
+ int64_t overlap_offset;
119
+ int64_t overlap_bytes;
120
+
121
+ QLIST_ENTRY(BdrvTrackedRequest) list;
122
+ Coroutine *co; /* owner, used for deadlock detection */
123
+ CoQueue wait_queue; /* coroutines blocked on this request */
124
+
125
+ struct BdrvTrackedRequest *waiting_for;
126
+} BdrvTrackedRequest;
127
+
128
+
129
+struct BlockDriver {
130
+ const char *format_name;
131
+ int instance_size;
132
+
133
+ /*
134
+ * Set to true if the BlockDriver is a block filter. Block filters pass
135
+ * certain callbacks that refer to data (see block.c) to their bs->file
136
+ * or bs->backing (whichever one exists) if the driver doesn't implement
137
+ * them. Drivers that do not wish to forward must implement them and return
138
+ * -ENOTSUP.
139
+ * Note that filters are not allowed to modify data.
140
+ *
141
+ * Filters generally cannot have more than a single filtered child,
142
+ * because the data they present must at all times be the same as
143
+ * that on their filtered child. That would be impossible to
144
+ * achieve for multiple filtered children.
145
+ * (And this filtered child must then be bs->file or bs->backing.)
146
+ */
147
+ bool is_filter;
148
+ /*
149
+ * Set to true if the BlockDriver is a format driver. Format nodes
150
+ * generally do not expect their children to be other format nodes
151
+ * (except for backing files), and so format probing is disabled
152
+ * on those children.
153
+ */
154
+ bool is_format;
155
+
156
+ /*
157
+ * This function is invoked under BQL before .bdrv_co_amend()
158
+ * (which in contrast does not necessarily run under the BQL)
159
+ * to allow driver-specific initialization code that requires
160
+ * the BQL, like setting up specific permission flags.
161
+ */
162
+ int (*bdrv_amend_pre_run)(BlockDriverState *bs, Error **errp);
163
+ /*
164
+ * This function is invoked under BQL after .bdrv_co_amend()
165
+ * to allow cleaning up what was done in .bdrv_amend_pre_run().
166
+ */
167
+ void (*bdrv_amend_clean)(BlockDriverState *bs);
168
+
169
+ /*
170
+ * Return true if @to_replace can be replaced by a BDS with the
171
+ * same data as @bs without it affecting @bs's behavior (that is,
172
+ * without it being visible to @bs's parents).
173
+ */
174
+ bool (*bdrv_recurse_can_replace)(BlockDriverState *bs,
175
+ BlockDriverState *to_replace);
176
+
177
+ int (*bdrv_probe)(const uint8_t *buf, int buf_size, const char *filename);
178
+ int (*bdrv_probe_device)(const char *filename);
179
+
180
+ /*
181
+ * Any driver implementing this callback is expected to be able to handle
182
+ * NULL file names in its .bdrv_open() implementation.
183
+ */
184
+ void (*bdrv_parse_filename)(const char *filename, QDict *options,
185
+ Error **errp);
186
+ /*
187
+ * Drivers not implementing bdrv_parse_filename nor bdrv_open should have
188
+ * this field set to true, except ones that are defined only by their
189
+ * child's bs.
190
+ * An example of the last type will be the quorum block driver.
191
+ */
192
+ bool bdrv_needs_filename;
193
+
194
+ /*
195
+ * Set if a driver can support backing files. This also implies the
196
+ * following semantics:
197
+ *
198
+ * - Return status 0 of .bdrv_co_block_status means that corresponding
199
+ * blocks are not allocated in this layer of backing-chain
200
+ * - For such (unallocated) blocks, read will:
201
+ * - fill buffer with zeros if there is no backing file
202
+ * - read from the backing file otherwise, where the block layer
203
+ * takes care of reading zeros beyond EOF if backing file is short
204
+ */
205
+ bool supports_backing;
206
+
207
+ /* For handling image reopen for split or non-split files */
208
+ int (*bdrv_reopen_prepare)(BDRVReopenState *reopen_state,
209
+ BlockReopenQueue *queue, Error **errp);
210
+ void (*bdrv_reopen_commit)(BDRVReopenState *reopen_state);
211
+ void (*bdrv_reopen_commit_post)(BDRVReopenState *reopen_state);
212
+ void (*bdrv_reopen_abort)(BDRVReopenState *reopen_state);
213
+ void (*bdrv_join_options)(QDict *options, QDict *old_options);
214
+
215
+ int (*bdrv_open)(BlockDriverState *bs, QDict *options, int flags,
216
+ Error **errp);
217
+
218
+ /* Protocol drivers should implement this instead of bdrv_open */
219
+ int (*bdrv_file_open)(BlockDriverState *bs, QDict *options, int flags,
220
+ Error **errp);
221
+ void (*bdrv_close)(BlockDriverState *bs);
222
+
223
+
224
+ int coroutine_fn (*bdrv_co_create)(BlockdevCreateOptions *opts,
225
+ Error **errp);
226
+ int coroutine_fn (*bdrv_co_create_opts)(BlockDriver *drv,
227
+ const char *filename,
228
+ QemuOpts *opts,
229
+ Error **errp);
230
+
231
+ int coroutine_fn (*bdrv_co_amend)(BlockDriverState *bs,
232
+ BlockdevAmendOptions *opts,
233
+ bool force,
234
+ Error **errp);
235
+
236
+ int (*bdrv_amend_options)(BlockDriverState *bs,
237
+ QemuOpts *opts,
238
+ BlockDriverAmendStatusCB *status_cb,
239
+ void *cb_opaque,
240
+ bool force,
241
+ Error **errp);
242
+
243
+ int (*bdrv_make_empty)(BlockDriverState *bs);
244
+
245
+ /*
246
+ * Refreshes the bs->exact_filename field. If that is impossible,
247
+ * bs->exact_filename has to be left empty.
248
+ */
249
+ void (*bdrv_refresh_filename)(BlockDriverState *bs);
250
+
251
+ /*
252
+ * Gathers the open options for all children into @target.
253
+ * A simple format driver (without backing file support) might
254
+ * implement this function like this:
255
+ *
256
+ * QINCREF(bs->file->bs->full_open_options);
257
+ * qdict_put(target, "file", bs->file->bs->full_open_options);
258
+ *
259
+ * If not specified, the generic implementation will simply put
260
+ * all children's options under their respective name.
261
+ *
262
+ * @backing_overridden is true when bs->backing seems not to be
263
+ * the child that would result from opening bs->backing_file.
264
+ * Therefore, if it is true, the backing child's options should be
265
+ * gathered; otherwise, there is no need since the backing child
266
+ * is the one implied by the image header.
267
+ *
268
+ * Note that ideally this function would not be needed. Every
269
+ * block driver which implements it is probably doing something
270
+ * shady regarding its runtime option structure.
271
+ */
272
+ void (*bdrv_gather_child_options)(BlockDriverState *bs, QDict *target,
273
+ bool backing_overridden);
274
+
275
+ /*
276
+ * Returns an allocated string which is the directory name of this BDS: It
277
+ * will be used to make relative filenames absolute by prepending this
278
+ * function's return value to them.
279
+ */
280
+ char *(*bdrv_dirname)(BlockDriverState *bs, Error **errp);
281
+
282
+ /* aio */
283
+ BlockAIOCB *(*bdrv_aio_preadv)(BlockDriverState *bs,
284
+ int64_t offset, int64_t bytes, QEMUIOVector *qiov,
285
+ BdrvRequestFlags flags, BlockCompletionFunc *cb, void *opaque);
286
+ BlockAIOCB *(*bdrv_aio_pwritev)(BlockDriverState *bs,
287
+ int64_t offset, int64_t bytes, QEMUIOVector *qiov,
288
+ BdrvRequestFlags flags, BlockCompletionFunc *cb, void *opaque);
289
+ BlockAIOCB *(*bdrv_aio_flush)(BlockDriverState *bs,
290
+ BlockCompletionFunc *cb, void *opaque);
291
+ BlockAIOCB *(*bdrv_aio_pdiscard)(BlockDriverState *bs,
292
+ int64_t offset, int bytes,
293
+ BlockCompletionFunc *cb, void *opaque);
294
+
295
+ int coroutine_fn (*bdrv_co_readv)(BlockDriverState *bs,
296
+ int64_t sector_num, int nb_sectors, QEMUIOVector *qiov);
297
+
298
+ /**
299
+ * @offset: position in bytes to read at
300
+ * @bytes: number of bytes to read
301
+ * @qiov: the buffers to fill with read data
302
+ * @flags: currently unused, always 0
303
+ *
304
+ * @offset and @bytes will be a multiple of 'request_alignment',
305
+ * but the length of individual @qiov elements does not have to
306
+ * be a multiple.
307
+ *
308
+ * @bytes will always equal the total size of @qiov, and will be
309
+ * no larger than 'max_transfer'.
310
+ *
311
+ * The buffer in @qiov may point directly to guest memory.
312
+ */
313
+ int coroutine_fn (*bdrv_co_preadv)(BlockDriverState *bs,
314
+ int64_t offset, int64_t bytes, QEMUIOVector *qiov,
315
+ BdrvRequestFlags flags);
316
+
317
+ int coroutine_fn (*bdrv_co_preadv_part)(BlockDriverState *bs,
318
+ int64_t offset, int64_t bytes,
319
+ QEMUIOVector *qiov, size_t qiov_offset,
320
+ BdrvRequestFlags flags);
321
+
322
+ int coroutine_fn (*bdrv_co_writev)(BlockDriverState *bs,
323
+ int64_t sector_num, int nb_sectors, QEMUIOVector *qiov,
324
+ int flags);
325
+ /**
326
+ * @offset: position in bytes to write at
327
+ * @bytes: number of bytes to write
328
+ * @qiov: the buffers containing data to write
329
+ * @flags: zero or more bits allowed by 'supported_write_flags'
330
+ *
331
+ * @offset and @bytes will be a multiple of 'request_alignment',
332
+ * but the length of individual @qiov elements does not have to
333
+ * be a multiple.
334
+ *
335
+ * @bytes will always equal the total size of @qiov, and will be
336
+ * no larger than 'max_transfer'.
337
+ *
338
+ * The buffer in @qiov may point directly to guest memory.
339
+ */
340
+ int coroutine_fn (*bdrv_co_pwritev)(BlockDriverState *bs,
341
+ int64_t offset, int64_t bytes, QEMUIOVector *qiov,
342
+ BdrvRequestFlags flags);
343
+ int coroutine_fn (*bdrv_co_pwritev_part)(BlockDriverState *bs,
344
+ int64_t offset, int64_t bytes, QEMUIOVector *qiov, size_t qiov_offset,
345
+ BdrvRequestFlags flags);
346
+
347
+ /*
348
+ * Efficiently zero a region of the disk image. Typically an image format
349
+ * would use a compact metadata representation to implement this. This
350
+ * function pointer may be NULL or return -ENOSUP and .bdrv_co_writev()
351
+ * will be called instead.
352
+ */
353
+ int coroutine_fn (*bdrv_co_pwrite_zeroes)(BlockDriverState *bs,
354
+ int64_t offset, int64_t bytes, BdrvRequestFlags flags);
355
+ int coroutine_fn (*bdrv_co_pdiscard)(BlockDriverState *bs,
356
+ int64_t offset, int64_t bytes);
357
+
358
+ /*
359
+ * Map [offset, offset + nbytes) range onto a child of @bs to copy from,
360
+ * and invoke bdrv_co_copy_range_from(child, ...), or invoke
361
+ * bdrv_co_copy_range_to() if @bs is the leaf child to copy data from.
362
+ *
363
+ * See the comment of bdrv_co_copy_range for the parameter and return value
364
+ * semantics.
365
+ */
366
+ int coroutine_fn (*bdrv_co_copy_range_from)(BlockDriverState *bs,
367
+ BdrvChild *src,
368
+ int64_t offset,
369
+ BdrvChild *dst,
370
+ int64_t dst_offset,
371
+ int64_t bytes,
372
+ BdrvRequestFlags read_flags,
373
+ BdrvRequestFlags write_flags);
374
+
375
+ /*
376
+ * Map [offset, offset + nbytes) range onto a child of bs to copy data to,
377
+ * and invoke bdrv_co_copy_range_to(child, src, ...), or perform the copy
378
+ * operation if @bs is the leaf and @src has the same BlockDriver. Return
379
+ * -ENOTSUP if @bs is the leaf but @src has a different BlockDriver.
380
+ *
381
+ * See the comment of bdrv_co_copy_range for the parameter and return value
382
+ * semantics.
383
+ */
384
+ int coroutine_fn (*bdrv_co_copy_range_to)(BlockDriverState *bs,
385
+ BdrvChild *src,
386
+ int64_t src_offset,
387
+ BdrvChild *dst,
388
+ int64_t dst_offset,
389
+ int64_t bytes,
390
+ BdrvRequestFlags read_flags,
391
+ BdrvRequestFlags write_flags);
392
+
393
+ /*
394
+ * Building block for bdrv_block_status[_above] and
395
+ * bdrv_is_allocated[_above]. The driver should answer only
396
+ * according to the current layer, and should only need to set
397
+ * BDRV_BLOCK_DATA, BDRV_BLOCK_ZERO, BDRV_BLOCK_OFFSET_VALID,
398
+ * and/or BDRV_BLOCK_RAW; if the current layer defers to a backing
399
+ * layer, the result should be 0 (and not BDRV_BLOCK_ZERO). See
400
+ * block.h for the overall meaning of the bits. As a hint, the
401
+ * flag want_zero is true if the caller cares more about precise
402
+ * mappings (favor accurate _OFFSET_VALID/_ZERO) or false for
403
+ * overall allocation (favor larger *pnum, perhaps by reporting
404
+ * _DATA instead of _ZERO). The block layer guarantees input
405
+ * clamped to bdrv_getlength() and aligned to request_alignment,
406
+ * as well as non-NULL pnum, map, and file; in turn, the driver
407
+ * must return an error or set pnum to an aligned non-zero value.
408
+ *
409
+ * Note that @bytes is just a hint on how big of a region the
410
+ * caller wants to inspect. It is not a limit on *pnum.
411
+ * Implementations are free to return larger values of *pnum if
412
+ * doing so does not incur a performance penalty.
413
+ *
414
+ * block/io.c's bdrv_co_block_status() will utilize an unclamped
415
+ * *pnum value for the block-status cache on protocol nodes, prior
416
+ * to clamping *pnum for return to its caller.
417
+ */
418
+ int coroutine_fn (*bdrv_co_block_status)(BlockDriverState *bs,
419
+ bool want_zero, int64_t offset, int64_t bytes, int64_t *pnum,
420
+ int64_t *map, BlockDriverState **file);
421
+
422
+ /*
423
+ * This informs the driver that we are no longer interested in the result
424
+ * of in-flight requests, so don't waste the time if possible.
425
+ *
426
+ * One example usage is to avoid waiting for an nbd target node reconnect
427
+ * timeout during job-cancel with force=true.
428
+ */
429
+ void (*bdrv_cancel_in_flight)(BlockDriverState *bs);
430
+
431
+ /*
432
+ * Invalidate any cached meta-data.
433
+ */
434
+ void coroutine_fn (*bdrv_co_invalidate_cache)(BlockDriverState *bs,
435
+ Error **errp);
436
+ int (*bdrv_inactivate)(BlockDriverState *bs);
437
+
438
+ /*
439
+ * Flushes all data for all layers by calling bdrv_co_flush for underlying
440
+ * layers, if needed. This function is needed for deterministic
441
+ * synchronization of the flush finishing callback.
442
+ */
443
+ int coroutine_fn (*bdrv_co_flush)(BlockDriverState *bs);
444
+
445
+ /* Delete a created file. */
446
+ int coroutine_fn (*bdrv_co_delete_file)(BlockDriverState *bs,
447
+ Error **errp);
448
+
449
+ /*
450
+ * Flushes all data that was already written to the OS all the way down to
451
+ * the disk (for example file-posix.c calls fsync()).
452
+ */
453
+ int coroutine_fn (*bdrv_co_flush_to_disk)(BlockDriverState *bs);
454
+
455
+ /*
456
+ * Flushes all internal caches to the OS. The data may still sit in a
457
+ * writeback cache of the host OS, but it will survive a crash of the qemu
458
+ * process.
459
+ */
460
+ int coroutine_fn (*bdrv_co_flush_to_os)(BlockDriverState *bs);
461
+
462
+ /*
463
+ * Drivers setting this field must be able to work with just a plain
464
+ * filename with '<protocol_name>:' as a prefix, and no other options.
465
+ * Options may be extracted from the filename by implementing
466
+ * bdrv_parse_filename.
467
+ */
468
+ const char *protocol_name;
469
+
470
+ /*
471
+ * Truncate @bs to @offset bytes using the given @prealloc mode
472
+ * when growing. Modes other than PREALLOC_MODE_OFF should be
473
+ * rejected when shrinking @bs.
474
+ *
475
+ * If @exact is true, @bs must be resized to exactly @offset.
476
+ * Otherwise, it is sufficient for @bs (if it is a host block
477
+ * device and thus there is no way to resize it) to be at least
478
+ * @offset bytes in length.
479
+ *
480
+ * If @exact is true and this function fails but would succeed
481
+ * with @exact = false, it should return -ENOTSUP.
482
+ */
483
+ int coroutine_fn (*bdrv_co_truncate)(BlockDriverState *bs, int64_t offset,
484
+ bool exact, PreallocMode prealloc,
485
+ BdrvRequestFlags flags, Error **errp);
486
+ int64_t (*bdrv_getlength)(BlockDriverState *bs);
487
+ bool has_variable_length;
488
+ int64_t (*bdrv_get_allocated_file_size)(BlockDriverState *bs);
489
+ BlockMeasureInfo *(*bdrv_measure)(QemuOpts *opts, BlockDriverState *in_bs,
490
+ Error **errp);
491
+
492
+ int coroutine_fn (*bdrv_co_pwritev_compressed)(BlockDriverState *bs,
493
+ int64_t offset, int64_t bytes, QEMUIOVector *qiov);
494
+ int coroutine_fn (*bdrv_co_pwritev_compressed_part)(BlockDriverState *bs,
495
+ int64_t offset, int64_t bytes, QEMUIOVector *qiov,
496
+ size_t qiov_offset);
497
+
498
+ int (*bdrv_snapshot_create)(BlockDriverState *bs,
499
+ QEMUSnapshotInfo *sn_info);
500
+ int (*bdrv_snapshot_goto)(BlockDriverState *bs,
501
+ const char *snapshot_id);
502
+ int (*bdrv_snapshot_delete)(BlockDriverState *bs,
503
+ const char *snapshot_id,
504
+ const char *name,
505
+ Error **errp);
506
+ int (*bdrv_snapshot_list)(BlockDriverState *bs,
507
+ QEMUSnapshotInfo **psn_info);
508
+ int (*bdrv_snapshot_load_tmp)(BlockDriverState *bs,
509
+ const char *snapshot_id,
510
+ const char *name,
511
+ Error **errp);
512
+ int (*bdrv_get_info)(BlockDriverState *bs, BlockDriverInfo *bdi);
513
+
514
+ ImageInfoSpecific *(*bdrv_get_specific_info)(BlockDriverState *bs,
515
+ Error **errp);
516
+ BlockStatsSpecific *(*bdrv_get_specific_stats)(BlockDriverState *bs);
517
+
518
+ int coroutine_fn (*bdrv_save_vmstate)(BlockDriverState *bs,
519
+ QEMUIOVector *qiov,
520
+ int64_t pos);
521
+ int coroutine_fn (*bdrv_load_vmstate)(BlockDriverState *bs,
522
+ QEMUIOVector *qiov,
523
+ int64_t pos);
524
+
525
+ int (*bdrv_change_backing_file)(BlockDriverState *bs,
526
+ const char *backing_file, const char *backing_fmt);
527
+
528
+ /* removable device specific */
529
+ bool (*bdrv_is_inserted)(BlockDriverState *bs);
530
+ void (*bdrv_eject)(BlockDriverState *bs, bool eject_flag);
531
+ void (*bdrv_lock_medium)(BlockDriverState *bs, bool locked);
532
+
533
+ /* to control generic scsi devices */
534
+ BlockAIOCB *(*bdrv_aio_ioctl)(BlockDriverState *bs,
535
+ unsigned long int req, void *buf,
536
+ BlockCompletionFunc *cb, void *opaque);
537
+ int coroutine_fn (*bdrv_co_ioctl)(BlockDriverState *bs,
538
+ unsigned long int req, void *buf);
539
+
540
+ /* List of options for creating images, terminated by name == NULL */
541
+ QemuOptsList *create_opts;
542
+
543
+ /* List of options for image amend */
544
+ QemuOptsList *amend_opts;
545
+
546
+ /*
547
+ * If this driver supports reopening images this contains a
548
+ * NULL-terminated list of the runtime options that can be
549
+ * modified. If an option in this list is unspecified during
550
+ * reopen then it _must_ be reset to its default value or return
551
+ * an error.
552
+ */
553
+ const char *const *mutable_opts;
554
+
555
+ /*
556
+ * Returns 0 for completed check, -errno for internal errors.
557
+ * The check results are stored in result.
558
+ */
559
+ int coroutine_fn (*bdrv_co_check)(BlockDriverState *bs,
560
+ BdrvCheckResult *result,
561
+ BdrvCheckMode fix);
562
+
563
+ void (*bdrv_debug_event)(BlockDriverState *bs, BlkdebugEvent event);
564
+
565
+ /* TODO Better pass a option string/QDict/QemuOpts to add any rule? */
566
+ int (*bdrv_debug_breakpoint)(BlockDriverState *bs, const char *event,
567
+ const char *tag);
568
+ int (*bdrv_debug_remove_breakpoint)(BlockDriverState *bs,
569
+ const char *tag);
570
+ int (*bdrv_debug_resume)(BlockDriverState *bs, const char *tag);
571
+ bool (*bdrv_debug_is_suspended)(BlockDriverState *bs, const char *tag);
572
+
573
+ void (*bdrv_refresh_limits)(BlockDriverState *bs, Error **errp);
574
+
575
+ /*
576
+ * Returns 1 if newly created images are guaranteed to contain only
577
+ * zeros, 0 otherwise.
578
+ */
579
+ int (*bdrv_has_zero_init)(BlockDriverState *bs);
580
+
581
+ /*
582
+ * Remove fd handlers, timers, and other event loop callbacks so the event
583
+ * loop is no longer in use. Called with no in-flight requests and in
584
+ * depth-first traversal order with parents before child nodes.
585
+ */
586
+ void (*bdrv_detach_aio_context)(BlockDriverState *bs);
587
+
588
+ /*
589
+ * Add fd handlers, timers, and other event loop callbacks so I/O requests
590
+ * can be processed again. Called with no in-flight requests and in
591
+ * depth-first traversal order with child nodes before parent nodes.
592
+ */
593
+ void (*bdrv_attach_aio_context)(BlockDriverState *bs,
594
+ AioContext *new_context);
595
+
596
+ /* io queue for linux-aio */
597
+ void (*bdrv_io_plug)(BlockDriverState *bs);
598
+ void (*bdrv_io_unplug)(BlockDriverState *bs);
599
+
600
+ /**
601
+ * Try to get @bs's logical and physical block size.
602
+ * On success, store them in @bsz and return zero.
603
+ * On failure, return negative errno.
604
+ */
605
+ int (*bdrv_probe_blocksizes)(BlockDriverState *bs, BlockSizes *bsz);
606
+ /**
607
+ * Try to get @bs's geometry (cyls, heads, sectors)
608
+ * On success, store them in @geo and return 0.
609
+ * On failure return -errno.
610
+ * Only drivers that want to override guest geometry implement this
611
+ * callback; see hd_geometry_guess().
612
+ */
613
+ int (*bdrv_probe_geometry)(BlockDriverState *bs, HDGeometry *geo);
614
+
615
+ /**
616
+ * bdrv_co_drain_begin is called if implemented in the beginning of a
617
+ * drain operation to drain and stop any internal sources of requests in
618
+ * the driver.
619
+ * bdrv_co_drain_end is called if implemented at the end of the drain.
620
+ *
621
+ * They should be used by the driver to e.g. manage scheduled I/O
622
+ * requests, or toggle an internal state. After the end of the drain new
623
+ * requests will continue normally.
624
+ */
625
+ void coroutine_fn (*bdrv_co_drain_begin)(BlockDriverState *bs);
626
+ void coroutine_fn (*bdrv_co_drain_end)(BlockDriverState *bs);
627
+
628
+ void (*bdrv_add_child)(BlockDriverState *parent, BlockDriverState *child,
629
+ Error **errp);
630
+ void (*bdrv_del_child)(BlockDriverState *parent, BdrvChild *child,
631
+ Error **errp);
632
+
633
+ /**
634
+ * Informs the block driver that a permission change is intended. The
635
+ * driver checks whether the change is permissible and may take other
636
+ * preparations for the change (e.g. get file system locks). This operation
637
+ * is always followed either by a call to either .bdrv_set_perm or
638
+ * .bdrv_abort_perm_update.
639
+ *
640
+ * Checks whether the requested set of cumulative permissions in @perm
641
+ * can be granted for accessing @bs and whether no other users are using
642
+ * permissions other than those given in @shared (both arguments take
643
+ * BLK_PERM_* bitmasks).
644
+ *
645
+ * If both conditions are met, 0 is returned. Otherwise, -errno is returned
646
+ * and errp is set to an error describing the conflict.
647
+ */
648
+ int (*bdrv_check_perm)(BlockDriverState *bs, uint64_t perm,
649
+ uint64_t shared, Error **errp);
650
+
651
+ /**
652
+ * Called to inform the driver that the set of cumulative set of used
653
+ * permissions for @bs has changed to @perm, and the set of sharable
654
+ * permission to @shared. The driver can use this to propagate changes to
655
+ * its children (i.e. request permissions only if a parent actually needs
656
+ * them).
657
+ *
658
+ * This function is only invoked after bdrv_check_perm(), so block drivers
659
+ * may rely on preparations made in their .bdrv_check_perm implementation.
660
+ */
661
+ void (*bdrv_set_perm)(BlockDriverState *bs, uint64_t perm, uint64_t shared);
662
+
663
+ /*
664
+ * Called to inform the driver that after a previous bdrv_check_perm()
665
+ * call, the permission update is not performed and any preparations made
666
+ * for it (e.g. taken file locks) need to be undone.
667
+ *
668
+ * This function can be called even for nodes that never saw a
669
+ * bdrv_check_perm() call. It is a no-op then.
670
+ */
671
+ void (*bdrv_abort_perm_update)(BlockDriverState *bs);
672
+
673
+ /**
674
+ * Returns in @nperm and @nshared the permissions that the driver for @bs
675
+ * needs on its child @c, based on the cumulative permissions requested by
676
+ * the parents in @parent_perm and @parent_shared.
677
+ *
678
+ * If @c is NULL, return the permissions for attaching a new child for the
679
+ * given @child_class and @role.
680
+ *
681
+ * If @reopen_queue is non-NULL, don't return the currently needed
682
+ * permissions, but those that will be needed after applying the
683
+ * @reopen_queue.
684
+ */
685
+ void (*bdrv_child_perm)(BlockDriverState *bs, BdrvChild *c,
686
+ BdrvChildRole role,
687
+ BlockReopenQueue *reopen_queue,
688
+ uint64_t parent_perm, uint64_t parent_shared,
689
+ uint64_t *nperm, uint64_t *nshared);
690
+
691
+ bool (*bdrv_supports_persistent_dirty_bitmap)(BlockDriverState *bs);
692
+ bool (*bdrv_co_can_store_new_dirty_bitmap)(BlockDriverState *bs,
693
+ const char *name,
694
+ uint32_t granularity,
695
+ Error **errp);
696
+ int (*bdrv_co_remove_persistent_dirty_bitmap)(BlockDriverState *bs,
697
+ const char *name,
698
+ Error **errp);
699
+
700
+ /**
701
+ * Register/unregister a buffer for I/O. For example, when the driver is
702
+ * interested to know the memory areas that will later be used in iovs, so
703
+ * that it can do IOMMU mapping with VFIO etc., in order to get better
704
+ * performance. In the case of VFIO drivers, this callback is used to do
705
+ * DMA mapping for hot buffers.
706
+ */
707
+ void (*bdrv_register_buf)(BlockDriverState *bs, void *host, size_t size);
708
+ void (*bdrv_unregister_buf)(BlockDriverState *bs, void *host);
709
+ QLIST_ENTRY(BlockDriver) list;
710
+
711
+ /*
712
+ * Pointer to a NULL-terminated array of names of strong options
713
+ * that can be specified for bdrv_open(). A strong option is one
714
+ * that changes the data of a BDS.
715
+ * If this pointer is NULL, the array is considered empty.
716
+ * "filename" and "driver" are always considered strong.
717
+ */
718
+ const char *const *strong_runtime_opts;
719
+};
720
+
721
+static inline bool block_driver_can_compress(BlockDriver *drv)
722
+{
723
+ return drv->bdrv_co_pwritev_compressed ||
724
+ drv->bdrv_co_pwritev_compressed_part;
725
+}
726
+
727
+typedef struct BlockLimits {
728
+ /*
729
+ * Alignment requirement, in bytes, for offset/length of I/O
730
+ * requests. Must be a power of 2 less than INT_MAX; defaults to
731
+ * 1 for drivers with modern byte interfaces, and to 512
732
+ * otherwise.
733
+ */
734
+ uint32_t request_alignment;
735
+
736
+ /*
737
+ * Maximum number of bytes that can be discarded at once. Must be multiple
738
+ * of pdiscard_alignment, but need not be power of 2. May be 0 if no
739
+ * inherent 64-bit limit.
740
+ */
741
+ int64_t max_pdiscard;
742
+
743
+ /*
744
+ * Optimal alignment for discard requests in bytes. A power of 2
745
+ * is best but not mandatory. Must be a multiple of
746
+ * bl.request_alignment, and must be less than max_pdiscard if
747
+ * that is set. May be 0 if bl.request_alignment is good enough
748
+ */
749
+ uint32_t pdiscard_alignment;
750
+
751
+ /*
752
+ * Maximum number of bytes that can zeroized at once. Must be multiple of
753
+ * pwrite_zeroes_alignment. 0 means no limit.
754
+ */
755
+ int64_t max_pwrite_zeroes;
756
+
757
+ /*
758
+ * Optimal alignment for write zeroes requests in bytes. A power
759
+ * of 2 is best but not mandatory. Must be a multiple of
760
+ * bl.request_alignment, and must be less than max_pwrite_zeroes
761
+ * if that is set. May be 0 if bl.request_alignment is good
762
+ * enough
763
+ */
764
+ uint32_t pwrite_zeroes_alignment;
765
+
766
+ /*
767
+ * Optimal transfer length in bytes. A power of 2 is best but not
768
+ * mandatory. Must be a multiple of bl.request_alignment, or 0 if
769
+ * no preferred size
770
+ */
771
+ uint32_t opt_transfer;
772
+
773
+ /*
774
+ * Maximal transfer length in bytes. Need not be power of 2, but
775
+ * must be multiple of opt_transfer and bl.request_alignment, or 0
776
+ * for no 32-bit limit. For now, anything larger than INT_MAX is
777
+ * clamped down.
778
+ */
779
+ uint32_t max_transfer;
780
+
781
+ /*
782
+ * Maximal hardware transfer length in bytes. Applies whenever
783
+ * transfers to the device bypass the kernel I/O scheduler, for
784
+ * example with SG_IO. If larger than max_transfer or if zero,
785
+ * blk_get_max_hw_transfer will fall back to max_transfer.
786
+ */
787
+ uint64_t max_hw_transfer;
788
+
789
+ /*
790
+ * Maximal number of scatter/gather elements allowed by the hardware.
791
+ * Applies whenever transfers to the device bypass the kernel I/O
792
+ * scheduler, for example with SG_IO. If larger than max_iov
793
+ * or if zero, blk_get_max_hw_iov will fall back to max_iov.
794
+ */
795
+ int max_hw_iov;
796
+
797
+
798
+ /* memory alignment, in bytes so that no bounce buffer is needed */
799
+ size_t min_mem_alignment;
800
+
801
+ /* memory alignment, in bytes, for bounce buffer */
802
+ size_t opt_mem_alignment;
803
+
804
+ /* maximum number of iovec elements */
805
+ int max_iov;
806
+} BlockLimits;
807
+
808
+typedef struct BdrvOpBlocker BdrvOpBlocker;
809
+
810
+typedef struct BdrvAioNotifier {
811
+ void (*attached_aio_context)(AioContext *new_context, void *opaque);
812
+ void (*detach_aio_context)(void *opaque);
813
+
814
+ void *opaque;
815
+ bool deleted;
816
+
817
+ QLIST_ENTRY(BdrvAioNotifier) list;
818
+} BdrvAioNotifier;
819
+
820
+struct BdrvChildClass {
821
+ /*
822
+ * If true, bdrv_replace_node() doesn't change the node this BdrvChild
823
+ * points to.
824
+ */
825
+ bool stay_at_node;
826
+
827
+ /*
828
+ * If true, the parent is a BlockDriverState and bdrv_next_all_states()
829
+ * will return it. This information is used for drain_all, where every node
830
+ * will be drained separately, so the drain only needs to be propagated to
831
+ * non-BDS parents.
832
+ */
833
+ bool parent_is_bds;
834
+
835
+ void (*inherit_options)(BdrvChildRole role, bool parent_is_format,
836
+ int *child_flags, QDict *child_options,
837
+ int parent_flags, QDict *parent_options);
838
+
839
+ void (*change_media)(BdrvChild *child, bool load);
840
+ void (*resize)(BdrvChild *child);
841
+
842
+ /*
843
+ * Returns a name that is supposedly more useful for human users than the
844
+ * node name for identifying the node in question (in particular, a BB
845
+ * name), or NULL if the parent can't provide a better name.
846
+ */
847
+ const char *(*get_name)(BdrvChild *child);
848
+
849
+ /*
850
+ * Returns a malloced string that describes the parent of the child for a
851
+ * human reader. This could be a node-name, BlockBackend name, qdev ID or
852
+ * QOM path of the device owning the BlockBackend, job type and ID etc. The
853
+ * caller is responsible for freeing the memory.
854
+ */
855
+ char *(*get_parent_desc)(BdrvChild *child);
856
+
857
+ /*
858
+ * If this pair of functions is implemented, the parent doesn't issue new
859
+ * requests after returning from .drained_begin() until .drained_end() is
860
+ * called.
861
+ *
862
+ * These functions must not change the graph (and therefore also must not
863
+ * call aio_poll(), which could change the graph indirectly).
864
+ *
865
+ * If drained_end() schedules background operations, it must atomically
866
+ * increment *drained_end_counter for each such operation and atomically
867
+ * decrement it once the operation has settled.
868
+ *
869
+ * Note that this can be nested. If drained_begin() was called twice, new
870
+ * I/O is allowed only after drained_end() was called twice, too.
871
+ */
872
+ void (*drained_begin)(BdrvChild *child);
873
+ void (*drained_end)(BdrvChild *child, int *drained_end_counter);
874
+
875
+ /*
876
+ * Returns whether the parent has pending requests for the child. This
877
+ * callback is polled after .drained_begin() has been called until all
878
+ * activity on the child has stopped.
879
+ */
880
+ bool (*drained_poll)(BdrvChild *child);
881
+
882
+ /*
883
+ * Notifies the parent that the child has been activated/inactivated (e.g.
884
+ * when migration is completing) and it can start/stop requesting
885
+ * permissions and doing I/O on it.
886
+ */
887
+ void (*activate)(BdrvChild *child, Error **errp);
888
+ int (*inactivate)(BdrvChild *child);
889
+
890
+ void (*attach)(BdrvChild *child);
891
+ void (*detach)(BdrvChild *child);
892
+
893
+ /*
894
+ * Notifies the parent that the filename of its child has changed (e.g.
895
+ * because the direct child was removed from the backing chain), so that it
896
+ * can update its reference.
897
+ */
898
+ int (*update_filename)(BdrvChild *child, BlockDriverState *new_base,
899
+ const char *filename, Error **errp);
900
+
901
+ bool (*can_set_aio_ctx)(BdrvChild *child, AioContext *ctx,
902
+ GSList **ignore, Error **errp);
903
+ void (*set_aio_ctx)(BdrvChild *child, AioContext *ctx, GSList **ignore);
904
+
905
+ AioContext *(*get_parent_aio_context)(BdrvChild *child);
906
+};
907
+
908
+extern const BdrvChildClass child_of_bds;
909
+
910
+struct BdrvChild {
911
+ BlockDriverState *bs;
912
+ char *name;
913
+ const BdrvChildClass *klass;
914
+ BdrvChildRole role;
915
+ void *opaque;
916
+
917
+ /**
918
+ * Granted permissions for operating on this BdrvChild (BLK_PERM_* bitmask)
919
+ */
920
+ uint64_t perm;
921
+
922
+ /**
923
+ * Permissions that can still be granted to other users of @bs while this
924
+ * BdrvChild is still attached to it. (BLK_PERM_* bitmask)
925
+ */
926
+ uint64_t shared_perm;
927
+
928
+ /*
929
+ * This link is frozen: the child can neither be replaced nor
930
+ * detached from the parent.
931
+ */
932
+ bool frozen;
933
+
934
+ /*
935
+ * How many times the parent of this child has been drained
936
+ * (through klass->drained_*).
937
+ * Usually, this is equal to bs->quiesce_counter (potentially
938
+ * reduced by bdrv_drain_all_count). It may differ while the
939
+ * child is entering or leaving a drained section.
940
+ */
941
+ int parent_quiesce_counter;
942
+
943
+ QLIST_ENTRY(BdrvChild) next;
944
+ QLIST_ENTRY(BdrvChild) next_parent;
945
+};
946
+
947
+/*
948
+ * Allows bdrv_co_block_status() to cache one data region for a
949
+ * protocol node.
950
+ *
951
+ * @valid: Whether the cache is valid (should be accessed with atomic
952
+ * functions so this can be reset by RCU readers)
953
+ * @data_start: Offset where we know (or strongly assume) is data
954
+ * @data_end: Offset where the data region ends (which is not necessarily
955
+ * the start of a zeroed region)
956
+ */
957
+typedef struct BdrvBlockStatusCache {
958
+ struct rcu_head rcu;
959
+
960
+ bool valid;
961
+ int64_t data_start;
962
+ int64_t data_end;
963
+} BdrvBlockStatusCache;
964
+
965
+struct BlockDriverState {
966
+ /*
967
+ * Protected by big QEMU lock or read-only after opening. No special
968
+ * locking needed during I/O...
969
+ */
970
+ int open_flags; /* flags used to open the file, re-used for re-open */
971
+ bool encrypted; /* if true, the media is encrypted */
972
+ bool sg; /* if true, the device is a /dev/sg* */
973
+ bool probed; /* if true, format was probed rather than specified */
974
+ bool force_share; /* if true, always allow all shared permissions */
975
+ bool implicit; /* if true, this filter node was automatically inserted */
976
+
977
+ BlockDriver *drv; /* NULL means no media */
978
+ void *opaque;
979
+
980
+ AioContext *aio_context; /* event loop used for fd handlers, timers, etc */
981
+ /*
982
+ * long-running tasks intended to always use the same AioContext as this
983
+ * BDS may register themselves in this list to be notified of changes
984
+ * regarding this BDS's context
985
+ */
986
+ QLIST_HEAD(, BdrvAioNotifier) aio_notifiers;
987
+ bool walking_aio_notifiers; /* to make removal during iteration safe */
988
+
989
+ char filename[PATH_MAX];
990
+ /*
991
+ * If not empty, this image is a diff in relation to backing_file.
992
+ * Note that this is the name given in the image header and
993
+ * therefore may or may not be equal to .backing->bs->filename.
994
+ * If this field contains a relative path, it is to be resolved
995
+ * relatively to the overlay's location.
996
+ */
997
+ char backing_file[PATH_MAX];
998
+ /*
999
+ * The backing filename indicated by the image header. Contrary
1000
+ * to backing_file, if we ever open this file, auto_backing_file
1001
+ * is replaced by the resulting BDS's filename (i.e. after a
1002
+ * bdrv_refresh_filename() run).
1003
+ */
1004
+ char auto_backing_file[PATH_MAX];
1005
+ char backing_format[16]; /* if non-zero and backing_file exists */
1006
+
1007
+ QDict *full_open_options;
1008
+ char exact_filename[PATH_MAX];
1009
+
1010
+ BdrvChild *backing;
1011
+ BdrvChild *file;
1012
+
1013
+ /* I/O Limits */
1014
+ BlockLimits bl;
1015
+
1016
+ /*
1017
+ * Flags honored during pread
1018
+ */
1019
+ unsigned int supported_read_flags;
1020
+ /*
1021
+ * Flags honored during pwrite (so far: BDRV_REQ_FUA,
1022
+ * BDRV_REQ_WRITE_UNCHANGED).
1023
+ * If a driver does not support BDRV_REQ_WRITE_UNCHANGED, those
1024
+ * writes will be issued as normal writes without the flag set.
1025
+ * This is important to note for drivers that do not explicitly
1026
+ * request a WRITE permission for their children and instead take
1027
+ * the same permissions as their parent did (this is commonly what
1028
+ * block filters do). Such drivers have to be aware that the
1029
+ * parent may have taken a WRITE_UNCHANGED permission only and is
1030
+ * issuing such requests. Drivers either must make sure that
1031
+ * these requests do not result in plain WRITE accesses (usually
1032
+ * by supporting BDRV_REQ_WRITE_UNCHANGED, and then forwarding
1033
+ * every incoming write request as-is, including potentially that
1034
+ * flag), or they have to explicitly take the WRITE permission for
1035
+ * their children.
1036
+ */
1037
+ unsigned int supported_write_flags;
1038
+ /*
1039
+ * Flags honored during pwrite_zeroes (so far: BDRV_REQ_FUA,
1040
+ * BDRV_REQ_MAY_UNMAP, BDRV_REQ_WRITE_UNCHANGED)
1041
+ */
1042
+ unsigned int supported_zero_flags;
1043
+ /*
1044
+ * Flags honoured during truncate (so far: BDRV_REQ_ZERO_WRITE).
1045
+ *
1046
+ * If BDRV_REQ_ZERO_WRITE is given, the truncate operation must make sure
1047
+ * that any added space reads as all zeros. If this can't be guaranteed,
1048
+ * the operation must fail.
1049
+ */
1050
+ unsigned int supported_truncate_flags;
1051
+
1052
+ /* the following member gives a name to every node on the bs graph. */
1053
+ char node_name[32];
1054
+ /* element of the list of named nodes building the graph */
1055
+ QTAILQ_ENTRY(BlockDriverState) node_list;
1056
+ /* element of the list of all BlockDriverStates (all_bdrv_states) */
1057
+ QTAILQ_ENTRY(BlockDriverState) bs_list;
1058
+ /* element of the list of monitor-owned BDS */
1059
+ QTAILQ_ENTRY(BlockDriverState) monitor_list;
1060
+ int refcnt;
1061
+
1062
+ /* operation blockers. Protected by BQL. */
1063
+ QLIST_HEAD(, BdrvOpBlocker) op_blockers[BLOCK_OP_TYPE_MAX];
1064
+
1065
+ /*
1066
+ * The node that this node inherited default options from (and a reopen on
1067
+ * which can affect this node by changing these defaults). This is always a
1068
+ * parent node of this node.
1069
+ */
1070
+ BlockDriverState *inherits_from;
1071
+ QLIST_HEAD(, BdrvChild) children;
1072
+ QLIST_HEAD(, BdrvChild) parents;
1073
+
1074
+ QDict *options;
1075
+ QDict *explicit_options;
1076
+ BlockdevDetectZeroesOptions detect_zeroes;
1077
+
1078
+ /* The error object in use for blocking operations on backing_hd */
1079
+ Error *backing_blocker;
1080
+
1081
+ /* Protected by AioContext lock */
1082
+
1083
+ /*
1084
+ * If we are reading a disk image, give its size in sectors.
1085
+ * Generally read-only; it is written to by load_snapshot and
1086
+ * save_snaphost, but the block layer is quiescent during those.
1087
+ */
1088
+ int64_t total_sectors;
1089
+
1090
+ /* threshold limit for writes, in bytes. "High water mark". */
1091
+ uint64_t write_threshold_offset;
1092
+
1093
+ /*
1094
+ * Writing to the list requires the BQL _and_ the dirty_bitmap_mutex.
1095
+ * Reading from the list can be done with either the BQL or the
1096
+ * dirty_bitmap_mutex. Modifying a bitmap only requires
1097
+ * dirty_bitmap_mutex.
1098
+ */
1099
+ QemuMutex dirty_bitmap_mutex;
1100
+ QLIST_HEAD(, BdrvDirtyBitmap) dirty_bitmaps;
1101
+
1102
+ /* Offset after the highest byte written to */
1103
+ Stat64 wr_highest_offset;
1104
+
1105
+ /*
1106
+ * If true, copy read backing sectors into image. Can be >1 if more
1107
+ * than one client has requested copy-on-read. Accessed with atomic
1108
+ * ops.
1109
+ */
1110
+ int copy_on_read;
1111
+
1112
+ /*
1113
+ * number of in-flight requests; overall and serialising.
1114
+ * Accessed with atomic ops.
1115
+ */
1116
+ unsigned int in_flight;
1117
+ unsigned int serialising_in_flight;
1118
+
1119
+ /*
1120
+ * counter for nested bdrv_io_plug.
1121
+ * Accessed with atomic ops.
1122
+ */
1123
+ unsigned io_plugged;
1124
+
1125
+ /* do we need to tell the quest if we have a volatile write cache? */
1126
+ int enable_write_cache;
1127
+
1128
+ /* Accessed with atomic ops. */
1129
+ int quiesce_counter;
1130
+ int recursive_quiesce_counter;
1131
+
1132
+ unsigned int write_gen; /* Current data generation */
1133
+
1134
+ /* Protected by reqs_lock. */
1135
+ CoMutex reqs_lock;
1136
+ QLIST_HEAD(, BdrvTrackedRequest) tracked_requests;
1137
+ CoQueue flush_queue; /* Serializing flush queue */
1138
+ bool active_flush_req; /* Flush request in flight? */
1139
+
1140
+ /* Only read/written by whoever has set active_flush_req to true. */
1141
+ unsigned int flushed_gen; /* Flushed write generation */
1142
+
1143
+ /* BdrvChild links to this node may never be frozen */
1144
+ bool never_freeze;
1145
+
1146
+ /* Lock for block-status cache RCU writers */
1147
+ CoMutex bsc_modify_lock;
1148
+ /* Always non-NULL, but must only be dereferenced under an RCU read guard */
1149
+ BdrvBlockStatusCache *block_status_cache;
1150
+};
1151
+
1152
+struct BlockBackendRootState {
1153
+ int open_flags;
1154
+ BlockdevDetectZeroesOptions detect_zeroes;
1155
+};
1156
+
1157
+typedef enum BlockMirrorBackingMode {
1158
+ /*
1159
+ * Reuse the existing backing chain from the source for the target.
1160
+ * - sync=full: Set backing BDS to NULL.
1161
+ * - sync=top: Use source's backing BDS.
1162
+ * - sync=none: Use source as the backing BDS.
1163
+ */
1164
+ MIRROR_SOURCE_BACKING_CHAIN,
1165
+
1166
+ /* Open the target's backing chain completely anew */
1167
+ MIRROR_OPEN_BACKING_CHAIN,
1168
+
1169
+ /* Do not change the target's backing BDS after job completion */
1170
+ MIRROR_LEAVE_BACKING_CHAIN,
1171
+} BlockMirrorBackingMode;
1172
+
1173
+
1174
+/*
1175
+ * Essential block drivers which must always be statically linked into qemu, and
1176
+ * which therefore can be accessed without using bdrv_find_format()
1177
+ */
1178
+extern BlockDriver bdrv_file;
1179
+extern BlockDriver bdrv_raw;
1180
+extern BlockDriver bdrv_qcow2;
1181
+
1182
+extern unsigned int bdrv_drain_all_count;
1183
+extern QemuOptsList bdrv_create_opts_simple;
1184
+
1185
+/*
1186
+ * Common functions that are neither I/O nor Global State.
1187
+ *
1188
+ * See include/block/block-commmon.h for more information about
1189
+ * the Common API.
1190
+ */
1191
+
1192
+static inline BlockDriverState *child_bs(BdrvChild *child)
1193
+{
1194
+ return child ? child->bs : NULL;
1195
+}
1196
+
1197
+int bdrv_check_request(int64_t offset, int64_t bytes, Error **errp);
1198
+int get_tmp_filename(char *filename, int size);
1199
+void bdrv_parse_filename_strip_prefix(const char *filename, const char *prefix,
1200
+ QDict *options);
1201
+
1202
+
1203
+int bdrv_check_qiov_request(int64_t offset, int64_t bytes,
1204
+ QEMUIOVector *qiov, size_t qiov_offset,
1205
+ Error **errp);
1206
+
1207
+#ifdef _WIN32
1208
+int is_windows_drive(const char *filename);
1209
+#endif
1210
+
1211
+#endif /* BLOCK_INT_COMMON_H */
1212
diff --git a/include/block/block_int-global-state.h b/include/block/block_int-global-state.h
1213
new file mode 100644
1214
index XXXXXXX..XXXXXXX
1215
--- /dev/null
1216
+++ b/include/block/block_int-global-state.h
1217
@@ -XXX,XX +XXX,XX @@
1218
+/*
1219
+ * QEMU System Emulator block driver
1220
+ *
1221
+ * Copyright (c) 2003 Fabrice Bellard
1222
+ *
1223
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
1224
+ * of this software and associated documentation files (the "Software"), to deal
1225
+ * in the Software without restriction, including without limitation the rights
1226
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
1227
+ * copies of the Software, and to permit persons to whom the Software is
1228
+ * furnished to do so, subject to the following conditions:
1229
+ *
1230
+ * The above copyright notice and this permission notice shall be included in
1231
+ * all copies or substantial portions of the Software.
1232
+ *
1233
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1234
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1235
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
1236
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1237
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
1238
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
1239
+ * THE SOFTWARE.
1240
+ */
1241
+#ifndef BLOCK_INT_GLOBAL_STATE_H
1242
+#define BLOCK_INT_GLOBAL_STATE_H
1243
+
1244
+#include "block_int-common.h"
1245
+
1246
+/*
1247
+ * Global state (GS) API. These functions run under the BQL.
1248
+ *
1249
+ * See include/block/block-global-state.h for more information about
1250
+ * the GS API.
1251
+ */
1252
+
1253
+/**
1254
+ * stream_start:
1255
+ * @job_id: The id of the newly-created job, or %NULL to use the
1256
+ * device name of @bs.
1257
+ * @bs: Block device to operate on.
1258
+ * @base: Block device that will become the new base, or %NULL to
1259
+ * flatten the whole backing file chain onto @bs.
1260
+ * @backing_file_str: The file name that will be written to @bs as the
1261
+ * the new backing file if the job completes. Ignored if @base is %NULL.
1262
+ * @creation_flags: Flags that control the behavior of the Job lifetime.
1263
+ * See @BlockJobCreateFlags
1264
+ * @speed: The maximum speed, in bytes per second, or 0 for unlimited.
1265
+ * @on_error: The action to take upon error.
1266
+ * @filter_node_name: The node name that should be assigned to the filter
1267
+ * driver that the stream job inserts into the graph above
1268
+ * @bs. NULL means that a node name should be autogenerated.
1269
+ * @errp: Error object.
1270
+ *
1271
+ * Start a streaming operation on @bs. Clusters that are unallocated
1272
+ * in @bs, but allocated in any image between @base and @bs (both
1273
+ * exclusive) will be written to @bs. At the end of a successful
1274
+ * streaming job, the backing file of @bs will be changed to
1275
+ * @backing_file_str in the written image and to @base in the live
1276
+ * BlockDriverState.
1277
+ */
1278
+void stream_start(const char *job_id, BlockDriverState *bs,
1279
+ BlockDriverState *base, const char *backing_file_str,
1280
+ BlockDriverState *bottom,
1281
+ int creation_flags, int64_t speed,
1282
+ BlockdevOnError on_error,
1283
+ const char *filter_node_name,
1284
+ Error **errp);
1285
+
1286
+/**
1287
+ * commit_start:
1288
+ * @job_id: The id of the newly-created job, or %NULL to use the
1289
+ * device name of @bs.
1290
+ * @bs: Active block device.
1291
+ * @top: Top block device to be committed.
1292
+ * @base: Block device that will be written into, and become the new top.
1293
+ * @creation_flags: Flags that control the behavior of the Job lifetime.
1294
+ * See @BlockJobCreateFlags
1295
+ * @speed: The maximum speed, in bytes per second, or 0 for unlimited.
1296
+ * @on_error: The action to take upon error.
1297
+ * @backing_file_str: String to use as the backing file in @top's overlay
1298
+ * @filter_node_name: The node name that should be assigned to the filter
1299
+ * driver that the commit job inserts into the graph above @top. NULL means
1300
+ * that a node name should be autogenerated.
1301
+ * @errp: Error object.
1302
+ *
1303
+ */
1304
+void commit_start(const char *job_id, BlockDriverState *bs,
1305
+ BlockDriverState *base, BlockDriverState *top,
1306
+ int creation_flags, int64_t speed,
1307
+ BlockdevOnError on_error, const char *backing_file_str,
1308
+ const char *filter_node_name, Error **errp);
1309
+/**
1310
+ * commit_active_start:
1311
+ * @job_id: The id of the newly-created job, or %NULL to use the
1312
+ * device name of @bs.
1313
+ * @bs: Active block device to be committed.
1314
+ * @base: Block device that will be written into, and become the new top.
1315
+ * @creation_flags: Flags that control the behavior of the Job lifetime.
1316
+ * See @BlockJobCreateFlags
1317
+ * @speed: The maximum speed, in bytes per second, or 0 for unlimited.
1318
+ * @on_error: The action to take upon error.
1319
+ * @filter_node_name: The node name that should be assigned to the filter
1320
+ * driver that the commit job inserts into the graph above @bs. NULL means that
1321
+ * a node name should be autogenerated.
1322
+ * @cb: Completion function for the job.
1323
+ * @opaque: Opaque pointer value passed to @cb.
1324
+ * @auto_complete: Auto complete the job.
1325
+ * @errp: Error object.
1326
+ *
1327
+ */
1328
+BlockJob *commit_active_start(const char *job_id, BlockDriverState *bs,
1329
+ BlockDriverState *base, int creation_flags,
1330
+ int64_t speed, BlockdevOnError on_error,
1331
+ const char *filter_node_name,
1332
+ BlockCompletionFunc *cb, void *opaque,
1333
+ bool auto_complete, Error **errp);
1334
+/*
1335
+ * mirror_start:
1336
+ * @job_id: The id of the newly-created job, or %NULL to use the
1337
+ * device name of @bs.
1338
+ * @bs: Block device to operate on.
1339
+ * @target: Block device to write to.
1340
+ * @replaces: Block graph node name to replace once the mirror is done. Can
1341
+ * only be used when full mirroring is selected.
1342
+ * @creation_flags: Flags that control the behavior of the Job lifetime.
1343
+ * See @BlockJobCreateFlags
1344
+ * @speed: The maximum speed, in bytes per second, or 0 for unlimited.
1345
+ * @granularity: The chosen granularity for the dirty bitmap.
1346
+ * @buf_size: The amount of data that can be in flight at one time.
1347
+ * @mode: Whether to collapse all images in the chain to the target.
1348
+ * @backing_mode: How to establish the target's backing chain after completion.
1349
+ * @zero_target: Whether the target should be explicitly zero-initialized
1350
+ * @on_source_error: The action to take upon error reading from the source.
1351
+ * @on_target_error: The action to take upon error writing to the target.
1352
+ * @unmap: Whether to unmap target where source sectors only contain zeroes.
1353
+ * @filter_node_name: The node name that should be assigned to the filter
1354
+ * driver that the mirror job inserts into the graph above @bs. NULL means that
1355
+ * a node name should be autogenerated.
1356
+ * @copy_mode: When to trigger writes to the target.
1357
+ * @errp: Error object.
1358
+ *
1359
+ * Start a mirroring operation on @bs. Clusters that are allocated
1360
+ * in @bs will be written to @target until the job is cancelled or
1361
+ * manually completed. At the end of a successful mirroring job,
1362
+ * @bs will be switched to read from @target.
1363
+ */
1364
+void mirror_start(const char *job_id, BlockDriverState *bs,
1365
+ BlockDriverState *target, const char *replaces,
1366
+ int creation_flags, int64_t speed,
1367
+ uint32_t granularity, int64_t buf_size,
1368
+ MirrorSyncMode mode, BlockMirrorBackingMode backing_mode,
1369
+ bool zero_target,
1370
+ BlockdevOnError on_source_error,
1371
+ BlockdevOnError on_target_error,
1372
+ bool unmap, const char *filter_node_name,
1373
+ MirrorCopyMode copy_mode, Error **errp);
1374
+
1375
+/*
1376
+ * backup_job_create:
1377
+ * @job_id: The id of the newly-created job, or %NULL to use the
1378
+ * device name of @bs.
1379
+ * @bs: Block device to operate on.
1380
+ * @target: Block device to write to.
1381
+ * @speed: The maximum speed, in bytes per second, or 0 for unlimited.
1382
+ * @sync_mode: What parts of the disk image should be copied to the destination.
1383
+ * @sync_bitmap: The dirty bitmap if sync_mode is 'bitmap' or 'incremental'
1384
+ * @bitmap_mode: The bitmap synchronization policy to use.
1385
+ * @perf: Performance options. All actual fields assumed to be present,
1386
+ * all ".has_*" fields are ignored.
1387
+ * @on_source_error: The action to take upon error reading from the source.
1388
+ * @on_target_error: The action to take upon error writing to the target.
1389
+ * @creation_flags: Flags that control the behavior of the Job lifetime.
1390
+ * See @BlockJobCreateFlags
1391
+ * @cb: Completion function for the job.
1392
+ * @opaque: Opaque pointer value passed to @cb.
1393
+ * @txn: Transaction that this job is part of (may be NULL).
1394
+ *
1395
+ * Create a backup operation on @bs. Clusters in @bs are written to @target
1396
+ * until the job is cancelled or manually completed.
1397
+ */
1398
+BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
1399
+ BlockDriverState *target, int64_t speed,
1400
+ MirrorSyncMode sync_mode,
1401
+ BdrvDirtyBitmap *sync_bitmap,
1402
+ BitmapSyncMode bitmap_mode,
1403
+ bool compress,
1404
+ const char *filter_node_name,
1405
+ BackupPerf *perf,
1406
+ BlockdevOnError on_source_error,
1407
+ BlockdevOnError on_target_error,
1408
+ int creation_flags,
1409
+ BlockCompletionFunc *cb, void *opaque,
1410
+ JobTxn *txn, Error **errp);
1411
+
1412
+BdrvChild *bdrv_root_attach_child(BlockDriverState *child_bs,
1413
+ const char *child_name,
1414
+ const BdrvChildClass *child_class,
1415
+ BdrvChildRole child_role,
1416
+ uint64_t perm, uint64_t shared_perm,
1417
+ void *opaque, Error **errp);
1418
+void bdrv_root_unref_child(BdrvChild *child);
1419
+
1420
+void bdrv_get_cumulative_perm(BlockDriverState *bs, uint64_t *perm,
1421
+ uint64_t *shared_perm);
1422
+
1423
+/**
1424
+ * Sets a BdrvChild's permissions. Avoid if the parent is a BDS; use
1425
+ * bdrv_child_refresh_perms() instead and make the parent's
1426
+ * .bdrv_child_perm() implementation return the correct values.
1427
+ */
1428
+int bdrv_child_try_set_perm(BdrvChild *c, uint64_t perm, uint64_t shared,
1429
+ Error **errp);
1430
+
1431
+/**
1432
+ * Calls bs->drv->bdrv_child_perm() and updates the child's permission
1433
+ * masks with the result.
1434
+ * Drivers should invoke this function whenever an event occurs that
1435
+ * makes their .bdrv_child_perm() implementation return different
1436
+ * values than before, but which will not result in the block layer
1437
+ * automatically refreshing the permissions.
1438
+ */
1439
+int bdrv_child_refresh_perms(BlockDriverState *bs, BdrvChild *c, Error **errp);
1440
+
1441
+bool bdrv_recurse_can_replace(BlockDriverState *bs,
1442
+ BlockDriverState *to_replace);
1443
+
1444
+/*
1445
+ * Default implementation for BlockDriver.bdrv_child_perm() that can
1446
+ * be used by block filters and image formats, as long as they use the
1447
+ * child_of_bds child class and set an appropriate BdrvChildRole.
1448
+ */
1449
+void bdrv_default_perms(BlockDriverState *bs, BdrvChild *c,
1450
+ BdrvChildRole role, BlockReopenQueue *reopen_queue,
1451
+ uint64_t perm, uint64_t shared,
1452
+ uint64_t *nperm, uint64_t *nshared);
1453
+
1454
+void blk_dev_change_media_cb(BlockBackend *blk, bool load, Error **errp);
1455
+bool blk_dev_has_removable_media(BlockBackend *blk);
1456
+void blk_dev_eject_request(BlockBackend *blk, bool force);
1457
+bool blk_dev_is_medium_locked(BlockBackend *blk);
1458
+
1459
+void bdrv_restore_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap *backup);
1460
+
1461
+void bdrv_set_monitor_owned(BlockDriverState *bs);
1462
+
1463
+void blockdev_close_all_bdrv_states(void);
1464
+
1465
+BlockDriverState *bds_tree_init(QDict *bs_opts, Error **errp);
1466
+
1467
+/**
1468
+ * Simple implementation of bdrv_co_create_opts for protocol drivers
1469
+ * which only support creation via opening a file
1470
+ * (usually existing raw storage device)
1471
+ */
1472
+int coroutine_fn bdrv_co_create_opts_simple(BlockDriver *drv,
1473
+ const char *filename,
1474
+ QemuOpts *opts,
1475
+ Error **errp);
1476
+
1477
+BdrvDirtyBitmap *block_dirty_bitmap_lookup(const char *node,
1478
+ const char *name,
1479
+ BlockDriverState **pbs,
1480
+ Error **errp);
1481
+BdrvDirtyBitmap *block_dirty_bitmap_merge(const char *node, const char *target,
1482
+ BlockDirtyBitmapMergeSourceList *bms,
1483
+ HBitmap **backup, Error **errp);
1484
+BdrvDirtyBitmap *block_dirty_bitmap_remove(const char *node, const char *name,
1485
+ bool release,
1486
+ BlockDriverState **bitmap_bs,
1487
+ Error **errp);
1488
+
1489
+
1490
+BlockDriverState *bdrv_skip_implicit_filters(BlockDriverState *bs);
1491
+
1492
+/**
1493
+ * bdrv_add_aio_context_notifier:
1494
+ *
1495
+ * If a long-running job intends to be always run in the same AioContext as a
1496
+ * certain BDS, it may use this function to be notified of changes regarding the
1497
+ * association of the BDS to an AioContext.
1498
+ *
1499
+ * attached_aio_context() is called after the target BDS has been attached to a
1500
+ * new AioContext; detach_aio_context() is called before the target BDS is being
1501
+ * detached from its old AioContext.
1502
+ */
1503
+void bdrv_add_aio_context_notifier(BlockDriverState *bs,
1504
+ void (*attached_aio_context)(AioContext *new_context, void *opaque),
1505
+ void (*detach_aio_context)(void *opaque), void *opaque);
1506
+
1507
+/**
1508
+ * bdrv_remove_aio_context_notifier:
1509
+ *
1510
+ * Unsubscribe of change notifications regarding the BDS's AioContext. The
1511
+ * parameters given here have to be the same as those given to
1512
+ * bdrv_add_aio_context_notifier().
1513
+ */
1514
+void bdrv_remove_aio_context_notifier(BlockDriverState *bs,
1515
+ void (*aio_context_attached)(AioContext *,
1516
+ void *),
1517
+ void (*aio_context_detached)(void *),
1518
+ void *opaque);
1519
+
1520
+/**
1521
+ * End all quiescent sections started by bdrv_drain_all_begin(). This is
1522
+ * needed when deleting a BDS before bdrv_drain_all_end() is called.
1523
+ *
1524
+ * NOTE: this is an internal helper for bdrv_close() *only*. No one else
1525
+ * should call it.
1526
+ */
1527
+void bdrv_drain_all_end_quiesce(BlockDriverState *bs);
1528
+
1529
+#endif /* BLOCK_INT_GLOBAL_STATE */
1530
diff --git a/include/block/block_int-io.h b/include/block/block_int-io.h
1531
new file mode 100644
1532
index XXXXXXX..XXXXXXX
1533
--- /dev/null
1534
+++ b/include/block/block_int-io.h
1535
@@ -XXX,XX +XXX,XX @@
1536
+/*
1537
+ * QEMU System Emulator block driver
1538
+ *
1539
+ * Copyright (c) 2003 Fabrice Bellard
1540
+ *
1541
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
1542
+ * of this software and associated documentation files (the "Software"), to deal
1543
+ * in the Software without restriction, including without limitation the rights
1544
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
1545
+ * copies of the Software, and to permit persons to whom the Software is
1546
+ * furnished to do so, subject to the following conditions:
1547
+ *
1548
+ * The above copyright notice and this permission notice shall be included in
1549
+ * all copies or substantial portions of the Software.
1550
+ *
1551
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1552
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1553
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
1554
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1555
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
1556
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
1557
+ * THE SOFTWARE.
1558
+ */
1559
+#ifndef BLOCK_INT_IO_H
1560
+#define BLOCK_INT_IO_H
1561
+
1562
+#include "block_int-common.h"
1563
+
1564
+/*
1565
+ * I/O API functions. These functions are thread-safe.
1566
+ *
1567
+ * See include/block/block-io.h for more information about
1568
+ * the I/O API.
1569
+ */
1570
+
1571
+int coroutine_fn bdrv_co_preadv(BdrvChild *child,
1572
+ int64_t offset, int64_t bytes, QEMUIOVector *qiov,
1573
+ BdrvRequestFlags flags);
1574
+int coroutine_fn bdrv_co_preadv_part(BdrvChild *child,
1575
+ int64_t offset, int64_t bytes,
1576
+ QEMUIOVector *qiov, size_t qiov_offset, BdrvRequestFlags flags);
1577
+int coroutine_fn bdrv_co_pwritev(BdrvChild *child,
1578
+ int64_t offset, int64_t bytes, QEMUIOVector *qiov,
1579
+ BdrvRequestFlags flags);
1580
+int coroutine_fn bdrv_co_pwritev_part(BdrvChild *child,
1581
+ int64_t offset, int64_t bytes,
1582
+ QEMUIOVector *qiov, size_t qiov_offset, BdrvRequestFlags flags);
1583
+
1584
+static inline int coroutine_fn bdrv_co_pread(BdrvChild *child,
1585
+ int64_t offset, unsigned int bytes, void *buf, BdrvRequestFlags flags)
1586
+{
1587
+ QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, bytes);
1588
+
1589
+ return bdrv_co_preadv(child, offset, bytes, &qiov, flags);
1590
+}
1591
+
1592
+static inline int coroutine_fn bdrv_co_pwrite(BdrvChild *child,
1593
+ int64_t offset, unsigned int bytes, void *buf, BdrvRequestFlags flags)
1594
+{
1595
+ QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, bytes);
1596
+
1597
+ return bdrv_co_pwritev(child, offset, bytes, &qiov, flags);
1598
+}
1599
+
1600
+bool coroutine_fn bdrv_make_request_serialising(BdrvTrackedRequest *req,
1601
+ uint64_t align);
1602
+BdrvTrackedRequest *coroutine_fn bdrv_co_get_self_request(BlockDriverState *bs);
1603
+
1604
+BlockDriver *bdrv_probe_all(const uint8_t *buf, int buf_size,
1605
+ const char *filename);
1606
+
1607
+/**
1608
+ * bdrv_wakeup:
1609
+ * @bs: The BlockDriverState for which an I/O operation has been completed.
1610
+ *
1611
+ * Wake up the main thread if it is waiting on BDRV_POLL_WHILE. During
1612
+ * synchronous I/O on a BlockDriverState that is attached to another
1613
+ * I/O thread, the main thread lets the I/O thread's event loop run,
1614
+ * waiting for the I/O operation to complete. A bdrv_wakeup will wake
1615
+ * up the main thread if necessary.
1616
+ *
1617
+ * Manual calls to bdrv_wakeup are rarely necessary, because
1618
+ * bdrv_dec_in_flight already calls it.
1619
+ */
1620
+void bdrv_wakeup(BlockDriverState *bs);
1621
+
1622
+const char *bdrv_get_parent_name(const BlockDriverState *bs);
1623
+bool blk_dev_has_tray(BlockBackend *blk);
1624
+bool blk_dev_is_tray_open(BlockBackend *blk);
1625
+
1626
+void bdrv_set_dirty(BlockDriverState *bs, int64_t offset, int64_t bytes);
1627
+
1628
+void bdrv_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap **out);
1629
+bool bdrv_dirty_bitmap_merge_internal(BdrvDirtyBitmap *dest,
1630
+ const BdrvDirtyBitmap *src,
1631
+ HBitmap **backup, bool lock);
1632
+
1633
+void bdrv_inc_in_flight(BlockDriverState *bs);
1634
+void bdrv_dec_in_flight(BlockDriverState *bs);
1635
+
1636
+int coroutine_fn bdrv_co_copy_range_from(BdrvChild *src, int64_t src_offset,
1637
+ BdrvChild *dst, int64_t dst_offset,
1638
+ int64_t bytes,
1639
+ BdrvRequestFlags read_flags,
1640
+ BdrvRequestFlags write_flags);
1641
+int coroutine_fn bdrv_co_copy_range_to(BdrvChild *src, int64_t src_offset,
1642
+ BdrvChild *dst, int64_t dst_offset,
1643
+ int64_t bytes,
1644
+ BdrvRequestFlags read_flags,
1645
+ BdrvRequestFlags write_flags);
1646
+
1647
+int refresh_total_sectors(BlockDriverState *bs, int64_t hint);
1648
+
1649
+BdrvChild *bdrv_cow_child(BlockDriverState *bs);
1650
+BdrvChild *bdrv_filter_child(BlockDriverState *bs);
1651
+BdrvChild *bdrv_filter_or_cow_child(BlockDriverState *bs);
1652
+BdrvChild *bdrv_primary_child(BlockDriverState *bs);
1653
+BlockDriverState *bdrv_skip_filters(BlockDriverState *bs);
1654
+BlockDriverState *bdrv_backing_chain_next(BlockDriverState *bs);
1655
+
1656
+static inline BlockDriverState *bdrv_cow_bs(BlockDriverState *bs)
1657
+{
1658
+ return child_bs(bdrv_cow_child(bs));
1659
+}
1660
+
1661
+static inline BlockDriverState *bdrv_filter_bs(BlockDriverState *bs)
1662
+{
1663
+ return child_bs(bdrv_filter_child(bs));
1664
+}
1665
+
1666
+static inline BlockDriverState *bdrv_filter_or_cow_bs(BlockDriverState *bs)
1667
+{
1668
+ return child_bs(bdrv_filter_or_cow_child(bs));
1669
+}
1670
+
1671
+static inline BlockDriverState *bdrv_primary_bs(BlockDriverState *bs)
1672
+{
1673
+ return child_bs(bdrv_primary_child(bs));
1674
+}
1675
+
1676
+/**
1677
+ * Check whether the given offset is in the cached block-status data
1678
+ * region.
1679
+ *
1680
+ * If it is, and @pnum is not NULL, *pnum is set to
1681
+ * `bsc.data_end - offset`, i.e. how many bytes, starting from
1682
+ * @offset, are data (according to the cache).
1683
+ * Otherwise, *pnum is not touched.
1684
+ */
1685
+bool bdrv_bsc_is_data(BlockDriverState *bs, int64_t offset, int64_t *pnum);
1686
+
1687
+/**
1688
+ * If [offset, offset + bytes) overlaps with the currently cached
1689
+ * block-status region, invalidate the cache.
1690
+ *
1691
+ * (To be used by I/O paths that cause data regions to be zero or
1692
+ * holes.)
1693
+ */
1694
+void bdrv_bsc_invalidate_range(BlockDriverState *bs,
1695
+ int64_t offset, int64_t bytes);
1696
+
1697
+/**
1698
+ * Mark the range [offset, offset + bytes) as a data region.
1699
+ */
1700
+void bdrv_bsc_fill(BlockDriverState *bs, int64_t offset, int64_t bytes);
1701
+
1702
+
1703
+/*
1704
+ * "I/O or GS" API functions. These functions can run without
1705
+ * the BQL, but only in one specific iothread/main loop.
1706
+ *
1707
+ * See include/block/block-io.h for more information about
1708
+ * the "I/O or GS" API.
1709
+ */
1710
+
1711
+void bdrv_apply_subtree_drain(BdrvChild *child, BlockDriverState *new_parent);
1712
+void bdrv_unapply_subtree_drain(BdrvChild *child, BlockDriverState *old_parent);
1713
+
1714
+#endif /* BLOCK_INT_IO_H */
1715
diff --git a/include/block/block_int.h b/include/block/block_int.h
1716
index XXXXXXX..XXXXXXX 100644
1717
--- a/include/block/block_int.h
1718
+++ b/include/block/block_int.h
1719
@@ -XXX,XX +XXX,XX @@
1720
#ifndef BLOCK_INT_H
1721
#define BLOCK_INT_H
1722
1723
-#include "block/accounting.h"
1724
-#include "block/block.h"
1725
-#include "block/aio-wait.h"
1726
-#include "qemu/queue.h"
1727
-#include "qemu/coroutine.h"
1728
-#include "qemu/stats64.h"
1729
-#include "qemu/timer.h"
1730
-#include "qemu/hbitmap.h"
1731
-#include "block/snapshot.h"
1732
-#include "qemu/throttle.h"
1733
-#include "qemu/rcu.h"
1734
+#include "block_int-global-state.h"
1735
+#include "block_int-io.h"
1736
1737
-#define BLOCK_FLAG_LAZY_REFCOUNTS 8
1738
-
1739
-#define BLOCK_OPT_SIZE "size"
1740
-#define BLOCK_OPT_ENCRYPT "encryption"
1741
-#define BLOCK_OPT_ENCRYPT_FORMAT "encrypt.format"
1742
-#define BLOCK_OPT_COMPAT6 "compat6"
1743
-#define BLOCK_OPT_HWVERSION "hwversion"
1744
-#define BLOCK_OPT_BACKING_FILE "backing_file"
1745
-#define BLOCK_OPT_BACKING_FMT "backing_fmt"
1746
-#define BLOCK_OPT_CLUSTER_SIZE "cluster_size"
1747
-#define BLOCK_OPT_TABLE_SIZE "table_size"
1748
-#define BLOCK_OPT_PREALLOC "preallocation"
1749
-#define BLOCK_OPT_SUBFMT "subformat"
1750
-#define BLOCK_OPT_COMPAT_LEVEL "compat"
1751
-#define BLOCK_OPT_LAZY_REFCOUNTS "lazy_refcounts"
1752
-#define BLOCK_OPT_ADAPTER_TYPE "adapter_type"
1753
-#define BLOCK_OPT_REDUNDANCY "redundancy"
1754
-#define BLOCK_OPT_NOCOW "nocow"
1755
-#define BLOCK_OPT_EXTENT_SIZE_HINT "extent_size_hint"
1756
-#define BLOCK_OPT_OBJECT_SIZE "object_size"
1757
-#define BLOCK_OPT_REFCOUNT_BITS "refcount_bits"
1758
-#define BLOCK_OPT_DATA_FILE "data_file"
1759
-#define BLOCK_OPT_DATA_FILE_RAW "data_file_raw"
1760
-#define BLOCK_OPT_COMPRESSION_TYPE "compression_type"
1761
-#define BLOCK_OPT_EXTL2 "extended_l2"
1762
-
1763
-#define BLOCK_PROBE_BUF_SIZE 512
1764
-
1765
-enum BdrvTrackedRequestType {
1766
- BDRV_TRACKED_READ,
1767
- BDRV_TRACKED_WRITE,
1768
- BDRV_TRACKED_DISCARD,
1769
- BDRV_TRACKED_TRUNCATE,
1770
-};
1771
-
1772
-/*
1773
- * That is not quite good that BdrvTrackedRequest structure is public,
1774
- * as block/io.c is very careful about incoming offset/bytes being
1775
- * correct. Be sure to assert bdrv_check_request() succeeded after any
1776
- * modification of BdrvTrackedRequest object out of block/io.c
1777
- */
1778
-typedef struct BdrvTrackedRequest {
1779
- BlockDriverState *bs;
1780
- int64_t offset;
1781
- int64_t bytes;
1782
- enum BdrvTrackedRequestType type;
1783
-
1784
- bool serialising;
1785
- int64_t overlap_offset;
1786
- int64_t overlap_bytes;
1787
-
1788
- QLIST_ENTRY(BdrvTrackedRequest) list;
1789
- Coroutine *co; /* owner, used for deadlock detection */
1790
- CoQueue wait_queue; /* coroutines blocked on this request */
1791
-
1792
- struct BdrvTrackedRequest *waiting_for;
1793
-} BdrvTrackedRequest;
1794
-
1795
-int bdrv_check_qiov_request(int64_t offset, int64_t bytes,
1796
- QEMUIOVector *qiov, size_t qiov_offset,
1797
- Error **errp);
1798
-int bdrv_check_request(int64_t offset, int64_t bytes, Error **errp);
1799
-
1800
-struct BlockDriver {
1801
- const char *format_name;
1802
- int instance_size;
1803
-
1804
- /* set to true if the BlockDriver is a block filter. Block filters pass
1805
- * certain callbacks that refer to data (see block.c) to their bs->file
1806
- * or bs->backing (whichever one exists) if the driver doesn't implement
1807
- * them. Drivers that do not wish to forward must implement them and return
1808
- * -ENOTSUP.
1809
- * Note that filters are not allowed to modify data.
1810
- *
1811
- * Filters generally cannot have more than a single filtered child,
1812
- * because the data they present must at all times be the same as
1813
- * that on their filtered child. That would be impossible to
1814
- * achieve for multiple filtered children.
1815
- * (And this filtered child must then be bs->file or bs->backing.)
1816
- */
1817
- bool is_filter;
1818
- /*
1819
- * Set to true if the BlockDriver is a format driver. Format nodes
1820
- * generally do not expect their children to be other format nodes
1821
- * (except for backing files), and so format probing is disabled
1822
- * on those children.
1823
- */
1824
- bool is_format;
1825
-
1826
- /*
1827
- * This function is invoked under BQL before .bdrv_co_amend()
1828
- * (which in contrast does not necessarily run under the BQL)
1829
- * to allow driver-specific initialization code that requires
1830
- * the BQL, like setting up specific permission flags.
1831
- */
1832
- int (*bdrv_amend_pre_run)(BlockDriverState *bs, Error **errp);
1833
- /*
1834
- * This function is invoked under BQL after .bdrv_co_amend()
1835
- * to allow cleaning up what was done in .bdrv_amend_pre_run().
1836
- */
1837
- void (*bdrv_amend_clean)(BlockDriverState *bs);
1838
-
1839
- /*
1840
- * Return true if @to_replace can be replaced by a BDS with the
1841
- * same data as @bs without it affecting @bs's behavior (that is,
1842
- * without it being visible to @bs's parents).
1843
- */
1844
- bool (*bdrv_recurse_can_replace)(BlockDriverState *bs,
1845
- BlockDriverState *to_replace);
1846
-
1847
- int (*bdrv_probe)(const uint8_t *buf, int buf_size, const char *filename);
1848
- int (*bdrv_probe_device)(const char *filename);
1849
-
1850
- /* Any driver implementing this callback is expected to be able to handle
1851
- * NULL file names in its .bdrv_open() implementation */
1852
- void (*bdrv_parse_filename)(const char *filename, QDict *options, Error **errp);
1853
- /* Drivers not implementing bdrv_parse_filename nor bdrv_open should have
1854
- * this field set to true, except ones that are defined only by their
1855
- * child's bs.
1856
- * An example of the last type will be the quorum block driver.
1857
- */
1858
- bool bdrv_needs_filename;
1859
-
1860
- /*
1861
- * Set if a driver can support backing files. This also implies the
1862
- * following semantics:
1863
- *
1864
- * - Return status 0 of .bdrv_co_block_status means that corresponding
1865
- * blocks are not allocated in this layer of backing-chain
1866
- * - For such (unallocated) blocks, read will:
1867
- * - fill buffer with zeros if there is no backing file
1868
- * - read from the backing file otherwise, where the block layer
1869
- * takes care of reading zeros beyond EOF if backing file is short
1870
- */
1871
- bool supports_backing;
1872
-
1873
- /* For handling image reopen for split or non-split files */
1874
- int (*bdrv_reopen_prepare)(BDRVReopenState *reopen_state,
1875
- BlockReopenQueue *queue, Error **errp);
1876
- void (*bdrv_reopen_commit)(BDRVReopenState *reopen_state);
1877
- void (*bdrv_reopen_commit_post)(BDRVReopenState *reopen_state);
1878
- void (*bdrv_reopen_abort)(BDRVReopenState *reopen_state);
1879
- void (*bdrv_join_options)(QDict *options, QDict *old_options);
1880
-
1881
- int (*bdrv_open)(BlockDriverState *bs, QDict *options, int flags,
1882
- Error **errp);
1883
-
1884
- /* Protocol drivers should implement this instead of bdrv_open */
1885
- int (*bdrv_file_open)(BlockDriverState *bs, QDict *options, int flags,
1886
- Error **errp);
1887
- void (*bdrv_close)(BlockDriverState *bs);
1888
-
1889
-
1890
- int coroutine_fn (*bdrv_co_create)(BlockdevCreateOptions *opts,
1891
- Error **errp);
1892
- int coroutine_fn (*bdrv_co_create_opts)(BlockDriver *drv,
1893
- const char *filename,
1894
- QemuOpts *opts,
1895
- Error **errp);
1896
-
1897
- int coroutine_fn (*bdrv_co_amend)(BlockDriverState *bs,
1898
- BlockdevAmendOptions *opts,
1899
- bool force,
1900
- Error **errp);
1901
-
1902
- int (*bdrv_amend_options)(BlockDriverState *bs,
1903
- QemuOpts *opts,
1904
- BlockDriverAmendStatusCB *status_cb,
1905
- void *cb_opaque,
1906
- bool force,
1907
- Error **errp);
1908
-
1909
- int (*bdrv_make_empty)(BlockDriverState *bs);
1910
-
1911
- /*
1912
- * Refreshes the bs->exact_filename field. If that is impossible,
1913
- * bs->exact_filename has to be left empty.
1914
- */
1915
- void (*bdrv_refresh_filename)(BlockDriverState *bs);
1916
-
1917
- /*
1918
- * Gathers the open options for all children into @target.
1919
- * A simple format driver (without backing file support) might
1920
- * implement this function like this:
1921
- *
1922
- * QINCREF(bs->file->bs->full_open_options);
1923
- * qdict_put(target, "file", bs->file->bs->full_open_options);
1924
- *
1925
- * If not specified, the generic implementation will simply put
1926
- * all children's options under their respective name.
1927
- *
1928
- * @backing_overridden is true when bs->backing seems not to be
1929
- * the child that would result from opening bs->backing_file.
1930
- * Therefore, if it is true, the backing child's options should be
1931
- * gathered; otherwise, there is no need since the backing child
1932
- * is the one implied by the image header.
1933
- *
1934
- * Note that ideally this function would not be needed. Every
1935
- * block driver which implements it is probably doing something
1936
- * shady regarding its runtime option structure.
1937
- */
1938
- void (*bdrv_gather_child_options)(BlockDriverState *bs, QDict *target,
1939
- bool backing_overridden);
1940
-
1941
- /*
1942
- * Returns an allocated string which is the directory name of this BDS: It
1943
- * will be used to make relative filenames absolute by prepending this
1944
- * function's return value to them.
1945
- */
1946
- char *(*bdrv_dirname)(BlockDriverState *bs, Error **errp);
1947
-
1948
- /* aio */
1949
- BlockAIOCB *(*bdrv_aio_preadv)(BlockDriverState *bs,
1950
- int64_t offset, int64_t bytes, QEMUIOVector *qiov,
1951
- BdrvRequestFlags flags, BlockCompletionFunc *cb, void *opaque);
1952
- BlockAIOCB *(*bdrv_aio_pwritev)(BlockDriverState *bs,
1953
- int64_t offset, int64_t bytes, QEMUIOVector *qiov,
1954
- BdrvRequestFlags flags, BlockCompletionFunc *cb, void *opaque);
1955
- BlockAIOCB *(*bdrv_aio_flush)(BlockDriverState *bs,
1956
- BlockCompletionFunc *cb, void *opaque);
1957
- BlockAIOCB *(*bdrv_aio_pdiscard)(BlockDriverState *bs,
1958
- int64_t offset, int bytes,
1959
- BlockCompletionFunc *cb, void *opaque);
1960
-
1961
- int coroutine_fn (*bdrv_co_readv)(BlockDriverState *bs,
1962
- int64_t sector_num, int nb_sectors, QEMUIOVector *qiov);
1963
-
1964
- /**
1965
- * @offset: position in bytes to read at
1966
- * @bytes: number of bytes to read
1967
- * @qiov: the buffers to fill with read data
1968
- * @flags: currently unused, always 0
1969
- *
1970
- * @offset and @bytes will be a multiple of 'request_alignment',
1971
- * but the length of individual @qiov elements does not have to
1972
- * be a multiple.
1973
- *
1974
- * @bytes will always equal the total size of @qiov, and will be
1975
- * no larger than 'max_transfer'.
1976
- *
1977
- * The buffer in @qiov may point directly to guest memory.
1978
- */
1979
- int coroutine_fn (*bdrv_co_preadv)(BlockDriverState *bs,
1980
- int64_t offset, int64_t bytes, QEMUIOVector *qiov,
1981
- BdrvRequestFlags flags);
1982
- int coroutine_fn (*bdrv_co_preadv_part)(BlockDriverState *bs,
1983
- int64_t offset, int64_t bytes,
1984
- QEMUIOVector *qiov, size_t qiov_offset, BdrvRequestFlags flags);
1985
- int coroutine_fn (*bdrv_co_writev)(BlockDriverState *bs,
1986
- int64_t sector_num, int nb_sectors, QEMUIOVector *qiov, int flags);
1987
- /**
1988
- * @offset: position in bytes to write at
1989
- * @bytes: number of bytes to write
1990
- * @qiov: the buffers containing data to write
1991
- * @flags: zero or more bits allowed by 'supported_write_flags'
1992
- *
1993
- * @offset and @bytes will be a multiple of 'request_alignment',
1994
- * but the length of individual @qiov elements does not have to
1995
- * be a multiple.
1996
- *
1997
- * @bytes will always equal the total size of @qiov, and will be
1998
- * no larger than 'max_transfer'.
1999
- *
2000
- * The buffer in @qiov may point directly to guest memory.
2001
- */
2002
- int coroutine_fn (*bdrv_co_pwritev)(BlockDriverState *bs,
2003
- int64_t offset, int64_t bytes, QEMUIOVector *qiov,
2004
- BdrvRequestFlags flags);
2005
- int coroutine_fn (*bdrv_co_pwritev_part)(BlockDriverState *bs,
2006
- int64_t offset, int64_t bytes, QEMUIOVector *qiov, size_t qiov_offset,
2007
- BdrvRequestFlags flags);
2008
-
2009
- /*
2010
- * Efficiently zero a region of the disk image. Typically an image format
2011
- * would use a compact metadata representation to implement this. This
2012
- * function pointer may be NULL or return -ENOSUP and .bdrv_co_writev()
2013
- * will be called instead.
2014
- */
2015
- int coroutine_fn (*bdrv_co_pwrite_zeroes)(BlockDriverState *bs,
2016
- int64_t offset, int64_t bytes, BdrvRequestFlags flags);
2017
- int coroutine_fn (*bdrv_co_pdiscard)(BlockDriverState *bs,
2018
- int64_t offset, int64_t bytes);
2019
-
2020
- /* Map [offset, offset + nbytes) range onto a child of @bs to copy from,
2021
- * and invoke bdrv_co_copy_range_from(child, ...), or invoke
2022
- * bdrv_co_copy_range_to() if @bs is the leaf child to copy data from.
2023
- *
2024
- * See the comment of bdrv_co_copy_range for the parameter and return value
2025
- * semantics.
2026
- */
2027
- int coroutine_fn (*bdrv_co_copy_range_from)(BlockDriverState *bs,
2028
- BdrvChild *src,
2029
- int64_t offset,
2030
- BdrvChild *dst,
2031
- int64_t dst_offset,
2032
- int64_t bytes,
2033
- BdrvRequestFlags read_flags,
2034
- BdrvRequestFlags write_flags);
2035
-
2036
- /* Map [offset, offset + nbytes) range onto a child of bs to copy data to,
2037
- * and invoke bdrv_co_copy_range_to(child, src, ...), or perform the copy
2038
- * operation if @bs is the leaf and @src has the same BlockDriver. Return
2039
- * -ENOTSUP if @bs is the leaf but @src has a different BlockDriver.
2040
- *
2041
- * See the comment of bdrv_co_copy_range for the parameter and return value
2042
- * semantics.
2043
- */
2044
- int coroutine_fn (*bdrv_co_copy_range_to)(BlockDriverState *bs,
2045
- BdrvChild *src,
2046
- int64_t src_offset,
2047
- BdrvChild *dst,
2048
- int64_t dst_offset,
2049
- int64_t bytes,
2050
- BdrvRequestFlags read_flags,
2051
- BdrvRequestFlags write_flags);
2052
-
2053
- /*
2054
- * Building block for bdrv_block_status[_above] and
2055
- * bdrv_is_allocated[_above]. The driver should answer only
2056
- * according to the current layer, and should only need to set
2057
- * BDRV_BLOCK_DATA, BDRV_BLOCK_ZERO, BDRV_BLOCK_OFFSET_VALID,
2058
- * and/or BDRV_BLOCK_RAW; if the current layer defers to a backing
2059
- * layer, the result should be 0 (and not BDRV_BLOCK_ZERO). See
2060
- * block.h for the overall meaning of the bits. As a hint, the
2061
- * flag want_zero is true if the caller cares more about precise
2062
- * mappings (favor accurate _OFFSET_VALID/_ZERO) or false for
2063
- * overall allocation (favor larger *pnum, perhaps by reporting
2064
- * _DATA instead of _ZERO). The block layer guarantees input
2065
- * clamped to bdrv_getlength() and aligned to request_alignment,
2066
- * as well as non-NULL pnum, map, and file; in turn, the driver
2067
- * must return an error or set pnum to an aligned non-zero value.
2068
- *
2069
- * Note that @bytes is just a hint on how big of a region the
2070
- * caller wants to inspect. It is not a limit on *pnum.
2071
- * Implementations are free to return larger values of *pnum if
2072
- * doing so does not incur a performance penalty.
2073
- *
2074
- * block/io.c's bdrv_co_block_status() will utilize an unclamped
2075
- * *pnum value for the block-status cache on protocol nodes, prior
2076
- * to clamping *pnum for return to its caller.
2077
- */
2078
- int coroutine_fn (*bdrv_co_block_status)(BlockDriverState *bs,
2079
- bool want_zero, int64_t offset, int64_t bytes, int64_t *pnum,
2080
- int64_t *map, BlockDriverState **file);
2081
-
2082
- /*
2083
- * This informs the driver that we are no longer interested in the result
2084
- * of in-flight requests, so don't waste the time if possible.
2085
- *
2086
- * One example usage is to avoid waiting for an nbd target node reconnect
2087
- * timeout during job-cancel with force=true.
2088
- */
2089
- void (*bdrv_cancel_in_flight)(BlockDriverState *bs);
2090
-
2091
- /*
2092
- * Invalidate any cached meta-data.
2093
- */
2094
- void coroutine_fn (*bdrv_co_invalidate_cache)(BlockDriverState *bs,
2095
- Error **errp);
2096
- int (*bdrv_inactivate)(BlockDriverState *bs);
2097
-
2098
- /*
2099
- * Flushes all data for all layers by calling bdrv_co_flush for underlying
2100
- * layers, if needed. This function is needed for deterministic
2101
- * synchronization of the flush finishing callback.
2102
- */
2103
- int coroutine_fn (*bdrv_co_flush)(BlockDriverState *bs);
2104
-
2105
- /* Delete a created file. */
2106
- int coroutine_fn (*bdrv_co_delete_file)(BlockDriverState *bs,
2107
- Error **errp);
2108
-
2109
- /*
2110
- * Flushes all data that was already written to the OS all the way down to
2111
- * the disk (for example file-posix.c calls fsync()).
2112
- */
2113
- int coroutine_fn (*bdrv_co_flush_to_disk)(BlockDriverState *bs);
2114
-
2115
- /*
2116
- * Flushes all internal caches to the OS. The data may still sit in a
2117
- * writeback cache of the host OS, but it will survive a crash of the qemu
2118
- * process.
2119
- */
2120
- int coroutine_fn (*bdrv_co_flush_to_os)(BlockDriverState *bs);
2121
-
2122
- /*
2123
- * Drivers setting this field must be able to work with just a plain
2124
- * filename with '<protocol_name>:' as a prefix, and no other options.
2125
- * Options may be extracted from the filename by implementing
2126
- * bdrv_parse_filename.
2127
- */
2128
- const char *protocol_name;
2129
-
2130
- /*
2131
- * Truncate @bs to @offset bytes using the given @prealloc mode
2132
- * when growing. Modes other than PREALLOC_MODE_OFF should be
2133
- * rejected when shrinking @bs.
2134
- *
2135
- * If @exact is true, @bs must be resized to exactly @offset.
2136
- * Otherwise, it is sufficient for @bs (if it is a host block
2137
- * device and thus there is no way to resize it) to be at least
2138
- * @offset bytes in length.
2139
- *
2140
- * If @exact is true and this function fails but would succeed
2141
- * with @exact = false, it should return -ENOTSUP.
2142
- */
2143
- int coroutine_fn (*bdrv_co_truncate)(BlockDriverState *bs, int64_t offset,
2144
- bool exact, PreallocMode prealloc,
2145
- BdrvRequestFlags flags, Error **errp);
2146
-
2147
- int64_t (*bdrv_getlength)(BlockDriverState *bs);
2148
- bool has_variable_length;
2149
- int64_t (*bdrv_get_allocated_file_size)(BlockDriverState *bs);
2150
- BlockMeasureInfo *(*bdrv_measure)(QemuOpts *opts, BlockDriverState *in_bs,
2151
- Error **errp);
2152
-
2153
- int coroutine_fn (*bdrv_co_pwritev_compressed)(BlockDriverState *bs,
2154
- int64_t offset, int64_t bytes, QEMUIOVector *qiov);
2155
- int coroutine_fn (*bdrv_co_pwritev_compressed_part)(BlockDriverState *bs,
2156
- int64_t offset, int64_t bytes, QEMUIOVector *qiov, size_t qiov_offset);
2157
-
2158
- int (*bdrv_snapshot_create)(BlockDriverState *bs,
2159
- QEMUSnapshotInfo *sn_info);
2160
- int (*bdrv_snapshot_goto)(BlockDriverState *bs,
2161
- const char *snapshot_id);
2162
- int (*bdrv_snapshot_delete)(BlockDriverState *bs,
2163
- const char *snapshot_id,
2164
- const char *name,
2165
- Error **errp);
2166
- int (*bdrv_snapshot_list)(BlockDriverState *bs,
2167
- QEMUSnapshotInfo **psn_info);
2168
- int (*bdrv_snapshot_load_tmp)(BlockDriverState *bs,
2169
- const char *snapshot_id,
2170
- const char *name,
2171
- Error **errp);
2172
- int (*bdrv_get_info)(BlockDriverState *bs, BlockDriverInfo *bdi);
2173
- ImageInfoSpecific *(*bdrv_get_specific_info)(BlockDriverState *bs,
2174
- Error **errp);
2175
- BlockStatsSpecific *(*bdrv_get_specific_stats)(BlockDriverState *bs);
2176
-
2177
- int coroutine_fn (*bdrv_save_vmstate)(BlockDriverState *bs,
2178
- QEMUIOVector *qiov,
2179
- int64_t pos);
2180
- int coroutine_fn (*bdrv_load_vmstate)(BlockDriverState *bs,
2181
- QEMUIOVector *qiov,
2182
- int64_t pos);
2183
-
2184
- int (*bdrv_change_backing_file)(BlockDriverState *bs,
2185
- const char *backing_file, const char *backing_fmt);
2186
-
2187
- /* removable device specific */
2188
- bool (*bdrv_is_inserted)(BlockDriverState *bs);
2189
- void (*bdrv_eject)(BlockDriverState *bs, bool eject_flag);
2190
- void (*bdrv_lock_medium)(BlockDriverState *bs, bool locked);
2191
-
2192
- /* to control generic scsi devices */
2193
- BlockAIOCB *(*bdrv_aio_ioctl)(BlockDriverState *bs,
2194
- unsigned long int req, void *buf,
2195
- BlockCompletionFunc *cb, void *opaque);
2196
- int coroutine_fn (*bdrv_co_ioctl)(BlockDriverState *bs,
2197
- unsigned long int req, void *buf);
2198
-
2199
- /* List of options for creating images, terminated by name == NULL */
2200
- QemuOptsList *create_opts;
2201
-
2202
- /* List of options for image amend */
2203
- QemuOptsList *amend_opts;
2204
-
2205
- /*
2206
- * If this driver supports reopening images this contains a
2207
- * NULL-terminated list of the runtime options that can be
2208
- * modified. If an option in this list is unspecified during
2209
- * reopen then it _must_ be reset to its default value or return
2210
- * an error.
2211
- */
2212
- const char *const *mutable_opts;
2213
-
2214
- /*
2215
- * Returns 0 for completed check, -errno for internal errors.
2216
- * The check results are stored in result.
2217
- */
2218
- int coroutine_fn (*bdrv_co_check)(BlockDriverState *bs,
2219
- BdrvCheckResult *result,
2220
- BdrvCheckMode fix);
2221
-
2222
- void (*bdrv_debug_event)(BlockDriverState *bs, BlkdebugEvent event);
2223
-
2224
- /* TODO Better pass a option string/QDict/QemuOpts to add any rule? */
2225
- int (*bdrv_debug_breakpoint)(BlockDriverState *bs, const char *event,
2226
- const char *tag);
2227
- int (*bdrv_debug_remove_breakpoint)(BlockDriverState *bs,
2228
- const char *tag);
2229
- int (*bdrv_debug_resume)(BlockDriverState *bs, const char *tag);
2230
- bool (*bdrv_debug_is_suspended)(BlockDriverState *bs, const char *tag);
2231
-
2232
- void (*bdrv_refresh_limits)(BlockDriverState *bs, Error **errp);
2233
-
2234
- /*
2235
- * Returns 1 if newly created images are guaranteed to contain only
2236
- * zeros, 0 otherwise.
2237
- */
2238
- int (*bdrv_has_zero_init)(BlockDriverState *bs);
2239
-
2240
- /* Remove fd handlers, timers, and other event loop callbacks so the event
2241
- * loop is no longer in use. Called with no in-flight requests and in
2242
- * depth-first traversal order with parents before child nodes.
2243
- */
2244
- void (*bdrv_detach_aio_context)(BlockDriverState *bs);
2245
-
2246
- /* Add fd handlers, timers, and other event loop callbacks so I/O requests
2247
- * can be processed again. Called with no in-flight requests and in
2248
- * depth-first traversal order with child nodes before parent nodes.
2249
- */
2250
- void (*bdrv_attach_aio_context)(BlockDriverState *bs,
2251
- AioContext *new_context);
2252
-
2253
- /* io queue for linux-aio */
2254
- void (*bdrv_io_plug)(BlockDriverState *bs);
2255
- void (*bdrv_io_unplug)(BlockDriverState *bs);
2256
-
2257
- /**
2258
- * Try to get @bs's logical and physical block size.
2259
- * On success, store them in @bsz and return zero.
2260
- * On failure, return negative errno.
2261
- */
2262
- int (*bdrv_probe_blocksizes)(BlockDriverState *bs, BlockSizes *bsz);
2263
- /**
2264
- * Try to get @bs's geometry (cyls, heads, sectors)
2265
- * On success, store them in @geo and return 0.
2266
- * On failure return -errno.
2267
- * Only drivers that want to override guest geometry implement this
2268
- * callback; see hd_geometry_guess().
2269
- */
2270
- int (*bdrv_probe_geometry)(BlockDriverState *bs, HDGeometry *geo);
2271
-
2272
- /**
2273
- * bdrv_co_drain_begin is called if implemented in the beginning of a
2274
- * drain operation to drain and stop any internal sources of requests in
2275
- * the driver.
2276
- * bdrv_co_drain_end is called if implemented at the end of the drain.
2277
- *
2278
- * They should be used by the driver to e.g. manage scheduled I/O
2279
- * requests, or toggle an internal state. After the end of the drain new
2280
- * requests will continue normally.
2281
- */
2282
- void coroutine_fn (*bdrv_co_drain_begin)(BlockDriverState *bs);
2283
- void coroutine_fn (*bdrv_co_drain_end)(BlockDriverState *bs);
2284
-
2285
- void (*bdrv_add_child)(BlockDriverState *parent, BlockDriverState *child,
2286
- Error **errp);
2287
- void (*bdrv_del_child)(BlockDriverState *parent, BdrvChild *child,
2288
- Error **errp);
2289
-
2290
- /**
2291
- * Informs the block driver that a permission change is intended. The
2292
- * driver checks whether the change is permissible and may take other
2293
- * preparations for the change (e.g. get file system locks). This operation
2294
- * is always followed either by a call to either .bdrv_set_perm or
2295
- * .bdrv_abort_perm_update.
2296
- *
2297
- * Checks whether the requested set of cumulative permissions in @perm
2298
- * can be granted for accessing @bs and whether no other users are using
2299
- * permissions other than those given in @shared (both arguments take
2300
- * BLK_PERM_* bitmasks).
2301
- *
2302
- * If both conditions are met, 0 is returned. Otherwise, -errno is returned
2303
- * and errp is set to an error describing the conflict.
2304
- */
2305
- int (*bdrv_check_perm)(BlockDriverState *bs, uint64_t perm,
2306
- uint64_t shared, Error **errp);
2307
-
2308
- /**
2309
- * Called to inform the driver that the set of cumulative set of used
2310
- * permissions for @bs has changed to @perm, and the set of sharable
2311
- * permission to @shared. The driver can use this to propagate changes to
2312
- * its children (i.e. request permissions only if a parent actually needs
2313
- * them).
2314
- *
2315
- * This function is only invoked after bdrv_check_perm(), so block drivers
2316
- * may rely on preparations made in their .bdrv_check_perm implementation.
2317
- */
2318
- void (*bdrv_set_perm)(BlockDriverState *bs, uint64_t perm, uint64_t shared);
2319
-
2320
- /*
2321
- * Called to inform the driver that after a previous bdrv_check_perm()
2322
- * call, the permission update is not performed and any preparations made
2323
- * for it (e.g. taken file locks) need to be undone.
2324
- *
2325
- * This function can be called even for nodes that never saw a
2326
- * bdrv_check_perm() call. It is a no-op then.
2327
- */
2328
- void (*bdrv_abort_perm_update)(BlockDriverState *bs);
2329
-
2330
- /**
2331
- * Returns in @nperm and @nshared the permissions that the driver for @bs
2332
- * needs on its child @c, based on the cumulative permissions requested by
2333
- * the parents in @parent_perm and @parent_shared.
2334
- *
2335
- * If @c is NULL, return the permissions for attaching a new child for the
2336
- * given @child_class and @role.
2337
- *
2338
- * If @reopen_queue is non-NULL, don't return the currently needed
2339
- * permissions, but those that will be needed after applying the
2340
- * @reopen_queue.
2341
- */
2342
- void (*bdrv_child_perm)(BlockDriverState *bs, BdrvChild *c,
2343
- BdrvChildRole role,
2344
- BlockReopenQueue *reopen_queue,
2345
- uint64_t parent_perm, uint64_t parent_shared,
2346
- uint64_t *nperm, uint64_t *nshared);
2347
-
2348
- bool (*bdrv_supports_persistent_dirty_bitmap)(BlockDriverState *bs);
2349
- bool (*bdrv_co_can_store_new_dirty_bitmap)(BlockDriverState *bs,
2350
- const char *name,
2351
- uint32_t granularity,
2352
- Error **errp);
2353
- int (*bdrv_co_remove_persistent_dirty_bitmap)(BlockDriverState *bs,
2354
- const char *name,
2355
- Error **errp);
2356
-
2357
- /**
2358
- * Register/unregister a buffer for I/O. For example, when the driver is
2359
- * interested to know the memory areas that will later be used in iovs, so
2360
- * that it can do IOMMU mapping with VFIO etc., in order to get better
2361
- * performance. In the case of VFIO drivers, this callback is used to do
2362
- * DMA mapping for hot buffers.
2363
- */
2364
- void (*bdrv_register_buf)(BlockDriverState *bs, void *host, size_t size);
2365
- void (*bdrv_unregister_buf)(BlockDriverState *bs, void *host);
2366
- QLIST_ENTRY(BlockDriver) list;
2367
-
2368
- /* Pointer to a NULL-terminated array of names of strong options
2369
- * that can be specified for bdrv_open(). A strong option is one
2370
- * that changes the data of a BDS.
2371
- * If this pointer is NULL, the array is considered empty.
2372
- * "filename" and "driver" are always considered strong. */
2373
- const char *const *strong_runtime_opts;
2374
-};
2375
-
2376
-static inline bool block_driver_can_compress(BlockDriver *drv)
2377
-{
2378
- return drv->bdrv_co_pwritev_compressed ||
2379
- drv->bdrv_co_pwritev_compressed_part;
2380
-}
2381
-
2382
-typedef struct BlockLimits {
2383
- /* Alignment requirement, in bytes, for offset/length of I/O
2384
- * requests. Must be a power of 2 less than INT_MAX; defaults to
2385
- * 1 for drivers with modern byte interfaces, and to 512
2386
- * otherwise. */
2387
- uint32_t request_alignment;
2388
-
2389
- /*
2390
- * Maximum number of bytes that can be discarded at once. Must be multiple
2391
- * of pdiscard_alignment, but need not be power of 2. May be 0 if no
2392
- * inherent 64-bit limit.
2393
- */
2394
- int64_t max_pdiscard;
2395
-
2396
- /* Optimal alignment for discard requests in bytes. A power of 2
2397
- * is best but not mandatory. Must be a multiple of
2398
- * bl.request_alignment, and must be less than max_pdiscard if
2399
- * that is set. May be 0 if bl.request_alignment is good enough */
2400
- uint32_t pdiscard_alignment;
2401
-
2402
- /*
2403
- * Maximum number of bytes that can zeroized at once. Must be multiple of
2404
- * pwrite_zeroes_alignment. 0 means no limit.
2405
- */
2406
- int64_t max_pwrite_zeroes;
2407
-
2408
- /* Optimal alignment for write zeroes requests in bytes. A power
2409
- * of 2 is best but not mandatory. Must be a multiple of
2410
- * bl.request_alignment, and must be less than max_pwrite_zeroes
2411
- * if that is set. May be 0 if bl.request_alignment is good
2412
- * enough */
2413
- uint32_t pwrite_zeroes_alignment;
2414
-
2415
- /* Optimal transfer length in bytes. A power of 2 is best but not
2416
- * mandatory. Must be a multiple of bl.request_alignment, or 0 if
2417
- * no preferred size */
2418
- uint32_t opt_transfer;
2419
-
2420
- /* Maximal transfer length in bytes. Need not be power of 2, but
2421
- * must be multiple of opt_transfer and bl.request_alignment, or 0
2422
- * for no 32-bit limit. For now, anything larger than INT_MAX is
2423
- * clamped down. */
2424
- uint32_t max_transfer;
2425
-
2426
- /* Maximal hardware transfer length in bytes. Applies whenever
2427
- * transfers to the device bypass the kernel I/O scheduler, for
2428
- * example with SG_IO. If larger than max_transfer or if zero,
2429
- * blk_get_max_hw_transfer will fall back to max_transfer.
2430
- */
2431
- uint64_t max_hw_transfer;
2432
-
2433
- /* Maximal number of scatter/gather elements allowed by the hardware.
2434
- * Applies whenever transfers to the device bypass the kernel I/O
2435
- * scheduler, for example with SG_IO. If larger than max_iov
2436
- * or if zero, blk_get_max_hw_iov will fall back to max_iov.
2437
- */
2438
- int max_hw_iov;
2439
-
2440
- /* memory alignment, in bytes so that no bounce buffer is needed */
2441
- size_t min_mem_alignment;
2442
-
2443
- /* memory alignment, in bytes, for bounce buffer */
2444
- size_t opt_mem_alignment;
2445
-
2446
- /* maximum number of iovec elements */
2447
- int max_iov;
2448
-} BlockLimits;
2449
-
2450
-typedef struct BdrvOpBlocker BdrvOpBlocker;
2451
-
2452
-typedef struct BdrvAioNotifier {
2453
- void (*attached_aio_context)(AioContext *new_context, void *opaque);
2454
- void (*detach_aio_context)(void *opaque);
2455
-
2456
- void *opaque;
2457
- bool deleted;
2458
-
2459
- QLIST_ENTRY(BdrvAioNotifier) list;
2460
-} BdrvAioNotifier;
2461
-
2462
-struct BdrvChildClass {
2463
- /* If true, bdrv_replace_node() doesn't change the node this BdrvChild
2464
- * points to. */
2465
- bool stay_at_node;
2466
-
2467
- /* If true, the parent is a BlockDriverState and bdrv_next_all_states()
2468
- * will return it. This information is used for drain_all, where every node
2469
- * will be drained separately, so the drain only needs to be propagated to
2470
- * non-BDS parents. */
2471
- bool parent_is_bds;
2472
-
2473
- void (*inherit_options)(BdrvChildRole role, bool parent_is_format,
2474
- int *child_flags, QDict *child_options,
2475
- int parent_flags, QDict *parent_options);
2476
-
2477
- void (*change_media)(BdrvChild *child, bool load);
2478
- void (*resize)(BdrvChild *child);
2479
-
2480
- /* Returns a name that is supposedly more useful for human users than the
2481
- * node name for identifying the node in question (in particular, a BB
2482
- * name), or NULL if the parent can't provide a better name. */
2483
- const char *(*get_name)(BdrvChild *child);
2484
-
2485
- /* Returns a malloced string that describes the parent of the child for a
2486
- * human reader. This could be a node-name, BlockBackend name, qdev ID or
2487
- * QOM path of the device owning the BlockBackend, job type and ID etc. The
2488
- * caller is responsible for freeing the memory. */
2489
- char *(*get_parent_desc)(BdrvChild *child);
2490
-
2491
- /*
2492
- * If this pair of functions is implemented, the parent doesn't issue new
2493
- * requests after returning from .drained_begin() until .drained_end() is
2494
- * called.
2495
- *
2496
- * These functions must not change the graph (and therefore also must not
2497
- * call aio_poll(), which could change the graph indirectly).
2498
- *
2499
- * If drained_end() schedules background operations, it must atomically
2500
- * increment *drained_end_counter for each such operation and atomically
2501
- * decrement it once the operation has settled.
2502
- *
2503
- * Note that this can be nested. If drained_begin() was called twice, new
2504
- * I/O is allowed only after drained_end() was called twice, too.
2505
- */
2506
- void (*drained_begin)(BdrvChild *child);
2507
- void (*drained_end)(BdrvChild *child, int *drained_end_counter);
2508
-
2509
- /*
2510
- * Returns whether the parent has pending requests for the child. This
2511
- * callback is polled after .drained_begin() has been called until all
2512
- * activity on the child has stopped.
2513
- */
2514
- bool (*drained_poll)(BdrvChild *child);
2515
-
2516
- /* Notifies the parent that the child has been activated/inactivated (e.g.
2517
- * when migration is completing) and it can start/stop requesting
2518
- * permissions and doing I/O on it. */
2519
- void (*activate)(BdrvChild *child, Error **errp);
2520
- int (*inactivate)(BdrvChild *child);
2521
-
2522
- void (*attach)(BdrvChild *child);
2523
- void (*detach)(BdrvChild *child);
2524
-
2525
- /* Notifies the parent that the filename of its child has changed (e.g.
2526
- * because the direct child was removed from the backing chain), so that it
2527
- * can update its reference. */
2528
- int (*update_filename)(BdrvChild *child, BlockDriverState *new_base,
2529
- const char *filename, Error **errp);
2530
-
2531
- bool (*can_set_aio_ctx)(BdrvChild *child, AioContext *ctx,
2532
- GSList **ignore, Error **errp);
2533
- void (*set_aio_ctx)(BdrvChild *child, AioContext *ctx, GSList **ignore);
2534
-
2535
- AioContext *(*get_parent_aio_context)(BdrvChild *child);
2536
-};
2537
-
2538
-extern const BdrvChildClass child_of_bds;
2539
-
2540
-struct BdrvChild {
2541
- BlockDriverState *bs;
2542
- char *name;
2543
- const BdrvChildClass *klass;
2544
- BdrvChildRole role;
2545
- void *opaque;
2546
-
2547
- /**
2548
- * Granted permissions for operating on this BdrvChild (BLK_PERM_* bitmask)
2549
- */
2550
- uint64_t perm;
2551
-
2552
- /**
2553
- * Permissions that can still be granted to other users of @bs while this
2554
- * BdrvChild is still attached to it. (BLK_PERM_* bitmask)
2555
- */
2556
- uint64_t shared_perm;
2557
-
2558
- /*
2559
- * This link is frozen: the child can neither be replaced nor
2560
- * detached from the parent.
2561
- */
2562
- bool frozen;
2563
-
2564
- /*
2565
- * How many times the parent of this child has been drained
2566
- * (through klass->drained_*).
2567
- * Usually, this is equal to bs->quiesce_counter (potentially
2568
- * reduced by bdrv_drain_all_count). It may differ while the
2569
- * child is entering or leaving a drained section.
2570
- */
2571
- int parent_quiesce_counter;
2572
-
2573
- QLIST_ENTRY(BdrvChild) next;
2574
- QLIST_ENTRY(BdrvChild) next_parent;
2575
-};
2576
-
2577
-/*
2578
- * Allows bdrv_co_block_status() to cache one data region for a
2579
- * protocol node.
2580
- *
2581
- * @valid: Whether the cache is valid (should be accessed with atomic
2582
- * functions so this can be reset by RCU readers)
2583
- * @data_start: Offset where we know (or strongly assume) is data
2584
- * @data_end: Offset where the data region ends (which is not necessarily
2585
- * the start of a zeroed region)
2586
- */
2587
-typedef struct BdrvBlockStatusCache {
2588
- struct rcu_head rcu;
2589
-
2590
- bool valid;
2591
- int64_t data_start;
2592
- int64_t data_end;
2593
-} BdrvBlockStatusCache;
2594
-
2595
-struct BlockDriverState {
2596
- /* Protected by big QEMU lock or read-only after opening. No special
2597
- * locking needed during I/O...
2598
- */
2599
- int open_flags; /* flags used to open the file, re-used for re-open */
2600
- bool encrypted; /* if true, the media is encrypted */
2601
- bool sg; /* if true, the device is a /dev/sg* */
2602
- bool probed; /* if true, format was probed rather than specified */
2603
- bool force_share; /* if true, always allow all shared permissions */
2604
- bool implicit; /* if true, this filter node was automatically inserted */
2605
-
2606
- BlockDriver *drv; /* NULL means no media */
2607
- void *opaque;
2608
-
2609
- AioContext *aio_context; /* event loop used for fd handlers, timers, etc */
2610
- /* long-running tasks intended to always use the same AioContext as this
2611
- * BDS may register themselves in this list to be notified of changes
2612
- * regarding this BDS's context */
2613
- QLIST_HEAD(, BdrvAioNotifier) aio_notifiers;
2614
- bool walking_aio_notifiers; /* to make removal during iteration safe */
2615
-
2616
- char filename[PATH_MAX];
2617
- /*
2618
- * If not empty, this image is a diff in relation to backing_file.
2619
- * Note that this is the name given in the image header and
2620
- * therefore may or may not be equal to .backing->bs->filename.
2621
- * If this field contains a relative path, it is to be resolved
2622
- * relatively to the overlay's location.
2623
- */
2624
- char backing_file[PATH_MAX];
2625
- /*
2626
- * The backing filename indicated by the image header. Contrary
2627
- * to backing_file, if we ever open this file, auto_backing_file
2628
- * is replaced by the resulting BDS's filename (i.e. after a
2629
- * bdrv_refresh_filename() run).
2630
- */
2631
- char auto_backing_file[PATH_MAX];
2632
- char backing_format[16]; /* if non-zero and backing_file exists */
2633
-
2634
- QDict *full_open_options;
2635
- char exact_filename[PATH_MAX];
2636
-
2637
- BdrvChild *backing;
2638
- BdrvChild *file;
2639
-
2640
- /* I/O Limits */
2641
- BlockLimits bl;
2642
-
2643
- /*
2644
- * Flags honored during pread
2645
- */
2646
- unsigned int supported_read_flags;
2647
- /* Flags honored during pwrite (so far: BDRV_REQ_FUA,
2648
- * BDRV_REQ_WRITE_UNCHANGED).
2649
- * If a driver does not support BDRV_REQ_WRITE_UNCHANGED, those
2650
- * writes will be issued as normal writes without the flag set.
2651
- * This is important to note for drivers that do not explicitly
2652
- * request a WRITE permission for their children and instead take
2653
- * the same permissions as their parent did (this is commonly what
2654
- * block filters do). Such drivers have to be aware that the
2655
- * parent may have taken a WRITE_UNCHANGED permission only and is
2656
- * issuing such requests. Drivers either must make sure that
2657
- * these requests do not result in plain WRITE accesses (usually
2658
- * by supporting BDRV_REQ_WRITE_UNCHANGED, and then forwarding
2659
- * every incoming write request as-is, including potentially that
2660
- * flag), or they have to explicitly take the WRITE permission for
2661
- * their children. */
2662
- unsigned int supported_write_flags;
2663
- /* Flags honored during pwrite_zeroes (so far: BDRV_REQ_FUA,
2664
- * BDRV_REQ_MAY_UNMAP, BDRV_REQ_WRITE_UNCHANGED) */
2665
- unsigned int supported_zero_flags;
2666
- /*
2667
- * Flags honoured during truncate (so far: BDRV_REQ_ZERO_WRITE).
2668
- *
2669
- * If BDRV_REQ_ZERO_WRITE is given, the truncate operation must make sure
2670
- * that any added space reads as all zeros. If this can't be guaranteed,
2671
- * the operation must fail.
2672
- */
2673
- unsigned int supported_truncate_flags;
2674
-
2675
- /* the following member gives a name to every node on the bs graph. */
2676
- char node_name[32];
2677
- /* element of the list of named nodes building the graph */
2678
- QTAILQ_ENTRY(BlockDriverState) node_list;
2679
- /* element of the list of all BlockDriverStates (all_bdrv_states) */
2680
- QTAILQ_ENTRY(BlockDriverState) bs_list;
2681
- /* element of the list of monitor-owned BDS */
2682
- QTAILQ_ENTRY(BlockDriverState) monitor_list;
2683
- int refcnt;
2684
-
2685
- /* operation blockers */
2686
- QLIST_HEAD(, BdrvOpBlocker) op_blockers[BLOCK_OP_TYPE_MAX];
2687
-
2688
- /* The node that this node inherited default options from (and a reopen on
2689
- * which can affect this node by changing these defaults). This is always a
2690
- * parent node of this node. */
2691
- BlockDriverState *inherits_from;
2692
- QLIST_HEAD(, BdrvChild) children;
2693
- QLIST_HEAD(, BdrvChild) parents;
2694
-
2695
- QDict *options;
2696
- QDict *explicit_options;
2697
- BlockdevDetectZeroesOptions detect_zeroes;
2698
-
2699
- /* The error object in use for blocking operations on backing_hd */
2700
- Error *backing_blocker;
2701
-
2702
- /* Protected by AioContext lock */
2703
-
2704
- /* If we are reading a disk image, give its size in sectors.
2705
- * Generally read-only; it is written to by load_snapshot and
2706
- * save_snaphost, but the block layer is quiescent during those.
2707
- */
2708
- int64_t total_sectors;
2709
-
2710
- /* threshold limit for writes, in bytes. "High water mark". */
2711
- uint64_t write_threshold_offset;
2712
-
2713
- /* Writing to the list requires the BQL _and_ the dirty_bitmap_mutex.
2714
- * Reading from the list can be done with either the BQL or the
2715
- * dirty_bitmap_mutex. Modifying a bitmap only requires
2716
- * dirty_bitmap_mutex. */
2717
- QemuMutex dirty_bitmap_mutex;
2718
- QLIST_HEAD(, BdrvDirtyBitmap) dirty_bitmaps;
2719
-
2720
- /* Offset after the highest byte written to */
2721
- Stat64 wr_highest_offset;
2722
-
2723
- /* If true, copy read backing sectors into image. Can be >1 if more
2724
- * than one client has requested copy-on-read. Accessed with atomic
2725
- * ops.
2726
- */
2727
- int copy_on_read;
2728
-
2729
- /* number of in-flight requests; overall and serialising.
2730
- * Accessed with atomic ops.
2731
- */
2732
- unsigned int in_flight;
2733
- unsigned int serialising_in_flight;
2734
-
2735
- /* counter for nested bdrv_io_plug.
2736
- * Accessed with atomic ops.
2737
- */
2738
- unsigned io_plugged;
2739
-
2740
- /* do we need to tell the quest if we have a volatile write cache? */
2741
- int enable_write_cache;
2742
-
2743
- /* Accessed with atomic ops. */
2744
- int quiesce_counter;
2745
- int recursive_quiesce_counter;
2746
-
2747
- unsigned int write_gen; /* Current data generation */
2748
-
2749
- /* Protected by reqs_lock. */
2750
- CoMutex reqs_lock;
2751
- QLIST_HEAD(, BdrvTrackedRequest) tracked_requests;
2752
- CoQueue flush_queue; /* Serializing flush queue */
2753
- bool active_flush_req; /* Flush request in flight? */
2754
-
2755
- /* Only read/written by whoever has set active_flush_req to true. */
2756
- unsigned int flushed_gen; /* Flushed write generation */
2757
-
2758
- /* BdrvChild links to this node may never be frozen */
2759
- bool never_freeze;
2760
-
2761
- /* Lock for block-status cache RCU writers */
2762
- CoMutex bsc_modify_lock;
2763
- /* Always non-NULL, but must only be dereferenced under an RCU read guard */
2764
- BdrvBlockStatusCache *block_status_cache;
2765
-};
2766
-
2767
-struct BlockBackendRootState {
2768
- int open_flags;
2769
- BlockdevDetectZeroesOptions detect_zeroes;
2770
-};
2771
-
2772
-typedef enum BlockMirrorBackingMode {
2773
- /* Reuse the existing backing chain from the source for the target.
2774
- * - sync=full: Set backing BDS to NULL.
2775
- * - sync=top: Use source's backing BDS.
2776
- * - sync=none: Use source as the backing BDS. */
2777
- MIRROR_SOURCE_BACKING_CHAIN,
2778
-
2779
- /* Open the target's backing chain completely anew */
2780
- MIRROR_OPEN_BACKING_CHAIN,
2781
-
2782
- /* Do not change the target's backing BDS after job completion */
2783
- MIRROR_LEAVE_BACKING_CHAIN,
2784
-} BlockMirrorBackingMode;
2785
-
2786
-
2787
-/* Essential block drivers which must always be statically linked into qemu, and
2788
- * which therefore can be accessed without using bdrv_find_format() */
2789
-extern BlockDriver bdrv_file;
2790
-extern BlockDriver bdrv_raw;
2791
-extern BlockDriver bdrv_qcow2;
2792
-
2793
-int coroutine_fn bdrv_co_preadv(BdrvChild *child,
2794
- int64_t offset, int64_t bytes, QEMUIOVector *qiov,
2795
- BdrvRequestFlags flags);
2796
-int coroutine_fn bdrv_co_preadv_part(BdrvChild *child,
2797
- int64_t offset, int64_t bytes,
2798
- QEMUIOVector *qiov, size_t qiov_offset, BdrvRequestFlags flags);
2799
-int coroutine_fn bdrv_co_pwritev(BdrvChild *child,
2800
- int64_t offset, int64_t bytes, QEMUIOVector *qiov,
2801
- BdrvRequestFlags flags);
2802
-int coroutine_fn bdrv_co_pwritev_part(BdrvChild *child,
2803
- int64_t offset, int64_t bytes,
2804
- QEMUIOVector *qiov, size_t qiov_offset, BdrvRequestFlags flags);
2805
-
2806
-static inline int coroutine_fn bdrv_co_pread(BdrvChild *child,
2807
- int64_t offset, unsigned int bytes, void *buf, BdrvRequestFlags flags)
2808
-{
2809
- QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, bytes);
2810
-
2811
- return bdrv_co_preadv(child, offset, bytes, &qiov, flags);
2812
-}
2813
-
2814
-static inline int coroutine_fn bdrv_co_pwrite(BdrvChild *child,
2815
- int64_t offset, unsigned int bytes, void *buf, BdrvRequestFlags flags)
2816
-{
2817
- QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, bytes);
2818
-
2819
- return bdrv_co_pwritev(child, offset, bytes, &qiov, flags);
2820
-}
2821
-
2822
-extern unsigned int bdrv_drain_all_count;
2823
-void bdrv_apply_subtree_drain(BdrvChild *child, BlockDriverState *new_parent);
2824
-void bdrv_unapply_subtree_drain(BdrvChild *child, BlockDriverState *old_parent);
2825
-
2826
-bool coroutine_fn bdrv_make_request_serialising(BdrvTrackedRequest *req,
2827
- uint64_t align);
2828
-BdrvTrackedRequest *coroutine_fn bdrv_co_get_self_request(BlockDriverState *bs);
2829
-
2830
-int get_tmp_filename(char *filename, int size);
2831
-BlockDriver *bdrv_probe_all(const uint8_t *buf, int buf_size,
2832
- const char *filename);
2833
-
2834
-void bdrv_parse_filename_strip_prefix(const char *filename, const char *prefix,
2835
- QDict *options);
2836
-
2837
-/**
2838
- * bdrv_add_aio_context_notifier:
2839
- *
2840
- * If a long-running job intends to be always run in the same AioContext as a
2841
- * certain BDS, it may use this function to be notified of changes regarding the
2842
- * association of the BDS to an AioContext.
2843
- *
2844
- * attached_aio_context() is called after the target BDS has been attached to a
2845
- * new AioContext; detach_aio_context() is called before the target BDS is being
2846
- * detached from its old AioContext.
2847
- */
2848
-void bdrv_add_aio_context_notifier(BlockDriverState *bs,
2849
- void (*attached_aio_context)(AioContext *new_context, void *opaque),
2850
- void (*detach_aio_context)(void *opaque), void *opaque);
2851
-
2852
-/**
2853
- * bdrv_remove_aio_context_notifier:
2854
- *
2855
- * Unsubscribe of change notifications regarding the BDS's AioContext. The
2856
- * parameters given here have to be the same as those given to
2857
- * bdrv_add_aio_context_notifier().
2858
- */
2859
-void bdrv_remove_aio_context_notifier(BlockDriverState *bs,
2860
- void (*aio_context_attached)(AioContext *,
2861
- void *),
2862
- void (*aio_context_detached)(void *),
2863
- void *opaque);
2864
-
2865
-/**
2866
- * bdrv_wakeup:
2867
- * @bs: The BlockDriverState for which an I/O operation has been completed.
2868
- *
2869
- * Wake up the main thread if it is waiting on BDRV_POLL_WHILE. During
2870
- * synchronous I/O on a BlockDriverState that is attached to another
2871
- * I/O thread, the main thread lets the I/O thread's event loop run,
2872
- * waiting for the I/O operation to complete. A bdrv_wakeup will wake
2873
- * up the main thread if necessary.
2874
- *
2875
- * Manual calls to bdrv_wakeup are rarely necessary, because
2876
- * bdrv_dec_in_flight already calls it.
2877
- */
2878
-void bdrv_wakeup(BlockDriverState *bs);
2879
-
2880
-#ifdef _WIN32
2881
-int is_windows_drive(const char *filename);
2882
-#endif
2883
-
2884
-/**
2885
- * stream_start:
2886
- * @job_id: The id of the newly-created job, or %NULL to use the
2887
- * device name of @bs.
2888
- * @bs: Block device to operate on.
2889
- * @base: Block device that will become the new base, or %NULL to
2890
- * flatten the whole backing file chain onto @bs.
2891
- * @backing_file_str: The file name that will be written to @bs as the
2892
- * the new backing file if the job completes. Ignored if @base is %NULL.
2893
- * @creation_flags: Flags that control the behavior of the Job lifetime.
2894
- * See @BlockJobCreateFlags
2895
- * @speed: The maximum speed, in bytes per second, or 0 for unlimited.
2896
- * @on_error: The action to take upon error.
2897
- * @filter_node_name: The node name that should be assigned to the filter
2898
- * driver that the stream job inserts into the graph above
2899
- * @bs. NULL means that a node name should be autogenerated.
2900
- * @errp: Error object.
2901
- *
2902
- * Start a streaming operation on @bs. Clusters that are unallocated
2903
- * in @bs, but allocated in any image between @base and @bs (both
2904
- * exclusive) will be written to @bs. At the end of a successful
2905
- * streaming job, the backing file of @bs will be changed to
2906
- * @backing_file_str in the written image and to @base in the live
2907
- * BlockDriverState.
2908
- */
2909
-void stream_start(const char *job_id, BlockDriverState *bs,
2910
- BlockDriverState *base, const char *backing_file_str,
2911
- BlockDriverState *bottom,
2912
- int creation_flags, int64_t speed,
2913
- BlockdevOnError on_error,
2914
- const char *filter_node_name,
2915
- Error **errp);
2916
-
2917
-/**
2918
- * commit_start:
2919
- * @job_id: The id of the newly-created job, or %NULL to use the
2920
- * device name of @bs.
2921
- * @bs: Active block device.
2922
- * @top: Top block device to be committed.
2923
- * @base: Block device that will be written into, and become the new top.
2924
- * @creation_flags: Flags that control the behavior of the Job lifetime.
2925
- * See @BlockJobCreateFlags
2926
- * @speed: The maximum speed, in bytes per second, or 0 for unlimited.
2927
- * @on_error: The action to take upon error.
2928
- * @backing_file_str: String to use as the backing file in @top's overlay
2929
- * @filter_node_name: The node name that should be assigned to the filter
2930
- * driver that the commit job inserts into the graph above @top. NULL means
2931
- * that a node name should be autogenerated.
2932
- * @errp: Error object.
2933
- *
2934
- */
2935
-void commit_start(const char *job_id, BlockDriverState *bs,
2936
- BlockDriverState *base, BlockDriverState *top,
2937
- int creation_flags, int64_t speed,
2938
- BlockdevOnError on_error, const char *backing_file_str,
2939
- const char *filter_node_name, Error **errp);
2940
-/**
2941
- * commit_active_start:
2942
- * @job_id: The id of the newly-created job, or %NULL to use the
2943
- * device name of @bs.
2944
- * @bs: Active block device to be committed.
2945
- * @base: Block device that will be written into, and become the new top.
2946
- * @creation_flags: Flags that control the behavior of the Job lifetime.
2947
- * See @BlockJobCreateFlags
2948
- * @speed: The maximum speed, in bytes per second, or 0 for unlimited.
2949
- * @on_error: The action to take upon error.
2950
- * @filter_node_name: The node name that should be assigned to the filter
2951
- * driver that the commit job inserts into the graph above @bs. NULL means that
2952
- * a node name should be autogenerated.
2953
- * @cb: Completion function for the job.
2954
- * @opaque: Opaque pointer value passed to @cb.
2955
- * @auto_complete: Auto complete the job.
2956
- * @errp: Error object.
2957
- *
2958
- */
2959
-BlockJob *commit_active_start(const char *job_id, BlockDriverState *bs,
2960
- BlockDriverState *base, int creation_flags,
2961
- int64_t speed, BlockdevOnError on_error,
2962
- const char *filter_node_name,
2963
- BlockCompletionFunc *cb, void *opaque,
2964
- bool auto_complete, Error **errp);
2965
-/*
2966
- * mirror_start:
2967
- * @job_id: The id of the newly-created job, or %NULL to use the
2968
- * device name of @bs.
2969
- * @bs: Block device to operate on.
2970
- * @target: Block device to write to.
2971
- * @replaces: Block graph node name to replace once the mirror is done. Can
2972
- * only be used when full mirroring is selected.
2973
- * @creation_flags: Flags that control the behavior of the Job lifetime.
2974
- * See @BlockJobCreateFlags
2975
- * @speed: The maximum speed, in bytes per second, or 0 for unlimited.
2976
- * @granularity: The chosen granularity for the dirty bitmap.
2977
- * @buf_size: The amount of data that can be in flight at one time.
2978
- * @mode: Whether to collapse all images in the chain to the target.
2979
- * @backing_mode: How to establish the target's backing chain after completion.
2980
- * @zero_target: Whether the target should be explicitly zero-initialized
2981
- * @on_source_error: The action to take upon error reading from the source.
2982
- * @on_target_error: The action to take upon error writing to the target.
2983
- * @unmap: Whether to unmap target where source sectors only contain zeroes.
2984
- * @filter_node_name: The node name that should be assigned to the filter
2985
- * driver that the mirror job inserts into the graph above @bs. NULL means that
2986
- * a node name should be autogenerated.
2987
- * @copy_mode: When to trigger writes to the target.
2988
- * @errp: Error object.
2989
- *
2990
- * Start a mirroring operation on @bs. Clusters that are allocated
2991
- * in @bs will be written to @target until the job is cancelled or
2992
- * manually completed. At the end of a successful mirroring job,
2993
- * @bs will be switched to read from @target.
2994
- */
2995
-void mirror_start(const char *job_id, BlockDriverState *bs,
2996
- BlockDriverState *target, const char *replaces,
2997
- int creation_flags, int64_t speed,
2998
- uint32_t granularity, int64_t buf_size,
2999
- MirrorSyncMode mode, BlockMirrorBackingMode backing_mode,
3000
- bool zero_target,
3001
- BlockdevOnError on_source_error,
3002
- BlockdevOnError on_target_error,
3003
- bool unmap, const char *filter_node_name,
3004
- MirrorCopyMode copy_mode, Error **errp);
3005
-
3006
-/*
3007
- * backup_job_create:
3008
- * @job_id: The id of the newly-created job, or %NULL to use the
3009
- * device name of @bs.
3010
- * @bs: Block device to operate on.
3011
- * @target: Block device to write to.
3012
- * @speed: The maximum speed, in bytes per second, or 0 for unlimited.
3013
- * @sync_mode: What parts of the disk image should be copied to the destination.
3014
- * @sync_bitmap: The dirty bitmap if sync_mode is 'bitmap' or 'incremental'
3015
- * @bitmap_mode: The bitmap synchronization policy to use.
3016
- * @perf: Performance options. All actual fields assumed to be present,
3017
- * all ".has_*" fields are ignored.
3018
- * @on_source_error: The action to take upon error reading from the source.
3019
- * @on_target_error: The action to take upon error writing to the target.
3020
- * @creation_flags: Flags that control the behavior of the Job lifetime.
3021
- * See @BlockJobCreateFlags
3022
- * @cb: Completion function for the job.
3023
- * @opaque: Opaque pointer value passed to @cb.
3024
- * @txn: Transaction that this job is part of (may be NULL).
3025
- *
3026
- * Create a backup operation on @bs. Clusters in @bs are written to @target
3027
- * until the job is cancelled or manually completed.
3028
- */
3029
-BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
3030
- BlockDriverState *target, int64_t speed,
3031
- MirrorSyncMode sync_mode,
3032
- BdrvDirtyBitmap *sync_bitmap,
3033
- BitmapSyncMode bitmap_mode,
3034
- bool compress,
3035
- const char *filter_node_name,
3036
- BackupPerf *perf,
3037
- BlockdevOnError on_source_error,
3038
- BlockdevOnError on_target_error,
3039
- int creation_flags,
3040
- BlockCompletionFunc *cb, void *opaque,
3041
- JobTxn *txn, Error **errp);
3042
-
3043
-BdrvChild *bdrv_root_attach_child(BlockDriverState *child_bs,
3044
- const char *child_name,
3045
- const BdrvChildClass *child_class,
3046
- BdrvChildRole child_role,
3047
- uint64_t perm, uint64_t shared_perm,
3048
- void *opaque, Error **errp);
3049
-void bdrv_root_unref_child(BdrvChild *child);
3050
-
3051
-void bdrv_get_cumulative_perm(BlockDriverState *bs, uint64_t *perm,
3052
- uint64_t *shared_perm);
3053
-
3054
-/**
3055
- * Sets a BdrvChild's permissions. Avoid if the parent is a BDS; use
3056
- * bdrv_child_refresh_perms() instead and make the parent's
3057
- * .bdrv_child_perm() implementation return the correct values.
3058
- */
3059
-int bdrv_child_try_set_perm(BdrvChild *c, uint64_t perm, uint64_t shared,
3060
- Error **errp);
3061
-
3062
-/**
3063
- * Calls bs->drv->bdrv_child_perm() and updates the child's permission
3064
- * masks with the result.
3065
- * Drivers should invoke this function whenever an event occurs that
3066
- * makes their .bdrv_child_perm() implementation return different
3067
- * values than before, but which will not result in the block layer
3068
- * automatically refreshing the permissions.
3069
- */
3070
-int bdrv_child_refresh_perms(BlockDriverState *bs, BdrvChild *c, Error **errp);
3071
-
3072
-bool bdrv_recurse_can_replace(BlockDriverState *bs,
3073
- BlockDriverState *to_replace);
3074
-
3075
-/*
3076
- * Default implementation for BlockDriver.bdrv_child_perm() that can
3077
- * be used by block filters and image formats, as long as they use the
3078
- * child_of_bds child class and set an appropriate BdrvChildRole.
3079
- */
3080
-void bdrv_default_perms(BlockDriverState *bs, BdrvChild *c,
3081
- BdrvChildRole role, BlockReopenQueue *reopen_queue,
3082
- uint64_t perm, uint64_t shared,
3083
- uint64_t *nperm, uint64_t *nshared);
3084
-
3085
-const char *bdrv_get_parent_name(const BlockDriverState *bs);
3086
-void blk_dev_change_media_cb(BlockBackend *blk, bool load, Error **errp);
3087
-bool blk_dev_has_removable_media(BlockBackend *blk);
3088
-bool blk_dev_has_tray(BlockBackend *blk);
3089
-void blk_dev_eject_request(BlockBackend *blk, bool force);
3090
-bool blk_dev_is_tray_open(BlockBackend *blk);
3091
-bool blk_dev_is_medium_locked(BlockBackend *blk);
3092
-
3093
-void bdrv_set_dirty(BlockDriverState *bs, int64_t offset, int64_t bytes);
3094
-
3095
-void bdrv_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap **out);
3096
-void bdrv_restore_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap *backup);
3097
-bool bdrv_dirty_bitmap_merge_internal(BdrvDirtyBitmap *dest,
3098
- const BdrvDirtyBitmap *src,
3099
- HBitmap **backup, bool lock);
3100
-
3101
-void bdrv_inc_in_flight(BlockDriverState *bs);
3102
-void bdrv_dec_in_flight(BlockDriverState *bs);
3103
-
3104
-void blockdev_close_all_bdrv_states(void);
3105
-
3106
-int coroutine_fn bdrv_co_copy_range_from(BdrvChild *src, int64_t src_offset,
3107
- BdrvChild *dst, int64_t dst_offset,
3108
- int64_t bytes,
3109
- BdrvRequestFlags read_flags,
3110
- BdrvRequestFlags write_flags);
3111
-int coroutine_fn bdrv_co_copy_range_to(BdrvChild *src, int64_t src_offset,
3112
- BdrvChild *dst, int64_t dst_offset,
3113
- int64_t bytes,
3114
- BdrvRequestFlags read_flags,
3115
- BdrvRequestFlags write_flags);
3116
-
3117
-int refresh_total_sectors(BlockDriverState *bs, int64_t hint);
3118
-
3119
-void bdrv_set_monitor_owned(BlockDriverState *bs);
3120
-BlockDriverState *bds_tree_init(QDict *bs_opts, Error **errp);
3121
-
3122
-/**
3123
- * Simple implementation of bdrv_co_create_opts for protocol drivers
3124
- * which only support creation via opening a file
3125
- * (usually existing raw storage device)
3126
- */
3127
-int coroutine_fn bdrv_co_create_opts_simple(BlockDriver *drv,
3128
- const char *filename,
3129
- QemuOpts *opts,
3130
- Error **errp);
3131
-extern QemuOptsList bdrv_create_opts_simple;
3132
-
3133
-BdrvDirtyBitmap *block_dirty_bitmap_lookup(const char *node,
3134
- const char *name,
3135
- BlockDriverState **pbs,
3136
- Error **errp);
3137
-BdrvDirtyBitmap *block_dirty_bitmap_merge(const char *node, const char *target,
3138
- BlockDirtyBitmapMergeSourceList *bms,
3139
- HBitmap **backup, Error **errp);
3140
-BdrvDirtyBitmap *block_dirty_bitmap_remove(const char *node, const char *name,
3141
- bool release,
3142
- BlockDriverState **bitmap_bs,
3143
- Error **errp);
3144
-
3145
-BdrvChild *bdrv_cow_child(BlockDriverState *bs);
3146
-BdrvChild *bdrv_filter_child(BlockDriverState *bs);
3147
-BdrvChild *bdrv_filter_or_cow_child(BlockDriverState *bs);
3148
-BdrvChild *bdrv_primary_child(BlockDriverState *bs);
3149
-BlockDriverState *bdrv_skip_implicit_filters(BlockDriverState *bs);
3150
-BlockDriverState *bdrv_skip_filters(BlockDriverState *bs);
3151
-BlockDriverState *bdrv_backing_chain_next(BlockDriverState *bs);
3152
-
3153
-static inline BlockDriverState *child_bs(BdrvChild *child)
3154
-{
3155
- return child ? child->bs : NULL;
3156
-}
3157
-
3158
-static inline BlockDriverState *bdrv_cow_bs(BlockDriverState *bs)
3159
-{
3160
- return child_bs(bdrv_cow_child(bs));
3161
-}
3162
-
3163
-static inline BlockDriverState *bdrv_filter_bs(BlockDriverState *bs)
3164
-{
3165
- return child_bs(bdrv_filter_child(bs));
3166
-}
3167
-
3168
-static inline BlockDriverState *bdrv_filter_or_cow_bs(BlockDriverState *bs)
3169
-{
3170
- return child_bs(bdrv_filter_or_cow_child(bs));
3171
-}
3172
-
3173
-static inline BlockDriverState *bdrv_primary_bs(BlockDriverState *bs)
3174
-{
3175
- return child_bs(bdrv_primary_child(bs));
3176
-}
3177
-
3178
-/**
3179
- * End all quiescent sections started by bdrv_drain_all_begin(). This is
3180
- * needed when deleting a BDS before bdrv_drain_all_end() is called.
3181
- *
3182
- * NOTE: this is an internal helper for bdrv_close() *only*. No one else
3183
- * should call it.
3184
- */
3185
-void bdrv_drain_all_end_quiesce(BlockDriverState *bs);
3186
-
3187
-/**
3188
- * Check whether the given offset is in the cached block-status data
3189
- * region.
3190
- *
3191
- * If it is, and @pnum is not NULL, *pnum is set to
3192
- * `bsc.data_end - offset`, i.e. how many bytes, starting from
3193
- * @offset, are data (according to the cache).
3194
- * Otherwise, *pnum is not touched.
3195
- */
3196
-bool bdrv_bsc_is_data(BlockDriverState *bs, int64_t offset, int64_t *pnum);
3197
-
3198
-/**
3199
- * If [offset, offset + bytes) overlaps with the currently cached
3200
- * block-status region, invalidate the cache.
3201
- *
3202
- * (To be used by I/O paths that cause data regions to be zero or
3203
- * holes.)
3204
- */
3205
-void bdrv_bsc_invalidate_range(BlockDriverState *bs,
3206
- int64_t offset, int64_t bytes);
3207
-
3208
-/**
3209
- * Mark the range [offset, offset + bytes) as a data region.
3210
- */
3211
-void bdrv_bsc_fill(BlockDriverState *bs, int64_t offset, int64_t bytes);
3212
+/* DO NOT ADD ANYTHING IN HERE. USE ONE OF THE HEADERS INCLUDED ABOVE */
3213
3214
#endif /* BLOCK_INT_H */
3215
diff --git a/blockdev.c b/blockdev.c
3216
index XXXXXXX..XXXXXXX 100644
3217
--- a/blockdev.c
3218
+++ b/blockdev.c
3219
@@ -XXX,XX +XXX,XX @@
3220
#include "qemu/main-loop.h"
3221
#include "qemu/throttle-options.h"
3222
3223
+/* Protected by BQL */
3224
QTAILQ_HEAD(, BlockDriverState) monitor_bdrv_states =
3225
QTAILQ_HEAD_INITIALIZER(monitor_bdrv_states);
3226
3227
@@ -XXX,XX +XXX,XX @@ typedef struct BlkActionState BlkActionState;
3228
*
3229
* Only prepare() may fail. In a single transaction, only one of commit() or
3230
* abort() will be called. clean() will always be called if it is present.
3231
+ *
3232
+ * Always run under BQL.
3233
*/
3234
typedef struct BlkActionOps {
3235
size_t instance_size;
3236
@@ -XXX,XX +XXX,XX @@ static TransactionProperties *get_transaction_properties(
3237
/*
3238
* 'Atomic' group operations. The operations are performed as a set, and if
3239
* any fail then we roll back all operations in the group.
3240
+ *
3241
+ * Always run under BQL.
3242
*/
3243
void qmp_transaction(TransactionActionList *dev_list,
3244
bool has_props,
3245
--
3246
2.35.1
diff view generated by jsdifflib
1
Now that node level interface bdrv_truncate() supports passing request
1
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
2
flags to the block driver, expose this on the BlockBackend level, too.
3
2
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
3
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
5
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
4
Message-Id: <20220303151616.325444-13-eesposit@redhat.com>
6
Reviewed-by: Alberto Garcia <berto@igalia.com>
7
Reviewed-by: Max Reitz <mreitz@redhat.com>
8
Message-Id: <20200424125448.63318-4-kwolf@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
6
---
11
include/sysemu/block-backend.h | 2 +-
7
block.c | 15 +++++++++++++++
12
block.c | 3 ++-
8
block/backup.c | 1 +
13
block/block-backend.c | 4 ++--
9
block/block-backend.c | 3 +++
14
block/commit.c | 4 ++--
10
block/commit.c | 2 ++
15
block/crypto.c | 2 +-
11
block/dirty-bitmap.c | 1 +
16
block/mirror.c | 2 +-
12
block/io.c | 1 +
17
block/qcow2.c | 4 ++--
13
block/mirror.c | 4 ++++
18
block/qed.c | 2 +-
14
block/monitor/bitmap-qmp-cmds.c | 6 ++++++
19
block/vdi.c | 2 +-
15
block/stream.c | 2 ++
20
block/vhdx.c | 4 ++--
16
blockdev.c | 7 +++++++
21
block/vmdk.c | 6 +++---
17
10 files changed, 42 insertions(+)
22
block/vpc.c | 2 +-
23
blockdev.c | 2 +-
24
qemu-img.c | 2 +-
25
qemu-io-cmds.c | 2 +-
26
15 files changed, 22 insertions(+), 21 deletions(-)
27
18
28
diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h
29
index XXXXXXX..XXXXXXX 100644
30
--- a/include/sysemu/block-backend.h
31
+++ b/include/sysemu/block-backend.h
32
@@ -XXX,XX +XXX,XX @@ int coroutine_fn blk_co_pwrite_zeroes(BlockBackend *blk, int64_t offset,
33
int blk_pwrite_compressed(BlockBackend *blk, int64_t offset, const void *buf,
34
int bytes);
35
int blk_truncate(BlockBackend *blk, int64_t offset, bool exact,
36
- PreallocMode prealloc, Error **errp);
37
+ PreallocMode prealloc, BdrvRequestFlags flags, Error **errp);
38
int blk_pdiscard(BlockBackend *blk, int64_t offset, int bytes);
39
int blk_save_vmstate(BlockBackend *blk, const uint8_t *buf,
40
int64_t pos, int size);
41
diff --git a/block.c b/block.c
19
diff --git a/block.c b/block.c
42
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
43
--- a/block.c
21
--- a/block.c
44
+++ b/block.c
22
+++ b/block.c
45
@@ -XXX,XX +XXX,XX @@ static int64_t create_file_fallback_truncate(BlockBackend *blk,
23
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_create_opts_simple(BlockDriver *drv,
46
int64_t size;
24
Error *local_err = NULL;
47
int ret;
25
int ret;
48
26
49
- ret = blk_truncate(blk, minimum_size, false, PREALLOC_MODE_OFF, &local_err);
27
+ GLOBAL_STATE_CODE();
50
+ ret = blk_truncate(blk, minimum_size, false, PREALLOC_MODE_OFF, 0,
28
+
51
+ &local_err);
29
size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0);
52
if (ret < 0 && ret != -ENOTSUP) {
30
buf = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC);
53
error_propagate(errp, local_err);
31
prealloc = qapi_enum_parse(&PreallocMode_lookup, buf,
54
return ret;
32
@@ -XXX,XX +XXX,XX @@ void bdrv_get_cumulative_perm(BlockDriverState *bs, uint64_t *perm,
33
uint64_t cumulative_perms = 0;
34
uint64_t cumulative_shared_perms = BLK_PERM_ALL;
35
36
+ GLOBAL_STATE_CODE();
37
+
38
QLIST_FOREACH(c, &bs->parents, next_parent) {
39
cumulative_perms |= c->perm;
40
cumulative_shared_perms &= c->shared_perm;
41
@@ -XXX,XX +XXX,XX @@ int bdrv_child_try_set_perm(BdrvChild *c, uint64_t perm, uint64_t shared,
42
Transaction *tran = tran_new();
43
int ret;
44
45
+ GLOBAL_STATE_CODE();
46
+
47
bdrv_child_set_perm(c, perm, shared, tran);
48
49
ret = bdrv_refresh_perms(c->bs, &local_err);
50
@@ -XXX,XX +XXX,XX @@ int bdrv_child_refresh_perms(BlockDriverState *bs, BdrvChild *c, Error **errp)
51
uint64_t parent_perms, parent_shared;
52
uint64_t perms, shared;
53
54
+ GLOBAL_STATE_CODE();
55
+
56
bdrv_get_cumulative_perm(bs, &parent_perms, &parent_shared);
57
bdrv_child_perm(bs, c->bs, c, c->role, NULL,
58
parent_perms, parent_shared, &perms, &shared);
59
@@ -XXX,XX +XXX,XX @@ void bdrv_default_perms(BlockDriverState *bs, BdrvChild *c,
60
uint64_t perm, uint64_t shared,
61
uint64_t *nperm, uint64_t *nshared)
62
{
63
+ GLOBAL_STATE_CODE();
64
if (role & BDRV_CHILD_FILTERED) {
65
assert(!(role & (BDRV_CHILD_DATA | BDRV_CHILD_METADATA |
66
BDRV_CHILD_COW)));
67
@@ -XXX,XX +XXX,XX @@ BdrvChild *bdrv_root_attach_child(BlockDriverState *child_bs,
68
BdrvChild *child = NULL;
69
Transaction *tran = tran_new();
70
71
+ GLOBAL_STATE_CODE();
72
+
73
ret = bdrv_attach_child_common(child_bs, child_name, child_class,
74
child_role, perm, shared_perm, opaque,
75
&child, tran, errp);
76
@@ -XXX,XX +XXX,XX @@ bool bdrv_recurse_can_replace(BlockDriverState *bs,
77
{
78
BlockDriverState *filtered;
79
80
+ GLOBAL_STATE_CODE();
81
+
82
if (!bs || !bs->drv) {
83
return false;
84
}
85
@@ -XXX,XX +XXX,XX @@ static bool append_strong_runtime_options(QDict *d, BlockDriverState *bs)
86
* would result in exactly bs->backing. */
87
static bool bdrv_backing_overridden(BlockDriverState *bs)
88
{
89
+ GLOBAL_STATE_CODE();
90
if (bs->backing) {
91
return strcmp(bs->auto_backing_file,
92
bs->backing->bs->filename);
93
@@ -XXX,XX +XXX,XX @@ static BlockDriverState *bdrv_do_skip_filters(BlockDriverState *bs,
94
*/
95
BlockDriverState *bdrv_skip_implicit_filters(BlockDriverState *bs)
96
{
97
+ GLOBAL_STATE_CODE();
98
return bdrv_do_skip_filters(bs, true);
99
}
100
101
diff --git a/block/backup.c b/block/backup.c
102
index XXXXXXX..XXXXXXX 100644
103
--- a/block/backup.c
104
+++ b/block/backup.c
105
@@ -XXX,XX +XXX,XX @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
106
107
assert(bs);
108
assert(target);
109
+ GLOBAL_STATE_CODE();
110
111
/* QMP interface protects us from these cases */
112
assert(sync_mode != MIRROR_SYNC_MODE_INCREMENTAL);
55
diff --git a/block/block-backend.c b/block/block-backend.c
113
diff --git a/block/block-backend.c b/block/block-backend.c
56
index XXXXXXX..XXXXXXX 100644
114
index XXXXXXX..XXXXXXX 100644
57
--- a/block/block-backend.c
115
--- a/block/block-backend.c
58
+++ b/block/block-backend.c
116
+++ b/block/block-backend.c
59
@@ -XXX,XX +XXX,XX @@ int blk_pwrite_compressed(BlockBackend *blk, int64_t offset, const void *buf,
117
@@ -XXX,XX +XXX,XX @@ static void blk_root_change_media(BdrvChild *child, bool load)
60
}
118
*/
61
119
bool blk_dev_has_removable_media(BlockBackend *blk)
62
int blk_truncate(BlockBackend *blk, int64_t offset, bool exact,
120
{
63
- PreallocMode prealloc, Error **errp)
121
+ GLOBAL_STATE_CODE();
64
+ PreallocMode prealloc, BdrvRequestFlags flags, Error **errp)
122
return !blk->dev || (blk->dev_ops && blk->dev_ops->change_media_cb);
65
{
123
}
66
if (!blk_is_available(blk)) {
124
67
error_setg(errp, "No medium inserted");
125
@@ -XXX,XX +XXX,XX @@ bool blk_dev_has_tray(BlockBackend *blk)
68
return -ENOMEDIUM;
126
*/
127
void blk_dev_eject_request(BlockBackend *blk, bool force)
128
{
129
+ GLOBAL_STATE_CODE();
130
if (blk->dev_ops && blk->dev_ops->eject_request_cb) {
131
blk->dev_ops->eject_request_cb(blk->dev_opaque, force);
69
}
132
}
70
133
@@ -XXX,XX +XXX,XX @@ bool blk_dev_is_tray_open(BlockBackend *blk)
71
- return bdrv_truncate(blk->root, offset, exact, prealloc, 0, errp);
134
*/
72
+ return bdrv_truncate(blk->root, offset, exact, prealloc, flags, errp);
135
bool blk_dev_is_medium_locked(BlockBackend *blk)
73
}
136
{
74
137
+ GLOBAL_STATE_CODE();
75
int blk_save_vmstate(BlockBackend *blk, const uint8_t *buf,
138
if (blk->dev_ops && blk->dev_ops->is_medium_locked) {
139
return blk->dev_ops->is_medium_locked(blk->dev_opaque);
140
}
76
diff --git a/block/commit.c b/block/commit.c
141
diff --git a/block/commit.c b/block/commit.c
77
index XXXXXXX..XXXXXXX 100644
142
index XXXXXXX..XXXXXXX 100644
78
--- a/block/commit.c
143
--- a/block/commit.c
79
+++ b/block/commit.c
144
+++ b/block/commit.c
80
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn commit_run(Job *job, Error **errp)
145
@@ -XXX,XX +XXX,XX @@ void commit_start(const char *job_id, BlockDriverState *bs,
81
}
146
uint64_t base_perms, iter_shared_perms;
82
147
int ret;
83
if (base_len < len) {
148
84
- ret = blk_truncate(s->base, len, false, PREALLOC_MODE_OFF, NULL);
149
+ GLOBAL_STATE_CODE();
85
+ ret = blk_truncate(s->base, len, false, PREALLOC_MODE_OFF, 0, NULL);
150
+
86
if (ret) {
151
assert(top != bs);
87
goto out;
152
if (bdrv_skip_filters(top) == bdrv_skip_filters(base)) {
88
}
153
error_setg(errp, "Invalid files for merge: top and base are the same");
89
@@ -XXX,XX +XXX,XX @@ int bdrv_commit(BlockDriverState *bs)
154
diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c
90
* grow the backing file image if possible. If not possible,
155
index XXXXXXX..XXXXXXX 100644
91
* we must return an error */
156
--- a/block/dirty-bitmap.c
92
if (length > backing_length) {
157
+++ b/block/dirty-bitmap.c
93
- ret = blk_truncate(backing, length, false, PREALLOC_MODE_OFF,
158
@@ -XXX,XX +XXX,XX @@ void bdrv_restore_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap *backup)
94
+ ret = blk_truncate(backing, length, false, PREALLOC_MODE_OFF, 0,
159
{
95
&local_err);
160
HBitmap *tmp = bitmap->bitmap;
96
if (ret < 0) {
161
assert(!bdrv_dirty_bitmap_readonly(bitmap));
97
error_report_err(local_err);
162
+ GLOBAL_STATE_CODE();
98
diff --git a/block/crypto.c b/block/crypto.c
163
bitmap->bitmap = backup;
99
index XXXXXXX..XXXXXXX 100644
164
hbitmap_free(tmp);
100
--- a/block/crypto.c
165
}
101
+++ b/block/crypto.c
166
diff --git a/block/io.c b/block/io.c
102
@@ -XXX,XX +XXX,XX @@ static ssize_t block_crypto_init_func(QCryptoBlock *block,
167
index XXXXXXX..XXXXXXX 100644
103
* which will be used by the crypto header
168
--- a/block/io.c
104
*/
169
+++ b/block/io.c
105
return blk_truncate(data->blk, data->size + headerlen, false,
170
@@ -XXX,XX +XXX,XX @@ void bdrv_drain_all_begin(void)
106
- data->prealloc, errp);
171
void bdrv_drain_all_end_quiesce(BlockDriverState *bs)
107
+ data->prealloc, 0, errp);
172
{
108
}
173
int drained_end_counter = 0;
109
174
+ GLOBAL_STATE_CODE();
110
175
176
g_assert(bs->quiesce_counter > 0);
177
g_assert(!bs->refcnt);
111
diff --git a/block/mirror.c b/block/mirror.c
178
diff --git a/block/mirror.c b/block/mirror.c
112
index XXXXXXX..XXXXXXX 100644
179
index XXXXXXX..XXXXXXX 100644
113
--- a/block/mirror.c
180
--- a/block/mirror.c
114
+++ b/block/mirror.c
181
+++ b/block/mirror.c
115
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn mirror_run(Job *job, Error **errp)
182
@@ -XXX,XX +XXX,XX @@ void mirror_start(const char *job_id, BlockDriverState *bs,
116
183
bool is_none_mode;
117
if (s->bdev_length > base_length) {
184
BlockDriverState *base;
118
ret = blk_truncate(s->target, s->bdev_length, false,
185
119
- PREALLOC_MODE_OFF, NULL);
186
+ GLOBAL_STATE_CODE();
120
+ PREALLOC_MODE_OFF, 0, NULL);
187
+
121
if (ret < 0) {
188
if ((mode == MIRROR_SYNC_MODE_INCREMENTAL) ||
122
goto immediate_exit;
189
(mode == MIRROR_SYNC_MODE_BITMAP)) {
123
}
190
error_setg(errp, "Sync mode '%s' not supported",
124
diff --git a/block/qcow2.c b/block/qcow2.c
191
@@ -XXX,XX +XXX,XX @@ BlockJob *commit_active_start(const char *job_id, BlockDriverState *bs,
125
index XXXXXXX..XXXXXXX 100644
192
bool base_read_only;
126
--- a/block/qcow2.c
193
BlockJob *job;
127
+++ b/block/qcow2.c
194
128
@@ -XXX,XX +XXX,XX @@ qcow2_co_create(BlockdevCreateOptions *create_options, Error **errp)
195
+ GLOBAL_STATE_CODE();
129
196
+
130
/* Okay, now that we have a valid image, let's give it the right size */
197
base_read_only = bdrv_is_read_only(base);
131
ret = blk_truncate(blk, qcow2_opts->size, false, qcow2_opts->preallocation,
198
132
- errp);
199
if (base_read_only) {
133
+ 0, errp);
200
diff --git a/block/monitor/bitmap-qmp-cmds.c b/block/monitor/bitmap-qmp-cmds.c
134
if (ret < 0) {
201
index XXXXXXX..XXXXXXX 100644
135
error_prepend(errp, "Could not resize image: ");
202
--- a/block/monitor/bitmap-qmp-cmds.c
136
goto out;
203
+++ b/block/monitor/bitmap-qmp-cmds.c
137
@@ -XXX,XX +XXX,XX @@ static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts,
204
@@ -XXX,XX +XXX,XX @@ BdrvDirtyBitmap *block_dirty_bitmap_lookup(const char *node,
138
* Amending image options should ensure that the image has
205
BlockDriverState *bs;
139
* exactly the given new values, so pass exact=true here.
206
BdrvDirtyBitmap *bitmap;
140
*/
207
141
- ret = blk_truncate(blk, new_size, true, PREALLOC_MODE_OFF, errp);
208
+ GLOBAL_STATE_CODE();
142
+ ret = blk_truncate(blk, new_size, true, PREALLOC_MODE_OFF, 0, errp);
209
+
143
blk_unref(blk);
210
if (!node) {
144
if (ret < 0) {
211
error_setg(errp, "Node cannot be NULL");
145
return ret;
212
return NULL;
146
diff --git a/block/qed.c b/block/qed.c
213
@@ -XXX,XX +XXX,XX @@ BdrvDirtyBitmap *block_dirty_bitmap_remove(const char *node, const char *name,
147
index XXXXXXX..XXXXXXX 100644
214
BdrvDirtyBitmap *bitmap;
148
--- a/block/qed.c
215
AioContext *aio_context;
149
+++ b/block/qed.c
216
150
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_qed_co_create(BlockdevCreateOptions *opts,
217
+ GLOBAL_STATE_CODE();
151
* The QED format associates file length with allocation status,
218
+
152
* so a new file (which is empty) must have a length of 0.
219
bitmap = block_dirty_bitmap_lookup(node, name, &bs, errp);
153
*/
220
if (!bitmap || !bs) {
154
- ret = blk_truncate(blk, 0, true, PREALLOC_MODE_OFF, errp);
221
return NULL;
155
+ ret = blk_truncate(blk, 0, true, PREALLOC_MODE_OFF, 0, errp);
222
@@ -XXX,XX +XXX,XX @@ BdrvDirtyBitmap *block_dirty_bitmap_merge(const char *node, const char *target,
156
if (ret < 0) {
223
BlockDirtyBitmapMergeSourceList *lst;
157
goto out;
224
Error *local_err = NULL;
158
}
225
159
diff --git a/block/vdi.c b/block/vdi.c
226
+ GLOBAL_STATE_CODE();
160
index XXXXXXX..XXXXXXX 100644
227
+
161
--- a/block/vdi.c
228
dst = block_dirty_bitmap_lookup(node, target, &bs, errp);
162
+++ b/block/vdi.c
229
if (!dst) {
163
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn vdi_co_do_create(BlockdevCreateOptions *create_options,
230
return NULL;
164
231
diff --git a/block/stream.c b/block/stream.c
165
if (image_type == VDI_TYPE_STATIC) {
232
index XXXXXXX..XXXXXXX 100644
166
ret = blk_truncate(blk, offset + blocks * block_size, false,
233
--- a/block/stream.c
167
- PREALLOC_MODE_OFF, errp);
234
+++ b/block/stream.c
168
+ PREALLOC_MODE_OFF, 0, errp);
235
@@ -XXX,XX +XXX,XX @@ void stream_start(const char *job_id, BlockDriverState *bs,
169
if (ret < 0) {
236
QDict *opts;
170
error_prepend(errp, "Failed to statically allocate file");
237
int ret;
171
goto exit;
238
172
diff --git a/block/vhdx.c b/block/vhdx.c
239
+ GLOBAL_STATE_CODE();
173
index XXXXXXX..XXXXXXX 100644
240
+
174
--- a/block/vhdx.c
241
assert(!(base && bottom));
175
+++ b/block/vhdx.c
242
assert(!(backing_file_str && bottom));
176
@@ -XXX,XX +XXX,XX @@ static int vhdx_create_bat(BlockBackend *blk, BDRVVHDXState *s,
243
177
/* All zeroes, so we can just extend the file - the end of the BAT
178
* is the furthest thing we have written yet */
179
ret = blk_truncate(blk, data_file_offset, false, PREALLOC_MODE_OFF,
180
- errp);
181
+ 0, errp);
182
if (ret < 0) {
183
goto exit;
184
}
185
} else if (type == VHDX_TYPE_FIXED) {
186
ret = blk_truncate(blk, data_file_offset + image_size, false,
187
- PREALLOC_MODE_OFF, errp);
188
+ PREALLOC_MODE_OFF, 0, errp);
189
if (ret < 0) {
190
goto exit;
191
}
192
diff --git a/block/vmdk.c b/block/vmdk.c
193
index XXXXXXX..XXXXXXX 100644
194
--- a/block/vmdk.c
195
+++ b/block/vmdk.c
196
@@ -XXX,XX +XXX,XX @@ static int vmdk_init_extent(BlockBackend *blk,
197
int gd_buf_size;
198
199
if (flat) {
200
- ret = blk_truncate(blk, filesize, false, PREALLOC_MODE_OFF, errp);
201
+ ret = blk_truncate(blk, filesize, false, PREALLOC_MODE_OFF, 0, errp);
202
goto exit;
203
}
204
magic = cpu_to_be32(VMDK4_MAGIC);
205
@@ -XXX,XX +XXX,XX @@ static int vmdk_init_extent(BlockBackend *blk,
206
}
207
208
ret = blk_truncate(blk, le64_to_cpu(header.grain_offset) << 9, false,
209
- PREALLOC_MODE_OFF, errp);
210
+ PREALLOC_MODE_OFF, 0, errp);
211
if (ret < 0) {
212
goto exit;
213
}
214
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn vmdk_co_do_create(int64_t size,
215
/* bdrv_pwrite write padding zeros to align to sector, we don't need that
216
* for description file */
217
if (desc_offset == 0) {
218
- ret = blk_truncate(blk, desc_len, false, PREALLOC_MODE_OFF, errp);
219
+ ret = blk_truncate(blk, desc_len, false, PREALLOC_MODE_OFF, 0, errp);
220
if (ret < 0) {
221
goto exit;
222
}
223
diff --git a/block/vpc.c b/block/vpc.c
224
index XXXXXXX..XXXXXXX 100644
225
--- a/block/vpc.c
226
+++ b/block/vpc.c
227
@@ -XXX,XX +XXX,XX @@ static int create_fixed_disk(BlockBackend *blk, uint8_t *buf,
228
/* Add footer to total size */
229
total_size += HEADER_SIZE;
230
231
- ret = blk_truncate(blk, total_size, false, PREALLOC_MODE_OFF, errp);
232
+ ret = blk_truncate(blk, total_size, false, PREALLOC_MODE_OFF, 0, errp);
233
if (ret < 0) {
234
return ret;
235
}
236
diff --git a/blockdev.c b/blockdev.c
244
diff --git a/blockdev.c b/blockdev.c
237
index XXXXXXX..XXXXXXX 100644
245
index XXXXXXX..XXXXXXX 100644
238
--- a/blockdev.c
246
--- a/blockdev.c
239
+++ b/blockdev.c
247
+++ b/blockdev.c
240
@@ -XXX,XX +XXX,XX @@ void qmp_block_resize(bool has_device, const char *device,
248
@@ -XXX,XX +XXX,XX @@ QTAILQ_HEAD(, BlockDriverState) monitor_bdrv_states =
241
}
249
242
250
void bdrv_set_monitor_owned(BlockDriverState *bs)
243
bdrv_drained_begin(bs);
251
{
244
- ret = blk_truncate(blk, size, false, PREALLOC_MODE_OFF, errp);
252
+ GLOBAL_STATE_CODE();
245
+ ret = blk_truncate(blk, size, false, PREALLOC_MODE_OFF, 0, errp);
253
QTAILQ_INSERT_TAIL(&monitor_bdrv_states, bs, monitor_list);
246
bdrv_drained_end(bs);
254
}
247
255
248
out:
256
@@ -XXX,XX +XXX,XX @@ BlockDriverState *bds_tree_init(QDict *bs_opts, Error **errp)
249
diff --git a/qemu-img.c b/qemu-img.c
257
{
250
index XXXXXXX..XXXXXXX 100644
258
int bdrv_flags = 0;
251
--- a/qemu-img.c
259
252
+++ b/qemu-img.c
260
+ GLOBAL_STATE_CODE();
253
@@ -XXX,XX +XXX,XX @@ static int img_resize(int argc, char **argv)
261
/* bdrv_open() defaults to the values in bdrv_flags (for compatibility
254
* resizing, so pass @exact=true. It is of no use to report
262
* with other callers) rather than what we want as the real defaults.
255
* success when the image has not actually been resized.
263
* Apply the defaults here instead. */
256
*/
264
@@ -XXX,XX +XXX,XX @@ void blockdev_close_all_bdrv_states(void)
257
- ret = blk_truncate(blk, total_size, true, prealloc, &err);
265
{
258
+ ret = blk_truncate(blk, total_size, true, prealloc, 0, &err);
266
BlockDriverState *bs, *next_bs;
259
if (!ret) {
267
260
qprintf(quiet, "Image resized.\n");
268
+ GLOBAL_STATE_CODE();
261
} else {
269
QTAILQ_FOREACH_SAFE(bs, &monitor_bdrv_states, monitor_list, next_bs) {
262
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
270
AioContext *ctx = bdrv_get_aio_context(bs);
263
index XXXXXXX..XXXXXXX 100644
271
264
--- a/qemu-io-cmds.c
272
@@ -XXX,XX +XXX,XX @@ void qmp_transaction(TransactionActionList *dev_list,
265
+++ b/qemu-io-cmds.c
273
BlkActionState *state, *next;
266
@@ -XXX,XX +XXX,XX @@ static int truncate_f(BlockBackend *blk, int argc, char **argv)
274
Error *local_err = NULL;
267
* exact=true. It is better to err on the "emit more errors" side
275
268
* than to be overly permissive.
276
+ GLOBAL_STATE_CODE();
269
*/
277
+
270
- ret = blk_truncate(blk, offset, true, PREALLOC_MODE_OFF, &local_err);
278
QTAILQ_HEAD(, BlkActionState) snap_bdrv_states;
271
+ ret = blk_truncate(blk, offset, true, PREALLOC_MODE_OFF, 0, &local_err);
279
QTAILQ_INIT(&snap_bdrv_states);
272
if (ret < 0) {
280
273
error_report_err(local_err);
281
@@ -XXX,XX +XXX,XX @@ void qmp_blockdev_del(const char *node_name, Error **errp)
274
return ret;
282
AioContext *aio_context;
283
BlockDriverState *bs;
284
285
+ GLOBAL_STATE_CODE();
286
+
287
bs = bdrv_find_node(node_name);
288
if (!bs) {
289
error_setg(errp, "Failed to find node with node-name='%s'", node_name);
275
--
290
--
276
2.25.3
291
2.35.1
277
278
diff view generated by jsdifflib
New patch
1
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
1
2
3
Mark all I/O functions with IO_CODE, and all "I/O OR GS" with
4
IO_OR_GS_CODE.
5
6
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
7
Message-Id: <20220303151616.325444-14-eesposit@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
---
10
include/block/block_int-io.h | 6 ++++++
11
block.c | 14 +++++++++++++-
12
block/block-backend.c | 2 ++
13
block/dirty-bitmap.c | 3 +++
14
block/io.c | 13 +++++++++++++
15
5 files changed, 37 insertions(+), 1 deletion(-)
16
17
diff --git a/include/block/block_int-io.h b/include/block/block_int-io.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/include/block/block_int-io.h
20
+++ b/include/block/block_int-io.h
21
@@ -XXX,XX +XXX,XX @@ static inline int coroutine_fn bdrv_co_pread(BdrvChild *child,
22
int64_t offset, unsigned int bytes, void *buf, BdrvRequestFlags flags)
23
{
24
QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, bytes);
25
+ IO_CODE();
26
27
return bdrv_co_preadv(child, offset, bytes, &qiov, flags);
28
}
29
@@ -XXX,XX +XXX,XX @@ static inline int coroutine_fn bdrv_co_pwrite(BdrvChild *child,
30
int64_t offset, unsigned int bytes, void *buf, BdrvRequestFlags flags)
31
{
32
QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, bytes);
33
+ IO_CODE();
34
35
return bdrv_co_pwritev(child, offset, bytes, &qiov, flags);
36
}
37
@@ -XXX,XX +XXX,XX @@ BlockDriverState *bdrv_backing_chain_next(BlockDriverState *bs);
38
39
static inline BlockDriverState *bdrv_cow_bs(BlockDriverState *bs)
40
{
41
+ IO_CODE();
42
return child_bs(bdrv_cow_child(bs));
43
}
44
45
static inline BlockDriverState *bdrv_filter_bs(BlockDriverState *bs)
46
{
47
+ IO_CODE();
48
return child_bs(bdrv_filter_child(bs));
49
}
50
51
static inline BlockDriverState *bdrv_filter_or_cow_bs(BlockDriverState *bs)
52
{
53
+ IO_CODE();
54
return child_bs(bdrv_filter_or_cow_child(bs));
55
}
56
57
static inline BlockDriverState *bdrv_primary_bs(BlockDriverState *bs)
58
{
59
+ IO_CODE();
60
return child_bs(bdrv_primary_child(bs));
61
}
62
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 @@ BlockDriver *bdrv_probe_all(const uint8_t *buf, int buf_size,
68
{
69
int score_max = 0, score;
70
BlockDriver *drv = NULL, *d;
71
+ IO_CODE();
72
73
QLIST_FOREACH(d, &bdrv_drivers, list) {
74
if (d->bdrv_probe) {
75
@@ -XXX,XX +XXX,XX @@ static int find_image_format(BlockBackend *file, const char *filename,
76
int refresh_total_sectors(BlockDriverState *bs, int64_t hint)
77
{
78
BlockDriver *drv = bs->drv;
79
+ IO_CODE();
80
81
if (!drv) {
82
return -ENOMEDIUM;
83
@@ -XXX,XX +XXX,XX @@ const char *bdrv_get_parent_name(const BlockDriverState *bs)
84
{
85
BdrvChild *c;
86
const char *name;
87
+ IO_CODE();
88
89
/* If multiple parents have a name, just pick the first one. */
90
QLIST_FOREACH(c, &bs->parents, next_parent) {
91
@@ -XXX,XX +XXX,XX @@ int bdrv_make_empty(BdrvChild *c, Error **errp)
92
*/
93
BdrvChild *bdrv_cow_child(BlockDriverState *bs)
94
{
95
+ IO_CODE();
96
+
97
if (!bs || !bs->drv) {
98
return NULL;
99
}
100
@@ -XXX,XX +XXX,XX @@ BdrvChild *bdrv_cow_child(BlockDriverState *bs)
101
BdrvChild *bdrv_filter_child(BlockDriverState *bs)
102
{
103
BdrvChild *c;
104
+ IO_CODE();
105
106
if (!bs || !bs->drv) {
107
return NULL;
108
@@ -XXX,XX +XXX,XX @@ BdrvChild *bdrv_filter_or_cow_child(BlockDriverState *bs)
109
{
110
BdrvChild *cow_child = bdrv_cow_child(bs);
111
BdrvChild *filter_child = bdrv_filter_child(bs);
112
+ IO_CODE();
113
114
/* Filter nodes cannot have COW backing files */
115
assert(!(cow_child && filter_child));
116
@@ -XXX,XX +XXX,XX @@ BdrvChild *bdrv_filter_or_cow_child(BlockDriverState *bs)
117
BdrvChild *bdrv_primary_child(BlockDriverState *bs)
118
{
119
BdrvChild *c, *found = NULL;
120
+ IO_CODE();
121
122
QLIST_FOREACH(c, &bs->children, next) {
123
if (c->role & BDRV_CHILD_PRIMARY) {
124
@@ -XXX,XX +XXX,XX @@ BlockDriverState *bdrv_skip_implicit_filters(BlockDriverState *bs)
125
*/
126
BlockDriverState *bdrv_skip_filters(BlockDriverState *bs)
127
{
128
+ IO_CODE();
129
return bdrv_do_skip_filters(bs, false);
130
}
131
132
@@ -XXX,XX +XXX,XX @@ BlockDriverState *bdrv_skip_filters(BlockDriverState *bs)
133
*/
134
BlockDriverState *bdrv_backing_chain_next(BlockDriverState *bs)
135
{
136
+ IO_CODE();
137
return bdrv_skip_filters(bdrv_cow_bs(bdrv_skip_filters(bs)));
138
}
139
140
@@ -XXX,XX +XXX,XX @@ static bool bdrv_bsc_range_overlaps_locked(BlockDriverState *bs,
141
*/
142
bool bdrv_bsc_is_data(BlockDriverState *bs, int64_t offset, int64_t *pnum)
143
{
144
+ IO_CODE();
145
RCU_READ_LOCK_GUARD();
146
-
147
return bdrv_bsc_range_overlaps_locked(bs, offset, 1, pnum);
148
}
149
150
@@ -XXX,XX +XXX,XX @@ bool bdrv_bsc_is_data(BlockDriverState *bs, int64_t offset, int64_t *pnum)
151
void bdrv_bsc_invalidate_range(BlockDriverState *bs,
152
int64_t offset, int64_t bytes)
153
{
154
+ IO_CODE();
155
RCU_READ_LOCK_GUARD();
156
157
if (bdrv_bsc_range_overlaps_locked(bs, offset, bytes, NULL)) {
158
@@ -XXX,XX +XXX,XX @@ void bdrv_bsc_fill(BlockDriverState *bs, int64_t offset, int64_t bytes)
159
{
160
BdrvBlockStatusCache *new_bsc = g_new(BdrvBlockStatusCache, 1);
161
BdrvBlockStatusCache *old_bsc;
162
+ IO_CODE();
163
164
*new_bsc = (BdrvBlockStatusCache) {
165
.valid = true,
166
diff --git a/block/block-backend.c b/block/block-backend.c
167
index XXXXXXX..XXXXXXX 100644
168
--- a/block/block-backend.c
169
+++ b/block/block-backend.c
170
@@ -XXX,XX +XXX,XX @@ bool blk_dev_has_removable_media(BlockBackend *blk)
171
*/
172
bool blk_dev_has_tray(BlockBackend *blk)
173
{
174
+ IO_CODE();
175
return blk->dev_ops && blk->dev_ops->is_tray_open;
176
}
177
178
@@ -XXX,XX +XXX,XX @@ void blk_dev_eject_request(BlockBackend *blk, bool force)
179
*/
180
bool blk_dev_is_tray_open(BlockBackend *blk)
181
{
182
+ IO_CODE();
183
if (blk_dev_has_tray(blk)) {
184
return blk->dev_ops->is_tray_open(blk->dev_opaque);
185
}
186
diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c
187
index XXXXXXX..XXXXXXX 100644
188
--- a/block/dirty-bitmap.c
189
+++ b/block/dirty-bitmap.c
190
@@ -XXX,XX +XXX,XX @@ void bdrv_reset_dirty_bitmap(BdrvDirtyBitmap *bitmap,
191
192
void bdrv_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap **out)
193
{
194
+ IO_CODE();
195
assert(!bdrv_dirty_bitmap_readonly(bitmap));
196
bdrv_dirty_bitmaps_lock(bitmap->bs);
197
if (!out) {
198
@@ -XXX,XX +XXX,XX @@ void bdrv_dirty_bitmap_deserialize_finish(BdrvDirtyBitmap *bitmap)
199
void bdrv_set_dirty(BlockDriverState *bs, int64_t offset, int64_t bytes)
200
{
201
BdrvDirtyBitmap *bitmap;
202
+ IO_CODE();
203
204
if (QLIST_EMPTY(&bs->dirty_bitmaps)) {
205
return;
206
@@ -XXX,XX +XXX,XX @@ bool bdrv_dirty_bitmap_merge_internal(BdrvDirtyBitmap *dest,
207
bool lock)
208
{
209
bool ret;
210
+ IO_CODE();
211
212
assert(!bdrv_dirty_bitmap_readonly(dest));
213
assert(!bdrv_dirty_bitmap_inconsistent(dest));
214
diff --git a/block/io.c b/block/io.c
215
index XXXXXXX..XXXXXXX 100644
216
--- a/block/io.c
217
+++ b/block/io.c
218
@@ -XXX,XX +XXX,XX @@ void bdrv_subtree_drained_end(BlockDriverState *bs)
219
void bdrv_apply_subtree_drain(BdrvChild *child, BlockDriverState *new_parent)
220
{
221
int i;
222
+ IO_OR_GS_CODE();
223
224
for (i = 0; i < new_parent->recursive_quiesce_counter; i++) {
225
bdrv_do_drained_begin(child->bs, true, child, false, true);
226
@@ -XXX,XX +XXX,XX @@ void bdrv_unapply_subtree_drain(BdrvChild *child, BlockDriverState *old_parent)
227
{
228
int drained_end_counter = 0;
229
int i;
230
+ IO_OR_GS_CODE();
231
232
for (i = 0; i < old_parent->recursive_quiesce_counter; i++) {
233
bdrv_do_drained_end(child->bs, true, child, false,
234
@@ -XXX,XX +XXX,XX @@ BdrvTrackedRequest *coroutine_fn bdrv_co_get_self_request(BlockDriverState *bs)
235
{
236
BdrvTrackedRequest *req;
237
Coroutine *self = qemu_coroutine_self();
238
+ IO_CODE();
239
240
QLIST_FOREACH(req, &bs->tracked_requests, list) {
241
if (req->co == self) {
242
@@ -XXX,XX +XXX,XX @@ static int bdrv_get_cluster_size(BlockDriverState *bs)
243
244
void bdrv_inc_in_flight(BlockDriverState *bs)
245
{
246
+ IO_CODE();
247
qatomic_inc(&bs->in_flight);
248
}
249
250
void bdrv_wakeup(BlockDriverState *bs)
251
{
252
+ IO_CODE();
253
aio_wait_kick();
254
}
255
256
void bdrv_dec_in_flight(BlockDriverState *bs)
257
{
258
+ IO_CODE();
259
qatomic_dec(&bs->in_flight);
260
bdrv_wakeup(bs);
261
}
262
@@ -XXX,XX +XXX,XX @@ bool coroutine_fn bdrv_make_request_serialising(BdrvTrackedRequest *req,
263
uint64_t align)
264
{
265
bool waited;
266
+ IO_CODE();
267
268
qemu_co_mutex_lock(&req->bs->reqs_lock);
269
270
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_preadv(BdrvChild *child,
271
int64_t offset, int64_t bytes, QEMUIOVector *qiov,
272
BdrvRequestFlags flags)
273
{
274
+ IO_CODE();
275
return bdrv_co_preadv_part(child, offset, bytes, qiov, 0, flags);
276
}
277
278
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_preadv_part(BdrvChild *child,
279
BdrvTrackedRequest req;
280
BdrvRequestPadding pad;
281
int ret;
282
+ IO_CODE();
283
284
trace_bdrv_co_preadv_part(bs, offset, bytes, flags);
285
286
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_pwritev(BdrvChild *child,
287
int64_t offset, int64_t bytes, QEMUIOVector *qiov,
288
BdrvRequestFlags flags)
289
{
290
+ IO_CODE();
291
return bdrv_co_pwritev_part(child, offset, bytes, qiov, 0, flags);
292
}
293
294
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_pwritev_part(BdrvChild *child,
295
BdrvRequestPadding pad;
296
int ret;
297
bool padded = false;
298
+ IO_CODE();
299
300
trace_bdrv_co_pwritev_part(child->bs, offset, bytes, flags);
301
302
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_copy_range_from(BdrvChild *src, int64_t src_offset,
303
BdrvRequestFlags read_flags,
304
BdrvRequestFlags write_flags)
305
{
306
+ IO_CODE();
307
trace_bdrv_co_copy_range_from(src, src_offset, dst, dst_offset, bytes,
308
read_flags, write_flags);
309
return bdrv_co_copy_range_internal(src, src_offset, dst, dst_offset,
310
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_copy_range_to(BdrvChild *src, int64_t src_offset,
311
BdrvRequestFlags read_flags,
312
BdrvRequestFlags write_flags)
313
{
314
+ IO_CODE();
315
trace_bdrv_co_copy_range_to(src, src_offset, dst, dst_offset, bytes,
316
read_flags, write_flags);
317
return bdrv_co_copy_range_internal(src, src_offset, dst, dst_offset,
318
--
319
2.35.1
diff view generated by jsdifflib
1
The QMP handler qmp_object_add() and the implementation of --object in
1
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
2
qemu-storage-daemon can share most of the code. Currently,
3
qemu-storage-daemon calls qmp_object_add(), but this is not correct
4
because different visitors need to be used.
5
2
6
As a first step towards a fix, make qmp_object_add() a wrapper around a
3
We want to be sure that the functions that write the child and
7
new function user_creatable_add_dict() that can get an additional
4
parent list of a bs are under BQL and drain.
8
parameter. The handling of "props" is only required for compatibility
9
and not required for the qemu-storage-daemon command line, so it stays
10
in qmp_object_add().
11
5
6
BQL prevents from concurrent writings from the GS API, while
7
drains protect from I/O.
8
9
TODO: drains are missing in some functions using this assert.
10
Therefore a proper assertion will fail. Because adding drains
11
requires additional discussions, they will be added in future
12
series.
13
14
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
15
Message-Id: <20220303151616.325444-15-eesposit@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
16
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
---
17
---
14
include/qom/object_interfaces.h | 12 ++++++++++++
18
include/block/block_int-global-state.h | 17 +++++++++++++++++
15
qom/object_interfaces.c | 27 +++++++++++++++++++++++++++
19
block.c | 4 ++++
16
qom/qom-qmp-cmds.c | 24 +-----------------------
20
2 files changed, 21 insertions(+)
17
3 files changed, 40 insertions(+), 23 deletions(-)
18
21
19
diff --git a/include/qom/object_interfaces.h b/include/qom/object_interfaces.h
22
diff --git a/include/block/block_int-global-state.h b/include/block/block_int-global-state.h
20
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
21
--- a/include/qom/object_interfaces.h
24
--- a/include/block/block_int-global-state.h
22
+++ b/include/qom/object_interfaces.h
25
+++ b/include/block/block_int-global-state.h
23
@@ -XXX,XX +XXX,XX @@ Object *user_creatable_add_type(const char *type, const char *id,
26
@@ -XXX,XX +XXX,XX @@ void bdrv_remove_aio_context_notifier(BlockDriverState *bs,
24
const QDict *qdict,
27
*/
25
Visitor *v, Error **errp);
28
void bdrv_drain_all_end_quiesce(BlockDriverState *bs);
26
29
27
+/**
30
+/**
28
+ * user_creatable_add_dict:
31
+ * Make sure that the function is running under both drain and BQL.
29
+ * @qdict: the object definition
32
+ * The latter protects from concurrent writings
30
+ * @errp: if an error occurs, a pointer to an area to store the error
33
+ * from the GS API, while the former prevents concurrent reads
31
+ *
34
+ * from I/O.
32
+ * Create an instance of the user creatable object that is defined by
33
+ * @qdict. The object type is taken from the QDict key 'qom-type', its
34
+ * ID from the key 'id'. The remaining entries in @qdict are used to
35
+ * initialize the object properties.
36
+ */
35
+ */
37
+void user_creatable_add_dict(QDict *qdict, Error **errp);
36
+static inline void assert_bdrv_graph_writable(BlockDriverState *bs)
37
+{
38
+ /*
39
+ * TODO: this function is incomplete. Because the users of this
40
+ * assert lack the necessary drains, check only for BQL.
41
+ * Once the necessary drains are added,
42
+ * assert also for qatomic_read(&bs->quiesce_counter) > 0
43
+ */
44
+ assert(qemu_in_main_thread());
45
+}
38
+
46
+
39
/**
47
#endif /* BLOCK_INT_GLOBAL_STATE */
40
* user_creatable_add_opts:
48
diff --git a/block.c b/block.c
41
* @opts: the object definition
42
diff --git a/qom/object_interfaces.c b/qom/object_interfaces.c
43
index XXXXXXX..XXXXXXX 100644
49
index XXXXXXX..XXXXXXX 100644
44
--- a/qom/object_interfaces.c
50
--- a/block.c
45
+++ b/qom/object_interfaces.c
51
+++ b/block.c
46
@@ -XXX,XX +XXX,XX @@
52
@@ -XXX,XX +XXX,XX @@ static void bdrv_child_cb_attach(BdrvChild *child)
47
#include "qapi/qmp/qerror.h"
53
{
48
#include "qapi/qmp/qjson.h"
54
BlockDriverState *bs = child->opaque;
49
#include "qapi/qmp/qstring.h"
55
50
+#include "qapi/qobject-input-visitor.h"
56
+ assert_bdrv_graph_writable(bs);
51
#include "qom/object_interfaces.h"
57
QLIST_INSERT_HEAD(&bs->children, child, next);
52
#include "qemu/help_option.h"
58
53
#include "qemu/module.h"
59
if (child->role & BDRV_CHILD_COW) {
54
@@ -XXX,XX +XXX,XX @@ out:
60
@@ -XXX,XX +XXX,XX @@ static void bdrv_child_cb_detach(BdrvChild *child)
55
return obj;
61
62
bdrv_unapply_subtree_drain(child, bs);
63
64
+ assert_bdrv_graph_writable(bs);
65
QLIST_REMOVE(child, next);
56
}
66
}
57
67
58
+void user_creatable_add_dict(QDict *qdict, Error **errp)
68
@@ -XXX,XX +XXX,XX @@ static void bdrv_replace_child_noperm(BdrvChild **childp,
59
+{
69
if (child->klass->detach) {
60
+ Visitor *v;
70
child->klass->detach(child);
61
+ Object *obj;
71
}
62
+ g_autofree char *type = NULL;
72
+ assert_bdrv_graph_writable(old_bs);
63
+ g_autofree char *id = NULL;
73
QLIST_REMOVE(child, next_parent);
64
+
65
+ type = g_strdup(qdict_get_try_str(qdict, "qom-type"));
66
+ if (!type) {
67
+ error_setg(errp, QERR_MISSING_PARAMETER, "qom-type");
68
+ return;
69
+ }
70
+ qdict_del(qdict, "qom-type");
71
+
72
+ id = g_strdup(qdict_get_try_str(qdict, "id"));
73
+ if (!id) {
74
+ error_setg(errp, QERR_MISSING_PARAMETER, "id");
75
+ return;
76
+ }
77
+ qdict_del(qdict, "id");
78
+
79
+ v = qobject_input_visitor_new(QOBJECT(qdict));
80
+ obj = user_creatable_add_type(type, id, qdict, v, errp);
81
+ visit_free(v);
82
+ object_unref(obj);
83
+}
84
85
Object *user_creatable_add_opts(QemuOpts *opts, Error **errp)
86
{
87
diff --git a/qom/qom-qmp-cmds.c b/qom/qom-qmp-cmds.c
88
index XXXXXXX..XXXXXXX 100644
89
--- a/qom/qom-qmp-cmds.c
90
+++ b/qom/qom-qmp-cmds.c
91
@@ -XXX,XX +XXX,XX @@
92
#include "qapi/qapi-commands-qom.h"
93
#include "qapi/qmp/qdict.h"
94
#include "qapi/qmp/qerror.h"
95
-#include "qapi/qobject-input-visitor.h"
96
#include "qemu/cutils.h"
97
#include "qom/object_interfaces.h"
98
#include "qom/qom-qobject.h"
99
@@ -XXX,XX +XXX,XX @@ void qmp_object_add(QDict *qdict, QObject **ret_data, Error **errp)
100
{
101
QObject *props;
102
QDict *pdict;
103
- Visitor *v;
104
- Object *obj;
105
- g_autofree char *type = NULL;
106
- g_autofree char *id = NULL;
107
-
108
- type = g_strdup(qdict_get_try_str(qdict, "qom-type"));
109
- if (!type) {
110
- error_setg(errp, QERR_MISSING_PARAMETER, "qom-type");
111
- return;
112
- }
113
- qdict_del(qdict, "qom-type");
114
-
115
- id = g_strdup(qdict_get_try_str(qdict, "id"));
116
- if (!id) {
117
- error_setg(errp, QERR_MISSING_PARAMETER, "id");
118
- return;
119
- }
120
- qdict_del(qdict, "id");
121
122
props = qdict_get(qdict, "props");
123
if (props) {
124
@@ -XXX,XX +XXX,XX @@ void qmp_object_add(QDict *qdict, QObject **ret_data, Error **errp)
125
qobject_unref(pdict);
126
}
74
}
127
75
128
- v = qobject_input_visitor_new(QOBJECT(qdict));
76
@@ -XXX,XX +XXX,XX @@ static void bdrv_replace_child_noperm(BdrvChild **childp,
129
- obj = user_creatable_add_type(type, id, qdict, v, errp);
77
}
130
- visit_free(v);
78
131
- object_unref(obj);
79
if (new_bs) {
132
+ user_creatable_add_dict(qdict, errp);
80
+ assert_bdrv_graph_writable(new_bs);
133
}
81
QLIST_INSERT_HEAD(&new_bs->parents, child, next_parent);
134
82
135
void qmp_object_del(const char *id, Error **errp)
83
/*
136
--
84
--
137
2.25.3
85
2.35.1
138
139
diff view generated by jsdifflib
New patch
1
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
1
2
3
Since the I/O functions are not many, keep a single file.
4
Also split the function pointers in BlockJobDriver.
5
6
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
7
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
8
Message-Id: <20220303151616.325444-16-eesposit@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
11
include/block/blockjob_int.h | 28 ++++++++++++++++++++++++++++
12
1 file changed, 28 insertions(+)
13
14
diff --git a/include/block/blockjob_int.h b/include/block/blockjob_int.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/include/block/blockjob_int.h
17
+++ b/include/block/blockjob_int.h
18
@@ -XXX,XX +XXX,XX @@ struct BlockJobDriver {
19
/** Generic JobDriver callbacks and settings */
20
JobDriver job_driver;
21
22
+ /*
23
+ * I/O API functions. These functions are thread-safe.
24
+ *
25
+ * See include/block/block-io.h for more information about
26
+ * the I/O API.
27
+ */
28
+
29
/*
30
* Returns whether the job has pending requests for the child or will
31
* submit new requests before the next pause point. This callback is polled
32
@@ -XXX,XX +XXX,XX @@ struct BlockJobDriver {
33
*/
34
bool (*drained_poll)(BlockJob *job);
35
36
+ /*
37
+ * Global state (GS) API. These functions run under the BQL.
38
+ *
39
+ * See include/block/block-global-state.h for more information about
40
+ * the GS API.
41
+ */
42
+
43
/*
44
* If the callback is not NULL, it will be invoked before the job is
45
* resumed in a new AioContext. This is the place to move any resources
46
@@ -XXX,XX +XXX,XX @@ struct BlockJobDriver {
47
void (*set_speed)(BlockJob *job, int64_t speed);
48
};
49
50
+/*
51
+ * Global state (GS) API. These functions run under the BQL.
52
+ *
53
+ * See include/block/block-global-state.h for more information about
54
+ * the GS API.
55
+ */
56
+
57
/**
58
* block_job_create:
59
* @job_id: The id of the newly-created job, or %NULL to have one
60
@@ -XXX,XX +XXX,XX @@ void block_job_free(Job *job);
61
*/
62
void block_job_user_resume(Job *job);
63
64
+/*
65
+ * I/O API functions. These functions are thread-safe.
66
+ *
67
+ * See include/block/block-io.h for more information about
68
+ * the I/O API.
69
+ */
70
+
71
/**
72
* block_job_ratelimit_get_delay:
73
*
74
--
75
2.35.1
diff view generated by jsdifflib
1
After processing the option string with the keyval parser, we get a
1
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
2
QDict that contains only strings. This QDict must be fed to a keyval
3
visitor which converts the strings into the right data types.
4
2
5
qmp_object_add(), however, uses the normal QObject input visitor, which
3
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
6
expects a QDict where all properties already have the QType that matches
4
Message-Id: <20220303151616.325444-17-eesposit@redhat.com>
7
the data type required by the QOM object type.
8
9
Change the --object implementation in qemu-storage-daemon so that it
10
doesn't call qmp_object_add(), but calls user_creatable_add_dict()
11
directly instead and pass it a new keyval boolean that decides which
12
visitor must be used.
13
14
Reported-by: Coiby Xu <coiby.xu@gmail.com>
15
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
16
---
6
---
17
include/qom/object_interfaces.h | 6 +++++-
7
blockjob.c | 5 +++++
18
qemu-storage-daemon.c | 4 +---
8
1 file changed, 5 insertions(+)
19
qom/object_interfaces.c | 8 ++++++--
20
qom/qom-qmp-cmds.c | 2 +-
21
4 files changed, 13 insertions(+), 7 deletions(-)
22
9
23
diff --git a/include/qom/object_interfaces.h b/include/qom/object_interfaces.h
10
diff --git a/blockjob.c b/blockjob.c
24
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
25
--- a/include/qom/object_interfaces.h
12
--- a/blockjob.c
26
+++ b/include/qom/object_interfaces.h
13
+++ b/blockjob.c
27
@@ -XXX,XX +XXX,XX @@ Object *user_creatable_add_type(const char *type, const char *id,
14
@@ -XXX,XX +XXX,XX @@ BlockJob *block_job_get(const char *id)
28
/**
15
void block_job_free(Job *job)
29
* user_creatable_add_dict:
16
{
30
* @qdict: the object definition
17
BlockJob *bjob = container_of(job, BlockJob, job);
31
+ * @keyval: if true, use a keyval visitor for processing @qdict (i.e.
18
+ GLOBAL_STATE_CODE();
32
+ * assume that all @qdict values are strings); otherwise, use
19
33
+ * the normal QObject visitor (i.e. assume all @qdict values
20
block_job_remove_all_bdrv(bjob);
34
+ * have the QType expected by the QOM object type)
21
ratelimit_destroy(&bjob->limit);
35
* @errp: if an error occurs, a pointer to an area to store the error
22
@@ -XXX,XX +XXX,XX @@ bool block_job_set_speed(BlockJob *job, int64_t speed, Error **errp)
36
*
23
37
* Create an instance of the user creatable object that is defined by
24
int64_t block_job_ratelimit_get_delay(BlockJob *job, uint64_t n)
38
@@ -XXX,XX +XXX,XX @@ Object *user_creatable_add_type(const char *type, const char *id,
25
{
39
* ID from the key 'id'. The remaining entries in @qdict are used to
26
+ IO_CODE();
40
* initialize the object properties.
27
return ratelimit_calculate_delay(&job->limit, n);
41
*/
42
-void user_creatable_add_dict(QDict *qdict, Error **errp);
43
+void user_creatable_add_dict(QDict *qdict, bool keyval, Error **errp);
44
45
/**
46
* user_creatable_add_opts:
47
diff --git a/qemu-storage-daemon.c b/qemu-storage-daemon.c
48
index XXXXXXX..XXXXXXX 100644
49
--- a/qemu-storage-daemon.c
50
+++ b/qemu-storage-daemon.c
51
@@ -XXX,XX +XXX,XX @@ static void process_options(int argc, char *argv[])
52
QemuOpts *opts;
53
const char *type;
54
QDict *args;
55
- QObject *ret_data = NULL;
56
57
/* FIXME The keyval parser rejects 'help' arguments, so we must
58
* unconditionall try QemuOpts first. */
59
@@ -XXX,XX +XXX,XX @@ static void process_options(int argc, char *argv[])
60
qemu_opts_del(opts);
61
62
args = keyval_parse(optarg, "qom-type", &error_fatal);
63
- qmp_object_add(args, &ret_data, &error_fatal);
64
+ user_creatable_add_dict(args, true, &error_fatal);
65
qobject_unref(args);
66
- qobject_unref(ret_data);
67
break;
68
}
69
default:
70
diff --git a/qom/object_interfaces.c b/qom/object_interfaces.c
71
index XXXXXXX..XXXXXXX 100644
72
--- a/qom/object_interfaces.c
73
+++ b/qom/object_interfaces.c
74
@@ -XXX,XX +XXX,XX @@ out:
75
return obj;
76
}
28
}
77
29
78
-void user_creatable_add_dict(QDict *qdict, Error **errp)
30
@@ -XXX,XX +XXX,XX @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver,
79
+void user_creatable_add_dict(QDict *qdict, bool keyval, Error **errp)
80
{
31
{
81
Visitor *v;
32
BlockJob *job;
82
Object *obj;
33
int ret;
83
@@ -XXX,XX +XXX,XX @@ void user_creatable_add_dict(QDict *qdict, Error **errp)
34
+ GLOBAL_STATE_CODE();
84
}
35
85
qdict_del(qdict, "id");
36
if (job_id == NULL && !(flags & JOB_INTERNAL)) {
86
37
job_id = bdrv_get_device_name(bs);
87
- v = qobject_input_visitor_new(QOBJECT(qdict));
38
@@ -XXX,XX +XXX,XX @@ void block_job_iostatus_reset(BlockJob *job)
88
+ if (keyval) {
39
void block_job_user_resume(Job *job)
89
+ v = qobject_input_visitor_new_keyval(QOBJECT(qdict));
40
{
90
+ } else {
41
BlockJob *bjob = container_of(job, BlockJob, job);
91
+ v = qobject_input_visitor_new(QOBJECT(qdict));
42
+ GLOBAL_STATE_CODE();
92
+ }
43
block_job_iostatus_reset(bjob);
93
obj = user_creatable_add_type(type, id, qdict, v, errp);
94
visit_free(v);
95
object_unref(obj);
96
diff --git a/qom/qom-qmp-cmds.c b/qom/qom-qmp-cmds.c
97
index XXXXXXX..XXXXXXX 100644
98
--- a/qom/qom-qmp-cmds.c
99
+++ b/qom/qom-qmp-cmds.c
100
@@ -XXX,XX +XXX,XX @@ void qmp_object_add(QDict *qdict, QObject **ret_data, Error **errp)
101
qobject_unref(pdict);
102
}
103
104
- user_creatable_add_dict(qdict, errp);
105
+ user_creatable_add_dict(qdict, false, errp);
106
}
44
}
107
45
108
void qmp_object_del(const char *id, Error **errp)
46
@@ -XXX,XX +XXX,XX @@ BlockErrorAction block_job_error_action(BlockJob *job, BlockdevOnError on_err,
47
int is_read, int error)
48
{
49
BlockErrorAction action;
50
+ IO_CODE();
51
52
switch (on_err) {
53
case BLOCKDEV_ON_ERROR_ENOSPC:
109
--
54
--
110
2.25.3
55
2.35.1
111
112
diff view generated by jsdifflib
New patch
1
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
1
2
3
Following the assertion derived from the API split,
4
propagate the assertion also in the static functions.
5
6
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
7
Message-Id: <20220303151616.325444-18-eesposit@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
---
10
block.c | 46 ++++++++++++++++++++++++++++++++++++++++++-
11
block/block-backend.c | 3 +++
12
2 files changed, 48 insertions(+), 1 deletion(-)
13
14
diff --git a/block.c b/block.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/block.c
17
+++ b/block.c
18
@@ -XXX,XX +XXX,XX @@ BlockDriverState *bdrv_new(void)
19
static BlockDriver *bdrv_do_find_format(const char *format_name)
20
{
21
BlockDriver *drv1;
22
+ GLOBAL_STATE_CODE();
23
24
QLIST_FOREACH(drv1, &bdrv_drivers, list) {
25
if (!strcmp(drv1->format_name, format_name)) {
26
@@ -XXX,XX +XXX,XX @@ static int64_t create_file_fallback_truncate(BlockBackend *blk,
27
int64_t size;
28
int ret;
29
30
+ GLOBAL_STATE_CODE();
31
+
32
ret = blk_truncate(blk, minimum_size, false, PREALLOC_MODE_OFF, 0,
33
&local_err);
34
if (ret < 0 && ret != -ENOTSUP) {
35
@@ -XXX,XX +XXX,XX @@ static int create_file_fallback_zero_first_sector(BlockBackend *blk,
36
int64_t bytes_to_clear;
37
int ret;
38
39
+ GLOBAL_STATE_CODE();
40
+
41
bytes_to_clear = MIN(current_size, BDRV_SECTOR_SIZE);
42
if (bytes_to_clear) {
43
ret = blk_pwrite_zeroes(blk, 0, bytes_to_clear, BDRV_REQ_MAY_UNMAP);
44
@@ -XXX,XX +XXX,XX @@ static BlockDriver *find_hdev_driver(const char *filename)
45
{
46
int score_max = 0, score;
47
BlockDriver *drv = NULL, *d;
48
+ GLOBAL_STATE_CODE();
49
50
QLIST_FOREACH(d, &bdrv_drivers, list) {
51
if (d->bdrv_probe_device) {
52
@@ -XXX,XX +XXX,XX @@ static BlockDriver *find_hdev_driver(const char *filename)
53
static BlockDriver *bdrv_do_find_protocol(const char *protocol)
54
{
55
BlockDriver *drv1;
56
+ GLOBAL_STATE_CODE();
57
58
QLIST_FOREACH(drv1, &bdrv_drivers, list) {
59
if (drv1->protocol_name && !strcmp(drv1->protocol_name, protocol)) {
60
@@ -XXX,XX +XXX,XX @@ static int find_image_format(BlockBackend *file, const char *filename,
61
uint8_t buf[BLOCK_PROBE_BUF_SIZE];
62
int ret = 0;
63
64
+ GLOBAL_STATE_CODE();
65
+
66
/* Return the raw BlockDriver * to scsi-generic devices or empty drives */
67
if (blk_is_sg(file) || !blk_is_inserted(file) || blk_getlength(file) == 0) {
68
*pdrv = &bdrv_raw;
69
@@ -XXX,XX +XXX,XX @@ static BlockdevDetectZeroesOptions bdrv_parse_detect_zeroes(QemuOpts *opts,
70
BlockdevDetectZeroesOptions detect_zeroes =
71
qapi_enum_parse(&BlockdevDetectZeroesOptions_lookup, value,
72
BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF, &local_err);
73
+ GLOBAL_STATE_CODE();
74
g_free(value);
75
if (local_err) {
76
error_propagate(errp, local_err);
77
@@ -XXX,XX +XXX,XX @@ static void bdrv_child_cb_drained_end(BdrvChild *child,
78
static int bdrv_child_cb_inactivate(BdrvChild *child)
79
{
80
BlockDriverState *bs = child->opaque;
81
+ GLOBAL_STATE_CODE();
82
assert(bs->open_flags & BDRV_O_INACTIVE);
83
return 0;
84
}
85
@@ -XXX,XX +XXX,XX @@ static void bdrv_child_cb_set_aio_ctx(BdrvChild *child, AioContext *ctx,
86
static void bdrv_temp_snapshot_options(int *child_flags, QDict *child_options,
87
int parent_flags, QDict *parent_options)
88
{
89
+ GLOBAL_STATE_CODE();
90
*child_flags = (parent_flags & ~BDRV_O_SNAPSHOT) | BDRV_O_TEMPORARY;
91
92
/* For temporary files, unconditional cache=unsafe is fine */
93
@@ -XXX,XX +XXX,XX @@ static void bdrv_backing_attach(BdrvChild *c)
94
BlockDriverState *parent = c->opaque;
95
BlockDriverState *backing_hd = c->bs;
96
97
+ GLOBAL_STATE_CODE();
98
assert(!parent->backing_blocker);
99
error_setg(&parent->backing_blocker,
100
"node is used as backing hd of '%s'",
101
@@ -XXX,XX +XXX,XX @@ static void bdrv_backing_detach(BdrvChild *c)
102
{
103
BlockDriverState *parent = c->opaque;
104
105
+ GLOBAL_STATE_CODE();
106
assert(parent->backing_blocker);
107
bdrv_op_unblock_all(c->bs, parent->backing_blocker);
108
error_free(parent->backing_blocker);
109
@@ -XXX,XX +XXX,XX @@ static int bdrv_backing_update_filename(BdrvChild *c, BlockDriverState *base,
110
BlockDriverState *parent = c->opaque;
111
bool read_only = bdrv_is_read_only(parent);
112
int ret;
113
+ GLOBAL_STATE_CODE();
114
115
if (read_only) {
116
ret = bdrv_reopen_set_read_only(parent, false, errp);
117
@@ -XXX,XX +XXX,XX @@ static void bdrv_inherited_options(BdrvChildRole role, bool parent_is_format,
118
int parent_flags, QDict *parent_options)
119
{
120
int flags = parent_flags;
121
+ GLOBAL_STATE_CODE();
122
123
/*
124
* First, decide whether to set, clear, or leave BDRV_O_PROTOCOL.
125
@@ -XXX,XX +XXX,XX @@ AioContext *bdrv_child_get_parent_aio_context(BdrvChild *c)
126
static int bdrv_open_flags(BlockDriverState *bs, int flags)
127
{
128
int open_flags = flags;
129
+ GLOBAL_STATE_CODE();
130
131
/*
132
* Clear flags that are internal to the block layer before opening the
133
@@ -XXX,XX +XXX,XX @@ static int bdrv_open_flags(BlockDriverState *bs, int flags)
134
135
static void update_flags_from_options(int *flags, QemuOpts *opts)
136
{
137
+ GLOBAL_STATE_CODE();
138
+
139
*flags &= ~(BDRV_O_CACHE_MASK | BDRV_O_RDWR | BDRV_O_AUTO_RDONLY);
140
141
if (qemu_opt_get_bool_del(opts, BDRV_OPT_CACHE_NO_FLUSH, false)) {
142
@@ -XXX,XX +XXX,XX @@ static void update_flags_from_options(int *flags, QemuOpts *opts)
143
144
static void update_options_from_flags(QDict *options, int flags)
145
{
146
+ GLOBAL_STATE_CODE();
147
if (!qdict_haskey(options, BDRV_OPT_CACHE_DIRECT)) {
148
qdict_put_bool(options, BDRV_OPT_CACHE_DIRECT, flags & BDRV_O_NOCACHE);
149
}
150
@@ -XXX,XX +XXX,XX @@ static void bdrv_assign_node_name(BlockDriverState *bs,
151
Error **errp)
152
{
153
char *gen_node_name = NULL;
154
+ GLOBAL_STATE_CODE();
155
156
if (!node_name) {
157
node_name = gen_node_name = id_generate(ID_BLOCK);
158
@@ -XXX,XX +XXX,XX @@ static int bdrv_open_common(BlockDriverState *bs, BlockBackend *file,
159
160
assert(bs->file == NULL);
161
assert(options != NULL && bs->options != options);
162
+ GLOBAL_STATE_CODE();
163
164
opts = qemu_opts_create(&bdrv_runtime_opts, NULL, 0, &error_abort);
165
if (!qemu_opts_absorb_qdict(opts, options, errp)) {
166
@@ -XXX,XX +XXX,XX @@ static QDict *parse_json_filename(const char *filename, Error **errp)
167
QObject *options_obj;
168
QDict *options;
169
int ret;
170
+ GLOBAL_STATE_CODE();
171
172
ret = strstart(filename, "json:", &filename);
173
assert(ret);
174
@@ -XXX,XX +XXX,XX @@ static void parse_json_protocol(QDict *options, const char **pfilename,
175
{
176
QDict *json_options;
177
Error *local_err = NULL;
178
+ GLOBAL_STATE_CODE();
179
180
/* Parse json: pseudo-protocol */
181
if (!*pfilename || !g_str_has_prefix(*pfilename, "json:")) {
182
@@ -XXX,XX +XXX,XX @@ static GSList *bdrv_topological_dfs(GSList *list, GHashTable *found,
183
BdrvChild *child;
184
g_autoptr(GHashTable) local_found = NULL;
185
186
+ GLOBAL_STATE_CODE();
187
+
188
if (!found) {
189
assert(!list);
190
found = local_found = g_hash_table_new(NULL, NULL);
191
@@ -XXX,XX +XXX,XX @@ typedef struct BdrvReplaceChildState {
192
static void bdrv_replace_child_commit(void *opaque)
193
{
194
BdrvReplaceChildState *s = opaque;
195
+ GLOBAL_STATE_CODE();
196
197
if (s->free_empty_child && !s->child->bs) {
198
bdrv_child_free(s->child);
199
@@ -XXX,XX +XXX,XX @@ static void bdrv_replace_child_abort(void *opaque)
200
BdrvReplaceChildState *s = opaque;
201
BlockDriverState *new_bs = s->child->bs;
202
203
+ GLOBAL_STATE_CODE();
204
/*
205
* old_bs reference is transparently moved from @s to s->child.
206
*
207
@@ -XXX,XX +XXX,XX @@ static void bdrv_replace_child_noperm(BdrvChild **childp,
208
static void bdrv_child_free(BdrvChild *child)
209
{
210
assert(!child->bs);
211
+ GLOBAL_STATE_CODE();
212
assert(!child->next.le_prev); /* not in children list */
213
214
g_free(child->name);
215
@@ -XXX,XX +XXX,XX @@ static int bdrv_attach_child_common(BlockDriverState *child_bs,
216
assert(child);
217
assert(*child == NULL);
218
assert(child_class->get_parent_desc);
219
+ GLOBAL_STATE_CODE();
220
221
new_child = g_new(BdrvChild, 1);
222
*new_child = (BdrvChild) {
223
@@ -XXX,XX +XXX,XX @@ static int bdrv_attach_child_noperm(BlockDriverState *parent_bs,
224
uint64_t perm, shared_perm;
225
226
assert(parent_bs->drv);
227
+ GLOBAL_STATE_CODE();
228
229
if (bdrv_recurse_has_child(child_bs, parent_bs)) {
230
error_setg(errp, "Making '%s' a %s child of '%s' would create a cycle",
231
@@ -XXX,XX +XXX,XX @@ static void bdrv_detach_child(BdrvChild **childp)
232
{
233
BlockDriverState *old_bs = (*childp)->bs;
234
235
+ GLOBAL_STATE_CODE();
236
bdrv_replace_child_noperm(childp, NULL, true);
237
238
if (old_bs) {
239
@@ -XXX,XX +XXX,XX @@ static int bdrv_set_file_or_backing_noperm(BlockDriverState *parent_bs,
240
BdrvChild *child = is_backing ? parent_bs->backing : parent_bs->file;
241
BdrvChildRole role;
242
243
+ GLOBAL_STATE_CODE();
244
+
245
if (!parent_bs->drv) {
246
/*
247
* Node without drv is an object without a class :/. TODO: finally fix
248
@@ -XXX,XX +XXX,XX @@ static int bdrv_set_backing_noperm(BlockDriverState *bs,
249
BlockDriverState *backing_hd,
250
Transaction *tran, Error **errp)
251
{
252
+ GLOBAL_STATE_CODE();
253
return bdrv_set_file_or_backing_noperm(bs, backing_hd, true, tran, errp);
254
}
255
256
@@ -XXX,XX +XXX,XX @@ static BlockDriverState *bdrv_append_temp_snapshot(BlockDriverState *bs,
257
BlockDriverState *bs_snapshot = NULL;
258
int ret;
259
260
+ GLOBAL_STATE_CODE();
261
+
262
/* if snapshot, we create a temporary backing file and open it
263
instead of opening 'filename' directly */
264
265
@@ -XXX,XX +XXX,XX @@ static int bdrv_reopen_parse_file_or_backing(BDRVReopenState *reopen_state,
266
QObject *value;
267
const char *str;
268
269
+ GLOBAL_STATE_CODE();
270
+
271
value = qdict_get(reopen_state->options, child_name);
272
if (value == NULL) {
273
return 0;
274
@@ -XXX,XX +XXX,XX @@ static void bdrv_remove_filter_or_cow_child_abort(void *opaque)
275
static void bdrv_remove_filter_or_cow_child_commit(void *opaque)
276
{
277
BdrvRemoveFilterOrCowChild *s = opaque;
278
-
279
+ GLOBAL_STATE_CODE();
280
bdrv_child_free(s->child);
281
}
282
283
@@ -XXX,XX +XXX,XX @@ static int bdrv_replace_node_noperm(BlockDriverState *from,
284
BdrvChild *c, *next;
285
286
assert(to != NULL);
287
+ GLOBAL_STATE_CODE();
288
289
QLIST_FOREACH_SAFE(c, &from->parents, next_parent, next) {
290
assert(c->bs == from);
291
@@ -XXX,XX +XXX,XX @@ static int bdrv_replace_node_common(BlockDriverState *from,
292
BlockDriverState *to_cow_parent = NULL;
293
int ret;
294
295
+ GLOBAL_STATE_CODE();
296
assert(to != NULL);
297
298
if (detach_subchain) {
299
@@ -XXX,XX +XXX,XX @@ void bdrv_debug_event(BlockDriverState *bs, BlkdebugEvent event)
300
301
static BlockDriverState *bdrv_find_debug_node(BlockDriverState *bs)
302
{
303
+ GLOBAL_STATE_CODE();
304
while (bs && bs->drv && !bs->drv->bdrv_debug_breakpoint) {
305
bs = bdrv_primary_bs(bs);
306
}
307
@@ -XXX,XX +XXX,XX @@ void bdrv_activate_all(Error **errp)
308
static bool bdrv_has_bds_parent(BlockDriverState *bs, bool only_active)
309
{
310
BdrvChild *parent;
311
+ GLOBAL_STATE_CODE();
312
313
QLIST_FOREACH(parent, &bs->parents, next_parent) {
314
if (parent->klass->parent_is_bds) {
315
@@ -XXX,XX +XXX,XX @@ void bdrv_coroutine_enter(BlockDriverState *bs, Coroutine *co)
316
317
static void bdrv_do_remove_aio_context_notifier(BdrvAioNotifier *ban)
318
{
319
+ GLOBAL_STATE_CODE();
320
QLIST_REMOVE(ban, list);
321
g_free(ban);
322
}
323
diff --git a/block/block-backend.c b/block/block-backend.c
324
index XXXXXXX..XXXXXXX 100644
325
--- a/block/block-backend.c
326
+++ b/block/block-backend.c
327
@@ -XXX,XX +XXX,XX @@ BlockDriverState *blk_bs(BlockBackend *blk)
328
static BlockBackend *bdrv_first_blk(BlockDriverState *bs)
329
{
330
BdrvChild *child;
331
+
332
+ GLOBAL_STATE_CODE();
333
+
334
QLIST_FOREACH(child, &bs->parents, next_parent) {
335
if (child->klass == &child_root) {
336
return child->opaque;
337
--
338
2.35.1
diff view generated by jsdifflib
New patch
1
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
1
2
3
blockjob functions run always under the BQL lock.
4
5
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
6
Message-Id: <20220303151616.325444-19-eesposit@redhat.com>
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
---
9
include/block/blockjob.h | 29 ++++++++++++++++++++++-------
10
1 file changed, 22 insertions(+), 7 deletions(-)
11
12
diff --git a/include/block/blockjob.h b/include/block/blockjob.h
13
index XXXXXXX..XXXXXXX 100644
14
--- a/include/block/blockjob.h
15
+++ b/include/block/blockjob.h
16
@@ -XXX,XX +XXX,XX @@ typedef struct BlockJob {
17
GSList *nodes;
18
} BlockJob;
19
20
+/*
21
+ * Global state (GS) API. These functions run under the BQL.
22
+ *
23
+ * See include/block/block-global-state.h for more information about
24
+ * the GS API.
25
+ */
26
+
27
/**
28
* block_job_next:
29
* @job: A block job, or %NULL.
30
@@ -XXX,XX +XXX,XX @@ BlockJobInfo *block_job_query(BlockJob *job, Error **errp);
31
*/
32
void block_job_iostatus_reset(BlockJob *job);
33
34
+/*
35
+ * block_job_get_aio_context:
36
+ *
37
+ * Returns aio context associated with a block job.
38
+ */
39
+AioContext *block_job_get_aio_context(BlockJob *job);
40
+
41
+
42
+/*
43
+ * Common functions that are neither I/O nor Global State.
44
+ *
45
+ * See include/block/block-common.h for more information about
46
+ * the Common API.
47
+ */
48
+
49
/**
50
* block_job_is_internal:
51
* @job: The job to determine if it is user-visible or not.
52
@@ -XXX,XX +XXX,XX @@ bool block_job_is_internal(BlockJob *job);
53
*/
54
const BlockJobDriver *block_job_driver(BlockJob *job);
55
56
-/*
57
- * block_job_get_aio_context:
58
- *
59
- * Returns aio context associated with a block job.
60
- */
61
-AioContext *block_job_get_aio_context(BlockJob *job);
62
-
63
#endif
64
--
65
2.35.1
diff view generated by jsdifflib
New patch
1
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
1
2
3
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
4
Message-Id: <20220303151616.325444-20-eesposit@redhat.com>
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
---
7
blockjob.c | 11 +++++++++++
8
1 file changed, 11 insertions(+)
9
10
diff --git a/blockjob.c b/blockjob.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/blockjob.c
13
+++ b/blockjob.c
14
@@ -XXX,XX +XXX,XX @@ static bool is_block_job(Job *job)
15
BlockJob *block_job_next(BlockJob *bjob)
16
{
17
Job *job = bjob ? &bjob->job : NULL;
18
+ GLOBAL_STATE_CODE();
19
20
do {
21
job = job_next(job);
22
@@ -XXX,XX +XXX,XX @@ BlockJob *block_job_next(BlockJob *bjob)
23
BlockJob *block_job_get(const char *id)
24
{
25
Job *job = job_get(id);
26
+ GLOBAL_STATE_CODE();
27
28
if (job && is_block_job(job)) {
29
return container_of(job, BlockJob, job);
30
@@ -XXX,XX +XXX,XX @@ static const BdrvChildClass child_job = {
31
32
void block_job_remove_all_bdrv(BlockJob *job)
33
{
34
+ GLOBAL_STATE_CODE();
35
/*
36
* bdrv_root_unref_child() may reach child_job_[can_]set_aio_ctx(),
37
* which will also traverse job->nodes, so consume the list one by
38
@@ -XXX,XX +XXX,XX @@ void block_job_remove_all_bdrv(BlockJob *job)
39
bool block_job_has_bdrv(BlockJob *job, BlockDriverState *bs)
40
{
41
GSList *el;
42
+ GLOBAL_STATE_CODE();
43
44
for (el = job->nodes; el; el = el->next) {
45
BdrvChild *c = el->data;
46
@@ -XXX,XX +XXX,XX @@ int block_job_add_bdrv(BlockJob *job, const char *name, BlockDriverState *bs,
47
{
48
BdrvChild *c;
49
bool need_context_ops;
50
+ GLOBAL_STATE_CODE();
51
52
bdrv_ref(bs);
53
54
@@ -XXX,XX +XXX,XX @@ bool block_job_set_speed(BlockJob *job, int64_t speed, Error **errp)
55
const BlockJobDriver *drv = block_job_driver(job);
56
int64_t old_speed = job->speed;
57
58
+ GLOBAL_STATE_CODE();
59
+
60
if (job_apply_verb(&job->job, JOB_VERB_SET_SPEED, errp) < 0) {
61
return false;
62
}
63
@@ -XXX,XX +XXX,XX @@ BlockJobInfo *block_job_query(BlockJob *job, Error **errp)
64
BlockJobInfo *info;
65
uint64_t progress_current, progress_total;
66
67
+ GLOBAL_STATE_CODE();
68
+
69
if (block_job_is_internal(job)) {
70
error_setg(errp, "Cannot query QEMU internal jobs");
71
return NULL;
72
@@ -XXX,XX +XXX,XX @@ fail:
73
74
void block_job_iostatus_reset(BlockJob *job)
75
{
76
+ GLOBAL_STATE_CODE();
77
if (job->iostatus == BLOCK_DEVICE_IO_STATUS_OK) {
78
return;
79
}
80
@@ -XXX,XX +XXX,XX @@ BlockErrorAction block_job_error_action(BlockJob *job, BlockdevOnError on_err,
81
82
AioContext *block_job_get_aio_context(BlockJob *job)
83
{
84
+ GLOBAL_STATE_CODE();
85
return job->job.aio_context;
86
}
87
--
88
2.35.1
diff view generated by jsdifflib
New patch
1
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
1
2
3
blockdev functions run always under the BQL lock.
4
5
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
6
Message-Id: <20220303151616.325444-21-eesposit@redhat.com>
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
---
9
include/sysemu/blockdev.h | 13 ++++++++++---
10
1 file changed, 10 insertions(+), 3 deletions(-)
11
12
diff --git a/include/sysemu/blockdev.h b/include/sysemu/blockdev.h
13
index XXXXXXX..XXXXXXX 100644
14
--- a/include/sysemu/blockdev.h
15
+++ b/include/sysemu/blockdev.h
16
@@ -XXX,XX +XXX,XX @@
17
#include "block/block.h"
18
#include "qemu/queue.h"
19
20
-void blockdev_mark_auto_del(BlockBackend *blk);
21
-void blockdev_auto_del(BlockBackend *blk);
22
-
23
typedef enum {
24
IF_DEFAULT = -1, /* for use with drive_add() only */
25
/*
26
@@ -XXX,XX +XXX,XX @@ struct DriveInfo {
27
QTAILQ_ENTRY(DriveInfo) next;
28
};
29
30
+/*
31
+ * Global state (GS) API. These functions run under the BQL.
32
+ *
33
+ * See include/block/block-global-state.h for more information about
34
+ * the GS API.
35
+ */
36
+
37
+void blockdev_mark_auto_del(BlockBackend *blk);
38
+void blockdev_auto_del(BlockBackend *blk);
39
+
40
DriveInfo *blk_legacy_dinfo(BlockBackend *blk);
41
DriveInfo *blk_set_legacy_dinfo(BlockBackend *blk, DriveInfo *dinfo);
42
BlockBackend *blk_by_legacy_dinfo(DriveInfo *dinfo);
43
--
44
2.35.1
diff view generated by jsdifflib
New patch
1
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
1
2
3
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
4
Message-Id: <20220303151616.325444-22-eesposit@redhat.com>
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
---
7
block/block-backend.c | 3 +++
8
blockdev.c | 16 ++++++++++++++++
9
2 files changed, 19 insertions(+)
10
11
diff --git a/block/block-backend.c b/block/block-backend.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/block/block-backend.c
14
+++ b/block/block-backend.c
15
@@ -XXX,XX +XXX,XX @@ bool bdrv_is_root_node(BlockDriverState *bs)
16
*/
17
DriveInfo *blk_legacy_dinfo(BlockBackend *blk)
18
{
19
+ GLOBAL_STATE_CODE();
20
return blk->legacy_dinfo;
21
}
22
23
@@ -XXX,XX +XXX,XX @@ DriveInfo *blk_legacy_dinfo(BlockBackend *blk)
24
DriveInfo *blk_set_legacy_dinfo(BlockBackend *blk, DriveInfo *dinfo)
25
{
26
assert(!blk->legacy_dinfo);
27
+ GLOBAL_STATE_CODE();
28
return blk->legacy_dinfo = dinfo;
29
}
30
31
@@ -XXX,XX +XXX,XX @@ DriveInfo *blk_set_legacy_dinfo(BlockBackend *blk, DriveInfo *dinfo)
32
BlockBackend *blk_by_legacy_dinfo(DriveInfo *dinfo)
33
{
34
BlockBackend *blk = NULL;
35
+ GLOBAL_STATE_CODE();
36
37
while ((blk = blk_next(blk)) != NULL) {
38
if (blk->legacy_dinfo == dinfo) {
39
diff --git a/blockdev.c b/blockdev.c
40
index XXXXXXX..XXXXXXX 100644
41
--- a/blockdev.c
42
+++ b/blockdev.c
43
@@ -XXX,XX +XXX,XX @@ void override_max_devs(BlockInterfaceType type, int max_devs)
44
BlockBackend *blk;
45
DriveInfo *dinfo;
46
47
+ GLOBAL_STATE_CODE();
48
+
49
if (max_devs <= 0) {
50
return;
51
}
52
@@ -XXX,XX +XXX,XX @@ void blockdev_mark_auto_del(BlockBackend *blk)
53
DriveInfo *dinfo = blk_legacy_dinfo(blk);
54
BlockJob *job;
55
56
+ GLOBAL_STATE_CODE();
57
+
58
if (!dinfo) {
59
return;
60
}
61
@@ -XXX,XX +XXX,XX @@ void blockdev_mark_auto_del(BlockBackend *blk)
62
void blockdev_auto_del(BlockBackend *blk)
63
{
64
DriveInfo *dinfo = blk_legacy_dinfo(blk);
65
+ GLOBAL_STATE_CODE();
66
67
if (dinfo && dinfo->auto_del) {
68
monitor_remove_blk(blk);
69
@@ -XXX,XX +XXX,XX @@ QemuOpts *drive_add(BlockInterfaceType type, int index, const char *file,
70
{
71
QemuOpts *opts;
72
73
+ GLOBAL_STATE_CODE();
74
+
75
opts = qemu_opts_parse_noisily(qemu_find_opts("drive"), optstr, false);
76
if (!opts) {
77
return NULL;
78
@@ -XXX,XX +XXX,XX @@ DriveInfo *drive_get(BlockInterfaceType type, int bus, int unit)
79
BlockBackend *blk;
80
DriveInfo *dinfo;
81
82
+ GLOBAL_STATE_CODE();
83
+
84
for (blk = blk_next(NULL); blk; blk = blk_next(blk)) {
85
dinfo = blk_legacy_dinfo(blk);
86
if (dinfo && dinfo->type == type
87
@@ -XXX,XX +XXX,XX @@ void drive_check_orphaned(void)
88
Location loc;
89
bool orphans = false;
90
91
+ GLOBAL_STATE_CODE();
92
+
93
for (blk = blk_next(NULL); blk; blk = blk_next(blk)) {
94
dinfo = blk_legacy_dinfo(blk);
95
/*
96
@@ -XXX,XX +XXX,XX @@ void drive_check_orphaned(void)
97
98
DriveInfo *drive_get_by_index(BlockInterfaceType type, int index)
99
{
100
+ GLOBAL_STATE_CODE();
101
return drive_get(type,
102
drive_index_to_bus_id(type, index),
103
drive_index_to_unit_id(type, index));
104
@@ -XXX,XX +XXX,XX @@ int drive_get_max_bus(BlockInterfaceType type)
105
BlockBackend *blk;
106
DriveInfo *dinfo;
107
108
+ GLOBAL_STATE_CODE();
109
+
110
max_bus = -1;
111
for (blk = blk_next(NULL); blk; blk = blk_next(blk)) {
112
dinfo = blk_legacy_dinfo(blk);
113
@@ -XXX,XX +XXX,XX @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type,
114
const char *filename;
115
int i;
116
117
+ GLOBAL_STATE_CODE();
118
+
119
/* Change legacy command line options into QMP ones */
120
static const struct {
121
const char *from;
122
--
123
2.35.1
diff view generated by jsdifflib
New patch
1
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
1
2
3
Snapshots run also under the BQL, so they all are
4
in the global state API. The aiocontext lock that they hold
5
is currently an overkill and in future could be removed.
6
7
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
8
Message-Id: <20220303151616.325444-23-eesposit@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
11
include/block/snapshot.h | 13 +++++++++++--
12
block/snapshot.c | 28 ++++++++++++++++++++++++++++
13
migration/savevm.c | 2 ++
14
3 files changed, 41 insertions(+), 2 deletions(-)
15
16
diff --git a/include/block/snapshot.h b/include/block/snapshot.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/include/block/snapshot.h
19
+++ b/include/block/snapshot.h
20
@@ -XXX,XX +XXX,XX @@ typedef struct QEMUSnapshotInfo {
21
uint64_t icount; /* record/replay step */
22
} QEMUSnapshotInfo;
23
24
+/*
25
+ * Global state (GS) API. These functions run under the BQL.
26
+ *
27
+ * See include/block/block-global-state.h for more information about
28
+ * the GS API.
29
+ */
30
+
31
int bdrv_snapshot_find(BlockDriverState *bs, QEMUSnapshotInfo *sn_info,
32
const char *name);
33
bool bdrv_snapshot_find_by_id_and_name(BlockDriverState *bs,
34
@@ -XXX,XX +XXX,XX @@ int bdrv_snapshot_load_tmp_by_id_or_name(BlockDriverState *bs,
35
Error **errp);
36
37
38
-/* Group operations. All block drivers are involved.
39
+/*
40
+ * Group operations. All block drivers are involved.
41
* These functions will properly handle dataplane (take aio_context_acquire
42
- * when appropriate for appropriate block drivers */
43
+ * when appropriate for appropriate block drivers
44
+ */
45
46
bool bdrv_all_can_snapshot(bool has_devices, strList *devices,
47
Error **errp);
48
diff --git a/block/snapshot.c b/block/snapshot.c
49
index XXXXXXX..XXXXXXX 100644
50
--- a/block/snapshot.c
51
+++ b/block/snapshot.c
52
@@ -XXX,XX +XXX,XX @@ int bdrv_snapshot_find(BlockDriverState *bs, QEMUSnapshotInfo *sn_info,
53
QEMUSnapshotInfo *sn_tab, *sn;
54
int nb_sns, i, ret;
55
56
+ GLOBAL_STATE_CODE();
57
+
58
ret = -ENOENT;
59
nb_sns = bdrv_snapshot_list(bs, &sn_tab);
60
if (nb_sns < 0) {
61
@@ -XXX,XX +XXX,XX @@ bool bdrv_snapshot_find_by_id_and_name(BlockDriverState *bs,
62
bool ret = false;
63
64
assert(id || name);
65
+ GLOBAL_STATE_CODE();
66
67
nb_sns = bdrv_snapshot_list(bs, &sn_tab);
68
if (nb_sns < 0) {
69
@@ -XXX,XX +XXX,XX @@ static BlockDriverState *bdrv_snapshot_fallback(BlockDriverState *bs)
70
int bdrv_can_snapshot(BlockDriverState *bs)
71
{
72
BlockDriver *drv = bs->drv;
73
+ GLOBAL_STATE_CODE();
74
if (!drv || !bdrv_is_inserted(bs) || bdrv_is_read_only(bs)) {
75
return 0;
76
}
77
@@ -XXX,XX +XXX,XX @@ int bdrv_snapshot_create(BlockDriverState *bs,
78
{
79
BlockDriver *drv = bs->drv;
80
BlockDriverState *fallback_bs = bdrv_snapshot_fallback(bs);
81
+
82
+ GLOBAL_STATE_CODE();
83
+
84
if (!drv) {
85
return -ENOMEDIUM;
86
}
87
@@ -XXX,XX +XXX,XX @@ int bdrv_snapshot_goto(BlockDriverState *bs,
88
BdrvChild **fallback_ptr;
89
int ret, open_ret;
90
91
+ GLOBAL_STATE_CODE();
92
+
93
if (!drv) {
94
error_setg(errp, "Block driver is closed");
95
return -ENOMEDIUM;
96
@@ -XXX,XX +XXX,XX @@ int bdrv_snapshot_delete(BlockDriverState *bs,
97
BlockDriverState *fallback_bs = bdrv_snapshot_fallback(bs);
98
int ret;
99
100
+ GLOBAL_STATE_CODE();
101
+
102
if (!drv) {
103
error_setg(errp, QERR_DEVICE_HAS_NO_MEDIUM, bdrv_get_device_name(bs));
104
return -ENOMEDIUM;
105
@@ -XXX,XX +XXX,XX @@ int bdrv_snapshot_list(BlockDriverState *bs,
106
{
107
BlockDriver *drv = bs->drv;
108
BlockDriverState *fallback_bs = bdrv_snapshot_fallback(bs);
109
+
110
+ GLOBAL_STATE_CODE();
111
if (!drv) {
112
return -ENOMEDIUM;
113
}
114
@@ -XXX,XX +XXX,XX @@ int bdrv_snapshot_load_tmp(BlockDriverState *bs,
115
{
116
BlockDriver *drv = bs->drv;
117
118
+ GLOBAL_STATE_CODE();
119
+
120
if (!drv) {
121
error_setg(errp, QERR_DEVICE_HAS_NO_MEDIUM, bdrv_get_device_name(bs));
122
return -ENOMEDIUM;
123
@@ -XXX,XX +XXX,XX @@ int bdrv_snapshot_load_tmp_by_id_or_name(BlockDriverState *bs,
124
int ret;
125
Error *local_err = NULL;
126
127
+ GLOBAL_STATE_CODE();
128
+
129
ret = bdrv_snapshot_load_tmp(bs, id_or_name, NULL, &local_err);
130
if (ret == -ENOENT || ret == -EINVAL) {
131
error_free(local_err);
132
@@ -XXX,XX +XXX,XX @@ bool bdrv_all_can_snapshot(bool has_devices, strList *devices,
133
g_autoptr(GList) bdrvs = NULL;
134
GList *iterbdrvs;
135
136
+ GLOBAL_STATE_CODE();
137
+
138
if (bdrv_all_get_snapshot_devices(has_devices, devices, &bdrvs, errp) < 0) {
139
return false;
140
}
141
@@ -XXX,XX +XXX,XX @@ int bdrv_all_delete_snapshot(const char *name,
142
g_autoptr(GList) bdrvs = NULL;
143
GList *iterbdrvs;
144
145
+ GLOBAL_STATE_CODE();
146
+
147
if (bdrv_all_get_snapshot_devices(has_devices, devices, &bdrvs, errp) < 0) {
148
return -1;
149
}
150
@@ -XXX,XX +XXX,XX @@ int bdrv_all_goto_snapshot(const char *name,
151
g_autoptr(GList) bdrvs = NULL;
152
GList *iterbdrvs;
153
154
+ GLOBAL_STATE_CODE();
155
+
156
if (bdrv_all_get_snapshot_devices(has_devices, devices, &bdrvs, errp) < 0) {
157
return -1;
158
}
159
@@ -XXX,XX +XXX,XX @@ int bdrv_all_has_snapshot(const char *name,
160
g_autoptr(GList) bdrvs = NULL;
161
GList *iterbdrvs;
162
163
+ GLOBAL_STATE_CODE();
164
+
165
if (bdrv_all_get_snapshot_devices(has_devices, devices, &bdrvs, errp) < 0) {
166
return -1;
167
}
168
@@ -XXX,XX +XXX,XX @@ int bdrv_all_create_snapshot(QEMUSnapshotInfo *sn,
169
{
170
g_autoptr(GList) bdrvs = NULL;
171
GList *iterbdrvs;
172
+ GLOBAL_STATE_CODE();
173
174
if (bdrv_all_get_snapshot_devices(has_devices, devices, &bdrvs, errp) < 0) {
175
return -1;
176
@@ -XXX,XX +XXX,XX @@ BlockDriverState *bdrv_all_find_vmstate_bs(const char *vmstate_bs,
177
g_autoptr(GList) bdrvs = NULL;
178
GList *iterbdrvs;
179
180
+ GLOBAL_STATE_CODE();
181
+
182
if (bdrv_all_get_snapshot_devices(has_devices, devices, &bdrvs, errp) < 0) {
183
return NULL;
184
}
185
diff --git a/migration/savevm.c b/migration/savevm.c
186
index XXXXXXX..XXXXXXX 100644
187
--- a/migration/savevm.c
188
+++ b/migration/savevm.c
189
@@ -XXX,XX +XXX,XX @@ bool save_snapshot(const char *name, bool overwrite, const char *vmstate,
190
g_autoptr(GDateTime) now = g_date_time_new_now_local();
191
AioContext *aio_context;
192
193
+ GLOBAL_STATE_CODE();
194
+
195
if (migration_is_blocked(errp)) {
196
return false;
197
}
198
--
199
2.35.1
diff view generated by jsdifflib
New patch
1
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
1
2
3
copy-before-write functions always run under BQL.
4
5
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
6
Message-Id: <20220303151616.325444-24-eesposit@redhat.com>
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
---
9
block/copy-before-write.h | 7 +++++++
10
block/copy-before-write.c | 2 ++
11
2 files changed, 9 insertions(+)
12
13
diff --git a/block/copy-before-write.h b/block/copy-before-write.h
14
index XXXXXXX..XXXXXXX 100644
15
--- a/block/copy-before-write.h
16
+++ b/block/copy-before-write.h
17
@@ -XXX,XX +XXX,XX @@
18
#include "block/block_int.h"
19
#include "block/block-copy.h"
20
21
+/*
22
+ * Global state (GS) API. These functions run under the BQL.
23
+ *
24
+ * See include/block/block-global-state.h for more information about
25
+ * the GS API.
26
+ */
27
+
28
BlockDriverState *bdrv_cbw_append(BlockDriverState *source,
29
BlockDriverState *target,
30
const char *filter_node_name,
31
diff --git a/block/copy-before-write.c b/block/copy-before-write.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/block/copy-before-write.c
34
+++ b/block/copy-before-write.c
35
@@ -XXX,XX +XXX,XX @@ BlockDriverState *bdrv_cbw_append(BlockDriverState *source,
36
QDict *opts;
37
38
assert(source->total_sectors == target->total_sectors);
39
+ GLOBAL_STATE_CODE();
40
41
opts = qdict_new();
42
qdict_put_str(opts, "driver", "copy-before-write");
43
@@ -XXX,XX +XXX,XX @@ BlockDriverState *bdrv_cbw_append(BlockDriverState *source,
44
45
void bdrv_cbw_drop(BlockDriverState *bs)
46
{
47
+ GLOBAL_STATE_CODE();
48
bdrv_drop_filter(bs, &error_abort);
49
bdrv_unref(bs);
50
}
51
--
52
2.35.1
diff view generated by jsdifflib
New patch
1
1
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
2
3
block coroutines functions run in different aiocontext, and are
4
not protected by the BQL. Therefore are I/O.
5
6
On the other side, generated_co_wrapper functions use BDRV_POLL_WHILE,
7
meaning the caller can either be the main loop or a specific iothread.
8
9
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
10
Message-Id: <20220303151616.325444-25-eesposit@redhat.com>
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
---
13
block/coroutines.h | 81 +++++++++++++++++++++++++++----------------
14
block.c | 2 ++
15
block/block-backend.c | 6 ++++
16
block/io.c | 3 ++
17
block/nbd.c | 1 +
18
5 files changed, 64 insertions(+), 29 deletions(-)
19
20
diff --git a/block/coroutines.h b/block/coroutines.h
21
index XXXXXXX..XXXXXXX 100644
22
--- a/block/coroutines.h
23
+++ b/block/coroutines.h
24
@@ -XXX,XX +XXX,XX @@
25
/* For blk_bs() in generated block/block-gen.c */
26
#include "sysemu/block-backend.h"
27
28
+/*
29
+ * I/O API functions. These functions are thread-safe.
30
+ *
31
+ * See include/block/block-io.h for more information about
32
+ * the I/O API.
33
+ */
34
+
35
int coroutine_fn bdrv_co_check(BlockDriverState *bs,
36
BdrvCheckResult *res, BdrvCheckMode fix);
37
int coroutine_fn bdrv_co_invalidate_cache(BlockDriverState *bs, Error **errp);
38
39
-int generated_co_wrapper
40
-bdrv_preadv(BdrvChild *child, int64_t offset, unsigned int bytes,
41
- QEMUIOVector *qiov, BdrvRequestFlags flags);
42
-int generated_co_wrapper
43
-bdrv_pwritev(BdrvChild *child, int64_t offset, unsigned int bytes,
44
- QEMUIOVector *qiov, BdrvRequestFlags flags);
45
-
46
int coroutine_fn
47
bdrv_co_common_block_status_above(BlockDriverState *bs,
48
BlockDriverState *base,
49
@@ -XXX,XX +XXX,XX @@ bdrv_co_common_block_status_above(BlockDriverState *bs,
50
int64_t *map,
51
BlockDriverState **file,
52
int *depth);
53
+
54
+int coroutine_fn bdrv_co_readv_vmstate(BlockDriverState *bs,
55
+ QEMUIOVector *qiov, int64_t pos);
56
+int coroutine_fn bdrv_co_writev_vmstate(BlockDriverState *bs,
57
+ QEMUIOVector *qiov, int64_t pos);
58
+
59
+int coroutine_fn
60
+nbd_co_do_establish_connection(BlockDriverState *bs, Error **errp);
61
+
62
+
63
+int coroutine_fn
64
+blk_co_do_preadv(BlockBackend *blk, int64_t offset, int64_t bytes,
65
+ QEMUIOVector *qiov, BdrvRequestFlags flags);
66
+
67
+
68
+int coroutine_fn
69
+blk_co_do_pwritev_part(BlockBackend *blk, int64_t offset, int64_t bytes,
70
+ QEMUIOVector *qiov, size_t qiov_offset,
71
+ BdrvRequestFlags flags);
72
+
73
+int coroutine_fn
74
+blk_co_do_ioctl(BlockBackend *blk, unsigned long int req, void *buf);
75
+
76
+int coroutine_fn
77
+blk_co_do_pdiscard(BlockBackend *blk, int64_t offset, int64_t bytes);
78
+
79
+int coroutine_fn blk_co_do_flush(BlockBackend *blk);
80
+
81
+
82
+/*
83
+ * "I/O or GS" API functions. These functions can run without
84
+ * the BQL, but only in one specific iothread/main loop.
85
+ *
86
+ * See include/block/block-io.h for more information about
87
+ * the "I/O or GS" API.
88
+ */
89
+
90
+int generated_co_wrapper
91
+bdrv_preadv(BdrvChild *child, int64_t offset, unsigned int bytes,
92
+ QEMUIOVector *qiov, BdrvRequestFlags flags);
93
+
94
+int generated_co_wrapper
95
+bdrv_pwritev(BdrvChild *child, int64_t offset, unsigned int bytes,
96
+ QEMUIOVector *qiov, BdrvRequestFlags flags);
97
+
98
int generated_co_wrapper
99
bdrv_common_block_status_above(BlockDriverState *bs,
100
BlockDriverState *base,
101
@@ -XXX,XX +XXX,XX @@ bdrv_common_block_status_above(BlockDriverState *bs,
102
int64_t *map,
103
BlockDriverState **file,
104
int *depth);
105
-
106
-int coroutine_fn bdrv_co_readv_vmstate(BlockDriverState *bs,
107
- QEMUIOVector *qiov, int64_t pos);
108
-int coroutine_fn bdrv_co_writev_vmstate(BlockDriverState *bs,
109
- QEMUIOVector *qiov, int64_t pos);
110
-
111
int generated_co_wrapper
112
nbd_do_establish_connection(BlockDriverState *bs, Error **errp);
113
-int coroutine_fn
114
-nbd_co_do_establish_connection(BlockDriverState *bs, Error **errp);
115
-
116
117
int generated_co_wrapper
118
blk_do_preadv(BlockBackend *blk, int64_t offset, int64_t bytes,
119
QEMUIOVector *qiov, BdrvRequestFlags flags);
120
-int coroutine_fn
121
-blk_co_do_preadv(BlockBackend *blk, int64_t offset, int64_t bytes,
122
- QEMUIOVector *qiov, BdrvRequestFlags flags);
123
-
124
125
int generated_co_wrapper
126
blk_do_pwritev_part(BlockBackend *blk, int64_t offset, int64_t bytes,
127
QEMUIOVector *qiov, size_t qiov_offset,
128
BdrvRequestFlags flags);
129
-int coroutine_fn
130
-blk_co_do_pwritev_part(BlockBackend *blk, int64_t offset, int64_t bytes,
131
- QEMUIOVector *qiov, size_t qiov_offset,
132
- BdrvRequestFlags flags);
133
134
int generated_co_wrapper
135
blk_do_ioctl(BlockBackend *blk, unsigned long int req, void *buf);
136
-int coroutine_fn
137
-blk_co_do_ioctl(BlockBackend *blk, unsigned long int req, void *buf);
138
139
int generated_co_wrapper
140
blk_do_pdiscard(BlockBackend *blk, int64_t offset, int64_t bytes);
141
-int coroutine_fn
142
-blk_co_do_pdiscard(BlockBackend *blk, int64_t offset, int64_t bytes);
143
144
int generated_co_wrapper blk_do_flush(BlockBackend *blk);
145
-int coroutine_fn blk_co_do_flush(BlockBackend *blk);
146
147
#endif /* BLOCK_COROUTINES_INT_H */
148
diff --git a/block.c b/block.c
149
index XXXXXXX..XXXXXXX 100644
150
--- a/block.c
151
+++ b/block.c
152
@@ -XXX,XX +XXX,XX @@ fail:
153
int coroutine_fn bdrv_co_check(BlockDriverState *bs,
154
BdrvCheckResult *res, BdrvCheckMode fix)
155
{
156
+ IO_CODE();
157
if (bs->drv == NULL) {
158
return -ENOMEDIUM;
159
}
160
@@ -XXX,XX +XXX,XX @@ int bdrv_activate(BlockDriverState *bs, Error **errp)
161
int coroutine_fn bdrv_co_invalidate_cache(BlockDriverState *bs, Error **errp)
162
{
163
Error *local_err = NULL;
164
+ IO_CODE();
165
166
assert(!(bs->open_flags & BDRV_O_INACTIVE));
167
168
diff --git a/block/block-backend.c b/block/block-backend.c
169
index XXXXXXX..XXXXXXX 100644
170
--- a/block/block-backend.c
171
+++ b/block/block-backend.c
172
@@ -XXX,XX +XXX,XX @@ blk_co_do_preadv(BlockBackend *blk, int64_t offset, int64_t bytes,
173
{
174
int ret;
175
BlockDriverState *bs;
176
+ IO_CODE();
177
178
blk_wait_while_drained(blk);
179
180
@@ -XXX,XX +XXX,XX @@ blk_co_do_pwritev_part(BlockBackend *blk, int64_t offset, int64_t bytes,
181
{
182
int ret;
183
BlockDriverState *bs;
184
+ IO_CODE();
185
186
blk_wait_while_drained(blk);
187
188
@@ -XXX,XX +XXX,XX @@ void blk_aio_cancel_async(BlockAIOCB *acb)
189
int coroutine_fn
190
blk_co_do_ioctl(BlockBackend *blk, unsigned long int req, void *buf)
191
{
192
+ IO_CODE();
193
+
194
blk_wait_while_drained(blk);
195
196
if (!blk_is_available(blk)) {
197
@@ -XXX,XX +XXX,XX @@ int coroutine_fn
198
blk_co_do_pdiscard(BlockBackend *blk, int64_t offset, int64_t bytes)
199
{
200
int ret;
201
+ IO_CODE();
202
203
blk_wait_while_drained(blk);
204
205
@@ -XXX,XX +XXX,XX @@ int blk_pdiscard(BlockBackend *blk, int64_t offset, int64_t bytes)
206
int coroutine_fn blk_co_do_flush(BlockBackend *blk)
207
{
208
blk_wait_while_drained(blk);
209
+ IO_CODE();
210
211
if (!blk_is_available(blk)) {
212
return -ENOMEDIUM;
213
diff --git a/block/io.c b/block/io.c
214
index XXXXXXX..XXXXXXX 100644
215
--- a/block/io.c
216
+++ b/block/io.c
217
@@ -XXX,XX +XXX,XX @@ bdrv_co_common_block_status_above(BlockDriverState *bs,
218
BlockDriverState *p;
219
int64_t eof = 0;
220
int dummy;
221
+ IO_CODE();
222
223
assert(!include_base || base); /* Can't include NULL base */
224
225
@@ -XXX,XX +XXX,XX @@ bdrv_co_readv_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos)
226
BlockDriver *drv = bs->drv;
227
BlockDriverState *child_bs = bdrv_primary_bs(bs);
228
int ret;
229
+ IO_CODE();
230
231
ret = bdrv_check_qiov_request(pos, qiov->size, qiov, 0, NULL);
232
if (ret < 0) {
233
@@ -XXX,XX +XXX,XX @@ bdrv_co_writev_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos)
234
BlockDriver *drv = bs->drv;
235
BlockDriverState *child_bs = bdrv_primary_bs(bs);
236
int ret;
237
+ IO_CODE();
238
239
ret = bdrv_check_qiov_request(pos, qiov->size, qiov, 0, NULL);
240
if (ret < 0) {
241
diff --git a/block/nbd.c b/block/nbd.c
242
index XXXXXXX..XXXXXXX 100644
243
--- a/block/nbd.c
244
+++ b/block/nbd.c
245
@@ -XXX,XX +XXX,XX @@ int coroutine_fn nbd_co_do_establish_connection(BlockDriverState *bs,
246
BDRVNBDState *s = (BDRVNBDState *)bs->opaque;
247
int ret;
248
bool blocking = nbd_client_connecting_wait(s);
249
+ IO_CODE();
250
251
assert(!s->ioc);
252
253
--
254
2.35.1
diff view generated by jsdifflib
New patch
1
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
1
2
3
Similar to the header split, also the function pointers in BlockDriver
4
can be split in I/O and global state.
5
6
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
7
Message-Id: <20220303151616.325444-26-eesposit@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
---
10
include/block/block_int-common.h | 445 ++++++++++++++++---------------
11
1 file changed, 237 insertions(+), 208 deletions(-)
12
13
diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h
14
index XXXXXXX..XXXXXXX 100644
15
--- a/include/block/block_int-common.h
16
+++ b/include/block/block_int-common.h
17
@@ -XXX,XX +XXX,XX @@ typedef struct BdrvTrackedRequest {
18
19
20
struct BlockDriver {
21
+ /*
22
+ * These fields are initialized when this object is created,
23
+ * and are never changed afterwards.
24
+ */
25
+
26
const char *format_name;
27
int instance_size;
28
29
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
30
*/
31
bool is_format;
32
33
+ /*
34
+ * Drivers not implementing bdrv_parse_filename nor bdrv_open should have
35
+ * this field set to true, except ones that are defined only by their
36
+ * child's bs.
37
+ * An example of the last type will be the quorum block driver.
38
+ */
39
+ bool bdrv_needs_filename;
40
+
41
+ /*
42
+ * Set if a driver can support backing files. This also implies the
43
+ * following semantics:
44
+ *
45
+ * - Return status 0 of .bdrv_co_block_status means that corresponding
46
+ * blocks are not allocated in this layer of backing-chain
47
+ * - For such (unallocated) blocks, read will:
48
+ * - fill buffer with zeros if there is no backing file
49
+ * - read from the backing file otherwise, where the block layer
50
+ * takes care of reading zeros beyond EOF if backing file is short
51
+ */
52
+ bool supports_backing;
53
+
54
+ bool has_variable_length;
55
+
56
+ /*
57
+ * Drivers setting this field must be able to work with just a plain
58
+ * filename with '<protocol_name>:' as a prefix, and no other options.
59
+ * Options may be extracted from the filename by implementing
60
+ * bdrv_parse_filename.
61
+ */
62
+ const char *protocol_name;
63
+
64
+ /* List of options for creating images, terminated by name == NULL */
65
+ QemuOptsList *create_opts;
66
+
67
+ /* List of options for image amend */
68
+ QemuOptsList *amend_opts;
69
+
70
+ /*
71
+ * If this driver supports reopening images this contains a
72
+ * NULL-terminated list of the runtime options that can be
73
+ * modified. If an option in this list is unspecified during
74
+ * reopen then it _must_ be reset to its default value or return
75
+ * an error.
76
+ */
77
+ const char *const *mutable_opts;
78
+
79
+ /*
80
+ * Pointer to a NULL-terminated array of names of strong options
81
+ * that can be specified for bdrv_open(). A strong option is one
82
+ * that changes the data of a BDS.
83
+ * If this pointer is NULL, the array is considered empty.
84
+ * "filename" and "driver" are always considered strong.
85
+ */
86
+ const char *const *strong_runtime_opts;
87
+
88
+
89
+ /*
90
+ * Global state (GS) API. These functions run under the BQL.
91
+ *
92
+ * See include/block/block-global-state.h for more information about
93
+ * the GS API.
94
+ */
95
+
96
/*
97
* This function is invoked under BQL before .bdrv_co_amend()
98
* (which in contrast does not necessarily run under the BQL)
99
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
100
bool (*bdrv_recurse_can_replace)(BlockDriverState *bs,
101
BlockDriverState *to_replace);
102
103
- int (*bdrv_probe)(const uint8_t *buf, int buf_size, const char *filename);
104
int (*bdrv_probe_device)(const char *filename);
105
106
/*
107
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
108
*/
109
void (*bdrv_parse_filename)(const char *filename, QDict *options,
110
Error **errp);
111
- /*
112
- * Drivers not implementing bdrv_parse_filename nor bdrv_open should have
113
- * this field set to true, except ones that are defined only by their
114
- * child's bs.
115
- * An example of the last type will be the quorum block driver.
116
- */
117
- bool bdrv_needs_filename;
118
-
119
- /*
120
- * Set if a driver can support backing files. This also implies the
121
- * following semantics:
122
- *
123
- * - Return status 0 of .bdrv_co_block_status means that corresponding
124
- * blocks are not allocated in this layer of backing-chain
125
- * - For such (unallocated) blocks, read will:
126
- * - fill buffer with zeros if there is no backing file
127
- * - read from the backing file otherwise, where the block layer
128
- * takes care of reading zeros beyond EOF if backing file is short
129
- */
130
- bool supports_backing;
131
132
- /* For handling image reopen for split or non-split files */
133
+ /* For handling image reopen for split or non-split files. */
134
int (*bdrv_reopen_prepare)(BDRVReopenState *reopen_state,
135
BlockReopenQueue *queue, Error **errp);
136
void (*bdrv_reopen_commit)(BDRVReopenState *reopen_state);
137
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
138
Error **errp);
139
void (*bdrv_close)(BlockDriverState *bs);
140
141
-
142
int coroutine_fn (*bdrv_co_create)(BlockdevCreateOptions *opts,
143
Error **errp);
144
int coroutine_fn (*bdrv_co_create_opts)(BlockDriver *drv,
145
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
146
QemuOpts *opts,
147
Error **errp);
148
149
- int coroutine_fn (*bdrv_co_amend)(BlockDriverState *bs,
150
- BlockdevAmendOptions *opts,
151
- bool force,
152
- Error **errp);
153
-
154
int (*bdrv_amend_options)(BlockDriverState *bs,
155
QemuOpts *opts,
156
BlockDriverAmendStatusCB *status_cb,
157
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
158
*/
159
char *(*bdrv_dirname)(BlockDriverState *bs, Error **errp);
160
161
+ /*
162
+ * This informs the driver that we are no longer interested in the result
163
+ * of in-flight requests, so don't waste the time if possible.
164
+ *
165
+ * One example usage is to avoid waiting for an nbd target node reconnect
166
+ * timeout during job-cancel with force=true.
167
+ */
168
+ void (*bdrv_cancel_in_flight)(BlockDriverState *bs);
169
+
170
+ int (*bdrv_inactivate)(BlockDriverState *bs);
171
+
172
+ int (*bdrv_snapshot_create)(BlockDriverState *bs,
173
+ QEMUSnapshotInfo *sn_info);
174
+ int (*bdrv_snapshot_goto)(BlockDriverState *bs,
175
+ const char *snapshot_id);
176
+ int (*bdrv_snapshot_delete)(BlockDriverState *bs,
177
+ const char *snapshot_id,
178
+ const char *name,
179
+ Error **errp);
180
+ int (*bdrv_snapshot_list)(BlockDriverState *bs,
181
+ QEMUSnapshotInfo **psn_info);
182
+ int (*bdrv_snapshot_load_tmp)(BlockDriverState *bs,
183
+ const char *snapshot_id,
184
+ const char *name,
185
+ Error **errp);
186
+
187
+ int (*bdrv_change_backing_file)(BlockDriverState *bs,
188
+ const char *backing_file, const char *backing_fmt);
189
+
190
+ /* TODO Better pass a option string/QDict/QemuOpts to add any rule? */
191
+ int (*bdrv_debug_breakpoint)(BlockDriverState *bs, const char *event,
192
+ const char *tag);
193
+ int (*bdrv_debug_remove_breakpoint)(BlockDriverState *bs,
194
+ const char *tag);
195
+ int (*bdrv_debug_resume)(BlockDriverState *bs, const char *tag);
196
+ bool (*bdrv_debug_is_suspended)(BlockDriverState *bs, const char *tag);
197
+
198
+ void (*bdrv_refresh_limits)(BlockDriverState *bs, Error **errp);
199
+
200
+ /*
201
+ * Returns 1 if newly created images are guaranteed to contain only
202
+ * zeros, 0 otherwise.
203
+ */
204
+ int (*bdrv_has_zero_init)(BlockDriverState *bs);
205
+
206
+ /*
207
+ * Remove fd handlers, timers, and other event loop callbacks so the event
208
+ * loop is no longer in use. Called with no in-flight requests and in
209
+ * depth-first traversal order with parents before child nodes.
210
+ */
211
+ void (*bdrv_detach_aio_context)(BlockDriverState *bs);
212
+
213
+ /*
214
+ * Add fd handlers, timers, and other event loop callbacks so I/O requests
215
+ * can be processed again. Called with no in-flight requests and in
216
+ * depth-first traversal order with child nodes before parent nodes.
217
+ */
218
+ void (*bdrv_attach_aio_context)(BlockDriverState *bs,
219
+ AioContext *new_context);
220
+
221
+ /**
222
+ * Try to get @bs's logical and physical block size.
223
+ * On success, store them in @bsz and return zero.
224
+ * On failure, return negative errno.
225
+ */
226
+ int (*bdrv_probe_blocksizes)(BlockDriverState *bs, BlockSizes *bsz);
227
+ /**
228
+ * Try to get @bs's geometry (cyls, heads, sectors)
229
+ * On success, store them in @geo and return 0.
230
+ * On failure return -errno.
231
+ * Only drivers that want to override guest geometry implement this
232
+ * callback; see hd_geometry_guess().
233
+ */
234
+ int (*bdrv_probe_geometry)(BlockDriverState *bs, HDGeometry *geo);
235
+
236
+ void (*bdrv_add_child)(BlockDriverState *parent, BlockDriverState *child,
237
+ Error **errp);
238
+ void (*bdrv_del_child)(BlockDriverState *parent, BdrvChild *child,
239
+ Error **errp);
240
+
241
+ /**
242
+ * Informs the block driver that a permission change is intended. The
243
+ * driver checks whether the change is permissible and may take other
244
+ * preparations for the change (e.g. get file system locks). This operation
245
+ * is always followed either by a call to either .bdrv_set_perm or
246
+ * .bdrv_abort_perm_update.
247
+ *
248
+ * Checks whether the requested set of cumulative permissions in @perm
249
+ * can be granted for accessing @bs and whether no other users are using
250
+ * permissions other than those given in @shared (both arguments take
251
+ * BLK_PERM_* bitmasks).
252
+ *
253
+ * If both conditions are met, 0 is returned. Otherwise, -errno is returned
254
+ * and errp is set to an error describing the conflict.
255
+ */
256
+ int (*bdrv_check_perm)(BlockDriverState *bs, uint64_t perm,
257
+ uint64_t shared, Error **errp);
258
+
259
+ /**
260
+ * Called to inform the driver that the set of cumulative set of used
261
+ * permissions for @bs has changed to @perm, and the set of sharable
262
+ * permission to @shared. The driver can use this to propagate changes to
263
+ * its children (i.e. request permissions only if a parent actually needs
264
+ * them).
265
+ *
266
+ * This function is only invoked after bdrv_check_perm(), so block drivers
267
+ * may rely on preparations made in their .bdrv_check_perm implementation.
268
+ */
269
+ void (*bdrv_set_perm)(BlockDriverState *bs, uint64_t perm, uint64_t shared);
270
+
271
+ /*
272
+ * Called to inform the driver that after a previous bdrv_check_perm()
273
+ * call, the permission update is not performed and any preparations made
274
+ * for it (e.g. taken file locks) need to be undone.
275
+ *
276
+ * This function can be called even for nodes that never saw a
277
+ * bdrv_check_perm() call. It is a no-op then.
278
+ */
279
+ void (*bdrv_abort_perm_update)(BlockDriverState *bs);
280
+
281
+ /**
282
+ * Returns in @nperm and @nshared the permissions that the driver for @bs
283
+ * needs on its child @c, based on the cumulative permissions requested by
284
+ * the parents in @parent_perm and @parent_shared.
285
+ *
286
+ * If @c is NULL, return the permissions for attaching a new child for the
287
+ * given @child_class and @role.
288
+ *
289
+ * If @reopen_queue is non-NULL, don't return the currently needed
290
+ * permissions, but those that will be needed after applying the
291
+ * @reopen_queue.
292
+ */
293
+ void (*bdrv_child_perm)(BlockDriverState *bs, BdrvChild *c,
294
+ BdrvChildRole role,
295
+ BlockReopenQueue *reopen_queue,
296
+ uint64_t parent_perm, uint64_t parent_shared,
297
+ uint64_t *nperm, uint64_t *nshared);
298
+
299
+ /**
300
+ * Register/unregister a buffer for I/O. For example, when the driver is
301
+ * interested to know the memory areas that will later be used in iovs, so
302
+ * that it can do IOMMU mapping with VFIO etc., in order to get better
303
+ * performance. In the case of VFIO drivers, this callback is used to do
304
+ * DMA mapping for hot buffers.
305
+ */
306
+ void (*bdrv_register_buf)(BlockDriverState *bs, void *host, size_t size);
307
+ void (*bdrv_unregister_buf)(BlockDriverState *bs, void *host);
308
+
309
+ /*
310
+ * This field is modified only under the BQL, and is part of
311
+ * the global state.
312
+ */
313
+ QLIST_ENTRY(BlockDriver) list;
314
+
315
+ /*
316
+ * I/O API functions. These functions are thread-safe.
317
+ *
318
+ * See include/block/block-io.h for more information about
319
+ * the I/O API.
320
+ */
321
+
322
+ int (*bdrv_probe)(const uint8_t *buf, int buf_size, const char *filename);
323
+
324
+ int coroutine_fn (*bdrv_co_amend)(BlockDriverState *bs,
325
+ BlockdevAmendOptions *opts,
326
+ bool force,
327
+ Error **errp);
328
+
329
/* aio */
330
BlockAIOCB *(*bdrv_aio_preadv)(BlockDriverState *bs,
331
int64_t offset, int64_t bytes, QEMUIOVector *qiov,
332
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
333
bool want_zero, int64_t offset, int64_t bytes, int64_t *pnum,
334
int64_t *map, BlockDriverState **file);
335
336
- /*
337
- * This informs the driver that we are no longer interested in the result
338
- * of in-flight requests, so don't waste the time if possible.
339
- *
340
- * One example usage is to avoid waiting for an nbd target node reconnect
341
- * timeout during job-cancel with force=true.
342
- */
343
- void (*bdrv_cancel_in_flight)(BlockDriverState *bs);
344
-
345
/*
346
* Invalidate any cached meta-data.
347
*/
348
void coroutine_fn (*bdrv_co_invalidate_cache)(BlockDriverState *bs,
349
Error **errp);
350
- int (*bdrv_inactivate)(BlockDriverState *bs);
351
352
/*
353
* Flushes all data for all layers by calling bdrv_co_flush for underlying
354
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
355
*/
356
int coroutine_fn (*bdrv_co_flush_to_os)(BlockDriverState *bs);
357
358
- /*
359
- * Drivers setting this field must be able to work with just a plain
360
- * filename with '<protocol_name>:' as a prefix, and no other options.
361
- * Options may be extracted from the filename by implementing
362
- * bdrv_parse_filename.
363
- */
364
- const char *protocol_name;
365
-
366
/*
367
* Truncate @bs to @offset bytes using the given @prealloc mode
368
* when growing. Modes other than PREALLOC_MODE_OFF should be
369
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
370
bool exact, PreallocMode prealloc,
371
BdrvRequestFlags flags, Error **errp);
372
int64_t (*bdrv_getlength)(BlockDriverState *bs);
373
- bool has_variable_length;
374
int64_t (*bdrv_get_allocated_file_size)(BlockDriverState *bs);
375
BlockMeasureInfo *(*bdrv_measure)(QemuOpts *opts, BlockDriverState *in_bs,
376
Error **errp);
377
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
378
int64_t offset, int64_t bytes, QEMUIOVector *qiov,
379
size_t qiov_offset);
380
381
- int (*bdrv_snapshot_create)(BlockDriverState *bs,
382
- QEMUSnapshotInfo *sn_info);
383
- int (*bdrv_snapshot_goto)(BlockDriverState *bs,
384
- const char *snapshot_id);
385
- int (*bdrv_snapshot_delete)(BlockDriverState *bs,
386
- const char *snapshot_id,
387
- const char *name,
388
- Error **errp);
389
- int (*bdrv_snapshot_list)(BlockDriverState *bs,
390
- QEMUSnapshotInfo **psn_info);
391
- int (*bdrv_snapshot_load_tmp)(BlockDriverState *bs,
392
- const char *snapshot_id,
393
- const char *name,
394
- Error **errp);
395
int (*bdrv_get_info)(BlockDriverState *bs, BlockDriverInfo *bdi);
396
397
ImageInfoSpecific *(*bdrv_get_specific_info)(BlockDriverState *bs,
398
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
399
QEMUIOVector *qiov,
400
int64_t pos);
401
402
- int (*bdrv_change_backing_file)(BlockDriverState *bs,
403
- const char *backing_file, const char *backing_fmt);
404
-
405
/* removable device specific */
406
bool (*bdrv_is_inserted)(BlockDriverState *bs);
407
void (*bdrv_eject)(BlockDriverState *bs, bool eject_flag);
408
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
409
int coroutine_fn (*bdrv_co_ioctl)(BlockDriverState *bs,
410
unsigned long int req, void *buf);
411
412
- /* List of options for creating images, terminated by name == NULL */
413
- QemuOptsList *create_opts;
414
-
415
- /* List of options for image amend */
416
- QemuOptsList *amend_opts;
417
-
418
- /*
419
- * If this driver supports reopening images this contains a
420
- * NULL-terminated list of the runtime options that can be
421
- * modified. If an option in this list is unspecified during
422
- * reopen then it _must_ be reset to its default value or return
423
- * an error.
424
- */
425
- const char *const *mutable_opts;
426
-
427
/*
428
* Returns 0 for completed check, -errno for internal errors.
429
* The check results are stored in result.
430
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
431
432
void (*bdrv_debug_event)(BlockDriverState *bs, BlkdebugEvent event);
433
434
- /* TODO Better pass a option string/QDict/QemuOpts to add any rule? */
435
- int (*bdrv_debug_breakpoint)(BlockDriverState *bs, const char *event,
436
- const char *tag);
437
- int (*bdrv_debug_remove_breakpoint)(BlockDriverState *bs,
438
- const char *tag);
439
- int (*bdrv_debug_resume)(BlockDriverState *bs, const char *tag);
440
- bool (*bdrv_debug_is_suspended)(BlockDriverState *bs, const char *tag);
441
-
442
- void (*bdrv_refresh_limits)(BlockDriverState *bs, Error **errp);
443
-
444
- /*
445
- * Returns 1 if newly created images are guaranteed to contain only
446
- * zeros, 0 otherwise.
447
- */
448
- int (*bdrv_has_zero_init)(BlockDriverState *bs);
449
-
450
- /*
451
- * Remove fd handlers, timers, and other event loop callbacks so the event
452
- * loop is no longer in use. Called with no in-flight requests and in
453
- * depth-first traversal order with parents before child nodes.
454
- */
455
- void (*bdrv_detach_aio_context)(BlockDriverState *bs);
456
-
457
- /*
458
- * Add fd handlers, timers, and other event loop callbacks so I/O requests
459
- * can be processed again. Called with no in-flight requests and in
460
- * depth-first traversal order with child nodes before parent nodes.
461
- */
462
- void (*bdrv_attach_aio_context)(BlockDriverState *bs,
463
- AioContext *new_context);
464
-
465
/* io queue for linux-aio */
466
void (*bdrv_io_plug)(BlockDriverState *bs);
467
void (*bdrv_io_unplug)(BlockDriverState *bs);
468
469
- /**
470
- * Try to get @bs's logical and physical block size.
471
- * On success, store them in @bsz and return zero.
472
- * On failure, return negative errno.
473
- */
474
- int (*bdrv_probe_blocksizes)(BlockDriverState *bs, BlockSizes *bsz);
475
- /**
476
- * Try to get @bs's geometry (cyls, heads, sectors)
477
- * On success, store them in @geo and return 0.
478
- * On failure return -errno.
479
- * Only drivers that want to override guest geometry implement this
480
- * callback; see hd_geometry_guess().
481
- */
482
- int (*bdrv_probe_geometry)(BlockDriverState *bs, HDGeometry *geo);
483
-
484
/**
485
* bdrv_co_drain_begin is called if implemented in the beginning of a
486
* drain operation to drain and stop any internal sources of requests in
487
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
488
void coroutine_fn (*bdrv_co_drain_begin)(BlockDriverState *bs);
489
void coroutine_fn (*bdrv_co_drain_end)(BlockDriverState *bs);
490
491
- void (*bdrv_add_child)(BlockDriverState *parent, BlockDriverState *child,
492
- Error **errp);
493
- void (*bdrv_del_child)(BlockDriverState *parent, BdrvChild *child,
494
- Error **errp);
495
-
496
- /**
497
- * Informs the block driver that a permission change is intended. The
498
- * driver checks whether the change is permissible and may take other
499
- * preparations for the change (e.g. get file system locks). This operation
500
- * is always followed either by a call to either .bdrv_set_perm or
501
- * .bdrv_abort_perm_update.
502
- *
503
- * Checks whether the requested set of cumulative permissions in @perm
504
- * can be granted for accessing @bs and whether no other users are using
505
- * permissions other than those given in @shared (both arguments take
506
- * BLK_PERM_* bitmasks).
507
- *
508
- * If both conditions are met, 0 is returned. Otherwise, -errno is returned
509
- * and errp is set to an error describing the conflict.
510
- */
511
- int (*bdrv_check_perm)(BlockDriverState *bs, uint64_t perm,
512
- uint64_t shared, Error **errp);
513
-
514
- /**
515
- * Called to inform the driver that the set of cumulative set of used
516
- * permissions for @bs has changed to @perm, and the set of sharable
517
- * permission to @shared. The driver can use this to propagate changes to
518
- * its children (i.e. request permissions only if a parent actually needs
519
- * them).
520
- *
521
- * This function is only invoked after bdrv_check_perm(), so block drivers
522
- * may rely on preparations made in their .bdrv_check_perm implementation.
523
- */
524
- void (*bdrv_set_perm)(BlockDriverState *bs, uint64_t perm, uint64_t shared);
525
-
526
- /*
527
- * Called to inform the driver that after a previous bdrv_check_perm()
528
- * call, the permission update is not performed and any preparations made
529
- * for it (e.g. taken file locks) need to be undone.
530
- *
531
- * This function can be called even for nodes that never saw a
532
- * bdrv_check_perm() call. It is a no-op then.
533
- */
534
- void (*bdrv_abort_perm_update)(BlockDriverState *bs);
535
-
536
- /**
537
- * Returns in @nperm and @nshared the permissions that the driver for @bs
538
- * needs on its child @c, based on the cumulative permissions requested by
539
- * the parents in @parent_perm and @parent_shared.
540
- *
541
- * If @c is NULL, return the permissions for attaching a new child for the
542
- * given @child_class and @role.
543
- *
544
- * If @reopen_queue is non-NULL, don't return the currently needed
545
- * permissions, but those that will be needed after applying the
546
- * @reopen_queue.
547
- */
548
- void (*bdrv_child_perm)(BlockDriverState *bs, BdrvChild *c,
549
- BdrvChildRole role,
550
- BlockReopenQueue *reopen_queue,
551
- uint64_t parent_perm, uint64_t parent_shared,
552
- uint64_t *nperm, uint64_t *nshared);
553
-
554
bool (*bdrv_supports_persistent_dirty_bitmap)(BlockDriverState *bs);
555
bool (*bdrv_co_can_store_new_dirty_bitmap)(BlockDriverState *bs,
556
const char *name,
557
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
558
int (*bdrv_co_remove_persistent_dirty_bitmap)(BlockDriverState *bs,
559
const char *name,
560
Error **errp);
561
-
562
- /**
563
- * Register/unregister a buffer for I/O. For example, when the driver is
564
- * interested to know the memory areas that will later be used in iovs, so
565
- * that it can do IOMMU mapping with VFIO etc., in order to get better
566
- * performance. In the case of VFIO drivers, this callback is used to do
567
- * DMA mapping for hot buffers.
568
- */
569
- void (*bdrv_register_buf)(BlockDriverState *bs, void *host, size_t size);
570
- void (*bdrv_unregister_buf)(BlockDriverState *bs, void *host);
571
- QLIST_ENTRY(BlockDriver) list;
572
-
573
- /*
574
- * Pointer to a NULL-terminated array of names of strong options
575
- * that can be specified for bdrv_open(). A strong option is one
576
- * that changes the data of a BDS.
577
- * If this pointer is NULL, the array is considered empty.
578
- * "filename" and "driver" are always considered strong.
579
- */
580
- const char *const *strong_runtime_opts;
581
};
582
583
static inline bool block_driver_can_compress(BlockDriver *drv)
584
--
585
2.35.1
diff view generated by jsdifflib
New patch
1
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
1
2
3
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
4
Message-Id: <20220303151616.325444-27-eesposit@redhat.com>
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
---
7
block.c | 17 +++++++++++++++++
8
block/create.c | 2 ++
9
2 files changed, 19 insertions(+)
10
11
diff --git a/block.c b/block.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/block.c
14
+++ b/block.c
15
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn bdrv_create_co_entry(void *opaque)
16
17
CreateCo *cco = opaque;
18
assert(cco->drv);
19
+ GLOBAL_STATE_CODE();
20
21
ret = cco->drv->bdrv_co_create_opts(cco->drv,
22
cco->filename, cco->opts, &local_err);
23
@@ -XXX,XX +XXX,XX @@ int refresh_total_sectors(BlockDriverState *bs, int64_t hint)
24
static void bdrv_join_options(BlockDriverState *bs, QDict *options,
25
QDict *old_options)
26
{
27
+ GLOBAL_STATE_CODE();
28
if (bs->drv && bs->drv->bdrv_join_options) {
29
bs->drv->bdrv_join_options(options, old_options);
30
} else {
31
@@ -XXX,XX +XXX,XX @@ static int bdrv_open_driver(BlockDriverState *bs, BlockDriver *drv,
32
{
33
Error *local_err = NULL;
34
int i, ret;
35
+ GLOBAL_STATE_CODE();
36
37
bdrv_assign_node_name(bs, node_name, &local_err);
38
if (local_err) {
39
@@ -XXX,XX +XXX,XX @@ static int bdrv_fill_options(QDict **options, const char *filename,
40
BlockDriver *drv = NULL;
41
Error *local_err = NULL;
42
43
+ GLOBAL_STATE_CODE();
44
+
45
/*
46
* Caution: while qdict_get_try_str() is fine, getting non-string
47
* types would require more care. When @options come from
48
@@ -XXX,XX +XXX,XX @@ static void bdrv_child_perm(BlockDriverState *bs, BlockDriverState *child_bs,
49
uint64_t *nperm, uint64_t *nshared)
50
{
51
assert(bs->drv && bs->drv->bdrv_child_perm);
52
+ GLOBAL_STATE_CODE();
53
bs->drv->bdrv_child_perm(bs, c, role, reopen_queue,
54
parent_perm, parent_shared,
55
nperm, nshared);
56
@@ -XXX,XX +XXX,XX @@ static void bdrv_drv_set_perm_commit(void *opaque)
57
{
58
BlockDriverState *bs = opaque;
59
uint64_t cumulative_perms, cumulative_shared_perms;
60
+ GLOBAL_STATE_CODE();
61
62
if (bs->drv->bdrv_set_perm) {
63
bdrv_get_cumulative_perm(bs, &cumulative_perms,
64
@@ -XXX,XX +XXX,XX @@ static void bdrv_drv_set_perm_commit(void *opaque)
65
static void bdrv_drv_set_perm_abort(void *opaque)
66
{
67
BlockDriverState *bs = opaque;
68
+ GLOBAL_STATE_CODE();
69
70
if (bs->drv->bdrv_abort_perm_update) {
71
bs->drv->bdrv_abort_perm_update(bs);
72
@@ -XXX,XX +XXX,XX @@ static int bdrv_drv_set_perm(BlockDriverState *bs, uint64_t perm,
73
uint64_t shared_perm, Transaction *tran,
74
Error **errp)
75
{
76
+ GLOBAL_STATE_CODE();
77
if (!bs->drv) {
78
return 0;
79
}
80
@@ -XXX,XX +XXX,XX @@ int bdrv_reopen_multiple(BlockReopenQueue *bs_queue, Error **errp)
81
82
assert(qemu_get_current_aio_context() == qemu_get_aio_context());
83
assert(bs_queue != NULL);
84
+ GLOBAL_STATE_CODE();
85
86
QTAILQ_FOREACH(bs_entry, bs_queue, entry) {
87
ctx = bdrv_get_aio_context(bs_entry->state.bs);
88
@@ -XXX,XX +XXX,XX @@ static int bdrv_reopen_prepare(BDRVReopenState *reopen_state,
89
90
assert(reopen_state != NULL);
91
assert(reopen_state->bs->drv != NULL);
92
+ GLOBAL_STATE_CODE();
93
drv = reopen_state->bs->drv;
94
95
/* This function and each driver's bdrv_reopen_prepare() remove
96
@@ -XXX,XX +XXX,XX @@ static void bdrv_reopen_commit(BDRVReopenState *reopen_state)
97
bs = reopen_state->bs;
98
drv = bs->drv;
99
assert(drv != NULL);
100
+ GLOBAL_STATE_CODE();
101
102
/* If there are any driver level actions to take */
103
if (drv->bdrv_reopen_commit) {
104
@@ -XXX,XX +XXX,XX @@ static void bdrv_reopen_abort(BDRVReopenState *reopen_state)
105
assert(reopen_state != NULL);
106
drv = reopen_state->bs->drv;
107
assert(drv != NULL);
108
+ GLOBAL_STATE_CODE();
109
110
if (drv->bdrv_reopen_abort) {
111
drv->bdrv_reopen_abort(reopen_state);
112
@@ -XXX,XX +XXX,XX @@ static int bdrv_inactivate_recurse(BlockDriverState *bs)
113
int ret;
114
uint64_t cumulative_perms, cumulative_shared_perms;
115
116
+ GLOBAL_STATE_CODE();
117
+
118
if (!bs->drv) {
119
return -ENOMEDIUM;
120
}
121
@@ -XXX,XX +XXX,XX @@ static void bdrv_detach_aio_context(BlockDriverState *bs)
122
BdrvAioNotifier *baf, *baf_tmp;
123
124
assert(!bs->walking_aio_notifiers);
125
+ GLOBAL_STATE_CODE();
126
bs->walking_aio_notifiers = true;
127
QLIST_FOREACH_SAFE(baf, &bs->aio_notifiers, list, baf_tmp) {
128
if (baf->deleted) {
129
@@ -XXX,XX +XXX,XX @@ static void bdrv_attach_aio_context(BlockDriverState *bs,
130
AioContext *new_context)
131
{
132
BdrvAioNotifier *ban, *ban_tmp;
133
+ GLOBAL_STATE_CODE();
134
135
if (bs->quiesce_counter) {
136
aio_disable_external(new_context);
137
diff --git a/block/create.c b/block/create.c
138
index XXXXXXX..XXXXXXX 100644
139
--- a/block/create.c
140
+++ b/block/create.c
141
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn blockdev_create_run(Job *job, Error **errp)
142
BlockdevCreateJob *s = container_of(job, BlockdevCreateJob, common);
143
int ret;
144
145
+ GLOBAL_STATE_CODE();
146
+
147
job_progress_set_remaining(&s->common, 1);
148
ret = s->drv->bdrv_co_create(s->opts, errp);
149
job_progress_update(&s->common, 1);
150
--
151
2.35.1
diff view generated by jsdifflib
New patch
1
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
1
2
3
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
4
Message-Id: <20220303151616.325444-28-eesposit@redhat.com>
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
---
7
include/block/block_int-common.h | 81 ++++++++++++++++++--------------
8
1 file changed, 47 insertions(+), 34 deletions(-)
9
10
diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h
11
index XXXXXXX..XXXXXXX 100644
12
--- a/include/block/block_int-common.h
13
+++ b/include/block/block_int-common.h
14
@@ -XXX,XX +XXX,XX @@ struct BdrvChildClass {
15
*/
16
bool parent_is_bds;
17
18
+ /*
19
+ * Global state (GS) API. These functions run under the BQL.
20
+ *
21
+ * See include/block/block-global-state.h for more information about
22
+ * the GS API.
23
+ */
24
void (*inherit_options)(BdrvChildRole role, bool parent_is_format,
25
int *child_flags, QDict *child_options,
26
int parent_flags, QDict *parent_options);
27
-
28
void (*change_media)(BdrvChild *child, bool load);
29
- void (*resize)(BdrvChild *child);
30
-
31
- /*
32
- * Returns a name that is supposedly more useful for human users than the
33
- * node name for identifying the node in question (in particular, a BB
34
- * name), or NULL if the parent can't provide a better name.
35
- */
36
- const char *(*get_name)(BdrvChild *child);
37
38
/*
39
* Returns a malloced string that describes the parent of the child for a
40
@@ -XXX,XX +XXX,XX @@ struct BdrvChildClass {
41
*/
42
char *(*get_parent_desc)(BdrvChild *child);
43
44
+ /*
45
+ * Notifies the parent that the child has been activated/inactivated (e.g.
46
+ * when migration is completing) and it can start/stop requesting
47
+ * permissions and doing I/O on it.
48
+ */
49
+ void (*activate)(BdrvChild *child, Error **errp);
50
+ int (*inactivate)(BdrvChild *child);
51
+
52
+ void (*attach)(BdrvChild *child);
53
+ void (*detach)(BdrvChild *child);
54
+
55
+ /*
56
+ * Notifies the parent that the filename of its child has changed (e.g.
57
+ * because the direct child was removed from the backing chain), so that it
58
+ * can update its reference.
59
+ */
60
+ int (*update_filename)(BdrvChild *child, BlockDriverState *new_base,
61
+ const char *filename, Error **errp);
62
+
63
+ bool (*can_set_aio_ctx)(BdrvChild *child, AioContext *ctx,
64
+ GSList **ignore, Error **errp);
65
+ void (*set_aio_ctx)(BdrvChild *child, AioContext *ctx, GSList **ignore);
66
+
67
+ AioContext *(*get_parent_aio_context)(BdrvChild *child);
68
+
69
+ /*
70
+ * I/O API functions. These functions are thread-safe.
71
+ *
72
+ * See include/block/block-io.h for more information about
73
+ * the I/O API.
74
+ */
75
+
76
+ void (*resize)(BdrvChild *child);
77
+
78
+ /*
79
+ * Returns a name that is supposedly more useful for human users than the
80
+ * node name for identifying the node in question (in particular, a BB
81
+ * name), or NULL if the parent can't provide a better name.
82
+ */
83
+ const char *(*get_name)(BdrvChild *child);
84
+
85
/*
86
* If this pair of functions is implemented, the parent doesn't issue new
87
* requests after returning from .drained_begin() until .drained_end() is
88
@@ -XXX,XX +XXX,XX @@ struct BdrvChildClass {
89
* activity on the child has stopped.
90
*/
91
bool (*drained_poll)(BdrvChild *child);
92
-
93
- /*
94
- * Notifies the parent that the child has been activated/inactivated (e.g.
95
- * when migration is completing) and it can start/stop requesting
96
- * permissions and doing I/O on it.
97
- */
98
- void (*activate)(BdrvChild *child, Error **errp);
99
- int (*inactivate)(BdrvChild *child);
100
-
101
- void (*attach)(BdrvChild *child);
102
- void (*detach)(BdrvChild *child);
103
-
104
- /*
105
- * Notifies the parent that the filename of its child has changed (e.g.
106
- * because the direct child was removed from the backing chain), so that it
107
- * can update its reference.
108
- */
109
- int (*update_filename)(BdrvChild *child, BlockDriverState *new_base,
110
- const char *filename, Error **errp);
111
-
112
- bool (*can_set_aio_ctx)(BdrvChild *child, AioContext *ctx,
113
- GSList **ignore, Error **errp);
114
- void (*set_aio_ctx)(BdrvChild *child, AioContext *ctx, GSList **ignore);
115
-
116
- AioContext *(*get_parent_aio_context)(BdrvChild *child);
117
};
118
119
extern const BdrvChildClass child_of_bds;
120
--
121
2.35.1
diff view generated by jsdifflib
New patch
1
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
1
2
3
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
4
Message-Id: <20220303151616.325444-29-eesposit@redhat.com>
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
---
7
block.c | 10 +++++++++-
8
1 file changed, 9 insertions(+), 1 deletion(-)
9
10
diff --git a/block.c b/block.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/block.c
13
+++ b/block.c
14
@@ -XXX,XX +XXX,XX @@ const BdrvChildClass child_of_bds = {
15
16
AioContext *bdrv_child_get_parent_aio_context(BdrvChild *c)
17
{
18
- IO_CODE();
19
+ GLOBAL_STATE_CODE();
20
return c->klass->get_parent_aio_context(c);
21
}
22
23
@@ -XXX,XX +XXX,XX @@ bool bdrv_is_writable(BlockDriverState *bs)
24
25
static char *bdrv_child_user_desc(BdrvChild *c)
26
{
27
+ GLOBAL_STATE_CODE();
28
return c->klass->get_parent_desc(c);
29
}
30
31
@@ -XXX,XX +XXX,XX @@ static void bdrv_replace_child_noperm(BdrvChild **childp,
32
33
assert(!child->frozen);
34
assert(old_bs != new_bs);
35
+ GLOBAL_STATE_CODE();
36
37
if (old_bs && new_bs) {
38
assert(bdrv_get_aio_context(old_bs) == bdrv_get_aio_context(new_bs));
39
@@ -XXX,XX +XXX,XX @@ static void bdrv_attach_child_common_abort(void *opaque)
40
BdrvChild *child = *s->child;
41
BlockDriverState *bs = child->bs;
42
43
+ GLOBAL_STATE_CODE();
44
/*
45
* Pass free_empty_child=false, because we still need the child
46
* for the AioContext operations on the parent below; those
47
@@ -XXX,XX +XXX,XX @@ void bdrv_unref_child(BlockDriverState *parent, BdrvChild *child)
48
static void bdrv_parent_cb_change_media(BlockDriverState *bs, bool load)
49
{
50
BdrvChild *c;
51
+ GLOBAL_STATE_CODE();
52
QLIST_FOREACH(c, &bs->parents, next_parent) {
53
if (c->klass->change_media) {
54
c->klass->change_media(c, load);
55
@@ -XXX,XX +XXX,XX @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
56
57
assert(!child_class || !flags);
58
assert(!child_class == !parent);
59
+ GLOBAL_STATE_CODE();
60
61
if (reference) {
62
bool options_non_empty = options ? qdict_size(options) : false;
63
@@ -XXX,XX +XXX,XX @@ static BlockReopenQueue *bdrv_reopen_queue_child(BlockReopenQueue *bs_queue,
64
* important to avoid graph changes between the recursive queuing here and
65
* bdrv_reopen_multiple(). */
66
assert(bs->quiesce_counter > 0);
67
+ GLOBAL_STATE_CODE();
68
69
if (bs_queue == NULL) {
70
bs_queue = g_new0(BlockReopenQueue, 1);
71
@@ -XXX,XX +XXX,XX @@ void bdrv_set_aio_context_ignore(BlockDriverState *bs,
72
BdrvChild *child, *parent;
73
74
g_assert(qemu_get_current_aio_context() == qemu_get_aio_context());
75
+ GLOBAL_STATE_CODE();
76
77
if (old_context == new_context) {
78
return;
79
@@ -XXX,XX +XXX,XX @@ void bdrv_set_aio_context_ignore(BlockDriverState *bs,
80
static bool bdrv_parent_can_set_aio_context(BdrvChild *c, AioContext *ctx,
81
GSList **ignore, Error **errp)
82
{
83
+ GLOBAL_STATE_CODE();
84
if (g_slist_find(*ignore, c)) {
85
return true;
86
}
87
--
88
2.35.1
diff view generated by jsdifflib
1
The BDRV_REQ_ZERO_WRITE is currently implemented in a way that first the
1
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
2
image is possibly preallocated and then the zero flag is added to all
3
clusters. This means that a copy-on-write operation may be needed when
4
writing to these clusters, despite having used preallocation, negating
5
one of the major benefits of preallocation.
6
2
7
Instead, try to forward the BDRV_REQ_ZERO_WRITE to the protocol driver,
3
Assertions in the callers of the function pointrs are already
8
and if the protocol driver can ensure that the new area reads as zeros,
4
added by previous patches.
9
we can skip setting the zero flag in the qcow2 layer.
10
5
11
Unfortunately, the same approach doesn't work for metadata
6
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
12
preallocation, so we'll still set the zero flag there.
7
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
13
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
14
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
Message-Id: <20220303151616.325444-30-eesposit@redhat.com>
15
Reviewed-by: Max Reitz <mreitz@redhat.com>
16
Message-Id: <20200424142701.67053-1-kwolf@redhat.com>
17
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
18
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
19
---
11
---
20
block/qcow2.c | 22 +++++++++++++++++++---
12
include/sysemu/block-backend-common.h | 28 ++++++++++++++++++++++-----
21
tests/qemu-iotests/274.out | 4 ++--
13
1 file changed, 23 insertions(+), 5 deletions(-)
22
2 files changed, 21 insertions(+), 5 deletions(-)
23
14
24
diff --git a/block/qcow2.c b/block/qcow2.c
15
diff --git a/include/sysemu/block-backend-common.h b/include/sysemu/block-backend-common.h
25
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
26
--- a/block/qcow2.c
17
--- a/include/sysemu/block-backend-common.h
27
+++ b/block/qcow2.c
18
+++ b/include/sysemu/block-backend-common.h
28
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
19
@@ -XXX,XX +XXX,XX @@
29
/* Allocate the data area */
20
30
new_file_size = allocation_start +
21
/* Callbacks for block device models */
31
nb_new_data_clusters * s->cluster_size;
22
typedef struct BlockDevOps {
32
- /* Image file grows, so @exact does not matter */
23
+
33
- ret = bdrv_co_truncate(bs->file, new_file_size, false, prealloc, 0,
24
+ /*
34
- errp);
25
+ * Global state (GS) API. These functions run under the BQL.
35
+ /*
26
+ *
36
+ * Image file grows, so @exact does not matter.
27
+ * See include/block/block-global-state.h for more information about
37
+ *
28
+ * the GS API.
38
+ * If we need to zero out the new area, try first whether the protocol
29
+ */
39
+ * driver can already take care of this.
30
+
40
+ */
31
/*
41
+ if (flags & BDRV_REQ_ZERO_WRITE) {
32
* Runs when virtual media changed (monitor commands eject, change)
42
+ ret = bdrv_co_truncate(bs->file, new_file_size, false, prealloc,
33
* Argument load is true on load and false on eject.
43
+ BDRV_REQ_ZERO_WRITE, NULL);
34
@@ -XXX,XX +XXX,XX @@ typedef struct BlockDevOps {
44
+ if (ret >= 0) {
35
* true, even if they do not support eject requests.
45
+ flags &= ~BDRV_REQ_ZERO_WRITE;
36
*/
46
+ }
37
void (*eject_request_cb)(void *opaque, bool force);
47
+ } else {
38
- /*
48
+ ret = -1;
39
- * Is the virtual tray open?
49
+ }
40
- * Device models implement this only when the device has a tray.
50
+ if (ret < 0) {
41
- */
51
+ ret = bdrv_co_truncate(bs->file, new_file_size, false, prealloc, 0,
42
- bool (*is_tray_open)(void *opaque);
52
+ errp);
43
+
53
+ }
44
/*
54
if (ret < 0) {
45
* Is the virtual medium locked into the device?
55
error_prepend(errp, "Failed to resize underlying file: ");
46
* Device models implement this only when device has such a lock.
56
qcow2_free_clusters(bs, allocation_start,
47
*/
57
diff --git a/tests/qemu-iotests/274.out b/tests/qemu-iotests/274.out
48
bool (*is_medium_locked)(void *opaque);
58
index XXXXXXX..XXXXXXX 100644
49
+
59
--- a/tests/qemu-iotests/274.out
50
+ /*
60
+++ b/tests/qemu-iotests/274.out
51
+ * I/O API functions. These functions are thread-safe.
61
@@ -XXX,XX +XXX,XX @@ read 65536/65536 bytes at offset 9437184
52
+ *
62
10 MiB (0xa00000) bytes allocated at offset 5 MiB (0x500000)
53
+ * See include/block/block-io.h for more information about
63
54
+ * the I/O API.
64
[{ "start": 0, "length": 5242880, "depth": 1, "zero": true, "data": false},
55
+ */
65
-{ "start": 5242880, "length": 10485760, "depth": 0, "zero": true, "data": false, "offset": 327680}]
56
+
66
+{ "start": 5242880, "length": 10485760, "depth": 0, "zero": false, "data": true, "offset": 327680}]
57
+ /*
67
58
+ * Is the virtual tray open?
68
=== preallocation=full ===
59
+ * Device models implement this only when the device has a tray.
69
Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=16777216 cluster_size=65536 lazy_refcounts=off refcount_bits=16
60
+ */
70
@@ -XXX,XX +XXX,XX @@ read 65536/65536 bytes at offset 11534336
61
+ bool (*is_tray_open)(void *opaque);
71
4 MiB (0x400000) bytes allocated at offset 8 MiB (0x800000)
62
+
72
63
/*
73
[{ "start": 0, "length": 8388608, "depth": 1, "zero": true, "data": false},
64
* Runs when the size changed (e.g. monitor command block_resize)
74
-{ "start": 8388608, "length": 4194304, "depth": 0, "zero": true, "data": false, "offset": 327680}]
65
*/
75
+{ "start": 8388608, "length": 4194304, "depth": 0, "zero": false, "data": true, "offset": 327680}]
76
77
=== preallocation=off ===
78
Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=393216 cluster_size=65536 lazy_refcounts=off refcount_bits=16
79
--
66
--
80
2.25.3
67
2.35.1
81
68
82
69
diff view generated by jsdifflib
New patch
1
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
1
2
3
The job API will be handled separately in another serie.
4
5
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
6
Message-Id: <20220303151616.325444-31-eesposit@redhat.com>
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
---
9
include/qemu/job.h | 22 ++++++++++++++++++++++
10
1 file changed, 22 insertions(+)
11
12
diff --git a/include/qemu/job.h b/include/qemu/job.h
13
index XXXXXXX..XXXXXXX 100644
14
--- a/include/qemu/job.h
15
+++ b/include/qemu/job.h
16
@@ -XXX,XX +XXX,XX @@ typedef struct Job {
17
* Callbacks and other information about a Job driver.
18
*/
19
struct JobDriver {
20
+
21
+ /*
22
+ * These fields are initialized when this object is created,
23
+ * and are never changed afterwards
24
+ */
25
+
26
/** Derived Job struct size */
27
size_t instance_size;
28
29
@@ -XXX,XX +XXX,XX @@ struct JobDriver {
30
* aborted. If it returns zero, the job moves into the WAITING state. If it
31
* is the last job to complete in its transaction, all jobs in the
32
* transaction move from WAITING to PENDING.
33
+ *
34
+ * This callback must be run in the job's context.
35
*/
36
int coroutine_fn (*run)(Job *job, Error **errp);
37
38
+ /*
39
+ * Functions run without regard to the BQL that may run in any
40
+ * arbitrary thread. These functions do not need to be thread-safe
41
+ * because the caller ensures that they are invoked from one
42
+ * thread at time.
43
+ */
44
+
45
/**
46
* If the callback is not NULL, it will be invoked when the job transitions
47
* into the paused state. Paused jobs must not perform any asynchronous
48
@@ -XXX,XX +XXX,XX @@ struct JobDriver {
49
*/
50
void coroutine_fn (*resume)(Job *job);
51
52
+ /*
53
+ * Global state (GS) API. These functions run under the BQL.
54
+ *
55
+ * See include/block/block-global-state.h for more information about
56
+ * the GS API.
57
+ */
58
+
59
/**
60
* Called when the job is resumed by the user (i.e. user_paused becomes
61
* false). .user_resume is called before .resume.
62
--
63
2.35.1
diff view generated by jsdifflib
1
For regular files, we always get BDRV_REQ_ZERO_WRITE behaviour from the
1
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
2
OS, so we can advertise the flag and just ignore it.
3
2
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
3
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
5
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
4
Message-Id: <20220303151616.325444-32-eesposit@redhat.com>
6
Reviewed-by: Alberto Garcia <berto@igalia.com>
7
Reviewed-by: Max Reitz <mreitz@redhat.com>
8
Message-Id: <20200424125448.63318-7-kwolf@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
6
---
11
block/file-posix.c | 4 ++++
7
job.c | 10 ++++++++++
12
1 file changed, 4 insertions(+)
8
1 file changed, 10 insertions(+)
13
9
14
diff --git a/block/file-posix.c b/block/file-posix.c
10
diff --git a/job.c b/job.c
15
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
16
--- a/block/file-posix.c
12
--- a/job.c
17
+++ b/block/file-posix.c
13
+++ b/job.c
18
@@ -XXX,XX +XXX,XX @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
14
@@ -XXX,XX +XXX,XX @@ void job_ref(Job *job)
19
#endif
15
20
16
void job_unref(Job *job)
21
bs->supported_zero_flags = BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK;
17
{
22
+ if (S_ISREG(st.st_mode)) {
18
+ GLOBAL_STATE_CODE();
23
+ /* When extending regular files, we get zeros from the OS */
19
+
24
+ bs->supported_truncate_flags = BDRV_REQ_ZERO_WRITE;
20
if (--job->refcnt == 0) {
25
+ }
21
assert(job->status == JOB_STATUS_NULL);
26
ret = 0;
22
assert(!timer_pending(&job->sleep_timer));
27
fail:
23
@@ -XXX,XX +XXX,XX @@ bool job_user_paused(Job *job)
28
if (filename && (bdrv_flags & BDRV_O_TEMPORARY)) {
24
void job_user_resume(Job *job, Error **errp)
25
{
26
assert(job);
27
+ GLOBAL_STATE_CODE();
28
if (!job->user_paused || job->pause_count <= 0) {
29
error_setg(errp, "Can't resume a job that was not paused");
30
return;
31
@@ -XXX,XX +XXX,XX @@ static void job_update_rc(Job *job)
32
static void job_commit(Job *job)
33
{
34
assert(!job->ret);
35
+ GLOBAL_STATE_CODE();
36
if (job->driver->commit) {
37
job->driver->commit(job);
38
}
39
@@ -XXX,XX +XXX,XX @@ static void job_commit(Job *job)
40
static void job_abort(Job *job)
41
{
42
assert(job->ret);
43
+ GLOBAL_STATE_CODE();
44
if (job->driver->abort) {
45
job->driver->abort(job);
46
}
47
@@ -XXX,XX +XXX,XX @@ static void job_abort(Job *job)
48
49
static void job_clean(Job *job)
50
{
51
+ GLOBAL_STATE_CODE();
52
if (job->driver->clean) {
53
job->driver->clean(job);
54
}
55
@@ -XXX,XX +XXX,XX @@ static int job_finalize_single(Job *job)
56
57
static void job_cancel_async(Job *job, bool force)
58
{
59
+ GLOBAL_STATE_CODE();
60
if (job->driver->cancel) {
61
force = job->driver->cancel(job, force);
62
} else {
63
@@ -XXX,XX +XXX,XX @@ static void job_completed_txn_abort(Job *job)
64
65
static int job_prepare(Job *job)
66
{
67
+ GLOBAL_STATE_CODE();
68
if (job->ret == 0 && job->driver->prepare) {
69
job->ret = job->driver->prepare(job);
70
job_update_rc(job);
71
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn job_co_entry(void *opaque)
72
Job *job = opaque;
73
74
assert(job && job->driver && job->driver->run);
75
+ assert(job->aio_context == qemu_get_current_aio_context());
76
job_pause_point(job);
77
job->ret = job->driver->run(job, &job->err);
78
job->deferred_to_main_loop = true;
79
@@ -XXX,XX +XXX,XX @@ void job_complete(Job *job, Error **errp)
80
{
81
/* Should not be reachable via external interface for internal jobs */
82
assert(job->id);
83
+ GLOBAL_STATE_CODE();
84
if (job_apply_verb(job, JOB_VERB_COMPLETE, errp)) {
85
return;
86
}
29
--
87
--
30
2.25.3
88
2.35.1
31
32
diff view generated by jsdifflib
1
When extending the size of an image that has a backing file larger than
1
From: Hanna Reitz <hreitz@redhat.com>
2
its old size, make sure that the backing file data doesn't become
3
visible in the guest, but the added area is properly zeroed out.
4
2
5
Consider the following scenario where the overlay is shorter than its
3
bdrv_refresh_limits() recurses down to the node's children. That does
6
backing file:
4
not seem necessary: When we refresh limits on some node, and then
5
recurse down and were to change one of its children's BlockLimits, then
6
that would mean we noticed the changed limits by pure chance. The fact
7
that we refresh the parent's limits has nothing to do with it, so the
8
reason for the change probably happened before this point in time, and
9
we should have refreshed the limits then.
7
10
8
base.qcow2: AAAAAAAA
11
Consequently, we should actually propagate block limits changes upwards,
9
overlay.qcow2: BBBB
12
not downwards.  That is a separate and pre-existing issue, though, and
13
so will not be addressed in this patch.
10
14
11
When resizing (extending) overlay.qcow2, the new blocks should not stay
15
The problem with recursing is that bdrv_refresh_limits() is not atomic.
12
unallocated and make the additional As from base.qcow2 visible like
16
It begins with zeroing BDS.bl, and only then sets proper, valid limits.
13
before this patch, but zeros should be read.
17
If we do not drain all nodes whose limits are refreshed, then concurrent
18
I/O requests can encounter invalid request_alignment values and crash
19
qemu. Therefore, a recursing bdrv_refresh_limits() requires the whole
20
subtree to be drained, which is currently not ensured by most callers.
14
21
15
A similar case happens with the various variants of a commit job when an
22
A non-recursive bdrv_refresh_limits() only requires the node in question
16
intermediate file is short (- for unallocated):
23
to not receive I/O requests, and this is done by most callers in some
24
way or another:
25
- bdrv_open_driver() deals with a new node with no parents yet
26
- bdrv_set_file_or_backing_noperm() acts on a drained node
27
- bdrv_reopen_commit() acts only on drained nodes
28
- bdrv_append() should in theory require the node to be drained; in
29
practice most callers just lock the AioContext, which should at least
30
be enough to prevent concurrent I/O requests from accessing invalid
31
limits
17
32
18
base.qcow2: A-A-AAAA
33
So we can resolve the bug by making bdrv_refresh_limits() non-recursive.
19
mid.qcow2: BB-B
20
top.qcow2: C--C--C-
21
34
22
After commit top.qcow2 to mid.qcow2, the following happens:
35
Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=1879437
23
36
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
24
mid.qcow2: CB-C00C0 (correct result)
37
Reviewed-by: Eric Blake <eblake@redhat.com>
25
mid.qcow2: CB-C--C- (before this fix)
38
Message-Id: <20220216105355.30729-2-hreitz@redhat.com>
26
39
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
27
Without the fix, blocks that previously read as zeros on top.qcow2
28
suddenly turn into A.
29
30
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
31
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
32
Message-Id: <20200424125448.63318-8-kwolf@redhat.com>
33
Reviewed-by: Max Reitz <mreitz@redhat.com>
34
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
40
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
35
---
41
---
36
block/io.c | 25 +++++++++++++++++++++++++
42
block/io.c | 4 ----
37
1 file changed, 25 insertions(+)
43
1 file changed, 4 deletions(-)
38
44
39
diff --git a/block/io.c b/block/io.c
45
diff --git a/block/io.c b/block/io.c
40
index XXXXXXX..XXXXXXX 100644
46
index XXXXXXX..XXXXXXX 100644
41
--- a/block/io.c
47
--- a/block/io.c
42
+++ b/block/io.c
48
+++ b/block/io.c
43
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact,
49
@@ -XXX,XX +XXX,XX @@ void bdrv_refresh_limits(BlockDriverState *bs, Transaction *tran, Error **errp)
44
goto out;
50
QLIST_FOREACH(c, &bs->children, next) {
45
}
51
if (c->role & (BDRV_CHILD_DATA | BDRV_CHILD_FILTERED | BDRV_CHILD_COW))
46
52
{
47
+ /*
53
- bdrv_refresh_limits(c->bs, tran, errp);
48
+ * If the image has a backing file that is large enough that it would
54
- if (*errp) {
49
+ * provide data for the new area, we cannot leave it unallocated because
55
- return;
50
+ * then the backing file content would become visible. Instead, zero-fill
56
- }
51
+ * the new area.
57
bdrv_merge_limits(&bs->bl, &c->bs->bl);
52
+ *
58
have_limits = true;
53
+ * Note that if the image has a backing file, but was opened without the
59
}
54
+ * backing file, taking care of keeping things consistent with that backing
55
+ * file is the user's responsibility.
56
+ */
57
+ if (new_bytes && bs->backing) {
58
+ int64_t backing_len;
59
+
60
+ backing_len = bdrv_getlength(backing_bs(bs));
61
+ if (backing_len < 0) {
62
+ ret = backing_len;
63
+ error_setg_errno(errp, -ret, "Could not get backing file size");
64
+ goto out;
65
+ }
66
+
67
+ if (backing_len > old_size) {
68
+ flags |= BDRV_REQ_ZERO_WRITE;
69
+ }
70
+ }
71
+
72
if (drv->bdrv_co_truncate) {
73
if (flags & ~bs->supported_truncate_flags) {
74
error_setg(errp, "Block driver does not support requested flags");
75
--
60
--
76
2.25.3
61
2.35.1
77
62
78
63
diff view generated by jsdifflib
1
We want to keep TEST_IMG for the full path of the main test image, but
1
From: Hanna Reitz <hreitz@redhat.com>
2
filter_testfiles() must be called for other test images before replacing
3
other things like the image format because the test directory path could
4
contain the format as a substring.
5
2
6
Insert a filter_testfiles() call between both.
3
Add a parameter to optionally open a QMP connection when creating a
4
QemuStorageDaemon instance.
7
5
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
9
Reviewed-by: Max Reitz <mreitz@redhat.com>
7
Message-Id: <20220216105355.30729-3-hreitz@redhat.com>
10
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
8
Reviewed-by: Eric Blake <eblake@redhat.com>
11
Message-Id: <20200424125448.63318-9-kwolf@redhat.com>
9
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
---
11
---
14
tests/qemu-iotests/iotests.py | 5 +++--
12
tests/qemu-iotests/iotests.py | 32 +++++++++++++++++++++++++++++++-
15
1 file changed, 3 insertions(+), 2 deletions(-)
13
1 file changed, 31 insertions(+), 1 deletion(-)
16
14
17
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
15
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
18
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
19
--- a/tests/qemu-iotests/iotests.py
17
--- a/tests/qemu-iotests/iotests.py
20
+++ b/tests/qemu-iotests/iotests.py
18
+++ b/tests/qemu-iotests/iotests.py
21
@@ -XXX,XX +XXX,XX @@ def filter_img_info(output, filename):
19
@@ -XXX,XX +XXX,XX @@
22
for line in output.split('\n'):
20
23
if 'disk size' in line or 'actual-size' in line:
21
from qemu.machine import qtest
24
continue
22
from qemu.qmp import QMPMessage
25
- line = line.replace(filename, 'TEST_IMG') \
23
+from qemu.aqmp.legacy import QEMUMonitorProtocol
26
- .replace(imgfmt, 'IMGFMT')
24
27
+ line = line.replace(filename, 'TEST_IMG')
25
# Use this logger for logging messages directly from the iotests module
28
+ line = filter_testfiles(line)
26
logger = logging.getLogger('qemu.iotests')
29
+ line = line.replace(imgfmt, 'IMGFMT')
27
@@ -XXX,XX +XXX,XX @@ def cmd(self, cmd):
30
line = re.sub('iters: [0-9]+', 'iters: XXX', line)
28
31
line = re.sub('uuid: [-a-f0-9]+', 'uuid: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX', line)
29
32
line = re.sub('cid: [0-9]+', 'cid: XXXXXXXXXX', line)
30
class QemuStorageDaemon:
31
- def __init__(self, *args: str, instance_id: str = 'a'):
32
+ _qmp: Optional[QEMUMonitorProtocol] = None
33
+ _qmpsock: Optional[str] = None
34
+ # Python < 3.8 would complain if this type were not a string literal
35
+ # (importing `annotations` from `__future__` would work; but not on <= 3.6)
36
+ _p: 'Optional[subprocess.Popen[bytes]]' = None
37
+
38
+ def __init__(self, *args: str, instance_id: str = 'a', qmp: bool = False):
39
assert '--pidfile' not in args
40
self.pidfile = os.path.join(test_dir, f'qsd-{instance_id}-pid')
41
all_args = [qsd_prog] + list(args) + ['--pidfile', self.pidfile]
42
43
+ if qmp:
44
+ self._qmpsock = os.path.join(sock_dir, f'qsd-{instance_id}.sock')
45
+ all_args += ['--chardev',
46
+ f'socket,id=qmp-sock,path={self._qmpsock}',
47
+ '--monitor', 'qmp-sock']
48
+
49
+ self._qmp = QEMUMonitorProtocol(self._qmpsock, server=True)
50
+
51
# Cannot use with here, we want the subprocess to stay around
52
# pylint: disable=consider-using-with
53
self._p = subprocess.Popen(all_args)
54
+ if self._qmp is not None:
55
+ self._qmp.accept()
56
while not os.path.exists(self.pidfile):
57
if self._p.poll() is not None:
58
cmd = ' '.join(all_args)
59
@@ -XXX,XX +XXX,XX @@ def __init__(self, *args: str, instance_id: str = 'a'):
60
61
assert self._pid == self._p.pid
62
63
+ def qmp(self, cmd: str, args: Optional[Dict[str, object]] = None) \
64
+ -> QMPMessage:
65
+ assert self._qmp is not None
66
+ return self._qmp.cmd(cmd, args)
67
+
68
def stop(self, kill_signal=15):
69
self._p.send_signal(kill_signal)
70
self._p.wait()
71
self._p = None
72
73
+ if self._qmp:
74
+ self._qmp.close()
75
+
76
+ if self._qmpsock is not None:
77
+ try:
78
+ os.remove(self._qmpsock)
79
+ except OSError:
80
+ pass
81
try:
82
os.remove(self.pidfile)
83
except OSError:
33
--
84
--
34
2.25.3
85
2.35.1
35
36
diff view generated by jsdifflib
1
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
1
From: Hanna Reitz <hreitz@redhat.com>
2
Message-Id: <20200424125448.63318-10-kwolf@redhat.com>
2
3
Reviewed-by: Max Reitz <mreitz@redhat.com>
3
Test the following scenario:
4
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
4
1. Some block node (null-co) attached to a user (here: NBD server) that
5
performs I/O and keeps the node in an I/O thread
6
2. Repeatedly run blockdev-add/blockdev-del to add/remove an overlay
7
to/from that node
8
9
Each blockdev-add triggers bdrv_refresh_limits(), and because
10
blockdev-add runs in the main thread, it does not stop the I/O requests.
11
I/O can thus happen while the limits are refreshed, and when such a
12
request sees a temporarily invalid block limit (e.g. alignment is 0),
13
this may easily crash qemu (or the storage daemon in this case).
14
15
The block layer needs to ensure that I/O requests to a node are paused
16
while that node's BlockLimits are refreshed.
17
18
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
19
Reviewed-by: Eric Blake <eblake@redhat.com>
20
Message-Id: <20220216105355.30729-4-hreitz@redhat.com>
21
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
22
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
---
23
---
7
tests/qemu-iotests/274 | 155 +++++++++++++++++++++
24
.../qemu-iotests/tests/graph-changes-while-io | 91 +++++++++++++++++++
8
tests/qemu-iotests/274.out | 268 +++++++++++++++++++++++++++++++++++++
25
.../tests/graph-changes-while-io.out | 5 +
9
tests/qemu-iotests/group | 1 +
26
2 files changed, 96 insertions(+)
10
3 files changed, 424 insertions(+)
27
create mode 100755 tests/qemu-iotests/tests/graph-changes-while-io
11
create mode 100755 tests/qemu-iotests/274
28
create mode 100644 tests/qemu-iotests/tests/graph-changes-while-io.out
12
create mode 100644 tests/qemu-iotests/274.out
13
29
14
diff --git a/tests/qemu-iotests/274 b/tests/qemu-iotests/274
30
diff --git a/tests/qemu-iotests/tests/graph-changes-while-io b/tests/qemu-iotests/tests/graph-changes-while-io
15
new file mode 100755
31
new file mode 100755
16
index XXXXXXX..XXXXXXX
32
index XXXXXXX..XXXXXXX
17
--- /dev/null
33
--- /dev/null
18
+++ b/tests/qemu-iotests/274
34
+++ b/tests/qemu-iotests/tests/graph-changes-while-io
19
@@ -XXX,XX +XXX,XX @@
35
@@ -XXX,XX +XXX,XX @@
20
+#!/usr/bin/env python3
36
+#!/usr/bin/env python3
37
+# group: rw
21
+#
38
+#
22
+# Copyright (C) 2019 Red Hat, Inc.
39
+# Test graph changes while I/O is happening
40
+#
41
+# Copyright (C) 2022 Red Hat, Inc.
23
+#
42
+#
24
+# This program is free software; you can redistribute it and/or modify
43
+# This program is free software; you can redistribute it and/or modify
25
+# it under the terms of the GNU General Public License as published by
44
+# it under the terms of the GNU General Public License as published by
26
+# the Free Software Foundation; either version 2 of the License, or
45
+# the Free Software Foundation; either version 2 of the License, or
27
+# (at your option) any later version.
46
+# (at your option) any later version.
...
...
32
+# GNU General Public License for more details.
51
+# GNU General Public License for more details.
33
+#
52
+#
34
+# You should have received a copy of the GNU General Public License
53
+# You should have received a copy of the GNU General Public License
35
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
54
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
36
+#
55
+#
37
+# Creator/Owner: Kevin Wolf <kwolf@redhat.com>
38
+#
39
+# Some tests for short backing files and short overlays
40
+
56
+
57
+import os
58
+from threading import Thread
41
+import iotests
59
+import iotests
42
+
60
+from iotests import imgfmt, qemu_img, qemu_img_create, QMPTestCase, \
43
+iotests.verify_image_format(supported_fmts=['qcow2'])
61
+ QemuStorageDaemon
44
+iotests.verify_platform(['linux'])
45
+
46
+size_short = 1 * 1024 * 1024
47
+size_long = 2 * 1024 * 1024
48
+size_diff = size_long - size_short
49
+
50
+def create_chain() -> None:
51
+ iotests.qemu_img_log('create', '-f', iotests.imgfmt, base,
52
+ str(size_long))
53
+ iotests.qemu_img_log('create', '-f', iotests.imgfmt, '-b', base, mid,
54
+ str(size_short))
55
+ iotests.qemu_img_log('create', '-f', iotests.imgfmt, '-b', mid, top,
56
+ str(size_long))
57
+
58
+ iotests.qemu_io_log('-c', 'write -P 1 0 %d' % size_long, base)
59
+
60
+def create_vm() -> iotests.VM:
61
+ vm = iotests.VM()
62
+ vm.add_blockdev('file,filename=%s,node-name=base-file' % base)
63
+ vm.add_blockdev('%s,file=base-file,node-name=base' % iotests.imgfmt)
64
+ vm.add_blockdev('file,filename=%s,node-name=mid-file' % mid)
65
+ vm.add_blockdev('%s,file=mid-file,node-name=mid,backing=base'
66
+ % iotests.imgfmt)
67
+ vm.add_drive(top, 'backing=mid,node-name=top')
68
+ return vm
69
+
70
+with iotests.FilePath('base') as base, \
71
+ iotests.FilePath('mid') as mid, \
72
+ iotests.FilePath('top') as top:
73
+
74
+ iotests.log('== Commit tests ==')
75
+
76
+ create_chain()
77
+
78
+ iotests.log('=== Check visible data ===')
79
+
80
+ iotests.qemu_io_log('-c', 'read -P 1 0 %d' % size_short, top)
81
+ iotests.qemu_io_log('-c', 'read -P 0 %d %d' % (size_short, size_diff), top)
82
+
83
+ iotests.log('=== Checking allocation status ===')
84
+
85
+ iotests.qemu_io_log('-c', 'alloc 0 %d' % size_short,
86
+ '-c', 'alloc %d %d' % (size_short, size_diff),
87
+ base)
88
+
89
+ iotests.qemu_io_log('-c', 'alloc 0 %d' % size_short,
90
+ '-c', 'alloc %d %d' % (size_short, size_diff),
91
+ mid)
92
+
93
+ iotests.qemu_io_log('-c', 'alloc 0 %d' % size_short,
94
+ '-c', 'alloc %d %d' % (size_short, size_diff),
95
+ top)
96
+
97
+ iotests.log('=== Checking map ===')
98
+
99
+ iotests.qemu_img_log('map', '--output=json', base)
100
+ iotests.qemu_img_log('map', '--output=human', base)
101
+ iotests.qemu_img_log('map', '--output=json', mid)
102
+ iotests.qemu_img_log('map', '--output=human', mid)
103
+ iotests.qemu_img_log('map', '--output=json', top)
104
+ iotests.qemu_img_log('map', '--output=human', top)
105
+
106
+ iotests.log('=== Testing qemu-img commit (top -> mid) ===')
107
+
108
+ iotests.qemu_img_log('commit', top)
109
+ iotests.img_info_log(mid)
110
+ iotests.qemu_io_log('-c', 'read -P 1 0 %d' % size_short, mid)
111
+ iotests.qemu_io_log('-c', 'read -P 0 %d %d' % (size_short, size_diff), mid)
112
+
113
+ iotests.log('=== Testing HMP commit (top -> mid) ===')
114
+
115
+ create_chain()
116
+ with create_vm() as vm:
117
+ vm.launch()
118
+ vm.qmp_log('human-monitor-command', command_line='commit drive0')
119
+
120
+ iotests.img_info_log(mid)
121
+ iotests.qemu_io_log('-c', 'read -P 1 0 %d' % size_short, mid)
122
+ iotests.qemu_io_log('-c', 'read -P 0 %d %d' % (size_short, size_diff), mid)
123
+
124
+ iotests.log('=== Testing QMP active commit (top -> mid) ===')
125
+
126
+ create_chain()
127
+ with create_vm() as vm:
128
+ vm.launch()
129
+ vm.qmp_log('block-commit', device='top', base_node='mid',
130
+ job_id='job0', auto_dismiss=False)
131
+ vm.run_job('job0', wait=5)
132
+
133
+ iotests.img_info_log(mid)
134
+ iotests.qemu_io_log('-c', 'read -P 1 0 %d' % size_short, mid)
135
+ iotests.qemu_io_log('-c', 'read -P 0 %d %d' % (size_short, size_diff), mid)
136
+
62
+
137
+
63
+
138
+ iotests.log('== Resize tests ==')
64
+top = os.path.join(iotests.test_dir, 'top.img')
65
+nbd_sock = os.path.join(iotests.sock_dir, 'nbd.sock')
139
+
66
+
140
+ # Use different sizes for different allocation modes:
141
+ #
142
+ # We want to have at least one test where 32 bit truncation in the size of
143
+ # the overlapping area becomes visible. This is covered by the
144
+ # prealloc='off' case (1G to 6G is an overlap of 5G).
145
+ #
146
+ # However, we can only do this for modes that don't preallocate data
147
+ # because otherwise we might run out of space on the test host.
148
+ #
149
+ # We also want to test some unaligned combinations.
150
+ for (prealloc, base_size, top_size_old, top_size_new, off) in [
151
+ ('off', '6G', '1G', '8G', '5G'),
152
+ ('metadata', '32G', '30G', '33G', '31G'),
153
+ ('falloc', '10M', '5M', '15M', '9M'),
154
+ ('full', '16M', '8M', '12M', '11M'),
155
+ ('off', '384k', '253k', '512k', '253k'),
156
+ ('off', '400k', '256k', '512k', '336k'),
157
+ ('off', '512k', '256k', '500k', '436k')]:
158
+
67
+
159
+ iotests.log('=== preallocation=%s ===' % prealloc)
68
+def do_qemu_img_bench() -> None:
160
+ iotests.qemu_img_log('create', '-f', iotests.imgfmt, base, base_size)
69
+ """
161
+ iotests.qemu_img_log('create', '-f', iotests.imgfmt, '-b', base, top,
70
+ Do some I/O requests on `nbd_sock`.
162
+ top_size_old)
71
+ """
163
+ iotests.qemu_io_log('-c', 'write -P 1 %s 64k' % off, base)
72
+ assert qemu_img('bench', '-f', 'raw', '-c', '2000000',
73
+ f'nbd+unix:///node0?socket={nbd_sock}') == 0
164
+
74
+
165
+ # After this, top_size_old to base_size should be allocated/zeroed.
75
+
166
+ #
76
+class TestGraphChangesWhileIO(QMPTestCase):
167
+ # In theory, leaving base_size to top_size_new unallocated would be
77
+ def setUp(self) -> None:
168
+ # correct, but in practice, if we zero out anything, we zero out
78
+ # Create an overlay that can be added at runtime on top of the
169
+ # everything up to top_size_new.
79
+ # null-co block node that will receive I/O
170
+ iotests.qemu_img_log('resize', '-f', iotests.imgfmt,
80
+ assert qemu_img_create('-f', imgfmt, '-F', 'raw', '-b', 'null-co://',
171
+ '--preallocation', prealloc, top, top_size_new)
81
+ top) == 0
172
+ iotests.qemu_io_log('-c', 'read -P 0 %s 64k' % off, top)
82
+
173
+ iotests.qemu_io_log('-c', 'map', top)
83
+ # QSD instance with a null-co block node in an I/O thread,
174
+ iotests.qemu_img_log('map', '--output=json', top)
84
+ # exported over NBD (on `nbd_sock`, export name "node0")
175
diff --git a/tests/qemu-iotests/274.out b/tests/qemu-iotests/274.out
85
+ self.qsd = QemuStorageDaemon(
86
+ '--object', 'iothread,id=iothread0',
87
+ '--blockdev', 'null-co,node-name=node0,read-zeroes=true',
88
+ '--nbd-server', f'addr.type=unix,addr.path={nbd_sock}',
89
+ '--export', 'nbd,id=exp0,node-name=node0,iothread=iothread0,' +
90
+ 'fixed-iothread=true,writable=true',
91
+ qmp=True
92
+ )
93
+
94
+ def tearDown(self) -> None:
95
+ self.qsd.stop()
96
+
97
+ def test_blockdev_add_while_io(self) -> None:
98
+ # Run qemu-img bench in the background
99
+ bench_thr = Thread(target=do_qemu_img_bench)
100
+ bench_thr.start()
101
+
102
+ # While qemu-img bench is running, repeatedly add and remove an
103
+ # overlay to/from node0
104
+ while bench_thr.is_alive():
105
+ result = self.qsd.qmp('blockdev-add', {
106
+ 'driver': imgfmt,
107
+ 'node-name': 'overlay',
108
+ 'backing': 'node0',
109
+ 'file': {
110
+ 'driver': 'file',
111
+ 'filename': top
112
+ }
113
+ })
114
+ self.assert_qmp(result, 'return', {})
115
+
116
+ result = self.qsd.qmp('blockdev-del', {
117
+ 'node-name': 'overlay'
118
+ })
119
+ self.assert_qmp(result, 'return', {})
120
+
121
+ bench_thr.join()
122
+
123
+if __name__ == '__main__':
124
+ # Format must support raw backing files
125
+ iotests.main(supported_fmts=['qcow', 'qcow2', 'qed'],
126
+ supported_protocols=['file'])
127
diff --git a/tests/qemu-iotests/tests/graph-changes-while-io.out b/tests/qemu-iotests/tests/graph-changes-while-io.out
176
new file mode 100644
128
new file mode 100644
177
index XXXXXXX..XXXXXXX
129
index XXXXXXX..XXXXXXX
178
--- /dev/null
130
--- /dev/null
179
+++ b/tests/qemu-iotests/274.out
131
+++ b/tests/qemu-iotests/tests/graph-changes-while-io.out
180
@@ -XXX,XX +XXX,XX @@
132
@@ -XXX,XX +XXX,XX @@
181
+== Commit tests ==
133
+.
182
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=2097152 cluster_size=65536 lazy_refcounts=off refcount_bits=16
134
+----------------------------------------------------------------------
135
+Ran 1 tests
183
+
136
+
184
+Formatting 'TEST_DIR/PID-mid', fmt=qcow2 size=1048576 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
137
+OK
185
+
186
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=2097152 backing_file=TEST_DIR/PID-mid cluster_size=65536 lazy_refcounts=off refcount_bits=16
187
+
188
+wrote 2097152/2097152 bytes at offset 0
189
+2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
190
+
191
+=== Check visible data ===
192
+read 1048576/1048576 bytes at offset 0
193
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
194
+
195
+read 1048576/1048576 bytes at offset 1048576
196
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
197
+
198
+=== Checking allocation status ===
199
+1048576/1048576 bytes allocated at offset 0 bytes
200
+1048576/1048576 bytes allocated at offset 1 MiB
201
+
202
+0/1048576 bytes allocated at offset 0 bytes
203
+0/0 bytes allocated at offset 1 MiB
204
+
205
+0/1048576 bytes allocated at offset 0 bytes
206
+0/1048576 bytes allocated at offset 1 MiB
207
+
208
+=== Checking map ===
209
+[{ "start": 0, "length": 2097152, "depth": 0, "zero": false, "data": true, "offset": 327680}]
210
+
211
+Offset Length Mapped to File
212
+0 0x200000 0x50000 TEST_DIR/PID-base
213
+
214
+[{ "start": 0, "length": 1048576, "depth": 1, "zero": false, "data": true, "offset": 327680}]
215
+
216
+Offset Length Mapped to File
217
+0 0x100000 0x50000 TEST_DIR/PID-base
218
+
219
+[{ "start": 0, "length": 1048576, "depth": 2, "zero": false, "data": true, "offset": 327680},
220
+{ "start": 1048576, "length": 1048576, "depth": 0, "zero": true, "data": false}]
221
+
222
+Offset Length Mapped to File
223
+0 0x100000 0x50000 TEST_DIR/PID-base
224
+
225
+=== Testing qemu-img commit (top -> mid) ===
226
+Image committed.
227
+
228
+image: TEST_IMG
229
+file format: IMGFMT
230
+virtual size: 2 MiB (2097152 bytes)
231
+cluster_size: 65536
232
+backing file: TEST_DIR/PID-base
233
+Format specific information:
234
+ compat: 1.1
235
+ lazy refcounts: false
236
+ refcount bits: 16
237
+ corrupt: false
238
+
239
+read 1048576/1048576 bytes at offset 0
240
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
241
+
242
+read 1048576/1048576 bytes at offset 1048576
243
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
244
+
245
+=== Testing HMP commit (top -> mid) ===
246
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=2097152 cluster_size=65536 lazy_refcounts=off refcount_bits=16
247
+
248
+Formatting 'TEST_DIR/PID-mid', fmt=qcow2 size=1048576 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
249
+
250
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=2097152 backing_file=TEST_DIR/PID-mid cluster_size=65536 lazy_refcounts=off refcount_bits=16
251
+
252
+wrote 2097152/2097152 bytes at offset 0
253
+2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
254
+
255
+{"execute": "human-monitor-command", "arguments": {"command-line": "commit drive0"}}
256
+{"return": ""}
257
+image: TEST_IMG
258
+file format: IMGFMT
259
+virtual size: 2 MiB (2097152 bytes)
260
+cluster_size: 65536
261
+backing file: TEST_DIR/PID-base
262
+Format specific information:
263
+ compat: 1.1
264
+ lazy refcounts: false
265
+ refcount bits: 16
266
+ corrupt: false
267
+
268
+read 1048576/1048576 bytes at offset 0
269
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
270
+
271
+read 1048576/1048576 bytes at offset 1048576
272
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
273
+
274
+=== Testing QMP active commit (top -> mid) ===
275
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=2097152 cluster_size=65536 lazy_refcounts=off refcount_bits=16
276
+
277
+Formatting 'TEST_DIR/PID-mid', fmt=qcow2 size=1048576 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
278
+
279
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=2097152 backing_file=TEST_DIR/PID-mid cluster_size=65536 lazy_refcounts=off refcount_bits=16
280
+
281
+wrote 2097152/2097152 bytes at offset 0
282
+2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
283
+
284
+{"execute": "block-commit", "arguments": {"auto-dismiss": false, "base-node": "mid", "device": "top", "job-id": "job0"}}
285
+{"return": {}}
286
+{"execute": "job-complete", "arguments": {"id": "job0"}}
287
+{"return": {}}
288
+{"data": {"device": "job0", "len": 0, "offset": 0, "speed": 0, "type": "commit"}, "event": "BLOCK_JOB_READY", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
289
+{"data": {"device": "job0", "len": 0, "offset": 0, "speed": 0, "type": "commit"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
290
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
291
+{"return": {}}
292
+image: TEST_IMG
293
+file format: IMGFMT
294
+virtual size: 2 MiB (2097152 bytes)
295
+cluster_size: 65536
296
+backing file: TEST_DIR/PID-base
297
+Format specific information:
298
+ compat: 1.1
299
+ lazy refcounts: false
300
+ refcount bits: 16
301
+ corrupt: false
302
+
303
+read 1048576/1048576 bytes at offset 0
304
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
305
+
306
+read 1048576/1048576 bytes at offset 1048576
307
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
308
+
309
+== Resize tests ==
310
+=== preallocation=off ===
311
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=6442450944 cluster_size=65536 lazy_refcounts=off refcount_bits=16
312
+
313
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=1073741824 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
314
+
315
+wrote 65536/65536 bytes at offset 5368709120
316
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
317
+
318
+Image resized.
319
+
320
+read 65536/65536 bytes at offset 5368709120
321
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
322
+
323
+1 GiB (0x40000000) bytes not allocated at offset 0 bytes (0x0)
324
+7 GiB (0x1c0000000) bytes allocated at offset 1 GiB (0x40000000)
325
+
326
+[{ "start": 0, "length": 1073741824, "depth": 1, "zero": true, "data": false},
327
+{ "start": 1073741824, "length": 7516192768, "depth": 0, "zero": true, "data": false}]
328
+
329
+=== preallocation=metadata ===
330
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=34359738368 cluster_size=65536 lazy_refcounts=off refcount_bits=16
331
+
332
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=32212254720 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
333
+
334
+wrote 65536/65536 bytes at offset 33285996544
335
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
336
+
337
+Image resized.
338
+
339
+read 65536/65536 bytes at offset 33285996544
340
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
341
+
342
+30 GiB (0x780000000) bytes not allocated at offset 0 bytes (0x0)
343
+3 GiB (0xc0000000) bytes allocated at offset 30 GiB (0x780000000)
344
+
345
+[{ "start": 0, "length": 32212254720, "depth": 1, "zero": true, "data": false},
346
+{ "start": 32212254720, "length": 536870912, "depth": 0, "zero": true, "data": false, "offset": 327680},
347
+{ "start": 32749125632, "length": 536870912, "depth": 0, "zero": true, "data": false, "offset": 537264128},
348
+{ "start": 33285996544, "length": 536870912, "depth": 0, "zero": true, "data": false, "offset": 1074200576},
349
+{ "start": 33822867456, "length": 536870912, "depth": 0, "zero": true, "data": false, "offset": 1611137024},
350
+{ "start": 34359738368, "length": 536870912, "depth": 0, "zero": true, "data": false, "offset": 2148139008},
351
+{ "start": 34896609280, "length": 536870912, "depth": 0, "zero": true, "data": false, "offset": 2685075456}]
352
+
353
+=== preallocation=falloc ===
354
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=10485760 cluster_size=65536 lazy_refcounts=off refcount_bits=16
355
+
356
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=5242880 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
357
+
358
+wrote 65536/65536 bytes at offset 9437184
359
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
360
+
361
+Image resized.
362
+
363
+read 65536/65536 bytes at offset 9437184
364
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
365
+
366
+5 MiB (0x500000) bytes not allocated at offset 0 bytes (0x0)
367
+10 MiB (0xa00000) bytes allocated at offset 5 MiB (0x500000)
368
+
369
+[{ "start": 0, "length": 5242880, "depth": 1, "zero": true, "data": false},
370
+{ "start": 5242880, "length": 10485760, "depth": 0, "zero": true, "data": false, "offset": 327680}]
371
+
372
+=== preallocation=full ===
373
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=16777216 cluster_size=65536 lazy_refcounts=off refcount_bits=16
374
+
375
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=8388608 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
376
+
377
+wrote 65536/65536 bytes at offset 11534336
378
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
379
+
380
+Image resized.
381
+
382
+read 65536/65536 bytes at offset 11534336
383
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
384
+
385
+8 MiB (0x800000) bytes not allocated at offset 0 bytes (0x0)
386
+4 MiB (0x400000) bytes allocated at offset 8 MiB (0x800000)
387
+
388
+[{ "start": 0, "length": 8388608, "depth": 1, "zero": true, "data": false},
389
+{ "start": 8388608, "length": 4194304, "depth": 0, "zero": true, "data": false, "offset": 327680}]
390
+
391
+=== preallocation=off ===
392
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=393216 cluster_size=65536 lazy_refcounts=off refcount_bits=16
393
+
394
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=259072 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
395
+
396
+wrote 65536/65536 bytes at offset 259072
397
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
398
+
399
+Image resized.
400
+
401
+read 65536/65536 bytes at offset 259072
402
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
403
+
404
+192 KiB (0x30000) bytes not allocated at offset 0 bytes (0x0)
405
+320 KiB (0x50000) bytes allocated at offset 192 KiB (0x30000)
406
+
407
+[{ "start": 0, "length": 196608, "depth": 1, "zero": true, "data": false},
408
+{ "start": 196608, "length": 65536, "depth": 0, "zero": false, "data": true, "offset": 327680},
409
+{ "start": 262144, "length": 262144, "depth": 0, "zero": true, "data": false}]
410
+
411
+=== preallocation=off ===
412
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=409600 cluster_size=65536 lazy_refcounts=off refcount_bits=16
413
+
414
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=262144 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
415
+
416
+wrote 65536/65536 bytes at offset 344064
417
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
418
+
419
+Image resized.
420
+
421
+read 65536/65536 bytes at offset 344064
422
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
423
+
424
+256 KiB (0x40000) bytes not allocated at offset 0 bytes (0x0)
425
+256 KiB (0x40000) bytes allocated at offset 256 KiB (0x40000)
426
+
427
+[{ "start": 0, "length": 262144, "depth": 1, "zero": true, "data": false},
428
+{ "start": 262144, "length": 262144, "depth": 0, "zero": true, "data": false}]
429
+
430
+=== preallocation=off ===
431
+Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=524288 cluster_size=65536 lazy_refcounts=off refcount_bits=16
432
+
433
+Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=262144 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16
434
+
435
+wrote 65536/65536 bytes at offset 446464
436
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
437
+
438
+Image resized.
439
+
440
+read 65536/65536 bytes at offset 446464
441
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
442
+
443
+256 KiB (0x40000) bytes not allocated at offset 0 bytes (0x0)
444
+244 KiB (0x3d000) bytes allocated at offset 256 KiB (0x40000)
445
+
446
+[{ "start": 0, "length": 262144, "depth": 1, "zero": true, "data": false},
447
+{ "start": 262144, "length": 249856, "depth": 0, "zero": true, "data": false}]
448
+
449
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
450
index XXXXXXX..XXXXXXX 100644
451
--- a/tests/qemu-iotests/group
452
+++ b/tests/qemu-iotests/group
453
@@ -XXX,XX +XXX,XX @@
454
270 rw backing quick
455
272 rw
456
273 backing quick
457
+274 rw backing
458
277 rw quick
459
279 rw backing quick
460
280 rw migration quick
461
--
138
--
462
2.25.3
139
2.35.1
463
464
diff view generated by jsdifflib
1
From: Paolo Bonzini <pbonzini@redhat.com>
1
From: Thomas Huth <thuth@redhat.com>
2
2
3
Test 244 checks the expected behavior of qcow2 external data files
3
Instead of failing the iotests if GNU sed is not available (or skipping
4
with respect to zero and discarded clusters. Filesystems however
4
them completely in the check-block.sh script), it would be better to
5
are free to ignore discard requests, and this seems to be the
5
simply skip the bash-based tests that rely on GNU sed, so that the other
6
case for overlayfs. Relax the tests to skip checks on the
6
tests could still be run. Thus we now explicitely use "gsed" (either as
7
external data file for discarded areas, which implies not using
7
direct program or as a wrapper around "sed" if it's the GNU version)
8
qemu-img compare in the data_file_raw=on case.
8
in the spots that rely on the GNU sed behavior. Statements that use the
9
9
"-r" parameter of sed have been switched to use "-E" instead, since this
10
This fixes docker tests on RHEL8.
10
switch is supported by all sed versions on our supported build hosts
11
11
(most also support "-r", but macOS' sed only supports "-E"). With all
12
Cc: Kevin Wolf <kwolf@redhat.com>
12
these changes in place, we then can also remove the sed checks from the
13
Cc: qemu-block@nongnu.org
13
check-block.sh script, so that "make check-block" can now be run on
14
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
14
systems without GNU sed, too.
15
Message-Id: <20200409191006.24429-1-pbonzini@redhat.com>
15
16
Signed-off-by: Thomas Huth <thuth@redhat.com>
17
Message-Id: <20220216125454.465041-1-thuth@redhat.com>
18
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
19
Reviewed-by: Eric Blake <eblake@redhat.com>
16
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
20
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
17
---
21
---
18
tests/qemu-iotests/244 | 10 ++++++++--
22
tests/check-block.sh | 12 ------
19
tests/qemu-iotests/244.out | 9 ++++++---
23
tests/qemu-iotests/271 | 2 +-
20
2 files changed, 14 insertions(+), 5 deletions(-)
24
tests/qemu-iotests/common.filter | 65 ++++++++++++++++----------------
21
25
tests/qemu-iotests/common.rc | 45 +++++++++++-----------
22
diff --git a/tests/qemu-iotests/244 b/tests/qemu-iotests/244
26
4 files changed, 57 insertions(+), 67 deletions(-)
27
28
diff --git a/tests/check-block.sh b/tests/check-block.sh
23
index XXXXXXX..XXXXXXX 100755
29
index XXXXXXX..XXXXXXX 100755
24
--- a/tests/qemu-iotests/244
30
--- a/tests/check-block.sh
25
+++ b/tests/qemu-iotests/244
31
+++ b/tests/check-block.sh
26
@@ -XXX,XX +XXX,XX @@ $QEMU_IO -c 'read -P 0 0 1M' \
32
@@ -XXX,XX +XXX,XX @@ if LANG=C bash --version | grep -q 'GNU bash, version [123]' ; then
27
echo
33
skip "bash version too old ==> Not running the qemu-iotests."
28
$QEMU_IO -c 'read -P 0 0 1M' \
34
fi
29
-c 'read -P 0x11 1M 1M' \
35
30
- -c 'read -P 0 2M 2M' \
36
-if ! (sed --version | grep 'GNU sed') > /dev/null 2>&1 ; then
31
-c 'read -P 0x11 4M 1M' \
37
- if ! command -v gsed >/dev/null 2>&1; then
32
-c 'read -P 0 5M 1M' \
38
- skip "GNU sed not available ==> Not running the qemu-iotests."
33
-f raw "$TEST_IMG.data" |
39
- fi
34
@@ -XXX,XX +XXX,XX @@ $QEMU_IO -c 'read -P 0 0 1M' \
40
-else
35
-f $IMGFMT "$TEST_IMG" |
41
- # Double-check that we're not using BusyBox' sed which says
36
_filter_qemu_io
42
- # that "This is not GNU sed version 4.0" ...
37
43
- if sed --version | grep -q 'not GNU sed' ; then
38
+# Discarded clusters are only marked as such in the qcow2 metadata, but
44
- skip "BusyBox sed not supported ==> Not running the qemu-iotests."
39
+# they can contain stale data in the external data file. Instead, zero
45
- fi
40
+# clusters must be zeroed in the external data file too.
46
-fi
41
echo
47
-
42
-$QEMU_IMG compare "$TEST_IMG" "$TEST_IMG.data"
48
cd tests/qemu-iotests
43
+$QEMU_IO -c 'read -P 0 0 1M' \
49
44
+ -c 'read -P 0x11 1M 1M' \
50
# QEMU_CHECK_BLOCK_AUTO is used to disable some unstable sub-tests
45
+ -c 'read -P 0 3M 3M' \
51
diff --git a/tests/qemu-iotests/271 b/tests/qemu-iotests/271
46
+ -f raw "$TEST_IMG".data |
52
index XXXXXXX..XXXXXXX 100755
47
+ _filter_qemu_io
53
--- a/tests/qemu-iotests/271
48
54
+++ b/tests/qemu-iotests/271
49
echo -n "qcow2 file size after I/O: "
55
@@ -XXX,XX +XXX,XX @@ _make_test_img -o extended_l2=on 1M
50
du -b $TEST_IMG | cut -f1
56
# Second and third writes in _concurrent_io() are independent and may finish in
51
diff --git a/tests/qemu-iotests/244.out b/tests/qemu-iotests/244.out
57
# different order. So, filter offset out to match both possible variants.
58
_concurrent_io | $QEMU_IO | _filter_qemu_io | \
59
- $SED -e 's/\(20480\|40960\)/OFFSET/'
60
+ sed -e 's/\(20480\|40960\)/OFFSET/'
61
_concurrent_verify | $QEMU_IO | _filter_qemu_io
62
63
# success, all done
64
diff --git a/tests/qemu-iotests/common.filter b/tests/qemu-iotests/common.filter
52
index XXXXXXX..XXXXXXX 100644
65
index XXXXXXX..XXXXXXX 100644
53
--- a/tests/qemu-iotests/244.out
66
--- a/tests/qemu-iotests/common.filter
54
+++ b/tests/qemu-iotests/244.out
67
+++ b/tests/qemu-iotests/common.filter
55
@@ -XXX,XX +XXX,XX @@ read 1048576/1048576 bytes at offset 0
68
@@ -XXX,XX +XXX,XX @@
56
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
69
57
read 1048576/1048576 bytes at offset 1048576
70
_filter_date()
58
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
71
{
59
-read 2097152/2097152 bytes at offset 2097152
72
- $SED -re 's/[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/yyyy-mm-dd hh:mm:ss/'
60
-2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
73
+ sed -Ee 's/[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/yyyy-mm-dd hh:mm:ss/'
61
read 1048576/1048576 bytes at offset 4194304
74
}
62
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
75
63
read 1048576/1048576 bytes at offset 5242880
76
_filter_vmstate_size()
64
@@ -XXX,XX +XXX,XX @@ read 1048576/1048576 bytes at offset 1048576
77
{
65
read 4194304/4194304 bytes at offset 2097152
78
- $SED -r -e 's/[0-9. ]{5} [KMGT]iB/ SIZE/' \
66
4 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
79
- -e 's/[0-9. ]{5} B/ SIZE/'
67
80
+ sed -E -e 's/[0-9. ]{5} [KMGT]iB/ SIZE/' \
68
-Images are identical.
81
+ -e 's/[0-9. ]{5} B/ SIZE/'
69
+read 1048576/1048576 bytes at offset 0
82
}
70
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
83
71
+read 1048576/1048576 bytes at offset 1048576
84
_filter_generated_node_ids()
72
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
85
{
73
+read 3145728/3145728 bytes at offset 3145728
86
- $SED -re 's/\#block[0-9]{3,}/NODE_NAME/'
74
+3 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
87
+ sed -Ee 's/\#block[0-9]{3,}/NODE_NAME/'
75
qcow2 file size after I/O: 327680
88
}
76
89
77
=== bdrv_co_block_status test for file and offset=0 ===
90
_filter_qom_path()
91
{
92
- $SED -e '/Attached to:/s/\device[[0-9]\+\]/device[N]/g'
93
+ gsed -e '/Attached to:/s/\device[[0-9]\+\]/device[N]/g'
94
}
95
96
# replace occurrences of the actual TEST_DIR value with TEST_DIR
97
_filter_testdir()
98
{
99
- $SED -e "s#$TEST_DIR/#TEST_DIR/#g" \
100
- -e "s#$SOCK_DIR/#SOCK_DIR/#g" \
101
- -e "s#SOCK_DIR/fuse-#TEST_DIR/#g"
102
+ sed -e "s#$TEST_DIR/#TEST_DIR/#g" \
103
+ -e "s#$SOCK_DIR/#SOCK_DIR/#g" \
104
+ -e "s#SOCK_DIR/fuse-#TEST_DIR/#g"
105
}
106
107
# replace occurrences of the actual IMGFMT value with IMGFMT
108
_filter_imgfmt()
109
{
110
- $SED -e "s#$IMGFMT#IMGFMT#g"
111
+ sed -e "s#$IMGFMT#IMGFMT#g"
112
}
113
114
# Replace error message when the format is not supported and delete
115
# the output lines after the first one
116
_filter_qemu_img_check()
117
{
118
- $SED -e '/allocated.*fragmented.*compressed clusters/d' \
119
+ gsed -e '/allocated.*fragmented.*compressed clusters/d' \
120
-e 's/qemu-img: This image format does not support checks/No errors were found on the image./' \
121
-e '/Image end offset: [0-9]\+/d'
122
}
123
@@ -XXX,XX +XXX,XX @@ _filter_qemu_img_check()
124
# Removes \r from messages
125
_filter_win32()
126
{
127
- $SED -e 's/\r//g'
128
+ gsed -e 's/\r//g'
129
}
130
131
# sanitize qemu-io output
132
_filter_qemu_io()
133
{
134
- _filter_win32 | $SED -e "s/[0-9]* ops\; [0-9/:. sec]* ([0-9/.inf]* [EPTGMKiBbytes]*\/sec and [0-9/.inf]* ops\/sec)/X ops\; XX:XX:XX.X (XXX YYY\/sec and XXX ops\/sec)/" \
135
+ _filter_win32 | \
136
+ gsed -e "s/[0-9]* ops\; [0-9/:. sec]* ([0-9/.inf]* [EPTGMKiBbytes]*\/sec and [0-9/.inf]* ops\/sec)/X ops\; XX:XX:XX.X (XXX YYY\/sec and XXX ops\/sec)/" \
137
-e "s/: line [0-9][0-9]*: *[0-9][0-9]*\( Aborted\| Killed\)/:\1/" \
138
-e "s/qemu-io> //g"
139
}
140
@@ -XXX,XX +XXX,XX @@ _filter_qemu_io()
141
# replace occurrences of QEMU_PROG with "qemu"
142
_filter_qemu()
143
{
144
- $SED -e "s#\\(^\\|(qemu) \\)$(basename $QEMU_PROG):#\1QEMU_PROG:#" \
145
+ gsed -e "s#\\(^\\|(qemu) \\)$(basename $QEMU_PROG):#\1QEMU_PROG:#" \
146
-e 's#^QEMU [0-9]\+\.[0-9]\+\.[0-9]\+ monitor#QEMU X.Y.Z monitor#' \
147
-e $'s#\r##' # QEMU monitor uses \r\n line endings
148
}
149
@@ -XXX,XX +XXX,XX @@ _filter_qemu()
150
_filter_qmp()
151
{
152
_filter_win32 | \
153
- $SED -e 's#\("\(micro\)\?seconds": \)[0-9]\+#\1 TIMESTAMP#g' \
154
+ gsed -e 's#\("\(micro\)\?seconds": \)[0-9]\+#\1 TIMESTAMP#g' \
155
-e 's#^{"QMP":.*}$#QMP_VERSION#' \
156
-e '/^ "QMP": {\s*$/, /^ }\s*$/ c\' \
157
-e ' QMP_VERSION'
158
@@ -XXX,XX +XXX,XX @@ _filter_qmp()
159
# readline makes HMP command strings so long that git complains
160
_filter_hmp()
161
{
162
- $SED -e $'s/^\\((qemu) \\)\\?.*\e\\[D/\\1/g' \
163
+ gsed -e $'s/^\\((qemu) \\)\\?.*\e\\[D/\\1/g' \
164
-e $'s/\e\\[K//g'
165
}
166
167
# replace block job offset
168
_filter_block_job_offset()
169
{
170
- $SED -e 's/, "offset": [0-9]\+,/, "offset": OFFSET,/'
171
+ sed -e 's/, "offset": [0-9]\+,/, "offset": OFFSET,/'
172
}
173
174
# replace block job len
175
_filter_block_job_len()
176
{
177
- $SED -e 's/, "len": [0-9]\+,/, "len": LEN,/g'
178
+ sed -e 's/, "len": [0-9]\+,/, "len": LEN,/g'
179
}
180
181
# replace actual image size (depends on the host filesystem)
182
_filter_actual_image_size()
183
{
184
- $SED -s 's/\("actual-size":\s*\)[0-9]\+/\1SIZE/g'
185
+ gsed -s 's/\("actual-size":\s*\)[0-9]\+/\1SIZE/g'
186
}
187
188
# Filename filters for qemu-img create
189
_filter_img_create_filenames()
190
{
191
- $SED \
192
+ sed \
193
-e "s#$REMOTE_TEST_DIR#TEST_DIR#g" \
194
-e "s#$IMGPROTO:$TEST_DIR#TEST_DIR#g" \
195
-e "s#$TEST_DIR#TEST_DIR#g" \
196
@@ -XXX,XX +XXX,XX @@ _do_filter_img_create()
197
# precedes ", fmt=") and the options part ($options, which starts
198
# with "fmt=")
199
# (And just echo everything before the first "^Formatting")
200
- readarray formatting_line < <($SED -e 's/, fmt=/\n/')
201
+ readarray formatting_line < <(gsed -e 's/, fmt=/\n/')
202
203
filename_part=${formatting_line[0]}
204
unset formatting_line[0]
205
@@ -XXX,XX +XXX,XX @@ _do_filter_img_create()
206
options=$(
207
echo "$options" \
208
| tr '\n' '\0' \
209
- | $SED -e 's/ \([a-z0-9_.-]*\)=/\n\1=/g' \
210
+ | gsed -e 's/ \([a-z0-9_.-]*\)=/\n\1=/g' \
211
| grep -a -e '^fmt' -e '^size' -e '^backing' -e '^preallocation' \
212
-e '^encryption' "${grep_data_file[@]}" \
213
| _filter_img_create_filenames \
214
- | $SED \
215
+ | sed \
216
-e 's/^\(fmt\)/0-\1/' \
217
-e 's/^\(size\)/1-\1/' \
218
-e 's/^\(backing\)/2-\1/' \
219
@@ -XXX,XX +XXX,XX @@ _do_filter_img_create()
220
-e 's/^\(encryption\)/4-\1/' \
221
-e 's/^\(preallocation\)/8-\1/' \
222
| LC_ALL=C sort \
223
- | $SED -e 's/^[0-9]-//' \
224
+ | sed -e 's/^[0-9]-//' \
225
| tr '\n\0' ' \n' \
226
- | $SED -e 's/^ *$//' -e 's/ *$//'
227
+ | sed -e 's/^ *$//' -e 's/ *$//'
228
)
229
230
if [ -n "$options" ]; then
231
@@ -XXX,XX +XXX,XX @@ _filter_img_create()
232
233
_filter_img_create_size()
234
{
235
- $SED -e "s# size=[0-9]\\+# size=SIZE#g"
236
+ gsed -e "s# size=[0-9]\\+# size=SIZE#g"
237
}
238
239
_filter_img_info()
240
@@ -XXX,XX +XXX,XX @@ _filter_img_info()
241
242
discard=0
243
regex_json_spec_start='^ *"format-specific": \{'
244
- $SED -e "s#$REMOTE_TEST_DIR#TEST_DIR#g" \
245
+ gsed -e "s#$REMOTE_TEST_DIR#TEST_DIR#g" \
246
-e "s#$IMGPROTO:$TEST_DIR#TEST_DIR#g" \
247
-e "s#$TEST_DIR#TEST_DIR#g" \
248
-e "s#$SOCK_DIR#SOCK_DIR#g" \
249
@@ -XXX,XX +XXX,XX @@ _filter_qemu_img_map()
250
data_file_filter=(-e "s#$data_file_pattern#\\1#")
251
fi
252
253
- $SED -e 's/\([0-9a-fx]* *[0-9a-fx]* *\)[0-9a-fx]* */\1/g' \
254
+ sed -e 's/\([0-9a-fx]* *[0-9a-fx]* *\)[0-9a-fx]* */\1/g' \
255
-e 's/"offset": [0-9]\+/"offset": OFFSET/g' \
256
-e 's/Mapped to *//' \
257
"${data_file_filter[@]}" \
258
@@ -XXX,XX +XXX,XX @@ _filter_nbd()
259
# receive callbacks sometimes, making them unreliable.
260
#
261
# Filter out the TCP port number since this changes between runs.
262
- $SED -e '/nbd\/.*\.c:/d' \
263
+ sed -e '/nbd\/.*\.c:/d' \
264
-e 's#127\.0\.0\.1:[0-9]*#127.0.0.1:PORT#g' \
265
-e "s#?socket=$SOCK_DIR#?socket=SOCK_DIR#g" \
266
-e 's#\(foo\|PORT/\?\|.sock\): Failed to .*$#\1#'
267
@@ -XXX,XX +XXX,XX @@ sys.stdout.write(result)'
268
269
_filter_authz_check_tls()
270
{
271
- $SED -e 's/TLS x509 authz check for .* is denied/TLS x509 authz check for DISTINGUISHED-NAME is denied/'
272
+ sed -e 's/TLS x509 authz check for .* is denied/TLS x509 authz check for DISTINGUISHED-NAME is denied/'
273
}
274
275
_filter_qcow2_compression_type_bit()
276
{
277
- $SED -e 's/\(incompatible_features\s\+\)\[3\(, \)\?/\1[/' \
278
- -e 's/\(incompatible_features.*\), 3\]/\1]/' \
279
- -e 's/\(incompatible_features.*\), 3\(,.*\)/\1\2/'
280
+ gsed -e 's/\(incompatible_features\s\+\)\[3\(, \)\?/\1[/' \
281
+ -e 's/\(incompatible_features.*\), 3\]/\1]/' \
282
+ -e 's/\(incompatible_features.*\), 3\(,.*\)/\1\2/'
283
}
284
285
# make sure this script returns success
286
diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc
287
index XXXXXXX..XXXXXXX 100644
288
--- a/tests/qemu-iotests/common.rc
289
+++ b/tests/qemu-iotests/common.rc
290
@@ -XXX,XX +XXX,XX @@
291
# along with this program. If not, see <http://www.gnu.org/licenses/>.
292
#
293
294
-SED=
295
-for sed in sed gsed; do
296
- ($sed --version | grep 'GNU sed') > /dev/null 2>&1
297
- if [ "$?" -eq 0 ]; then
298
- SED=$sed
299
- break
300
- fi
301
-done
302
-if [ -z "$SED" ]; then
303
- echo "$0: GNU sed not found"
304
- exit 1
305
+# bail out, setting up .notrun file
306
+_notrun()
307
+{
308
+ echo "$*" >"$OUTPUT_DIR/$seq.notrun"
309
+ echo "$seq not run: $*"
310
+ status=0
311
+ exit
312
+}
313
+
314
+if ! command -v gsed >/dev/null 2>&1; then
315
+ if sed --version 2>&1 | grep -v 'not GNU sed' | grep 'GNU sed' > /dev/null;
316
+ then
317
+ gsed()
318
+ {
319
+ sed "$@"
320
+ }
321
+ else
322
+ gsed()
323
+ {
324
+ _notrun "GNU sed not available"
325
+ }
326
+ fi
327
fi
328
329
dd()
330
@@ -XXX,XX +XXX,XX @@ _img_info()
331
done
332
}
333
334
-# bail out, setting up .notrun file
335
-#
336
-_notrun()
337
-{
338
- echo "$*" >"$OUTPUT_DIR/$seq.notrun"
339
- echo "$seq not run: $*"
340
- status=0
341
- exit
342
-}
343
-
344
# bail out, setting up .casenotrun file
345
# The function _casenotrun() is used as a notifier. It is the
346
# caller's responsibility to make skipped a particular test.
347
@@ -XXX,XX +XXX,XX @@ _require_working_luks()
348
IMGFMT='luks' _rm_test_img "$file"
349
350
if [ $status != 0 ]; then
351
- reason=$(echo "$output" | grep "$file:" | $SED -e "s#.*$file: *##")
352
+ reason=$(echo "$output" | grep "$file:" | sed -e "s#.*$file: *##")
353
if [ -z "$reason" ]; then
354
reason="Failed to create a LUKS image"
355
fi
78
--
356
--
79
2.25.3
357
2.35.1
80
358
81
359
diff view generated by jsdifflib
1
The raw format driver can simply forward the flag and let its bs->file
1
From: Hanna Reitz <hreitz@redhat.com>
2
child take care of actually providing the zeros.
3
2
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
3
.bdrv_amend_clean() says block drivers can use it to clean up what was
5
Reviewed-by: Max Reitz <mreitz@redhat.com>
4
done in .bdrv_amend_pre_run(). Therefore, it should always be called
6
Reviewed-by: Eric Blake <eblake@redhat.com>
5
after .bdrv_amend_pre_run(), which means we need it to call it in the
7
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
6
JobDriver.free() callback, not in JobDriver.clean().
8
Message-Id: <20200424125448.63318-6-kwolf@redhat.com>
7
8
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
9
Message-Id: <20220304153729.711387-3-hreitz@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
11
---
11
block/raw-format.c | 4 +++-
12
block/amend.c | 4 ++--
12
1 file changed, 3 insertions(+), 1 deletion(-)
13
1 file changed, 2 insertions(+), 2 deletions(-)
13
14
14
diff --git a/block/raw-format.c b/block/raw-format.c
15
diff --git a/block/amend.c b/block/amend.c
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/block/raw-format.c
17
--- a/block/amend.c
17
+++ b/block/raw-format.c
18
+++ b/block/amend.c
18
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn raw_co_truncate(BlockDriverState *bs, int64_t offset,
19
@@ -XXX,XX +XXX,XX @@ static int blockdev_amend_pre_run(BlockdevAmendJob *s, Error **errp)
19
20
return 0;
20
s->size = offset;
21
offset += s->offset;
22
- return bdrv_co_truncate(bs->file, offset, exact, prealloc, 0, errp);
23
+ return bdrv_co_truncate(bs->file, offset, exact, prealloc, flags, errp);
24
}
21
}
25
22
26
static void raw_eject(BlockDriverState *bs, bool eject_flag)
23
-static void blockdev_amend_clean(Job *job)
27
@@ -XXX,XX +XXX,XX @@ static int raw_open(BlockDriverState *bs, QDict *options, int flags,
24
+static void blockdev_amend_free(Job *job)
28
bs->supported_zero_flags = BDRV_REQ_WRITE_UNCHANGED |
25
{
29
((BDRV_REQ_FUA | BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK) &
26
BlockdevAmendJob *s = container_of(job, BlockdevAmendJob, common);
30
bs->file->bs->supported_zero_flags);
27
31
+ bs->supported_truncate_flags = bs->file->bs->supported_truncate_flags &
28
@@ -XXX,XX +XXX,XX @@ static const JobDriver blockdev_amend_job_driver = {
32
+ BDRV_REQ_ZERO_WRITE;
29
.instance_size = sizeof(BlockdevAmendJob),
33
30
.job_type = JOB_TYPE_AMEND,
34
if (bs->probed && !bdrv_is_read_only(bs)) {
31
.run = blockdev_amend_run,
35
bdrv_refresh_filename(bs->file->bs);
32
- .clean = blockdev_amend_clean,
33
+ .free = blockdev_amend_free,
34
};
35
36
void qmp_x_blockdev_amend(const char *job_id,
36
--
37
--
37
2.25.3
38
2.35.1
38
39
diff view generated by jsdifflib
1
From: Alberto Garcia <berto@igalia.com>
1
From: Hanna Reitz <hreitz@redhat.com>
2
2
3
Backing files and raw external data files are mutually exclusive.
3
Otherwise, the BDS might be freed while the job is running, which would
4
The documentation of the raw external data bit (in autoclear_features)
4
cause a use-after-free.
5
already indicates that, but we should also mention it on the other
6
side.
7
5
8
Suggested-by: Eric Blake <eblake@redhat.com>
6
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
9
Signed-off-by: Alberto Garcia <berto@igalia.com>
7
Message-Id: <20220304153729.711387-5-hreitz@redhat.com>
10
Message-Id: <20200410121816.8334-1-berto@igalia.com>
11
Reviewed-by: Eric Blake <eblake@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
---
9
---
14
docs/interop/qcow2.txt | 3 +++
10
block/amend.c | 3 +++
15
1 file changed, 3 insertions(+)
11
1 file changed, 3 insertions(+)
16
12
17
diff --git a/docs/interop/qcow2.txt b/docs/interop/qcow2.txt
13
diff --git a/block/amend.c b/block/amend.c
18
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
19
--- a/docs/interop/qcow2.txt
15
--- a/block/amend.c
20
+++ b/docs/interop/qcow2.txt
16
+++ b/block/amend.c
21
@@ -XXX,XX +XXX,XX @@ The first cluster of a qcow2 image contains the file header:
17
@@ -XXX,XX +XXX,XX @@ static void blockdev_amend_free(Job *job)
22
is stored (NB: The string is not null terminated). 0 if the
18
if (s->bs->drv->bdrv_amend_clean) {
23
image doesn't have a backing file.
19
s->bs->drv->bdrv_amend_clean(s->bs);
24
20
}
25
+ Note: backing files are incompatible with raw external data
26
+ files (auto-clear feature bit 1).
27
+
21
+
28
16 - 19: backing_file_size
22
+ bdrv_unref(s->bs);
29
Length of the backing file name in bytes. Must not be
23
}
30
longer than 1023 bytes. Undefined if the image doesn't have
24
25
static const JobDriver blockdev_amend_job_driver = {
26
@@ -XXX,XX +XXX,XX @@ void qmp_x_blockdev_amend(const char *job_id,
27
return;
28
}
29
30
+ bdrv_ref(bs);
31
s->bs = bs,
32
s->opts = QAPI_CLONE(BlockdevAmendOptions, options),
33
s->force = has_force ? force : false;
31
--
34
--
32
2.25.3
35
2.35.1
33
34
diff view generated by jsdifflib