1
The following changes since commit 79b677d658d3d35e1e776826ac4abb28cdce69b8:
1
The following changes since commit 86f4c7e05b1c44dbe1b329a51f311f10aef6ff34:
2
2
3
Merge tag 'net-pull-request' of https://github.com/jasowang/qemu into staging (2023-02-21 11:28:31 +0000)
3
Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20180302' into staging (2018-03-02 14:37:10 +0000)
4
4
5
are available in the Git repository at:
5
are available in the git repository at:
6
6
7
https://repo.or.cz/qemu/kevin.git tags/for-upstream
7
git://repo.or.cz/qemu/kevin.git tags/for-upstream
8
8
9
for you to fetch changes up to 0f385a2420d2c3f8ae7ed65fbe2712027664059e:
9
for you to fetch changes up to bfe1a14c180ec44c033be12b9151252ffda69292:
10
10
11
block/rbd: Add support for layered encryption (2023-02-23 19:49:35 +0100)
11
block: Fix NULL dereference on empty drive error (2018-03-05 18:45:32 +0100)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
Block layer patches
14
Block layer patches
15
15
16
- Lock the graph, part 2 (BlockDriver callbacks)
16
----------------------------------------------------------------
17
- virtio-scsi: fix SCSIDevice hot unplug with IOThread
17
Alberto Garcia (3):
18
- rbd: Add support for layered encryption
18
specs/qcow2: Fix documentation of the compressed cluster descriptor
19
docs: document how to use the l2-cache-entry-size parameter
20
qcow2: Replace align_offset() with ROUND_UP()
19
21
20
----------------------------------------------------------------
22
Anton Nefedov (2):
21
Emanuele Giuseppe Esposito (5):
23
block: fix write with zero flag set and iovector provided
22
block/qed: add missing graph rdlock in qed_need_check_timer_entry
24
iotest 033: add misaligned write-zeroes test via truncate
23
block: Mark bdrv_co_flush() and callers GRAPH_RDLOCK
24
block: Mark bdrv_co_pdiscard() and callers GRAPH_RDLOCK
25
block: Mark bdrv_co_copy_range() GRAPH_RDLOCK
26
block: Mark bdrv_co_is_inserted() and callers GRAPH_RDLOCK
27
25
28
Kevin Wolf (18):
26
Eric Blake (21):
29
block: Make bdrv_can_set_read_only() static
27
block: Add .bdrv_co_block_status() callback
30
mirror: Fix access of uninitialised fields during start
28
nvme: Drop pointless .bdrv_co_get_block_status()
31
block: Mark bdrv_co_truncate() and callers GRAPH_RDLOCK
29
block: Switch passthrough drivers to .bdrv_co_block_status()
32
block: Mark bdrv_co_block_status() and callers GRAPH_RDLOCK
30
file-posix: Switch to .bdrv_co_block_status()
33
block: Mark bdrv_co_ioctl() and callers GRAPH_RDLOCK
31
gluster: Switch to .bdrv_co_block_status()
34
block: Mark bdrv_co_pwrite_zeroes() and callers GRAPH_RDLOCK
32
iscsi: Switch cluster_sectors to byte-based
35
block: Mark read/write in block/io.c GRAPH_RDLOCK
33
iscsi: Switch iscsi_allocmap_update() to byte-based
36
block: Mark public read/write functions GRAPH_RDLOCK
34
iscsi: Switch to .bdrv_co_block_status()
37
block: Mark bdrv_co_pwrite_sync() and callers GRAPH_RDLOCK
35
null: Switch to .bdrv_co_block_status()
38
block: Mark bdrv_co_do_pwrite_zeroes() GRAPH_RDLOCK
36
parallels: Switch to .bdrv_co_block_status()
39
block: Mark preadv_snapshot/snapshot_block_status GRAPH_RDLOCK
37
qcow: Switch to .bdrv_co_block_status()
40
block: Mark bdrv_co_create() and callers GRAPH_RDLOCK
38
qcow2: Switch to .bdrv_co_block_status()
41
block: Mark bdrv_co_io_(un)plug() and callers GRAPH_RDLOCK
39
qed: Switch to .bdrv_co_block_status()
42
block: Mark bdrv_co_eject/lock_medium() and callers GRAPH_RDLOCK
40
raw: Switch to .bdrv_co_block_status()
43
block: Mark bdrv_(un)register_buf() GRAPH_RDLOCK
41
sheepdog: Switch to .bdrv_co_block_status()
44
block: Mark bdrv_co_delete_file() and callers GRAPH_RDLOCK
42
vdi: Avoid bitrot of debugging code
45
block: Mark bdrv_*_dirty_bitmap() and callers GRAPH_RDLOCK
43
vdi: Switch to .bdrv_co_block_status()
46
block: Mark bdrv_co_refresh_total_sectors() and callers GRAPH_RDLOCK
44
vmdk: Switch to .bdrv_co_block_status()
45
vpc: Switch to .bdrv_co_block_status()
46
vvfat: Switch to .bdrv_co_block_status()
47
block: Drop unused .bdrv_co_get_block_status()
47
48
48
Or Ozeri (3):
49
Kevin Wolf (3):
49
block/rbd: Remove redundant stack variable passphrase_len
50
block: test blk_aio_flush() with blk->root == NULL
50
block/rbd: Add luks-any encryption opening option
51
Merge remote-tracking branch 'mreitz/tags/pull-block-2018-03-02' into queue-block
51
block/rbd: Add support for layered encryption
52
block: Fix NULL dereference on empty drive error
52
53
53
Stefan Hajnoczi (3):
54
Max Reitz (4):
54
scsi: protect req->aiocb with AioContext lock
55
qemu-img: Make resize error message more general
55
dma-helpers: prevent dma_blk_cb() vs dma_aio_cancel() race
56
block/ssh: Pull ssh_grow_file() from ssh_create()
56
virtio-scsi: reset SCSI devices from main loop thread
57
block/ssh: Make ssh_grow_file() blocking
58
block/ssh: Add basic .bdrv_truncate()
57
59
58
qapi/block-core.json | 27 +++++-
60
Stefan Hajnoczi (6):
59
block/coroutines.h | 2 +-
61
aio: rename aio_context_in_iothread() to in_aio_context_home_thread()
60
block/qcow2.h | 27 ++++--
62
block: extract AIO_WAIT_WHILE() from BlockDriverState
61
block/qed.h | 45 +++++----
63
block: add BlockBackend->in_flight counter
62
include/block/block-copy.h | 6 +-
64
Revert "IDE: Do not flush empty CDROM drives"
63
include/block/block-global-state.h | 14 +--
65
block: rename .bdrv_create() to .bdrv_co_create_opts()
64
include/block/block-io.h | 110 ++++++++++++----------
66
qcow2: make qcow2_co_create2() a coroutine_fn
65
include/block/block_int-common.h | 173 ++++++++++++++++++----------------
67
66
include/block/block_int-io.h | 53 ++++++-----
68
qapi/block-core.json | 6 +-
67
include/block/dirty-bitmap.h | 12 +--
69
docs/interop/qcow2.txt | 16 ++++-
68
include/hw/virtio/virtio-scsi.h | 11 ++-
70
docs/qcow2-cache.txt | 46 ++++++++++++-
69
include/sysemu/block-backend-io.h | 7 +-
71
block/qcow2.h | 6 --
70
block.c | 12 ++-
72
include/block/aio-wait.h | 116 ++++++++++++++++++++++++++++++++
71
block/backup.c | 3 +
73
include/block/aio.h | 7 +-
72
block/blkdebug.c | 19 ++--
74
include/block/block.h | 54 ++++-----------
73
block/blklogwrites.c | 35 ++++---
75
include/block/block_int.h | 61 ++++++++++-------
74
block/blkreplay.c | 24 +++--
76
block.c | 11 ++-
75
block/blkverify.c | 5 +-
77
block/blkdebug.c | 20 +++---
76
block/block-backend.c | 39 +++++---
78
block/block-backend.c | 65 +++++++++++++++---
77
block/block-copy.c | 32 ++++---
79
block/commit.c | 2 +-
78
block/bochs.c | 2 +-
80
block/crypto.c | 8 +--
79
block/commit.c | 5 +-
81
block/file-posix.c | 79 +++++++++++-----------
80
block/copy-before-write.c | 33 ++++---
82
block/file-win32.c | 5 +-
81
block/copy-on-read.c | 44 +++++----
83
block/gluster.c | 83 ++++++++++++-----------
82
block/create.c | 9 +-
84
block/io.c | 98 +++++++++++----------------
83
block/crypto.c | 16 ++--
85
block/iscsi.c | 164 ++++++++++++++++++++++++---------------------
84
block/dirty-bitmap.c | 2 +
86
block/mirror.c | 2 +-
85
block/file-posix.c | 27 +++---
87
block/nfs.c | 5 +-
86
block/file-win32.c | 7 +-
88
block/null.c | 23 ++++---
87
block/filter-compress.c | 36 ++++---
89
block/nvme.c | 14 ----
88
block/io.c | 108 +++++++++++++--------
90
block/parallels.c | 28 +++++---
89
block/iscsi.c | 28 +++---
91
block/qcow.c | 32 +++++----
90
block/mirror.c | 59 ++++++++----
92
block/qcow2-bitmap.c | 4 +-
91
block/parallels.c | 33 +++----
93
block/qcow2-cluster.c | 4 +-
92
block/preallocate.c | 38 ++++----
94
block/qcow2-refcount.c | 4 +-
93
block/qcow.c | 46 +++++----
95
block/qcow2-snapshot.c | 10 +--
94
block/qcow2-cluster.c | 17 ++--
96
block/qcow2.c | 60 +++++++++--------
95
block/qcow2.c | 136 +++++++++++++++------------
97
block/qed.c | 82 ++++++++---------------
96
block/qed-check.c | 3 +-
98
block/raw-format.c | 21 +++---
97
block/qed-table.c | 10 +-
99
block/rbd.c | 6 +-
98
block/qed.c | 101 ++++++++++----------
100
block/sheepdog.c | 36 +++++-----
99
block/quorum.c | 62 +++++++-----
101
block/ssh.c | 66 +++++++++++++++---
100
block/raw-format.c | 76 ++++++++-------
102
block/throttle.c | 2 +-
101
block/rbd.c | 188 ++++++++++++++++++++++++++++++++++---
103
block/vdi.c | 50 +++++++-------
102
block/replication.c | 18 ++--
104
block/vhdx.c | 5 +-
103
block/snapshot-access.c | 8 +-
105
block/vmdk.c | 43 +++++-------
104
block/stream.c | 40 ++++----
106
block/vpc.c | 50 +++++++-------
105
block/throttle.c | 36 ++++---
107
block/vvfat.c | 16 ++---
106
block/vdi.c | 11 +--
108
hw/ide/core.c | 10 +--
107
block/vhdx.c | 18 ++--
109
qemu-img.c | 2 +-
108
block/vmdk.c | 132 ++++++++++++--------------
110
tests/test-block-backend.c | 82 +++++++++++++++++++++++
109
block/vpc.c | 11 +--
111
util/aio-wait.c | 40 +++++++++++
110
hw/scsi/scsi-disk.c | 23 +++--
112
tests/Makefile.include | 2 +
111
hw/scsi/scsi-generic.c | 11 ++-
113
tests/qemu-iotests/033 | 29 ++++++++
112
hw/scsi/virtio-scsi.c | 169 ++++++++++++++++++++++++++-------
114
tests/qemu-iotests/033.out | 13 ++++
113
qemu-img.c | 8 +-
115
util/Makefile.objs | 2 +-
114
softmmu/dma-helpers.c | 12 ++-
116
48 files changed, 980 insertions(+), 610 deletions(-)
115
tests/unit/test-bdrv-drain.c | 20 ++--
117
create mode 100644 include/block/aio-wait.h
116
tests/unit/test-block-iothread.c | 3 +-
118
create mode 100644 tests/test-block-backend.c
117
59 files changed, 1355 insertions(+), 907 deletions(-)
119
create mode 100644 util/aio-wait.c
120
diff view generated by jsdifflib
Deleted patch
1
It is never called outside of block.c.
2
1
3
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
4
Message-Id: <20230203152202.49054-2-kwolf@redhat.com>
5
Reviewed-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
6
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
---
9
include/block/block-io.h | 2 --
10
block.c | 4 ++--
11
2 files changed, 2 insertions(+), 4 deletions(-)
12
13
diff --git a/include/block/block-io.h b/include/block/block-io.h
14
index XXXXXXX..XXXXXXX 100644
15
--- a/include/block/block-io.h
16
+++ b/include/block/block-io.h
17
@@ -XXX,XX +XXX,XX @@ int bdrv_is_allocated_above(BlockDriverState *top, BlockDriverState *base,
18
int coroutine_fn bdrv_co_is_zero_fast(BlockDriverState *bs, int64_t offset,
19
int64_t bytes);
20
21
-int bdrv_can_set_read_only(BlockDriverState *bs, bool read_only,
22
- bool ignore_allow_rdw, Error **errp);
23
int bdrv_apply_auto_read_only(BlockDriverState *bs, const char *errmsg,
24
Error **errp);
25
bool bdrv_is_read_only(BlockDriverState *bs);
26
diff --git a/block.c b/block.c
27
index XXXXXXX..XXXXXXX 100644
28
--- a/block.c
29
+++ b/block.c
30
@@ -XXX,XX +XXX,XX @@ bool bdrv_is_read_only(BlockDriverState *bs)
31
return !(bs->open_flags & BDRV_O_RDWR);
32
}
33
34
-int bdrv_can_set_read_only(BlockDriverState *bs, bool read_only,
35
- bool ignore_allow_rdw, Error **errp)
36
+static int bdrv_can_set_read_only(BlockDriverState *bs, bool read_only,
37
+ bool ignore_allow_rdw, Error **errp)
38
{
39
IO_CODE();
40
41
--
42
2.39.2
diff view generated by jsdifflib
Deleted patch
1
bdrv_mirror_top_pwritev() accesses the job object when active mirroring
2
is enabled. It disables this code during early initialisation while
3
s->job isn't set yet.
4
1
5
However, s->job is still set way too early when the job object isn't
6
fully initialised. For example, &s->ops_in_flight isn't initialised yet
7
and the in_flight bitmap doesn't exist yet. This causes crashes when a
8
write request comes in too early.
9
10
Move the assignment of s->job to when the mirror job is actually fully
11
initialised to make sure that the mirror_top driver doesn't access it
12
too early.
13
14
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
15
Message-Id: <20230203152202.49054-3-kwolf@redhat.com>
16
Reviewed-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
17
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
18
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
19
---
20
block/mirror.c | 8 +++++++-
21
1 file changed, 7 insertions(+), 1 deletion(-)
22
23
diff --git a/block/mirror.c b/block/mirror.c
24
index XXXXXXX..XXXXXXX 100644
25
--- a/block/mirror.c
26
+++ b/block/mirror.c
27
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn mirror_run(Job *job, Error **errp)
28
{
29
MirrorBlockJob *s = container_of(job, MirrorBlockJob, common.job);
30
BlockDriverState *bs = s->mirror_top_bs->backing->bs;
31
+ MirrorBDSOpaque *mirror_top_opaque = s->mirror_top_bs->opaque;
32
BlockDriverState *target_bs = blk_bs(s->target);
33
bool need_drain = true;
34
BlockDeviceIoStatus iostatus;
35
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn mirror_run(Job *job, Error **errp)
36
}
37
}
38
39
+ /*
40
+ * Only now the job is fully initialised and mirror_top_bs should start
41
+ * accessing it.
42
+ */
43
+ mirror_top_opaque->job = s;
44
+
45
assert(!s->dbi);
46
s->dbi = bdrv_dirty_iter_new(s->dirty_bitmap);
47
for (;;) {
48
@@ -XXX,XX +XXX,XX @@ static BlockJob *mirror_start_job(
49
if (!s) {
50
goto fail;
51
}
52
- bs_opaque->job = s;
53
54
/* The block job now has a reference to this node */
55
bdrv_unref(mirror_top_bs);
56
--
57
2.39.2
diff view generated by jsdifflib
Deleted patch
1
This adds GRAPH_RDLOCK annotations to declare that callers of
2
bdrv_co_truncate() need to hold a reader lock for the graph.
3
1
4
For some places, we know that they will hold the lock, but we don't have
5
the GRAPH_RDLOCK annotations yet. In this case, add assume_graph_lock()
6
with a FIXME comment. These places will be removed once everything is
7
properly annotated.
8
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
Message-Id: <20230203152202.49054-4-kwolf@redhat.com>
11
Reviewed-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
---
14
include/block/block-io.h | 6 +++---
15
include/block/block_int-common.h | 7 ++++---
16
block/block-backend.c | 1 +
17
block/crypto.c | 2 +-
18
block/io.c | 1 +
19
block/parallels.c | 14 ++++++++------
20
block/preallocate.c | 2 +-
21
block/qcow.c | 17 ++++++++++++-----
22
block/qcow2.c | 14 ++++++++------
23
block/raw-format.c | 6 +++---
24
block/vmdk.c | 2 ++
25
11 files changed, 44 insertions(+), 28 deletions(-)
26
27
diff --git a/include/block/block-io.h b/include/block/block-io.h
28
index XXXXXXX..XXXXXXX 100644
29
--- a/include/block/block-io.h
30
+++ b/include/block/block-io.h
31
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_pwrite_sync(BdrvChild *child, int64_t offset,
32
int coroutine_fn bdrv_co_pwrite_zeroes(BdrvChild *child, int64_t offset,
33
int64_t bytes, BdrvRequestFlags flags);
34
35
-int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact,
36
- PreallocMode prealloc, BdrvRequestFlags flags,
37
- Error **errp);
38
+int coroutine_fn GRAPH_RDLOCK
39
+bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact,
40
+ PreallocMode prealloc, BdrvRequestFlags flags, Error **errp);
41
42
int64_t coroutine_fn bdrv_co_nb_sectors(BlockDriverState *bs);
43
int64_t co_wrapper_mixed bdrv_nb_sectors(BlockDriverState *bs);
44
diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h
45
index XXXXXXX..XXXXXXX 100644
46
--- a/include/block/block_int-common.h
47
+++ b/include/block/block_int-common.h
48
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
49
* If @exact is true and this function fails but would succeed
50
* with @exact = false, it should return -ENOTSUP.
51
*/
52
- int coroutine_fn (*bdrv_co_truncate)(BlockDriverState *bs, int64_t offset,
53
- bool exact, PreallocMode prealloc,
54
- BdrvRequestFlags flags, Error **errp);
55
+ int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_truncate)(
56
+ BlockDriverState *bs, int64_t offset, bool exact,
57
+ PreallocMode prealloc, BdrvRequestFlags flags, Error **errp);
58
+
59
int64_t coroutine_fn (*bdrv_co_getlength)(BlockDriverState *bs);
60
int64_t coroutine_fn (*bdrv_co_get_allocated_file_size)(
61
BlockDriverState *bs);
62
diff --git a/block/block-backend.c b/block/block-backend.c
63
index XXXXXXX..XXXXXXX 100644
64
--- a/block/block-backend.c
65
+++ b/block/block-backend.c
66
@@ -XXX,XX +XXX,XX @@ int coroutine_fn blk_co_truncate(BlockBackend *blk, int64_t offset, bool exact,
67
Error **errp)
68
{
69
IO_OR_GS_CODE();
70
+ GRAPH_RDLOCK_GUARD();
71
if (!blk_is_available(blk)) {
72
error_setg(errp, "No medium inserted");
73
return -ENOMEDIUM;
74
diff --git a/block/crypto.c b/block/crypto.c
75
index XXXXXXX..XXXXXXX 100644
76
--- a/block/crypto.c
77
+++ b/block/crypto.c
78
@@ -XXX,XX +XXX,XX @@ block_crypto_co_create_generic(BlockDriverState *bs, int64_t size,
79
return ret;
80
}
81
82
-static int coroutine_fn
83
+static int coroutine_fn GRAPH_RDLOCK
84
block_crypto_co_truncate(BlockDriverState *bs, int64_t offset, bool exact,
85
PreallocMode prealloc, BdrvRequestFlags flags,
86
Error **errp)
87
diff --git a/block/io.c b/block/io.c
88
index XXXXXXX..XXXXXXX 100644
89
--- a/block/io.c
90
+++ b/block/io.c
91
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact,
92
int64_t old_size, new_bytes;
93
int ret;
94
IO_CODE();
95
+ assert_bdrv_graph_readable();
96
97
/* if bs->drv == NULL, bs is closed, so there's nothing to do here */
98
if (!drv) {
99
diff --git a/block/parallels.c b/block/parallels.c
100
index XXXXXXX..XXXXXXX 100644
101
--- a/block/parallels.c
102
+++ b/block/parallels.c
103
@@ -XXX,XX +XXX,XX @@ static int64_t block_status(BDRVParallelsState *s, int64_t sector_num,
104
return start_off;
105
}
106
107
-static coroutine_fn int64_t allocate_clusters(BlockDriverState *bs,
108
- int64_t sector_num,
109
- int nb_sectors, int *pnum)
110
+static int64_t coroutine_fn GRAPH_RDLOCK
111
+allocate_clusters(BlockDriverState *bs, int64_t sector_num,
112
+ int nb_sectors, int *pnum)
113
{
114
int ret = 0;
115
BDRVParallelsState *s = bs->opaque;
116
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int parallels_co_writev(BlockDriverState *bs,
117
QEMUIOVector hd_qiov;
118
int ret = 0;
119
120
+ assume_graph_lock(); /* FIXME */
121
+
122
qemu_iovec_init(&hd_qiov, qiov->niov);
123
124
while (nb_sectors > 0) {
125
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int parallels_co_readv(BlockDriverState *bs,
126
}
127
128
129
-static int coroutine_fn parallels_co_check(BlockDriverState *bs,
130
- BdrvCheckResult *res,
131
- BdrvCheckMode fix)
132
+static int coroutine_fn GRAPH_RDLOCK
133
+parallels_co_check(BlockDriverState *bs, BdrvCheckResult *res,
134
+ BdrvCheckMode fix)
135
{
136
BDRVParallelsState *s = bs->opaque;
137
int64_t size, prev_off, high_off;
138
diff --git a/block/preallocate.c b/block/preallocate.c
139
index XXXXXXX..XXXXXXX 100644
140
--- a/block/preallocate.c
141
+++ b/block/preallocate.c
142
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int preallocate_co_pwritev_part(BlockDriverState *bs,
143
flags);
144
}
145
146
-static int coroutine_fn
147
+static int coroutine_fn GRAPH_RDLOCK
148
preallocate_co_truncate(BlockDriverState *bs, int64_t offset,
149
bool exact, PreallocMode prealloc,
150
BdrvRequestFlags flags, Error **errp)
151
diff --git a/block/qcow.c b/block/qcow.c
152
index XXXXXXX..XXXXXXX 100644
153
--- a/block/qcow.c
154
+++ b/block/qcow.c
155
@@ -XXX,XX +XXX,XX @@ static int qcow_reopen_prepare(BDRVReopenState *state,
156
* return 0 if not allocated, 1 if *result is assigned, and negative
157
* errno on failure.
158
*/
159
-static int coroutine_fn get_cluster_offset(BlockDriverState *bs,
160
- uint64_t offset, int allocate,
161
- int compressed_size,
162
- int n_start, int n_end,
163
- uint64_t *result)
164
+static int coroutine_fn GRAPH_RDLOCK
165
+get_cluster_offset(BlockDriverState *bs, uint64_t offset, int allocate,
166
+ int compressed_size, int n_start, int n_end,
167
+ uint64_t *result)
168
{
169
BDRVQcowState *s = bs->opaque;
170
int min_index, i, j, l1_index, l2_index, ret;
171
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow_co_block_status(BlockDriverState *bs,
172
int64_t n;
173
uint64_t cluster_offset;
174
175
+ assume_graph_lock(); /* FIXME */
176
+
177
qemu_co_mutex_lock(&s->lock);
178
ret = get_cluster_offset(bs, offset, 0, 0, 0, 0, &cluster_offset);
179
qemu_co_mutex_unlock(&s->lock);
180
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow_co_preadv(BlockDriverState *bs, int64_t offset,
181
uint8_t *buf;
182
void *orig_buf;
183
184
+ assume_graph_lock(); /* FIXME */
185
+
186
if (qiov->niov > 1) {
187
buf = orig_buf = qemu_try_blockalign(bs, qiov->size);
188
if (buf == NULL) {
189
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow_co_pwritev(BlockDriverState *bs, int64_t offset,
190
uint8_t *buf;
191
void *orig_buf;
192
193
+ assume_graph_lock(); /* FIXME */
194
+
195
s->cluster_cache_offset = -1; /* disable compressed cache */
196
197
/* We must always copy the iov when encrypting, so we
198
@@ -XXX,XX +XXX,XX @@ qcow_co_pwritev_compressed(BlockDriverState *bs, int64_t offset, int64_t bytes,
199
uint8_t *buf, *out_buf;
200
uint64_t cluster_offset;
201
202
+ assume_graph_lock(); /* FIXME */
203
+
204
buf = qemu_blockalign(bs, s->cluster_size);
205
if (bytes != s->cluster_size) {
206
if (bytes > s->cluster_size ||
207
diff --git a/block/qcow2.c b/block/qcow2.c
208
index XXXXXXX..XXXXXXX 100644
209
--- a/block/qcow2.c
210
+++ b/block/qcow2.c
211
@@ -XXX,XX +XXX,XX @@ static int qcow2_set_up_encryption(BlockDriverState *bs,
212
*
213
* Returns: 0 on success, -errno on failure.
214
*/
215
-static int coroutine_fn preallocate_co(BlockDriverState *bs, uint64_t offset,
216
- uint64_t new_length, PreallocMode mode,
217
- Error **errp)
218
+static int coroutine_fn GRAPH_RDLOCK
219
+preallocate_co(BlockDriverState *bs, uint64_t offset, uint64_t new_length,
220
+ PreallocMode mode, Error **errp)
221
{
222
BDRVQcow2State *s = bs->opaque;
223
uint64_t bytes;
224
@@ -XXX,XX +XXX,XX @@ fail:
225
return ret;
226
}
227
228
-static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
229
- bool exact, PreallocMode prealloc,
230
- BdrvRequestFlags flags, Error **errp)
231
+static int coroutine_fn GRAPH_RDLOCK
232
+qcow2_co_truncate(BlockDriverState *bs, int64_t offset, bool exact,
233
+ PreallocMode prealloc, BdrvRequestFlags flags, Error **errp)
234
{
235
BDRVQcow2State *s = bs->opaque;
236
uint64_t old_length;
237
@@ -XXX,XX +XXX,XX @@ qcow2_co_pwritev_compressed_part(BlockDriverState *bs,
238
AioTaskPool *aio = NULL;
239
int ret = 0;
240
241
+ assume_graph_lock(); /* FIXME */
242
+
243
if (has_data_file(bs)) {
244
return -ENOTSUP;
245
}
246
diff --git a/block/raw-format.c b/block/raw-format.c
247
index XXXXXXX..XXXXXXX 100644
248
--- a/block/raw-format.c
249
+++ b/block/raw-format.c
250
@@ -XXX,XX +XXX,XX @@ static void raw_refresh_limits(BlockDriverState *bs, Error **errp)
251
}
252
}
253
254
-static int coroutine_fn raw_co_truncate(BlockDriverState *bs, int64_t offset,
255
- bool exact, PreallocMode prealloc,
256
- BdrvRequestFlags flags, Error **errp)
257
+static int coroutine_fn GRAPH_RDLOCK
258
+raw_co_truncate(BlockDriverState *bs, int64_t offset, bool exact,
259
+ PreallocMode prealloc, BdrvRequestFlags flags, Error **errp)
260
{
261
BDRVRawState *s = bs->opaque;
262
263
diff --git a/block/vmdk.c b/block/vmdk.c
264
index XXXXXXX..XXXXXXX 100644
265
--- a/block/vmdk.c
266
+++ b/block/vmdk.c
267
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn
268
vmdk_co_pwritev_compressed(BlockDriverState *bs, int64_t offset, int64_t bytes,
269
QEMUIOVector *qiov)
270
{
271
+ assume_graph_lock(); /* FIXME */
272
+
273
if (bytes == 0) {
274
/* The caller will write bytes 0 to signal EOF.
275
* When receive it, we align EOF to a sector boundary. */
276
--
277
2.39.2
diff view generated by jsdifflib
Deleted patch
1
This adds GRAPH_RDLOCK annotations to declare that callers of
2
bdrv_co_block_status() need to hold a reader lock for the graph.
3
1
4
For some places, we know that they will hold the lock, but we don't have
5
the GRAPH_RDLOCK annotations yet. In this case, add assume_graph_lock()
6
with a FIXME comment. These places will be removed once everything is
7
properly annotated.
8
9
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
Message-Id: <20230203152202.49054-5-kwolf@redhat.com>
12
Reviewed-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
13
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
---
15
block/coroutines.h | 2 +-
16
include/block/block-copy.h | 6 +++---
17
include/block/block-io.h | 22 +++++++++++-----------
18
include/block/block_int-common.h | 3 ++-
19
block/backup.c | 3 +++
20
block/block-backend.c | 2 ++
21
block/block-copy.c | 19 +++++++++++--------
22
block/io.c | 13 ++++++++-----
23
block/mirror.c | 14 +++++++++-----
24
block/qcow.c | 11 ++++-------
25
block/quorum.c | 9 ++++-----
26
block/stream.c | 32 ++++++++++++++++++--------------
27
qemu-img.c | 4 +++-
28
tests/unit/test-block-iothread.c | 3 ++-
29
14 files changed, 81 insertions(+), 62 deletions(-)
30
31
diff --git a/block/coroutines.h b/block/coroutines.h
32
index XXXXXXX..XXXXXXX 100644
33
--- a/block/coroutines.h
34
+++ b/block/coroutines.h
35
@@ -XXX,XX +XXX,XX @@ bdrv_co_check(BlockDriverState *bs, BdrvCheckResult *res, BdrvCheckMode fix);
36
int coroutine_fn GRAPH_RDLOCK
37
bdrv_co_invalidate_cache(BlockDriverState *bs, Error **errp);
38
39
-int coroutine_fn
40
+int coroutine_fn GRAPH_RDLOCK
41
bdrv_co_common_block_status_above(BlockDriverState *bs,
42
BlockDriverState *base,
43
bool include_base,
44
diff --git a/include/block/block-copy.h b/include/block/block-copy.h
45
index XXXXXXX..XXXXXXX 100644
46
--- a/include/block/block-copy.h
47
+++ b/include/block/block-copy.h
48
@@ -XXX,XX +XXX,XX @@ void block_copy_set_progress_meter(BlockCopyState *s, ProgressMeter *pm);
49
void block_copy_state_free(BlockCopyState *s);
50
51
void block_copy_reset(BlockCopyState *s, int64_t offset, int64_t bytes);
52
-int64_t coroutine_fn block_copy_reset_unallocated(BlockCopyState *s,
53
- int64_t offset,
54
- int64_t *count);
55
+
56
+int64_t coroutine_fn GRAPH_RDLOCK
57
+block_copy_reset_unallocated(BlockCopyState *s, int64_t offset, int64_t *count);
58
59
int coroutine_fn block_copy(BlockCopyState *s, int64_t offset, int64_t bytes,
60
bool ignore_ratelimit, uint64_t timeout_ns,
61
diff --git a/include/block/block-io.h b/include/block/block-io.h
62
index XXXXXXX..XXXXXXX 100644
63
--- a/include/block/block-io.h
64
+++ b/include/block/block-io.h
65
@@ -XXX,XX +XXX,XX @@ int bdrv_block_status(BlockDriverState *bs, int64_t offset,
66
int64_t bytes, int64_t *pnum, int64_t *map,
67
BlockDriverState **file);
68
69
-int coroutine_fn bdrv_co_block_status_above(BlockDriverState *bs,
70
- BlockDriverState *base,
71
- int64_t offset, int64_t bytes,
72
- int64_t *pnum, int64_t *map,
73
- BlockDriverState **file);
74
+int coroutine_fn GRAPH_RDLOCK
75
+bdrv_co_block_status_above(BlockDriverState *bs, BlockDriverState *base,
76
+ int64_t offset, int64_t bytes, int64_t *pnum,
77
+ int64_t *map, BlockDriverState **file);
78
int bdrv_block_status_above(BlockDriverState *bs, BlockDriverState *base,
79
int64_t offset, int64_t bytes, int64_t *pnum,
80
int64_t *map, BlockDriverState **file);
81
82
-int coroutine_fn bdrv_co_is_allocated(BlockDriverState *bs, int64_t offset,
83
- int64_t bytes, int64_t *pnum);
84
+int coroutine_fn GRAPH_RDLOCK
85
+bdrv_co_is_allocated(BlockDriverState *bs, int64_t offset, int64_t bytes,
86
+ int64_t *pnum);
87
int bdrv_is_allocated(BlockDriverState *bs, int64_t offset, int64_t bytes,
88
int64_t *pnum);
89
90
-int coroutine_fn bdrv_co_is_allocated_above(BlockDriverState *top,
91
- BlockDriverState *base,
92
- bool include_base, int64_t offset,
93
- int64_t bytes, int64_t *pnum);
94
+int coroutine_fn GRAPH_RDLOCK
95
+bdrv_co_is_allocated_above(BlockDriverState *top, BlockDriverState *base,
96
+ bool include_base, int64_t offset, int64_t bytes,
97
+ int64_t *pnum);
98
int bdrv_is_allocated_above(BlockDriverState *top, BlockDriverState *base,
99
bool include_base, int64_t offset, int64_t bytes,
100
int64_t *pnum);
101
diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h
102
index XXXXXXX..XXXXXXX 100644
103
--- a/include/block/block_int-common.h
104
+++ b/include/block/block_int-common.h
105
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
106
* *pnum value for the block-status cache on protocol nodes, prior
107
* to clamping *pnum for return to its caller.
108
*/
109
- int coroutine_fn (*bdrv_co_block_status)(BlockDriverState *bs,
110
+ int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_block_status)(
111
+ BlockDriverState *bs,
112
bool want_zero, int64_t offset, int64_t bytes, int64_t *pnum,
113
int64_t *map, BlockDriverState **file);
114
115
diff --git a/block/backup.c b/block/backup.c
116
index XXXXXXX..XXXXXXX 100644
117
--- a/block/backup.c
118
+++ b/block/backup.c
119
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn backup_run(Job *job, Error **errp)
120
return -ECANCELED;
121
}
122
123
+ /* rdlock protects the subsequent call to bdrv_is_allocated() */
124
+ bdrv_graph_co_rdlock();
125
ret = block_copy_reset_unallocated(s->bcs, offset, &count);
126
+ bdrv_graph_co_rdunlock();
127
if (ret < 0) {
128
return ret;
129
}
130
diff --git a/block/block-backend.c b/block/block-backend.c
131
index XXXXXXX..XXXXXXX 100644
132
--- a/block/block-backend.c
133
+++ b/block/block-backend.c
134
@@ -XXX,XX +XXX,XX @@ int coroutine_fn blk_co_block_status_above(BlockBackend *blk,
135
BlockDriverState **file)
136
{
137
IO_CODE();
138
+ GRAPH_RDLOCK_GUARD();
139
return bdrv_co_block_status_above(blk_bs(blk), base, offset, bytes, pnum,
140
map, file);
141
}
142
@@ -XXX,XX +XXX,XX @@ int coroutine_fn blk_co_is_allocated_above(BlockBackend *blk,
143
int64_t bytes, int64_t *pnum)
144
{
145
IO_CODE();
146
+ GRAPH_RDLOCK_GUARD();
147
return bdrv_co_is_allocated_above(blk_bs(blk), base, include_base, offset,
148
bytes, pnum);
149
}
150
diff --git a/block/block-copy.c b/block/block-copy.c
151
index XXXXXXX..XXXXXXX 100644
152
--- a/block/block-copy.c
153
+++ b/block/block-copy.c
154
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int block_copy_task_entry(AioTask *task)
155
return ret;
156
}
157
158
-static coroutine_fn int block_copy_block_status(BlockCopyState *s,
159
- int64_t offset,
160
- int64_t bytes, int64_t *pnum)
161
+static coroutine_fn GRAPH_RDLOCK
162
+int block_copy_block_status(BlockCopyState *s, int64_t offset, int64_t bytes,
163
+ int64_t *pnum)
164
{
165
int64_t num;
166
BlockDriverState *base;
167
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int block_copy_block_status(BlockCopyState *s,
168
* Check if the cluster starting at offset is allocated or not.
169
* return via pnum the number of contiguous clusters sharing this allocation.
170
*/
171
-static int coroutine_fn block_copy_is_cluster_allocated(BlockCopyState *s,
172
- int64_t offset,
173
- int64_t *pnum)
174
+static int coroutine_fn GRAPH_RDLOCK
175
+block_copy_is_cluster_allocated(BlockCopyState *s, int64_t offset,
176
+ int64_t *pnum)
177
{
178
BlockDriverState *bs = s->source->bs;
179
int64_t count, total_count = 0;
180
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn block_copy_is_cluster_allocated(BlockCopyState *s,
181
assert(QEMU_IS_ALIGNED(offset, s->cluster_size));
182
183
while (true) {
184
+ /* protected in backup_run() */
185
ret = bdrv_co_is_allocated(bs, offset, bytes, &count);
186
if (ret < 0) {
187
return ret;
188
@@ -XXX,XX +XXX,XX @@ int64_t coroutine_fn block_copy_reset_unallocated(BlockCopyState *s,
189
* Returns 1 if dirty clusters found and successfully copied, 0 if no dirty
190
* clusters found and -errno on failure.
191
*/
192
-static int coroutine_fn
193
+static int coroutine_fn GRAPH_RDLOCK
194
block_copy_dirty_clusters(BlockCopyCallState *call_state)
195
{
196
BlockCopyState *s = call_state->s;
197
@@ -XXX,XX +XXX,XX @@ void block_copy_kick(BlockCopyCallState *call_state)
198
* it means that some I/O operation failed in context of _this_ block_copy call,
199
* not some parallel operation.
200
*/
201
-static int coroutine_fn block_copy_common(BlockCopyCallState *call_state)
202
+static int coroutine_fn GRAPH_RDLOCK
203
+block_copy_common(BlockCopyCallState *call_state)
204
{
205
int ret;
206
BlockCopyState *s = call_state->s;
207
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn block_copy_common(BlockCopyCallState *call_state)
208
209
static void coroutine_fn block_copy_async_co_entry(void *opaque)
210
{
211
+ GRAPH_RDLOCK_GUARD();
212
block_copy_common(opaque);
213
}
214
215
diff --git a/block/io.c b/block/io.c
216
index XXXXXXX..XXXXXXX 100644
217
--- a/block/io.c
218
+++ b/block/io.c
219
@@ -XXX,XX +XXX,XX @@ int bdrv_flush_all(void)
220
* BDRV_BLOCK_OFFSET_VALID bit is set, 'map' and 'file' (if non-NULL) are
221
* set to the host mapping and BDS corresponding to the guest offset.
222
*/
223
-static int coroutine_fn bdrv_co_block_status(BlockDriverState *bs,
224
- bool want_zero,
225
- int64_t offset, int64_t bytes,
226
- int64_t *pnum, int64_t *map,
227
- BlockDriverState **file)
228
+static int coroutine_fn GRAPH_RDLOCK
229
+bdrv_co_block_status(BlockDriverState *bs, bool want_zero,
230
+ int64_t offset, int64_t bytes,
231
+ int64_t *pnum, int64_t *map, BlockDriverState **file)
232
{
233
int64_t total_size;
234
int64_t n; /* bytes */
235
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_co_block_status(BlockDriverState *bs,
236
bool has_filtered_child;
237
238
assert(pnum);
239
+ assert_bdrv_graph_readable();
240
*pnum = 0;
241
total_size = bdrv_getlength(bs);
242
if (total_size < 0) {
243
@@ -XXX,XX +XXX,XX @@ bdrv_co_common_block_status_above(BlockDriverState *bs,
244
IO_CODE();
245
246
assert(!include_base || base); /* Can't include NULL base */
247
+ assert_bdrv_graph_readable();
248
249
if (!depth) {
250
depth = &dummy;
251
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_is_zero_fast(BlockDriverState *bs, int64_t offset,
252
int64_t pnum = bytes;
253
IO_CODE();
254
255
+ assume_graph_lock(); /* FIXME */
256
+
257
if (!bytes) {
258
return 1;
259
}
260
diff --git a/block/mirror.c b/block/mirror.c
261
index XXXXXXX..XXXXXXX 100644
262
--- a/block/mirror.c
263
+++ b/block/mirror.c
264
@@ -XXX,XX +XXX,XX @@ static uint64_t coroutine_fn mirror_iteration(MirrorBlockJob *s)
265
MirrorMethod mirror_method = MIRROR_METHOD_COPY;
266
267
assert(!(offset % s->granularity));
268
- ret = bdrv_block_status_above(source, NULL, offset,
269
- nb_chunks * s->granularity,
270
- &io_bytes, NULL, NULL);
271
+ WITH_GRAPH_RDLOCK_GUARD() {
272
+ ret = bdrv_block_status_above(source, NULL, offset,
273
+ nb_chunks * s->granularity,
274
+ &io_bytes, NULL, NULL);
275
+ }
276
if (ret < 0) {
277
io_bytes = MIN(nb_chunks * s->granularity, max_io_bytes);
278
} else if (ret & BDRV_BLOCK_DATA) {
279
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn mirror_dirty_init(MirrorBlockJob *s)
280
return 0;
281
}
282
283
- ret = bdrv_is_allocated_above(bs, s->base_overlay, true, offset, bytes,
284
- &count);
285
+ WITH_GRAPH_RDLOCK_GUARD() {
286
+ ret = bdrv_is_allocated_above(bs, s->base_overlay, true, offset,
287
+ bytes, &count);
288
+ }
289
if (ret < 0) {
290
return ret;
291
}
292
diff --git a/block/qcow.c b/block/qcow.c
293
index XXXXXXX..XXXXXXX 100644
294
--- a/block/qcow.c
295
+++ b/block/qcow.c
296
@@ -XXX,XX +XXX,XX @@ get_cluster_offset(BlockDriverState *bs, uint64_t offset, int allocate,
297
return 1;
298
}
299
300
-static int coroutine_fn qcow_co_block_status(BlockDriverState *bs,
301
- bool want_zero,
302
- int64_t offset, int64_t bytes,
303
- int64_t *pnum, int64_t *map,
304
- BlockDriverState **file)
305
+static int coroutine_fn GRAPH_RDLOCK
306
+qcow_co_block_status(BlockDriverState *bs, bool want_zero,
307
+ int64_t offset, int64_t bytes, int64_t *pnum,
308
+ int64_t *map, BlockDriverState **file)
309
{
310
BDRVQcowState *s = bs->opaque;
311
int index_in_cluster, ret;
312
int64_t n;
313
uint64_t cluster_offset;
314
315
- assume_graph_lock(); /* FIXME */
316
-
317
qemu_co_mutex_lock(&s->lock);
318
ret = get_cluster_offset(bs, offset, 0, 0, 0, 0, &cluster_offset);
319
qemu_co_mutex_unlock(&s->lock);
320
diff --git a/block/quorum.c b/block/quorum.c
321
index XXXXXXX..XXXXXXX 100644
322
--- a/block/quorum.c
323
+++ b/block/quorum.c
324
@@ -XXX,XX +XXX,XX @@ static void quorum_child_perm(BlockDriverState *bs, BdrvChild *c,
325
* return BDRV_BLOCK_ZERO if *all* children agree that a certain
326
* region contains zeroes, and BDRV_BLOCK_DATA otherwise.
327
*/
328
-static int coroutine_fn quorum_co_block_status(BlockDriverState *bs,
329
- bool want_zero,
330
- int64_t offset, int64_t count,
331
- int64_t *pnum, int64_t *map,
332
- BlockDriverState **file)
333
+static int coroutine_fn GRAPH_RDLOCK
334
+quorum_co_block_status(BlockDriverState *bs, bool want_zero,
335
+ int64_t offset, int64_t count,
336
+ int64_t *pnum, int64_t *map, BlockDriverState **file)
337
{
338
BDRVQuorumState *s = bs->opaque;
339
int i, ret;
340
diff --git a/block/stream.c b/block/stream.c
341
index XXXXXXX..XXXXXXX 100644
342
--- a/block/stream.c
343
+++ b/block/stream.c
344
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn stream_run(Job *job, Error **errp)
345
346
copy = false;
347
348
- ret = bdrv_is_allocated(unfiltered_bs, offset, STREAM_CHUNK, &n);
349
- if (ret == 1) {
350
- /* Allocated in the top, no need to copy. */
351
- } else if (ret >= 0) {
352
- /* Copy if allocated in the intermediate images. Limit to the
353
- * known-unallocated area [offset, offset+n*BDRV_SECTOR_SIZE). */
354
- ret = bdrv_is_allocated_above(bdrv_cow_bs(unfiltered_bs),
355
- s->base_overlay, true,
356
- offset, n, &n);
357
- /* Finish early if end of backing file has been reached */
358
- if (ret == 0 && n == 0) {
359
- n = len - offset;
360
+ WITH_GRAPH_RDLOCK_GUARD() {
361
+ ret = bdrv_is_allocated(unfiltered_bs, offset, STREAM_CHUNK, &n);
362
+ if (ret == 1) {
363
+ /* Allocated in the top, no need to copy. */
364
+ } else if (ret >= 0) {
365
+ /*
366
+ * Copy if allocated in the intermediate images. Limit to the
367
+ * known-unallocated area [offset, offset+n*BDRV_SECTOR_SIZE).
368
+ */
369
+ ret = bdrv_is_allocated_above(bdrv_cow_bs(unfiltered_bs),
370
+ s->base_overlay, true,
371
+ offset, n, &n);
372
+ /* Finish early if end of backing file has been reached */
373
+ if (ret == 0 && n == 0) {
374
+ n = len - offset;
375
+ }
376
+
377
+ copy = (ret > 0);
378
}
379
-
380
- copy = (ret > 0);
381
}
382
trace_stream_one_iteration(s, offset, n, ret);
383
if (copy) {
384
diff --git a/qemu-img.c b/qemu-img.c
385
index XXXXXXX..XXXXXXX 100644
386
--- a/qemu-img.c
387
+++ b/qemu-img.c
388
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn convert_co_do_copy(void *opaque)
389
qemu_co_mutex_unlock(&s->lock);
390
break;
391
}
392
- n = convert_iteration_sectors(s, s->sector_num);
393
+ WITH_GRAPH_RDLOCK_GUARD() {
394
+ n = convert_iteration_sectors(s, s->sector_num);
395
+ }
396
if (n < 0) {
397
qemu_co_mutex_unlock(&s->lock);
398
s->ret = n;
399
diff --git a/tests/unit/test-block-iothread.c b/tests/unit/test-block-iothread.c
400
index XXXXXXX..XXXXXXX 100644
401
--- a/tests/unit/test-block-iothread.c
402
+++ b/tests/unit/test-block-iothread.c
403
@@ -XXX,XX +XXX,XX @@ static void test_sync_op_blk_truncate(BlockBackend *blk)
404
g_assert_cmpint(ret, ==, -EINVAL);
405
}
406
407
-static void test_sync_op_block_status(BdrvChild *c)
408
+/* Disable TSA to make bdrv_test.bdrv_co_block_status writable */
409
+static void TSA_NO_TSA test_sync_op_block_status(BdrvChild *c)
410
{
411
int ret;
412
int64_t n;
413
--
414
2.39.2
diff view generated by jsdifflib
Deleted patch
1
This adds GRAPH_RDLOCK annotations to declare that callers of
2
bdrv_co_ioctl() need to hold a reader lock for the graph.
3
1
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
Message-Id: <20230203152202.49054-6-kwolf@redhat.com>
6
Reviewed-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
---
9
include/block/block-io.h | 3 ++-
10
include/block/block_int-common.h | 9 +++++----
11
block/block-backend.c | 1 +
12
block/io.c | 1 +
13
block/raw-format.c | 4 ++--
14
5 files changed, 11 insertions(+), 7 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_aio_cancel(BlockAIOCB *acb);
21
void bdrv_aio_cancel_async(BlockAIOCB *acb);
22
23
/* sg packet commands */
24
-int coroutine_fn bdrv_co_ioctl(BlockDriverState *bs, int req, void *buf);
25
+int coroutine_fn GRAPH_RDLOCK
26
+bdrv_co_ioctl(BlockDriverState *bs, int req, void *buf);
27
28
/* Ensure contents are flushed to disk. */
29
int coroutine_fn bdrv_co_flush(BlockDriverState *bs);
30
diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h
31
index XXXXXXX..XXXXXXX 100644
32
--- a/include/block/block_int-common.h
33
+++ b/include/block/block_int-common.h
34
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
35
void coroutine_fn (*bdrv_co_lock_medium)(BlockDriverState *bs, bool locked);
36
37
/* to control generic scsi devices */
38
- BlockAIOCB *(*bdrv_aio_ioctl)(BlockDriverState *bs,
39
- unsigned long int req, void *buf,
40
+ BlockAIOCB *coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_aio_ioctl)(
41
+ BlockDriverState *bs, unsigned long int req, void *buf,
42
BlockCompletionFunc *cb, void *opaque);
43
- int coroutine_fn (*bdrv_co_ioctl)(BlockDriverState *bs,
44
- unsigned long int req, void *buf);
45
+
46
+ int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_ioctl)(
47
+ BlockDriverState *bs, unsigned long int req, void *buf);
48
49
/*
50
* Returns 0 for completed check, -errno for internal errors.
51
diff --git a/block/block-backend.c b/block/block-backend.c
52
index XXXXXXX..XXXXXXX 100644
53
--- a/block/block-backend.c
54
+++ b/block/block-backend.c
55
@@ -XXX,XX +XXX,XX @@ blk_co_do_ioctl(BlockBackend *blk, unsigned long int req, void *buf)
56
IO_CODE();
57
58
blk_wait_while_drained(blk);
59
+ GRAPH_RDLOCK_GUARD();
60
61
if (!blk_is_available(blk)) {
62
return -ENOMEDIUM;
63
diff --git a/block/io.c b/block/io.c
64
index XXXXXXX..XXXXXXX 100644
65
--- a/block/io.c
66
+++ b/block/io.c
67
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_ioctl(BlockDriverState *bs, int req, void *buf)
68
};
69
BlockAIOCB *acb;
70
IO_CODE();
71
+ assert_bdrv_graph_readable();
72
73
bdrv_inc_in_flight(bs);
74
if (!drv || (!drv->bdrv_aio_ioctl && !drv->bdrv_co_ioctl)) {
75
diff --git a/block/raw-format.c b/block/raw-format.c
76
index XXXXXXX..XXXXXXX 100644
77
--- a/block/raw-format.c
78
+++ b/block/raw-format.c
79
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn raw_co_lock_medium(BlockDriverState *bs, bool locked)
80
bdrv_co_lock_medium(bs->file->bs, locked);
81
}
82
83
-static int coroutine_fn raw_co_ioctl(BlockDriverState *bs,
84
- unsigned long int req, void *buf)
85
+static int coroutine_fn GRAPH_RDLOCK
86
+raw_co_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
87
{
88
BDRVRawState *s = bs->opaque;
89
if (s->offset || s->has_size) {
90
--
91
2.39.2
diff view generated by jsdifflib
Deleted patch
1
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
2
1
3
This function is called in two different places:
4
- timer callback, which does not take the graph rdlock.
5
- bdrv_qed_drain_begin(), which is .bdrv_drain_begin()
6
callback documented as function that does not take the lock.
7
8
Since it calls recursive functions that traverse the
9
graph, we need to protect them with the graph rdlock.
10
11
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
Message-Id: <20230203152202.49054-7-kwolf@redhat.com>
14
Reviewed-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
15
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
16
---
17
block/qed.c | 4 +++-
18
1 file changed, 3 insertions(+), 1 deletion(-)
19
20
diff --git a/block/qed.c b/block/qed.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/block/qed.c
23
+++ b/block/qed.c
24
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn qed_unplug_allocating_write_reqs(BDRVQEDState *s)
25
qemu_co_mutex_unlock(&s->table_lock);
26
}
27
28
-static void coroutine_fn qed_need_check_timer(BDRVQEDState *s)
29
+static void coroutine_fn GRAPH_RDLOCK qed_need_check_timer(BDRVQEDState *s)
30
{
31
int ret;
32
33
trace_qed_need_check_timer_cb(s);
34
+ assert_bdrv_graph_readable();
35
36
if (!qed_plug_allocating_write_reqs(s)) {
37
return;
38
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn qed_need_check_timer(BDRVQEDState *s)
39
static void coroutine_fn qed_need_check_timer_entry(void *opaque)
40
{
41
BDRVQEDState *s = opaque;
42
+ GRAPH_RDLOCK_GUARD();
43
44
qed_need_check_timer(opaque);
45
bdrv_dec_in_flight(s->bs);
46
--
47
2.39.2
diff view generated by jsdifflib
Deleted patch
1
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
2
1
3
This adds GRAPH_RDLOCK annotations to declare that callers of
4
bdrv_co_flush() need to hold a reader lock for the graph.
5
6
For some places, we know that they will hold the lock, but we don't have
7
the GRAPH_RDLOCK annotations yet. In this case, add assume_graph_lock()
8
with a FIXME comment. These places will be removed once everything is
9
properly annotated.
10
11
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
Message-Id: <20230203152202.49054-8-kwolf@redhat.com>
14
Reviewed-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
15
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
16
---
17
block/qcow2.h | 5 +++-
18
block/qed.h | 29 +++++++++++++--------
19
include/block/block-io.h | 2 +-
20
include/block/block_int-common.h | 12 +++++----
21
block/blkdebug.c | 2 +-
22
block/blklogwrites.c | 21 ++++++++++-----
23
block/blkreplay.c | 2 +-
24
block/blkverify.c | 2 +-
25
block/block-backend.c | 3 ++-
26
block/copy-before-write.c | 2 +-
27
block/file-posix.c | 4 +--
28
block/io.c | 7 +++++
29
block/mirror.c | 2 +-
30
block/preallocate.c | 2 +-
31
block/qed-check.c | 3 ++-
32
block/qed-table.c | 6 ++---
33
block/qed.c | 44 +++++++++++++++++++-------------
34
block/quorum.c | 2 +-
35
block/throttle.c | 2 +-
36
block/vmdk.c | 6 +++--
37
20 files changed, 98 insertions(+), 60 deletions(-)
38
39
diff --git a/block/qcow2.h b/block/qcow2.h
40
index XXXXXXX..XXXXXXX 100644
41
--- a/block/qcow2.h
42
+++ b/block/qcow2.h
43
@@ -XXX,XX +XXX,XX @@ int coroutine_fn qcow2_detect_metadata_preallocation(BlockDriverState *bs);
44
/* qcow2-cluster.c functions */
45
int qcow2_grow_l1_table(BlockDriverState *bs, uint64_t min_size,
46
bool exact_size);
47
-int coroutine_fn qcow2_shrink_l1_table(BlockDriverState *bs, uint64_t max_size);
48
+
49
+int coroutine_fn GRAPH_RDLOCK
50
+qcow2_shrink_l1_table(BlockDriverState *bs, uint64_t max_size);
51
+
52
int qcow2_write_l1_entry(BlockDriverState *bs, int l1_index);
53
int qcow2_encrypt_sectors(BDRVQcow2State *s, int64_t sector_num,
54
uint8_t *buf, int nb_sectors, bool enc, Error **errp);
55
diff --git a/block/qed.h b/block/qed.h
56
index XXXXXXX..XXXXXXX 100644
57
--- a/block/qed.h
58
+++ b/block/qed.h
59
@@ -XXX,XX +XXX,XX @@ void qed_commit_l2_cache_entry(L2TableCache *l2_cache, CachedL2Table *l2_table);
60
* Table I/O functions
61
*/
62
int coroutine_fn qed_read_l1_table_sync(BDRVQEDState *s);
63
-int coroutine_fn qed_write_l1_table(BDRVQEDState *s, unsigned int index,
64
- unsigned int n);
65
-int coroutine_fn qed_write_l1_table_sync(BDRVQEDState *s, unsigned int index,
66
- unsigned int n);
67
+
68
+int coroutine_fn GRAPH_RDLOCK
69
+qed_write_l1_table(BDRVQEDState *s, unsigned int index, unsigned int n);
70
+
71
+int coroutine_fn GRAPH_RDLOCK
72
+qed_write_l1_table_sync(BDRVQEDState *s, unsigned int index, unsigned int n);
73
+
74
int coroutine_fn qed_read_l2_table_sync(BDRVQEDState *s, QEDRequest *request,
75
uint64_t offset);
76
int coroutine_fn qed_read_l2_table(BDRVQEDState *s, QEDRequest *request,
77
uint64_t offset);
78
-int coroutine_fn qed_write_l2_table(BDRVQEDState *s, QEDRequest *request,
79
- unsigned int index, unsigned int n,
80
- bool flush);
81
-int coroutine_fn qed_write_l2_table_sync(BDRVQEDState *s, QEDRequest *request,
82
- unsigned int index, unsigned int n,
83
- bool flush);
84
+
85
+int coroutine_fn GRAPH_RDLOCK
86
+qed_write_l2_table(BDRVQEDState *s, QEDRequest *request, unsigned int index,
87
+ unsigned int n, bool flush);
88
+
89
+int coroutine_fn GRAPH_RDLOCK
90
+qed_write_l2_table_sync(BDRVQEDState *s, QEDRequest *request,
91
+ unsigned int index, unsigned int n, bool flush);
92
93
/**
94
* Cluster functions
95
@@ -XXX,XX +XXX,XX @@ int coroutine_fn qed_find_cluster(BDRVQEDState *s, QEDRequest *request,
96
/**
97
* Consistency check
98
*/
99
-int coroutine_fn qed_check(BDRVQEDState *s, BdrvCheckResult *result, bool fix);
100
+int coroutine_fn GRAPH_RDLOCK
101
+qed_check(BDRVQEDState *s, BdrvCheckResult *result, bool fix);
102
+
103
104
QEDTable *qed_alloc_table(BDRVQEDState *s);
105
106
diff --git a/include/block/block-io.h b/include/block/block-io.h
107
index XXXXXXX..XXXXXXX 100644
108
--- a/include/block/block-io.h
109
+++ b/include/block/block-io.h
110
@@ -XXX,XX +XXX,XX @@ int coroutine_fn GRAPH_RDLOCK
111
bdrv_co_ioctl(BlockDriverState *bs, int req, void *buf);
112
113
/* Ensure contents are flushed to disk. */
114
-int coroutine_fn bdrv_co_flush(BlockDriverState *bs);
115
+int coroutine_fn GRAPH_RDLOCK bdrv_co_flush(BlockDriverState *bs);
116
117
int coroutine_fn bdrv_co_pdiscard(BdrvChild *child, int64_t offset,
118
int64_t bytes);
119
diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h
120
index XXXXXXX..XXXXXXX 100644
121
--- a/include/block/block_int-common.h
122
+++ b/include/block/block_int-common.h
123
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
124
BlockAIOCB *(*bdrv_aio_pwritev)(BlockDriverState *bs,
125
int64_t offset, int64_t bytes, QEMUIOVector *qiov,
126
BdrvRequestFlags flags, BlockCompletionFunc *cb, void *opaque);
127
- BlockAIOCB *(*bdrv_aio_flush)(BlockDriverState *bs,
128
- BlockCompletionFunc *cb, void *opaque);
129
+ BlockAIOCB * GRAPH_RDLOCK_PTR (*bdrv_aio_flush)(
130
+ BlockDriverState *bs, BlockCompletionFunc *cb, void *opaque);
131
BlockAIOCB *(*bdrv_aio_pdiscard)(BlockDriverState *bs,
132
int64_t offset, int bytes,
133
BlockCompletionFunc *cb, void *opaque);
134
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
135
* layers, if needed. This function is needed for deterministic
136
* synchronization of the flush finishing callback.
137
*/
138
- int coroutine_fn (*bdrv_co_flush)(BlockDriverState *bs);
139
+ int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_flush)(BlockDriverState *bs);
140
141
/* Delete a created file. */
142
int coroutine_fn (*bdrv_co_delete_file)(BlockDriverState *bs,
143
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
144
* Flushes all data that was already written to the OS all the way down to
145
* the disk (for example file-posix.c calls fsync()).
146
*/
147
- int coroutine_fn (*bdrv_co_flush_to_disk)(BlockDriverState *bs);
148
+ int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_flush_to_disk)(
149
+ BlockDriverState *bs);
150
151
/*
152
* Flushes all internal caches to the OS. The data may still sit in a
153
* writeback cache of the host OS, but it will survive a crash of the qemu
154
* process.
155
*/
156
- int coroutine_fn (*bdrv_co_flush_to_os)(BlockDriverState *bs);
157
+ int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_flush_to_os)(
158
+ BlockDriverState *bs);
159
160
/*
161
* Truncate @bs to @offset bytes using the given @prealloc mode
162
diff --git a/block/blkdebug.c b/block/blkdebug.c
163
index XXXXXXX..XXXXXXX 100644
164
--- a/block/blkdebug.c
165
+++ b/block/blkdebug.c
166
@@ -XXX,XX +XXX,XX @@ blkdebug_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
167
return bdrv_co_pwritev(bs->file, offset, bytes, qiov, flags);
168
}
169
170
-static int coroutine_fn blkdebug_co_flush(BlockDriverState *bs)
171
+static int GRAPH_RDLOCK coroutine_fn blkdebug_co_flush(BlockDriverState *bs)
172
{
173
int err = rule_check(bs, 0, 0, BLKDEBUG_IO_TYPE_FLUSH);
174
175
diff --git a/block/blklogwrites.c b/block/blklogwrites.c
176
index XXXXXXX..XXXXXXX 100644
177
--- a/block/blklogwrites.c
178
+++ b/block/blklogwrites.c
179
@@ -XXX,XX +XXX,XX @@ typedef struct BlkLogWritesFileReq {
180
uint64_t bytes;
181
int file_flags;
182
QEMUIOVector *qiov;
183
- int (*func)(struct BlkLogWritesFileReq *r);
184
+ int GRAPH_RDLOCK_PTR (*func)(struct BlkLogWritesFileReq *r);
185
int file_ret;
186
} BlkLogWritesFileReq;
187
188
@@ -XXX,XX +XXX,XX @@ typedef struct {
189
int log_ret;
190
} BlkLogWritesLogReq;
191
192
-static void coroutine_fn blk_log_writes_co_do_log(BlkLogWritesLogReq *lr)
193
+static void coroutine_fn GRAPH_RDLOCK
194
+blk_log_writes_co_do_log(BlkLogWritesLogReq *lr)
195
{
196
BDRVBlkLogWritesState *s = lr->bs->opaque;
197
uint64_t cur_log_offset = s->cur_log_sector << s->sectorbits;
198
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn blk_log_writes_co_do_log(BlkLogWritesLogReq *lr)
199
}
200
}
201
202
-static void coroutine_fn blk_log_writes_co_do_file(BlkLogWritesFileReq *fr)
203
+static void coroutine_fn GRAPH_RDLOCK
204
+blk_log_writes_co_do_file(BlkLogWritesFileReq *fr)
205
{
206
fr->file_ret = fr->func(fr);
207
}
208
209
-static int coroutine_fn
210
+static int coroutine_fn GRAPH_RDLOCK
211
blk_log_writes_co_log(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
212
QEMUIOVector *qiov, int flags,
213
- int (*file_func)(BlkLogWritesFileReq *r),
214
+ int /*GRAPH_RDLOCK*/ (*file_func)(BlkLogWritesFileReq *r),
215
uint64_t entry_flags, bool is_zero_write)
216
{
217
QEMUIOVector log_qiov;
218
@@ -XXX,XX +XXX,XX @@ blk_log_writes_co_do_file_pwrite_zeroes(BlkLogWritesFileReq *fr)
219
fr->file_flags);
220
}
221
222
-static int coroutine_fn blk_log_writes_co_do_file_flush(BlkLogWritesFileReq *fr)
223
+static int coroutine_fn GRAPH_RDLOCK
224
+blk_log_writes_co_do_file_flush(BlkLogWritesFileReq *fr)
225
{
226
return bdrv_co_flush(fr->bs->file->bs);
227
}
228
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn
229
blk_log_writes_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
230
QEMUIOVector *qiov, BdrvRequestFlags flags)
231
{
232
+ assume_graph_lock(); /* FIXME */
233
return blk_log_writes_co_log(bs, offset, bytes, qiov, flags,
234
blk_log_writes_co_do_file_pwritev, 0, false);
235
}
236
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn
237
blk_log_writes_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset,
238
int64_t bytes, BdrvRequestFlags flags)
239
{
240
+ assume_graph_lock(); /* FIXME */
241
return blk_log_writes_co_log(bs, offset, bytes, NULL, flags,
242
blk_log_writes_co_do_file_pwrite_zeroes, 0,
243
true);
244
}
245
246
-static int coroutine_fn blk_log_writes_co_flush_to_disk(BlockDriverState *bs)
247
+static int coroutine_fn GRAPH_RDLOCK
248
+blk_log_writes_co_flush_to_disk(BlockDriverState *bs)
249
{
250
return blk_log_writes_co_log(bs, 0, 0, NULL, 0,
251
blk_log_writes_co_do_file_flush,
252
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn blk_log_writes_co_flush_to_disk(BlockDriverState *bs)
253
static int coroutine_fn
254
blk_log_writes_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes)
255
{
256
+ assume_graph_lock(); /* FIXME */
257
return blk_log_writes_co_log(bs, offset, bytes, NULL, 0,
258
blk_log_writes_co_do_file_pdiscard,
259
LOG_DISCARD_FLAG, false);
260
diff --git a/block/blkreplay.c b/block/blkreplay.c
261
index XXXXXXX..XXXXXXX 100644
262
--- a/block/blkreplay.c
263
+++ b/block/blkreplay.c
264
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn blkreplay_co_pdiscard(BlockDriverState *bs,
265
return ret;
266
}
267
268
-static int coroutine_fn blkreplay_co_flush(BlockDriverState *bs)
269
+static int coroutine_fn GRAPH_RDLOCK blkreplay_co_flush(BlockDriverState *bs)
270
{
271
uint64_t reqid = blkreplay_next_id();
272
int ret = bdrv_co_flush(bs->file->bs);
273
diff --git a/block/blkverify.c b/block/blkverify.c
274
index XXXXXXX..XXXXXXX 100644
275
--- a/block/blkverify.c
276
+++ b/block/blkverify.c
277
@@ -XXX,XX +XXX,XX @@ blkverify_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
278
return blkverify_co_prwv(bs, &r, offset, bytes, qiov, qiov, flags, true);
279
}
280
281
-static int coroutine_fn blkverify_co_flush(BlockDriverState *bs)
282
+static int coroutine_fn GRAPH_RDLOCK blkverify_co_flush(BlockDriverState *bs)
283
{
284
BDRVBlkverifyState *s = bs->opaque;
285
286
diff --git a/block/block-backend.c b/block/block-backend.c
287
index XXXXXXX..XXXXXXX 100644
288
--- a/block/block-backend.c
289
+++ b/block/block-backend.c
290
@@ -XXX,XX +XXX,XX @@ int coroutine_fn blk_co_pdiscard(BlockBackend *blk, int64_t offset,
291
/* To be called between exactly one pair of blk_inc/dec_in_flight() */
292
static int coroutine_fn blk_co_do_flush(BlockBackend *blk)
293
{
294
- blk_wait_while_drained(blk);
295
IO_CODE();
296
+ blk_wait_while_drained(blk);
297
+ GRAPH_RDLOCK_GUARD();
298
299
if (!blk_is_available(blk)) {
300
return -ENOMEDIUM;
301
diff --git a/block/copy-before-write.c b/block/copy-before-write.c
302
index XXXXXXX..XXXXXXX 100644
303
--- a/block/copy-before-write.c
304
+++ b/block/copy-before-write.c
305
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int cbw_co_pwritev(BlockDriverState *bs,
306
return bdrv_co_pwritev(bs->file, offset, bytes, qiov, flags);
307
}
308
309
-static int coroutine_fn cbw_co_flush(BlockDriverState *bs)
310
+static int coroutine_fn GRAPH_RDLOCK cbw_co_flush(BlockDriverState *bs)
311
{
312
if (!bs->file) {
313
return 0;
314
diff --git a/block/file-posix.c b/block/file-posix.c
315
index XXXXXXX..XXXXXXX 100644
316
--- a/block/file-posix.c
317
+++ b/block/file-posix.c
318
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn check_cache_dropped(BlockDriverState *bs, Error **errp)
319
}
320
#endif /* __linux__ */
321
322
-static void coroutine_fn raw_co_invalidate_cache(BlockDriverState *bs,
323
- Error **errp)
324
+static void coroutine_fn GRAPH_RDLOCK
325
+raw_co_invalidate_cache(BlockDriverState *bs, Error **errp)
326
{
327
BDRVRawState *s = bs->opaque;
328
int ret;
329
diff --git a/block/io.c b/block/io.c
330
index XXXXXXX..XXXXXXX 100644
331
--- a/block/io.c
332
+++ b/block/io.c
333
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_pwrite_sync(BdrvChild *child, int64_t offset,
334
int ret;
335
IO_CODE();
336
337
+ assume_graph_lock(); /* FIXME */
338
+
339
ret = bdrv_co_pwrite(child, offset, bytes, buf, flags);
340
if (ret < 0) {
341
return ret;
342
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_driver_pwritev(BlockDriverState *bs,
343
QEMUIOVector local_qiov;
344
int ret;
345
346
+ assume_graph_lock(); /* FIXME */
347
+
348
bdrv_check_qiov_request(offset, bytes, qiov, qiov_offset, &error_abort);
349
350
if (!drv) {
351
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_co_do_pwrite_zeroes(BlockDriverState *bs,
352
int head = 0;
353
int tail = 0;
354
355
+ assume_graph_lock(); /* FIXME */
356
+
357
int64_t max_write_zeroes = MIN_NON_ZERO(bs->bl.max_pwrite_zeroes,
358
INT64_MAX);
359
int alignment = MAX(bs->bl.pwrite_zeroes_alignment,
360
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_flush(BlockDriverState *bs)
361
int ret = 0;
362
IO_CODE();
363
364
+ assert_bdrv_graph_readable();
365
bdrv_inc_in_flight(bs);
366
367
if (!bdrv_co_is_inserted(bs) || bdrv_is_read_only(bs) ||
368
diff --git a/block/mirror.c b/block/mirror.c
369
index XXXXXXX..XXXXXXX 100644
370
--- a/block/mirror.c
371
+++ b/block/mirror.c
372
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_mirror_top_pwritev(BlockDriverState *bs,
373
return ret;
374
}
375
376
-static int coroutine_fn bdrv_mirror_top_flush(BlockDriverState *bs)
377
+static int coroutine_fn GRAPH_RDLOCK bdrv_mirror_top_flush(BlockDriverState *bs)
378
{
379
if (bs->backing == NULL) {
380
/* we can be here after failed bdrv_append in mirror_start_job */
381
diff --git a/block/preallocate.c b/block/preallocate.c
382
index XXXXXXX..XXXXXXX 100644
383
--- a/block/preallocate.c
384
+++ b/block/preallocate.c
385
@@ -XXX,XX +XXX,XX @@ preallocate_co_truncate(BlockDriverState *bs, int64_t offset,
386
return 0;
387
}
388
389
-static int coroutine_fn preallocate_co_flush(BlockDriverState *bs)
390
+static int coroutine_fn GRAPH_RDLOCK preallocate_co_flush(BlockDriverState *bs)
391
{
392
return bdrv_co_flush(bs->file->bs);
393
}
394
diff --git a/block/qed-check.c b/block/qed-check.c
395
index XXXXXXX..XXXXXXX 100644
396
--- a/block/qed-check.c
397
+++ b/block/qed-check.c
398
@@ -XXX,XX +XXX,XX @@ static unsigned int qed_check_l2_table(QEDCheck *check, QEDTable *table)
399
/**
400
* Descend tables and check each cluster is referenced once only
401
*/
402
-static int coroutine_fn qed_check_l1_table(QEDCheck *check, QEDTable *table)
403
+static int coroutine_fn GRAPH_RDLOCK
404
+qed_check_l1_table(QEDCheck *check, QEDTable *table)
405
{
406
BDRVQEDState *s = check->s;
407
unsigned int i, num_invalid_l1 = 0;
408
diff --git a/block/qed-table.c b/block/qed-table.c
409
index XXXXXXX..XXXXXXX 100644
410
--- a/block/qed-table.c
411
+++ b/block/qed-table.c
412
@@ -XXX,XX +XXX,XX @@ out:
413
*
414
* Called with table_lock held.
415
*/
416
-static int coroutine_fn qed_write_table(BDRVQEDState *s, uint64_t offset,
417
- QEDTable *table, unsigned int index,
418
- unsigned int n, bool flush)
419
+static int coroutine_fn GRAPH_RDLOCK
420
+qed_write_table(BDRVQEDState *s, uint64_t offset, QEDTable *table,
421
+ unsigned int index, unsigned int n, bool flush)
422
{
423
unsigned int sector_mask = BDRV_SECTOR_SIZE / sizeof(uint64_t) - 1;
424
unsigned int start, end, i;
425
diff --git a/block/qed.c b/block/qed.c
426
index XXXXXXX..XXXXXXX 100644
427
--- a/block/qed.c
428
+++ b/block/qed.c
429
@@ -XXX,XX +XXX,XX @@ static void bdrv_qed_init_state(BlockDriverState *bs)
430
}
431
432
/* Called with table_lock held. */
433
-static int coroutine_fn bdrv_qed_do_open(BlockDriverState *bs, QDict *options,
434
- int flags, Error **errp)
435
+static int coroutine_fn GRAPH_RDLOCK
436
+bdrv_qed_do_open(BlockDriverState *bs, QDict *options, int flags, Error **errp)
437
{
438
BDRVQEDState *s = bs->opaque;
439
QEDHeader le_header;
440
@@ -XXX,XX +XXX,XX @@ typedef struct QEDOpenCo {
441
int ret;
442
} QEDOpenCo;
443
444
-static void coroutine_fn bdrv_qed_open_entry(void *opaque)
445
+static void coroutine_fn GRAPH_RDLOCK bdrv_qed_open_entry(void *opaque)
446
{
447
QEDOpenCo *qoc = opaque;
448
BDRVQEDState *s = qoc->bs->opaque;
449
@@ -XXX,XX +XXX,XX @@ static int bdrv_qed_open(BlockDriverState *bs, QDict *options, int flags,
450
};
451
int ret;
452
453
+ assume_graph_lock(); /* FIXME */
454
+
455
ret = bdrv_open_file_child(NULL, options, "file", bs, errp);
456
if (ret < 0) {
457
return ret;
458
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn qed_aio_complete(QEDAIOCB *acb)
459
*
460
* Called with table_lock held.
461
*/
462
-static int coroutine_fn qed_aio_write_l1_update(QEDAIOCB *acb)
463
+static int coroutine_fn GRAPH_RDLOCK qed_aio_write_l1_update(QEDAIOCB *acb)
464
{
465
BDRVQEDState *s = acb_to_s(acb);
466
CachedL2Table *l2_table = acb->request.l2_table;
467
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qed_aio_write_l1_update(QEDAIOCB *acb)
468
*
469
* Called with table_lock held.
470
*/
471
-static int coroutine_fn qed_aio_write_l2_update(QEDAIOCB *acb, uint64_t offset)
472
+static int coroutine_fn GRAPH_RDLOCK
473
+qed_aio_write_l2_update(QEDAIOCB *acb, uint64_t offset)
474
{
475
BDRVQEDState *s = acb_to_s(acb);
476
bool need_alloc = acb->find_cluster_ret == QED_CLUSTER_L1;
477
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qed_aio_write_main(QEDAIOCB *acb)
478
*
479
* Called with table_lock held.
480
*/
481
-static int coroutine_fn qed_aio_write_cow(QEDAIOCB *acb)
482
+static int coroutine_fn GRAPH_RDLOCK qed_aio_write_cow(QEDAIOCB *acb)
483
{
484
BDRVQEDState *s = acb_to_s(acb);
485
uint64_t start, len, offset;
486
@@ -XXX,XX +XXX,XX @@ static bool qed_should_set_need_check(BDRVQEDState *s)
487
*
488
* Called with table_lock held.
489
*/
490
-static int coroutine_fn qed_aio_write_alloc(QEDAIOCB *acb, size_t len)
491
+static int coroutine_fn GRAPH_RDLOCK
492
+qed_aio_write_alloc(QEDAIOCB *acb, size_t len)
493
{
494
BDRVQEDState *s = acb_to_s(acb);
495
int ret;
496
@@ -XXX,XX +XXX,XX @@ out:
497
*
498
* Called with table_lock held.
499
*/
500
-static int coroutine_fn qed_aio_write_data(void *opaque, int ret,
501
- uint64_t offset, size_t len)
502
+static int coroutine_fn GRAPH_RDLOCK
503
+qed_aio_write_data(void *opaque, int ret, uint64_t offset, size_t len)
504
{
505
QEDAIOCB *acb = opaque;
506
507
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qed_aio_read_data(void *opaque, int ret,
508
/**
509
* Begin next I/O or complete the request
510
*/
511
-static int coroutine_fn qed_aio_next_io(QEDAIOCB *acb)
512
+static int coroutine_fn GRAPH_RDLOCK qed_aio_next_io(QEDAIOCB *acb)
513
{
514
BDRVQEDState *s = acb_to_s(acb);
515
uint64_t offset;
516
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qed_aio_next_io(QEDAIOCB *acb)
517
return ret;
518
}
519
520
-static int coroutine_fn qed_co_request(BlockDriverState *bs, int64_t sector_num,
521
- QEMUIOVector *qiov, int nb_sectors,
522
- int flags)
523
+static int coroutine_fn GRAPH_RDLOCK
524
+qed_co_request(BlockDriverState *bs, int64_t sector_num, QEMUIOVector *qiov,
525
+ int nb_sectors, int flags)
526
{
527
QEDAIOCB acb = {
528
.bs = bs,
529
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_qed_co_readv(BlockDriverState *bs,
530
int64_t sector_num, int nb_sectors,
531
QEMUIOVector *qiov)
532
{
533
+ assume_graph_lock(); /* FIXME */
534
return qed_co_request(bs, sector_num, qiov, nb_sectors, 0);
535
}
536
537
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_qed_co_writev(BlockDriverState *bs,
538
int64_t sector_num, int nb_sectors,
539
QEMUIOVector *qiov, int flags)
540
{
541
+ assume_graph_lock(); /* FIXME */
542
return qed_co_request(bs, sector_num, qiov, nb_sectors, QED_AIOCB_WRITE);
543
}
544
545
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_qed_co_pwrite_zeroes(BlockDriverState *bs,
546
{
547
BDRVQEDState *s = bs->opaque;
548
549
+ assume_graph_lock(); /* FIXME */
550
+
551
/*
552
* Zero writes start without an I/O buffer. If a buffer becomes necessary
553
* then it will be allocated during request processing.
554
@@ -XXX,XX +XXX,XX @@ static int bdrv_qed_change_backing_file(BlockDriverState *bs,
555
return ret;
556
}
557
558
-static void coroutine_fn bdrv_qed_co_invalidate_cache(BlockDriverState *bs,
559
- Error **errp)
560
+static void coroutine_fn GRAPH_RDLOCK
561
+bdrv_qed_co_invalidate_cache(BlockDriverState *bs, Error **errp)
562
{
563
BDRVQEDState *s = bs->opaque;
564
int ret;
565
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn bdrv_qed_co_invalidate_cache(BlockDriverState *bs,
566
}
567
}
568
569
-static int coroutine_fn bdrv_qed_co_check(BlockDriverState *bs,
570
- BdrvCheckResult *result,
571
- BdrvCheckMode fix)
572
+static int coroutine_fn GRAPH_RDLOCK
573
+bdrv_qed_co_check(BlockDriverState *bs, BdrvCheckResult *result,
574
+ BdrvCheckMode fix)
575
{
576
BDRVQEDState *s = bs->opaque;
577
int ret;
578
diff --git a/block/quorum.c b/block/quorum.c
579
index XXXXXXX..XXXXXXX 100644
580
--- a/block/quorum.c
581
+++ b/block/quorum.c
582
@@ -XXX,XX +XXX,XX @@ static int64_t coroutine_fn quorum_co_getlength(BlockDriverState *bs)
583
return result;
584
}
585
586
-static coroutine_fn int quorum_co_flush(BlockDriverState *bs)
587
+static coroutine_fn GRAPH_RDLOCK int quorum_co_flush(BlockDriverState *bs)
588
{
589
BDRVQuorumState *s = bs->opaque;
590
QuorumVoteVersion *winner = NULL;
591
diff --git a/block/throttle.c b/block/throttle.c
592
index XXXXXXX..XXXXXXX 100644
593
--- a/block/throttle.c
594
+++ b/block/throttle.c
595
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn throttle_co_pwritev_compressed(BlockDriverState *bs,
596
BDRV_REQ_WRITE_COMPRESSED);
597
}
598
599
-static int coroutine_fn throttle_co_flush(BlockDriverState *bs)
600
+static int coroutine_fn GRAPH_RDLOCK throttle_co_flush(BlockDriverState *bs)
601
{
602
return bdrv_co_flush(bs->file->bs);
603
}
604
diff --git a/block/vmdk.c b/block/vmdk.c
605
index XXXXXXX..XXXXXXX 100644
606
--- a/block/vmdk.c
607
+++ b/block/vmdk.c
608
@@ -XXX,XX +XXX,XX @@ exit:
609
return ret;
610
}
611
612
-static int coroutine_fn vmdk_L2update(VmdkExtent *extent, VmdkMetaData *m_data,
613
- uint32_t offset)
614
+static int coroutine_fn GRAPH_RDLOCK
615
+vmdk_L2update(VmdkExtent *extent, VmdkMetaData *m_data, uint32_t offset)
616
{
617
offset = cpu_to_le32(offset);
618
/* update L2 table */
619
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn vmdk_pwritev(BlockDriverState *bs, uint64_t offset,
620
uint64_t bytes_done = 0;
621
VmdkMetaData m_data;
622
623
+ assume_graph_lock(); /* FIXME */
624
+
625
if (DIV_ROUND_UP(offset, BDRV_SECTOR_SIZE) > bs->total_sectors) {
626
error_report("Wrong offset: offset=0x%" PRIx64
627
" total_sectors=0x%" PRIx64,
628
--
629
2.39.2
diff view generated by jsdifflib
Deleted patch
1
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
2
1
3
This adds GRAPH_RDLOCK annotations to declare that callers of
4
bdrv_co_pdiscard() need to hold a reader lock for the graph.
5
6
For some places, we know that they will hold the lock, but we don't have
7
the GRAPH_RDLOCK annotations yet. In this case, add assume_graph_lock()
8
with a FIXME comment. These places will be removed once everything is
9
properly annotated.
10
11
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
12
Message-Id: <20230203152202.49054-9-kwolf@redhat.com>
13
Reviewed-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
14
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
15
---
16
include/block/block-io.h | 5 +++--
17
include/block/block_int-common.h | 15 +++++++++------
18
include/block/block_int-io.h | 2 +-
19
block/blkdebug.c | 4 ++--
20
block/blklogwrites.c | 5 ++---
21
block/blkreplay.c | 4 ++--
22
block/block-backend.c | 1 +
23
block/copy-before-write.c | 8 ++++----
24
block/copy-on-read.c | 4 ++--
25
block/filter-compress.c | 4 ++--
26
block/io.c | 2 ++
27
block/mirror.c | 14 +++++++++-----
28
block/preallocate.c | 4 ++--
29
block/raw-format.c | 4 ++--
30
block/snapshot-access.c | 4 ++--
31
block/throttle.c | 4 ++--
32
16 files changed, 47 insertions(+), 37 deletions(-)
33
34
diff --git a/include/block/block-io.h b/include/block/block-io.h
35
index XXXXXXX..XXXXXXX 100644
36
--- a/include/block/block-io.h
37
+++ b/include/block/block-io.h
38
@@ -XXX,XX +XXX,XX @@ bdrv_co_ioctl(BlockDriverState *bs, int req, void *buf);
39
/* Ensure contents are flushed to disk. */
40
int coroutine_fn GRAPH_RDLOCK bdrv_co_flush(BlockDriverState *bs);
41
42
-int coroutine_fn bdrv_co_pdiscard(BdrvChild *child, int64_t offset,
43
- int64_t bytes);
44
+int coroutine_fn GRAPH_RDLOCK bdrv_co_pdiscard(BdrvChild *child, int64_t offset,
45
+ int64_t bytes);
46
+
47
bool bdrv_can_write_zeroes_with_unmap(BlockDriverState *bs);
48
int bdrv_block_status(BlockDriverState *bs, int64_t offset,
49
int64_t bytes, int64_t *pnum, int64_t *map,
50
diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h
51
index XXXXXXX..XXXXXXX 100644
52
--- a/include/block/block_int-common.h
53
+++ b/include/block/block_int-common.h
54
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
55
BdrvRequestFlags flags, BlockCompletionFunc *cb, void *opaque);
56
BlockAIOCB * GRAPH_RDLOCK_PTR (*bdrv_aio_flush)(
57
BlockDriverState *bs, BlockCompletionFunc *cb, void *opaque);
58
- BlockAIOCB *(*bdrv_aio_pdiscard)(BlockDriverState *bs,
59
- int64_t offset, int bytes,
60
+
61
+ BlockAIOCB * GRAPH_RDLOCK_PTR (*bdrv_aio_pdiscard)(
62
+ BlockDriverState *bs, int64_t offset, int bytes,
63
BlockCompletionFunc *cb, void *opaque);
64
65
int coroutine_fn (*bdrv_co_readv)(BlockDriverState *bs,
66
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
67
*/
68
int coroutine_fn (*bdrv_co_pwrite_zeroes)(BlockDriverState *bs,
69
int64_t offset, int64_t bytes, BdrvRequestFlags flags);
70
- int coroutine_fn (*bdrv_co_pdiscard)(BlockDriverState *bs,
71
- int64_t offset, int64_t bytes);
72
+
73
+ int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_pdiscard)(
74
+ BlockDriverState *bs, int64_t offset, int64_t bytes);
75
76
/*
77
* Map [offset, offset + nbytes) range onto a child of @bs to copy from,
78
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
79
int coroutine_fn (*bdrv_co_snapshot_block_status)(BlockDriverState *bs,
80
bool want_zero, int64_t offset, int64_t bytes, int64_t *pnum,
81
int64_t *map, BlockDriverState **file);
82
- int coroutine_fn (*bdrv_co_pdiscard_snapshot)(BlockDriverState *bs,
83
- int64_t offset, int64_t bytes);
84
+
85
+ int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_pdiscard_snapshot)(
86
+ BlockDriverState *bs, int64_t offset, int64_t bytes);
87
88
/*
89
* Invalidate any cached meta-data.
90
diff --git a/include/block/block_int-io.h b/include/block/block_int-io.h
91
index XXXXXXX..XXXXXXX 100644
92
--- a/include/block/block_int-io.h
93
+++ b/include/block/block_int-io.h
94
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_preadv_snapshot(BdrvChild *child,
95
int coroutine_fn bdrv_co_snapshot_block_status(BlockDriverState *bs,
96
bool want_zero, int64_t offset, int64_t bytes, int64_t *pnum,
97
int64_t *map, BlockDriverState **file);
98
-int coroutine_fn bdrv_co_pdiscard_snapshot(BlockDriverState *bs,
99
+int coroutine_fn GRAPH_RDLOCK bdrv_co_pdiscard_snapshot(BlockDriverState *bs,
100
int64_t offset, int64_t bytes);
101
102
103
diff --git a/block/blkdebug.c b/block/blkdebug.c
104
index XXXXXXX..XXXXXXX 100644
105
--- a/block/blkdebug.c
106
+++ b/block/blkdebug.c
107
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn blkdebug_co_pwrite_zeroes(BlockDriverState *bs,
108
return bdrv_co_pwrite_zeroes(bs->file, offset, bytes, flags);
109
}
110
111
-static int coroutine_fn blkdebug_co_pdiscard(BlockDriverState *bs,
112
- int64_t offset, int64_t bytes)
113
+static int coroutine_fn GRAPH_RDLOCK
114
+blkdebug_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes)
115
{
116
uint32_t align = bs->bl.pdiscard_alignment;
117
int err;
118
diff --git a/block/blklogwrites.c b/block/blklogwrites.c
119
index XXXXXXX..XXXXXXX 100644
120
--- a/block/blklogwrites.c
121
+++ b/block/blklogwrites.c
122
@@ -XXX,XX +XXX,XX @@ blk_log_writes_co_do_file_flush(BlkLogWritesFileReq *fr)
123
return bdrv_co_flush(fr->bs->file->bs);
124
}
125
126
-static int coroutine_fn
127
+static int coroutine_fn GRAPH_RDLOCK
128
blk_log_writes_co_do_file_pdiscard(BlkLogWritesFileReq *fr)
129
{
130
return bdrv_co_pdiscard(fr->bs->file, fr->offset, fr->bytes);
131
@@ -XXX,XX +XXX,XX @@ blk_log_writes_co_flush_to_disk(BlockDriverState *bs)
132
LOG_FLUSH_FLAG, false);
133
}
134
135
-static int coroutine_fn
136
+static int coroutine_fn GRAPH_RDLOCK
137
blk_log_writes_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes)
138
{
139
- assume_graph_lock(); /* FIXME */
140
return blk_log_writes_co_log(bs, offset, bytes, NULL, 0,
141
blk_log_writes_co_do_file_pdiscard,
142
LOG_DISCARD_FLAG, false);
143
diff --git a/block/blkreplay.c b/block/blkreplay.c
144
index XXXXXXX..XXXXXXX 100644
145
--- a/block/blkreplay.c
146
+++ b/block/blkreplay.c
147
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn blkreplay_co_pwrite_zeroes(BlockDriverState *bs,
148
return ret;
149
}
150
151
-static int coroutine_fn blkreplay_co_pdiscard(BlockDriverState *bs,
152
- int64_t offset, int64_t bytes)
153
+static int coroutine_fn GRAPH_RDLOCK
154
+blkreplay_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes)
155
{
156
uint64_t reqid = blkreplay_next_id();
157
int ret = bdrv_co_pdiscard(bs->file, offset, bytes);
158
diff --git a/block/block-backend.c b/block/block-backend.c
159
index XXXXXXX..XXXXXXX 100644
160
--- a/block/block-backend.c
161
+++ b/block/block-backend.c
162
@@ -XXX,XX +XXX,XX @@ blk_co_do_pdiscard(BlockBackend *blk, int64_t offset, int64_t bytes)
163
IO_CODE();
164
165
blk_wait_while_drained(blk);
166
+ GRAPH_RDLOCK_GUARD();
167
168
ret = blk_check_byte_request(blk, offset, bytes);
169
if (ret < 0) {
170
diff --git a/block/copy-before-write.c b/block/copy-before-write.c
171
index XXXXXXX..XXXXXXX 100644
172
--- a/block/copy-before-write.c
173
+++ b/block/copy-before-write.c
174
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int cbw_do_copy_before_write(BlockDriverState *bs,
175
return 0;
176
}
177
178
-static int coroutine_fn cbw_co_pdiscard(BlockDriverState *bs,
179
- int64_t offset, int64_t bytes)
180
+static int coroutine_fn GRAPH_RDLOCK
181
+cbw_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes)
182
{
183
int ret = cbw_do_copy_before_write(bs, offset, bytes, 0);
184
if (ret < 0) {
185
@@ -XXX,XX +XXX,XX @@ cbw_co_snapshot_block_status(BlockDriverState *bs,
186
return ret;
187
}
188
189
-static int coroutine_fn cbw_co_pdiscard_snapshot(BlockDriverState *bs,
190
- int64_t offset, int64_t bytes)
191
+static int coroutine_fn GRAPH_RDLOCK
192
+cbw_co_pdiscard_snapshot(BlockDriverState *bs, int64_t offset, int64_t bytes)
193
{
194
BDRVCopyBeforeWriteState *s = bs->opaque;
195
196
diff --git a/block/copy-on-read.c b/block/copy-on-read.c
197
index XXXXXXX..XXXXXXX 100644
198
--- a/block/copy-on-read.c
199
+++ b/block/copy-on-read.c
200
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn cor_co_pwrite_zeroes(BlockDriverState *bs,
201
}
202
203
204
-static int coroutine_fn cor_co_pdiscard(BlockDriverState *bs,
205
- int64_t offset, int64_t bytes)
206
+static int coroutine_fn GRAPH_RDLOCK
207
+cor_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes)
208
{
209
return bdrv_co_pdiscard(bs->file, offset, bytes);
210
}
211
diff --git a/block/filter-compress.c b/block/filter-compress.c
212
index XXXXXXX..XXXXXXX 100644
213
--- a/block/filter-compress.c
214
+++ b/block/filter-compress.c
215
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn compress_co_pwrite_zeroes(BlockDriverState *bs,
216
}
217
218
219
-static int coroutine_fn compress_co_pdiscard(BlockDriverState *bs,
220
- int64_t offset, int64_t bytes)
221
+static int coroutine_fn GRAPH_RDLOCK
222
+compress_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes)
223
{
224
return bdrv_co_pdiscard(bs->file, offset, bytes);
225
}
226
diff --git a/block/io.c b/block/io.c
227
index XXXXXXX..XXXXXXX 100644
228
--- a/block/io.c
229
+++ b/block/io.c
230
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_pdiscard(BdrvChild *child, int64_t offset,
231
int head, tail, align;
232
BlockDriverState *bs = child->bs;
233
IO_CODE();
234
+ assert_bdrv_graph_readable();
235
236
if (!bs || !bs->drv || !bdrv_co_is_inserted(bs)) {
237
return -ENOMEDIUM;
238
@@ -XXX,XX +XXX,XX @@ bdrv_co_pdiscard_snapshot(BlockDriverState *bs, int64_t offset, int64_t bytes)
239
BlockDriver *drv = bs->drv;
240
int ret;
241
IO_CODE();
242
+ assert_bdrv_graph_readable();
243
244
if (!drv) {
245
return -ENOMEDIUM;
246
diff --git a/block/mirror.c b/block/mirror.c
247
index XXXXXXX..XXXXXXX 100644
248
--- a/block/mirror.c
249
+++ b/block/mirror.c
250
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_mirror_top_preadv(BlockDriverState *bs,
251
return bdrv_co_preadv(bs->backing, offset, bytes, qiov, flags);
252
}
253
254
-static int coroutine_fn bdrv_mirror_top_do_write(BlockDriverState *bs,
255
- MirrorMethod method, uint64_t offset, uint64_t bytes, QEMUIOVector *qiov,
256
- int flags)
257
+static int coroutine_fn GRAPH_RDLOCK
258
+bdrv_mirror_top_do_write(BlockDriverState *bs, MirrorMethod method,
259
+ uint64_t offset, uint64_t bytes, QEMUIOVector *qiov,
260
+ int flags)
261
{
262
MirrorOp *op = NULL;
263
MirrorBDSOpaque *s = bs->opaque;
264
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_mirror_top_pwritev(BlockDriverState *bs,
265
int ret = 0;
266
bool copy_to_target = false;
267
268
+ assume_graph_lock(); /* FIXME */
269
+
270
if (s->job) {
271
copy_to_target = s->job->ret >= 0 &&
272
!job_is_cancelled(&s->job->common.job) &&
273
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn GRAPH_RDLOCK bdrv_mirror_top_flush(BlockDriverState *bs)
274
static int coroutine_fn bdrv_mirror_top_pwrite_zeroes(BlockDriverState *bs,
275
int64_t offset, int64_t bytes, BdrvRequestFlags flags)
276
{
277
+ assume_graph_lock(); /* FIXME */
278
return bdrv_mirror_top_do_write(bs, MIRROR_METHOD_ZERO, offset, bytes, NULL,
279
flags);
280
}
281
282
-static int coroutine_fn bdrv_mirror_top_pdiscard(BlockDriverState *bs,
283
- int64_t offset, int64_t bytes)
284
+static int coroutine_fn GRAPH_RDLOCK
285
+bdrv_mirror_top_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes)
286
{
287
return bdrv_mirror_top_do_write(bs, MIRROR_METHOD_DISCARD, offset, bytes,
288
NULL, 0);
289
diff --git a/block/preallocate.c b/block/preallocate.c
290
index XXXXXXX..XXXXXXX 100644
291
--- a/block/preallocate.c
292
+++ b/block/preallocate.c
293
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int preallocate_co_preadv_part(
294
flags);
295
}
296
297
-static int coroutine_fn preallocate_co_pdiscard(BlockDriverState *bs,
298
- int64_t offset, int64_t bytes)
299
+static int coroutine_fn GRAPH_RDLOCK
300
+preallocate_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes)
301
{
302
return bdrv_co_pdiscard(bs->file, offset, bytes);
303
}
304
diff --git a/block/raw-format.c b/block/raw-format.c
305
index XXXXXXX..XXXXXXX 100644
306
--- a/block/raw-format.c
307
+++ b/block/raw-format.c
308
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn raw_co_pwrite_zeroes(BlockDriverState *bs,
309
return bdrv_co_pwrite_zeroes(bs->file, offset, bytes, flags);
310
}
311
312
-static int coroutine_fn raw_co_pdiscard(BlockDriverState *bs,
313
- int64_t offset, int64_t bytes)
314
+static int coroutine_fn GRAPH_RDLOCK
315
+raw_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes)
316
{
317
int ret;
318
319
diff --git a/block/snapshot-access.c b/block/snapshot-access.c
320
index XXXXXXX..XXXXXXX 100644
321
--- a/block/snapshot-access.c
322
+++ b/block/snapshot-access.c
323
@@ -XXX,XX +XXX,XX @@ snapshot_access_co_block_status(BlockDriverState *bs,
324
bytes, pnum, map, file);
325
}
326
327
-static int coroutine_fn snapshot_access_co_pdiscard(BlockDriverState *bs,
328
- int64_t offset, int64_t bytes)
329
+static int coroutine_fn GRAPH_RDLOCK
330
+snapshot_access_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes)
331
{
332
return bdrv_co_pdiscard_snapshot(bs->file->bs, offset, bytes);
333
}
334
diff --git a/block/throttle.c b/block/throttle.c
335
index XXXXXXX..XXXXXXX 100644
336
--- a/block/throttle.c
337
+++ b/block/throttle.c
338
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn throttle_co_pwrite_zeroes(BlockDriverState *bs,
339
return bdrv_co_pwrite_zeroes(bs->file, offset, bytes, flags);
340
}
341
342
-static int coroutine_fn throttle_co_pdiscard(BlockDriverState *bs,
343
- int64_t offset, int64_t bytes)
344
+static int coroutine_fn GRAPH_RDLOCK
345
+throttle_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes)
346
{
347
ThrottleGroupMember *tgm = bs->opaque;
348
throttle_group_co_io_limits_intercept(tgm, bytes, true);
349
--
350
2.39.2
diff view generated by jsdifflib
Deleted patch
1
This adds GRAPH_RDLOCK annotations to declare that callers of
2
bdrv_co_pwrite_zeroes() need to hold a reader lock for the graph.
3
1
4
For some places, we know that they will hold the lock, but we don't have
5
the GRAPH_RDLOCK annotations yet. In this case, add assume_graph_lock()
6
with a FIXME comment. These places will be removed once everything is
7
properly annotated.
8
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
Message-Id: <20230203152202.49054-10-kwolf@redhat.com>
11
Reviewed-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
---
14
block/qcow2.h | 6 ++++--
15
include/block/block-io.h | 9 +++++----
16
include/block/block_int-common.h | 5 +++--
17
block/blkdebug.c | 6 +++---
18
block/blklogwrites.c | 5 ++---
19
block/blkreplay.c | 5 +++--
20
block/block-copy.c | 13 +++++++------
21
block/copy-before-write.c | 5 +++--
22
block/copy-on-read.c | 6 +++---
23
block/filter-compress.c | 6 +++---
24
block/io.c | 12 +++++++++---
25
block/mirror.c | 6 +++---
26
block/preallocate.c | 11 +++++++----
27
block/qcow2.c | 30 ++++++++++++++++++------------
28
block/qed.c | 9 +++------
29
block/quorum.c | 15 ++++++++++-----
30
block/raw-format.c | 6 +++---
31
block/throttle.c | 6 +++---
32
18 files changed, 92 insertions(+), 69 deletions(-)
33
34
diff --git a/block/qcow2.h b/block/qcow2.h
35
index XXXXXXX..XXXXXXX 100644
36
--- a/block/qcow2.h
37
+++ b/block/qcow2.h
38
@@ -XXX,XX +XXX,XX @@ void qcow2_alloc_cluster_abort(BlockDriverState *bs, QCowL2Meta *m);
39
int qcow2_cluster_discard(BlockDriverState *bs, uint64_t offset,
40
uint64_t bytes, enum qcow2_discard_type type,
41
bool full_discard);
42
-int coroutine_fn qcow2_subcluster_zeroize(BlockDriverState *bs, uint64_t offset,
43
- uint64_t bytes, int flags);
44
+
45
+int coroutine_fn GRAPH_RDLOCK
46
+qcow2_subcluster_zeroize(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
47
+ int flags);
48
49
int qcow2_expand_zero_clusters(BlockDriverState *bs,
50
BlockDriverAmendStatusCB *status_cb,
51
diff --git a/include/block/block-io.h b/include/block/block-io.h
52
index XXXXXXX..XXXXXXX 100644
53
--- a/include/block/block-io.h
54
+++ b/include/block/block-io.h
55
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_pwrite_sync(BdrvChild *child, int64_t offset,
56
* function is not suitable for zeroing the entire image in a single request
57
* because it may allocate memory for the entire region.
58
*/
59
-int coroutine_fn bdrv_co_pwrite_zeroes(BdrvChild *child, int64_t offset,
60
- int64_t bytes, BdrvRequestFlags flags);
61
+int coroutine_fn GRAPH_RDLOCK
62
+bdrv_co_pwrite_zeroes(BdrvChild *child, int64_t offset, int64_t bytes,
63
+ BdrvRequestFlags flags);
64
65
int coroutine_fn GRAPH_RDLOCK
66
bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact,
67
@@ -XXX,XX +XXX,XX @@ int bdrv_is_allocated_above(BlockDriverState *top, BlockDriverState *base,
68
bool include_base, int64_t offset, int64_t bytes,
69
int64_t *pnum);
70
71
-int coroutine_fn bdrv_co_is_zero_fast(BlockDriverState *bs, int64_t offset,
72
- int64_t bytes);
73
+int coroutine_fn GRAPH_RDLOCK
74
+bdrv_co_is_zero_fast(BlockDriverState *bs, int64_t offset, int64_t bytes);
75
76
int bdrv_apply_auto_read_only(BlockDriverState *bs, const char *errmsg,
77
Error **errp);
78
diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h
79
index XXXXXXX..XXXXXXX 100644
80
--- a/include/block/block_int-common.h
81
+++ b/include/block/block_int-common.h
82
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
83
* function pointer may be NULL or return -ENOSUP and .bdrv_co_writev()
84
* will be called instead.
85
*/
86
- int coroutine_fn (*bdrv_co_pwrite_zeroes)(BlockDriverState *bs,
87
- int64_t offset, int64_t bytes, BdrvRequestFlags flags);
88
+ int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_pwrite_zeroes)(
89
+ BlockDriverState *bs, int64_t offset, int64_t bytes,
90
+ BdrvRequestFlags flags);
91
92
int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_pdiscard)(
93
BlockDriverState *bs, int64_t offset, int64_t bytes);
94
diff --git a/block/blkdebug.c b/block/blkdebug.c
95
index XXXXXXX..XXXXXXX 100644
96
--- a/block/blkdebug.c
97
+++ b/block/blkdebug.c
98
@@ -XXX,XX +XXX,XX @@ static int GRAPH_RDLOCK coroutine_fn blkdebug_co_flush(BlockDriverState *bs)
99
return bdrv_co_flush(bs->file->bs);
100
}
101
102
-static int coroutine_fn blkdebug_co_pwrite_zeroes(BlockDriverState *bs,
103
- int64_t offset, int64_t bytes,
104
- BdrvRequestFlags flags)
105
+static int coroutine_fn GRAPH_RDLOCK
106
+blkdebug_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes,
107
+ BdrvRequestFlags flags)
108
{
109
uint32_t align = MAX(bs->bl.request_alignment,
110
bs->bl.pwrite_zeroes_alignment);
111
diff --git a/block/blklogwrites.c b/block/blklogwrites.c
112
index XXXXXXX..XXXXXXX 100644
113
--- a/block/blklogwrites.c
114
+++ b/block/blklogwrites.c
115
@@ -XXX,XX +XXX,XX @@ blk_log_writes_co_do_file_pwritev(BlkLogWritesFileReq *fr)
116
fr->qiov, fr->file_flags);
117
}
118
119
-static int coroutine_fn
120
+static int coroutine_fn GRAPH_RDLOCK
121
blk_log_writes_co_do_file_pwrite_zeroes(BlkLogWritesFileReq *fr)
122
{
123
return bdrv_co_pwrite_zeroes(fr->bs->file, fr->offset, fr->bytes,
124
@@ -XXX,XX +XXX,XX @@ blk_log_writes_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
125
blk_log_writes_co_do_file_pwritev, 0, false);
126
}
127
128
-static int coroutine_fn
129
+static int coroutine_fn GRAPH_RDLOCK
130
blk_log_writes_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset,
131
int64_t bytes, BdrvRequestFlags flags)
132
{
133
- assume_graph_lock(); /* FIXME */
134
return blk_log_writes_co_log(bs, offset, bytes, NULL, flags,
135
blk_log_writes_co_do_file_pwrite_zeroes, 0,
136
true);
137
diff --git a/block/blkreplay.c b/block/blkreplay.c
138
index XXXXXXX..XXXXXXX 100644
139
--- a/block/blkreplay.c
140
+++ b/block/blkreplay.c
141
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn blkreplay_co_pwritev(BlockDriverState *bs,
142
return ret;
143
}
144
145
-static int coroutine_fn blkreplay_co_pwrite_zeroes(BlockDriverState *bs,
146
- int64_t offset, int64_t bytes, BdrvRequestFlags flags)
147
+static int coroutine_fn GRAPH_RDLOCK
148
+blkreplay_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes,
149
+ BdrvRequestFlags flags)
150
{
151
uint64_t reqid = blkreplay_next_id();
152
int ret = bdrv_co_pwrite_zeroes(bs->file, offset, bytes, flags);
153
diff --git a/block/block-copy.c b/block/block-copy.c
154
index XXXXXXX..XXXXXXX 100644
155
--- a/block/block-copy.c
156
+++ b/block/block-copy.c
157
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int block_copy_task_run(AioTaskPool *pool,
158
* value of @method should be used for subsequent tasks.
159
* Returns 0 on success.
160
*/
161
-static int coroutine_fn block_copy_do_copy(BlockCopyState *s,
162
- int64_t offset, int64_t bytes,
163
- BlockCopyMethod *method,
164
- bool *error_is_read)
165
+static int coroutine_fn GRAPH_RDLOCK
166
+block_copy_do_copy(BlockCopyState *s, int64_t offset, int64_t bytes,
167
+ BlockCopyMethod *method, bool *error_is_read)
168
{
169
int ret;
170
int64_t nbytes = MIN(offset + bytes, s->len) - offset;
171
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int block_copy_task_entry(AioTask *task)
172
BlockCopyMethod method = t->method;
173
int ret;
174
175
- ret = block_copy_do_copy(s, t->req.offset, t->req.bytes, &method,
176
- &error_is_read);
177
+ WITH_GRAPH_RDLOCK_GUARD() {
178
+ ret = block_copy_do_copy(s, t->req.offset, t->req.bytes, &method,
179
+ &error_is_read);
180
+ }
181
182
WITH_QEMU_LOCK_GUARD(&s->lock) {
183
if (s->method == t->method) {
184
diff --git a/block/copy-before-write.c b/block/copy-before-write.c
185
index XXXXXXX..XXXXXXX 100644
186
--- a/block/copy-before-write.c
187
+++ b/block/copy-before-write.c
188
@@ -XXX,XX +XXX,XX @@ cbw_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes)
189
return bdrv_co_pdiscard(bs->file, offset, bytes);
190
}
191
192
-static int coroutine_fn cbw_co_pwrite_zeroes(BlockDriverState *bs,
193
- int64_t offset, int64_t bytes, BdrvRequestFlags flags)
194
+static int coroutine_fn GRAPH_RDLOCK
195
+cbw_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes,
196
+ BdrvRequestFlags flags)
197
{
198
int ret = cbw_do_copy_before_write(bs, offset, bytes, flags);
199
if (ret < 0) {
200
diff --git a/block/copy-on-read.c b/block/copy-on-read.c
201
index XXXXXXX..XXXXXXX 100644
202
--- a/block/copy-on-read.c
203
+++ b/block/copy-on-read.c
204
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn cor_co_pwritev_part(BlockDriverState *bs,
205
}
206
207
208
-static int coroutine_fn cor_co_pwrite_zeroes(BlockDriverState *bs,
209
- int64_t offset, int64_t bytes,
210
- BdrvRequestFlags flags)
211
+static int coroutine_fn GRAPH_RDLOCK
212
+cor_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes,
213
+ BdrvRequestFlags flags)
214
{
215
return bdrv_co_pwrite_zeroes(bs->file, offset, bytes, flags);
216
}
217
diff --git a/block/filter-compress.c b/block/filter-compress.c
218
index XXXXXXX..XXXXXXX 100644
219
--- a/block/filter-compress.c
220
+++ b/block/filter-compress.c
221
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn compress_co_pwritev_part(BlockDriverState *bs,
222
}
223
224
225
-static int coroutine_fn compress_co_pwrite_zeroes(BlockDriverState *bs,
226
- int64_t offset, int64_t bytes,
227
- BdrvRequestFlags flags)
228
+static int coroutine_fn GRAPH_RDLOCK
229
+compress_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes,
230
+ BdrvRequestFlags flags)
231
{
232
return bdrv_co_pwrite_zeroes(bs->file, offset, bytes, flags);
233
}
234
diff --git a/block/io.c b/block/io.c
235
index XXXXXXX..XXXXXXX 100644
236
--- a/block/io.c
237
+++ b/block/io.c
238
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_co_do_copy_on_readv(BdrvChild *child,
239
int64_t progress = 0;
240
bool skip_write;
241
242
+ assume_graph_lock(); /* FIXME */
243
+
244
bdrv_check_qiov_request(offset, bytes, qiov, qiov_offset, &error_abort);
245
246
if (!drv) {
247
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_co_do_pwrite_zeroes(BlockDriverState *bs,
248
bs->bl.request_alignment);
249
int max_transfer = MIN_NON_ZERO(bs->bl.max_transfer, MAX_BOUNCE_BUFFER);
250
251
+ assert_bdrv_graph_readable();
252
bdrv_check_request(offset, bytes, &error_abort);
253
254
if (!drv) {
255
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_aligned_pwritev(BdrvChild *child,
256
int64_t bytes_remaining = bytes;
257
int max_transfer;
258
259
+ assume_graph_lock(); /* FIXME */
260
+
261
bdrv_check_qiov_request(offset, bytes, qiov, qiov_offset, &error_abort);
262
263
if (!drv) {
264
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_pwrite_zeroes(BdrvChild *child, int64_t offset,
265
{
266
IO_CODE();
267
trace_bdrv_co_pwrite_zeroes(child->bs, offset, bytes, flags);
268
+ assert_bdrv_graph_readable();
269
270
if (!(child->bs->open_flags & BDRV_O_UNMAP)) {
271
flags &= ~BDRV_REQ_MAY_UNMAP;
272
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_is_zero_fast(BlockDriverState *bs, int64_t offset,
273
int64_t pnum = bytes;
274
IO_CODE();
275
276
- assume_graph_lock(); /* FIXME */
277
-
278
if (!bytes) {
279
return 1;
280
}
281
@@ -XXX,XX +XXX,XX @@ void bdrv_unregister_buf(BlockDriverState *bs, void *host, size_t size)
282
}
283
}
284
285
-static int coroutine_fn bdrv_co_copy_range_internal(
286
+static int coroutine_fn GRAPH_RDLOCK bdrv_co_copy_range_internal(
287
BdrvChild *src, int64_t src_offset, BdrvChild *dst,
288
int64_t dst_offset, int64_t bytes,
289
BdrvRequestFlags read_flags, BdrvRequestFlags write_flags,
290
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_copy_range_from(BdrvChild *src, int64_t src_offset,
291
BdrvRequestFlags write_flags)
292
{
293
IO_CODE();
294
+ assume_graph_lock(); /* FIXME */
295
trace_bdrv_co_copy_range_from(src, src_offset, dst, dst_offset, bytes,
296
read_flags, write_flags);
297
return bdrv_co_copy_range_internal(src, src_offset, dst, dst_offset,
298
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_copy_range_to(BdrvChild *src, int64_t src_offset,
299
BdrvRequestFlags write_flags)
300
{
301
IO_CODE();
302
+ assume_graph_lock(); /* FIXME */
303
trace_bdrv_co_copy_range_to(src, src_offset, dst, dst_offset, bytes,
304
read_flags, write_flags);
305
return bdrv_co_copy_range_internal(src, src_offset, dst, dst_offset,
306
diff --git a/block/mirror.c b/block/mirror.c
307
index XXXXXXX..XXXXXXX 100644
308
--- a/block/mirror.c
309
+++ b/block/mirror.c
310
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn GRAPH_RDLOCK bdrv_mirror_top_flush(BlockDriverState *bs)
311
return bdrv_co_flush(bs->backing->bs);
312
}
313
314
-static int coroutine_fn bdrv_mirror_top_pwrite_zeroes(BlockDriverState *bs,
315
- int64_t offset, int64_t bytes, BdrvRequestFlags flags)
316
+static int coroutine_fn GRAPH_RDLOCK
317
+bdrv_mirror_top_pwrite_zeroes(BlockDriverState *bs, int64_t offset,
318
+ int64_t bytes, BdrvRequestFlags flags)
319
{
320
- assume_graph_lock(); /* FIXME */
321
return bdrv_mirror_top_do_write(bs, MIRROR_METHOD_ZERO, offset, bytes, NULL,
322
flags);
323
}
324
diff --git a/block/preallocate.c b/block/preallocate.c
325
index XXXXXXX..XXXXXXX 100644
326
--- a/block/preallocate.c
327
+++ b/block/preallocate.c
328
@@ -XXX,XX +XXX,XX @@ static bool has_prealloc_perms(BlockDriverState *bs)
329
* want_merge_zero is used to merge write-zero request with preallocation in
330
* one bdrv_co_pwrite_zeroes() call.
331
*/
332
-static bool coroutine_fn handle_write(BlockDriverState *bs, int64_t offset,
333
- int64_t bytes, bool want_merge_zero)
334
+static bool coroutine_fn GRAPH_RDLOCK
335
+handle_write(BlockDriverState *bs, int64_t offset, int64_t bytes,
336
+ bool want_merge_zero)
337
{
338
BDRVPreallocateState *s = bs->opaque;
339
int64_t end = offset + bytes;
340
@@ -XXX,XX +XXX,XX @@ static bool coroutine_fn handle_write(BlockDriverState *bs, int64_t offset,
341
return want_merge_zero;
342
}
343
344
-static int coroutine_fn preallocate_co_pwrite_zeroes(BlockDriverState *bs,
345
- int64_t offset, int64_t bytes, BdrvRequestFlags flags)
346
+static int coroutine_fn GRAPH_RDLOCK
347
+preallocate_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset,
348
+ int64_t bytes, BdrvRequestFlags flags)
349
{
350
bool want_merge_zero =
351
!(flags & ~(BDRV_REQ_ZERO_WRITE | BDRV_REQ_NO_FALLBACK));
352
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int preallocate_co_pwritev_part(BlockDriverState *bs,
353
size_t qiov_offset,
354
BdrvRequestFlags flags)
355
{
356
+ assume_graph_lock(); /* FIXME */
357
handle_write(bs, offset, bytes, false);
358
359
return bdrv_co_pwritev_part(bs->file, offset, bytes, qiov, qiov_offset,
360
diff --git a/block/qcow2.c b/block/qcow2.c
361
index XXXXXXX..XXXXXXX 100644
362
--- a/block/qcow2.c
363
+++ b/block/qcow2.c
364
@@ -XXX,XX +XXX,XX @@ static bool merge_cow(uint64_t offset, unsigned bytes,
365
* Return 1 if the COW regions read as zeroes, 0 if not, < 0 on error.
366
* Note that returning 0 does not guarantee non-zero data.
367
*/
368
-static int coroutine_fn is_zero_cow(BlockDriverState *bs, QCowL2Meta *m)
369
+static int coroutine_fn GRAPH_RDLOCK
370
+is_zero_cow(BlockDriverState *bs, QCowL2Meta *m)
371
{
372
/*
373
* This check is designed for optimization shortcut so it must be
374
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn is_zero_cow(BlockDriverState *bs, QCowL2Meta *m)
375
m->cow_end.nb_bytes);
376
}
377
378
-static int coroutine_fn handle_alloc_space(BlockDriverState *bs,
379
- QCowL2Meta *l2meta)
380
+static int coroutine_fn GRAPH_RDLOCK
381
+handle_alloc_space(BlockDriverState *bs, QCowL2Meta *l2meta)
382
{
383
BDRVQcow2State *s = bs->opaque;
384
QCowL2Meta *m;
385
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn handle_alloc_space(BlockDriverState *bs,
386
* l2meta - if not NULL, qcow2_co_pwritev_task() will consume it. Caller must
387
* not use it somehow after qcow2_co_pwritev_task() call
388
*/
389
-static coroutine_fn int qcow2_co_pwritev_task(BlockDriverState *bs,
390
- uint64_t host_offset,
391
- uint64_t offset, uint64_t bytes,
392
- QEMUIOVector *qiov,
393
- uint64_t qiov_offset,
394
- QCowL2Meta *l2meta)
395
+static coroutine_fn GRAPH_RDLOCK
396
+int qcow2_co_pwritev_task(BlockDriverState *bs, uint64_t host_offset,
397
+ uint64_t offset, uint64_t bytes, QEMUIOVector *qiov,
398
+ uint64_t qiov_offset, QCowL2Meta *l2meta)
399
{
400
int ret;
401
BDRVQcow2State *s = bs->opaque;
402
@@ -XXX,XX +XXX,XX @@ out_locked:
403
return ret;
404
}
405
406
-static coroutine_fn int qcow2_co_pwritev_task_entry(AioTask *task)
407
+/*
408
+ * This function can count as GRAPH_RDLOCK because qcow2_co_pwritev_part() holds
409
+ * the graph lock and keeps it until this coroutine has terminated.
410
+ */
411
+static coroutine_fn GRAPH_RDLOCK int qcow2_co_pwritev_task_entry(AioTask *task)
412
{
413
Qcow2AioTask *t = container_of(task, Qcow2AioTask, task);
414
415
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow2_co_pwritev_part(
416
QCowL2Meta *l2meta = NULL;
417
AioTaskPool *aio = NULL;
418
419
+ assume_graph_lock(); /* FIXME */
420
+
421
trace_qcow2_writev_start_req(qemu_coroutine_self(), offset, bytes);
422
423
while (bytes != 0 && aio_task_pool_status(aio) == 0) {
424
@@ -XXX,XX +XXX,XX @@ static bool is_zero(BlockDriverState *bs, int64_t offset, int64_t bytes)
425
return res >= 0 && (res & BDRV_BLOCK_ZERO) && bytes == 0;
426
}
427
428
-static coroutine_fn int qcow2_co_pwrite_zeroes(BlockDriverState *bs,
429
- int64_t offset, int64_t bytes, BdrvRequestFlags flags)
430
+static int coroutine_fn GRAPH_RDLOCK
431
+qcow2_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes,
432
+ BdrvRequestFlags flags)
433
{
434
int ret;
435
BDRVQcow2State *s = bs->opaque;
436
diff --git a/block/qed.c b/block/qed.c
437
index XXXXXXX..XXXXXXX 100644
438
--- a/block/qed.c
439
+++ b/block/qed.c
440
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_qed_co_writev(BlockDriverState *bs,
441
return qed_co_request(bs, sector_num, qiov, nb_sectors, QED_AIOCB_WRITE);
442
}
443
444
-static int coroutine_fn bdrv_qed_co_pwrite_zeroes(BlockDriverState *bs,
445
- int64_t offset,
446
- int64_t bytes,
447
- BdrvRequestFlags flags)
448
+static int coroutine_fn GRAPH_RDLOCK
449
+bdrv_qed_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes,
450
+ BdrvRequestFlags flags)
451
{
452
BDRVQEDState *s = bs->opaque;
453
454
- assume_graph_lock(); /* FIXME */
455
-
456
/*
457
* Zero writes start without an I/O buffer. If a buffer becomes necessary
458
* then it will be allocated during request processing.
459
diff --git a/block/quorum.c b/block/quorum.c
460
index XXXXXXX..XXXXXXX 100644
461
--- a/block/quorum.c
462
+++ b/block/quorum.c
463
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn quorum_co_preadv(BlockDriverState *bs,
464
return ret;
465
}
466
467
-static void coroutine_fn write_quorum_entry(void *opaque)
468
+/*
469
+ * This function can count as GRAPH_RDLOCK because quorum_co_pwritev() holds the
470
+ * graph lock and keeps it until this coroutine has terminated.
471
+ */
472
+static void coroutine_fn GRAPH_RDLOCK write_quorum_entry(void *opaque)
473
{
474
QuorumCo *co = opaque;
475
QuorumAIOCB *acb = co->acb;
476
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn quorum_co_pwritev(BlockDriverState *bs, int64_t offset,
477
QuorumAIOCB *acb = quorum_aio_get(bs, qiov, offset, bytes, flags);
478
int i, ret;
479
480
+ assume_graph_lock(); /* FIXME */
481
+
482
for (i = 0; i < s->num_children; i++) {
483
Coroutine *co;
484
QuorumCo data = {
485
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn quorum_co_pwritev(BlockDriverState *bs, int64_t offset,
486
return ret;
487
}
488
489
-static int coroutine_fn quorum_co_pwrite_zeroes(BlockDriverState *bs,
490
- int64_t offset, int64_t bytes,
491
- BdrvRequestFlags flags)
492
-
493
+static int coroutine_fn GRAPH_RDLOCK
494
+quorum_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes,
495
+ BdrvRequestFlags flags)
496
{
497
return quorum_co_pwritev(bs, offset, bytes, NULL,
498
flags | BDRV_REQ_ZERO_WRITE);
499
diff --git a/block/raw-format.c b/block/raw-format.c
500
index XXXXXXX..XXXXXXX 100644
501
--- a/block/raw-format.c
502
+++ b/block/raw-format.c
503
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn raw_co_block_status(BlockDriverState *bs,
504
return BDRV_BLOCK_RAW | BDRV_BLOCK_OFFSET_VALID;
505
}
506
507
-static int coroutine_fn raw_co_pwrite_zeroes(BlockDriverState *bs,
508
- int64_t offset, int64_t bytes,
509
- BdrvRequestFlags flags)
510
+static int coroutine_fn GRAPH_RDLOCK
511
+raw_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes,
512
+ BdrvRequestFlags flags)
513
{
514
int ret;
515
516
diff --git a/block/throttle.c b/block/throttle.c
517
index XXXXXXX..XXXXXXX 100644
518
--- a/block/throttle.c
519
+++ b/block/throttle.c
520
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn throttle_co_pwritev(BlockDriverState *bs,
521
return bdrv_co_pwritev(bs->file, offset, bytes, qiov, flags);
522
}
523
524
-static int coroutine_fn throttle_co_pwrite_zeroes(BlockDriverState *bs,
525
- int64_t offset, int64_t bytes,
526
- BdrvRequestFlags flags)
527
+static int coroutine_fn GRAPH_RDLOCK
528
+throttle_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes,
529
+ BdrvRequestFlags flags)
530
{
531
ThrottleGroupMember *tgm = bs->opaque;
532
throttle_group_co_io_limits_intercept(tgm, bytes, true);
533
--
534
2.39.2
diff view generated by jsdifflib
Deleted patch
1
This adds GRAPH_RDLOCK annotations to declare that callers of
2
bdrv_driver_*() need to hold a reader lock for the graph. It doesn't add
3
the annotation to public functions yet.
4
1
5
For some places, we know that they will hold the lock, but we don't have
6
the GRAPH_RDLOCK annotations yet. In this case, add assume_graph_lock()
7
with a FIXME comment. These places will be removed once everything is
8
properly annotated.
9
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
Message-Id: <20230203152202.49054-11-kwolf@redhat.com>
12
Reviewed-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
13
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
14
---
15
block/qcow2.h | 5 ++-
16
include/block/block_int-common.h | 40 ++++++++++---------
17
block/io.c | 66 +++++++++++++++-----------------
18
block/parallels.c | 8 ++--
19
block/qcow.c | 20 ++++------
20
block/qcow2-cluster.c | 10 ++---
21
block/qcow2.c | 37 ++++++++++--------
22
block/qed.c | 14 +++----
23
block/quorum.c | 8 ++--
24
block/vmdk.c | 4 +-
25
10 files changed, 101 insertions(+), 111 deletions(-)
26
27
diff --git a/block/qcow2.h b/block/qcow2.h
28
index XXXXXXX..XXXXXXX 100644
29
--- a/block/qcow2.h
30
+++ b/block/qcow2.h
31
@@ -XXX,XX +XXX,XX @@ int coroutine_fn qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs,
32
void qcow2_parse_compressed_l2_entry(BlockDriverState *bs, uint64_t l2_entry,
33
uint64_t *coffset, int *csize);
34
35
-int coroutine_fn qcow2_alloc_cluster_link_l2(BlockDriverState *bs,
36
- QCowL2Meta *m);
37
+int coroutine_fn GRAPH_RDLOCK
38
+qcow2_alloc_cluster_link_l2(BlockDriverState *bs, QCowL2Meta *m);
39
+
40
void qcow2_alloc_cluster_abort(BlockDriverState *bs, QCowL2Meta *m);
41
int qcow2_cluster_discard(BlockDriverState *bs, uint64_t offset,
42
uint64_t bytes, enum qcow2_discard_type type,
43
diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h
44
index XXXXXXX..XXXXXXX 100644
45
--- a/include/block/block_int-common.h
46
+++ b/include/block/block_int-common.h
47
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
48
Error **errp);
49
50
/* aio */
51
- BlockAIOCB *(*bdrv_aio_preadv)(BlockDriverState *bs,
52
+ BlockAIOCB * GRAPH_RDLOCK_PTR (*bdrv_aio_preadv)(BlockDriverState *bs,
53
int64_t offset, int64_t bytes, QEMUIOVector *qiov,
54
BdrvRequestFlags flags, BlockCompletionFunc *cb, void *opaque);
55
- BlockAIOCB *(*bdrv_aio_pwritev)(BlockDriverState *bs,
56
+
57
+ BlockAIOCB * GRAPH_RDLOCK_PTR (*bdrv_aio_pwritev)(BlockDriverState *bs,
58
int64_t offset, int64_t bytes, QEMUIOVector *qiov,
59
BdrvRequestFlags flags, BlockCompletionFunc *cb, void *opaque);
60
+
61
BlockAIOCB * GRAPH_RDLOCK_PTR (*bdrv_aio_flush)(
62
BlockDriverState *bs, BlockCompletionFunc *cb, void *opaque);
63
64
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
65
BlockDriverState *bs, int64_t offset, int bytes,
66
BlockCompletionFunc *cb, void *opaque);
67
68
- int coroutine_fn (*bdrv_co_readv)(BlockDriverState *bs,
69
+ int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_readv)(BlockDriverState *bs,
70
int64_t sector_num, int nb_sectors, QEMUIOVector *qiov);
71
72
/**
73
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
74
*
75
* The buffer in @qiov may point directly to guest memory.
76
*/
77
- int coroutine_fn (*bdrv_co_preadv)(BlockDriverState *bs,
78
+ int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_preadv)(BlockDriverState *bs,
79
int64_t offset, int64_t bytes, QEMUIOVector *qiov,
80
BdrvRequestFlags flags);
81
82
- int coroutine_fn (*bdrv_co_preadv_part)(BlockDriverState *bs,
83
- int64_t offset, int64_t bytes,
84
+ int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_preadv_part)(
85
+ BlockDriverState *bs, int64_t offset, int64_t bytes,
86
QEMUIOVector *qiov, size_t qiov_offset,
87
BdrvRequestFlags flags);
88
89
- int coroutine_fn (*bdrv_co_writev)(BlockDriverState *bs,
90
+ int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_writev)(BlockDriverState *bs,
91
int64_t sector_num, int nb_sectors, QEMUIOVector *qiov,
92
int flags);
93
/**
94
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
95
*
96
* The buffer in @qiov may point directly to guest memory.
97
*/
98
- int coroutine_fn (*bdrv_co_pwritev)(BlockDriverState *bs,
99
- int64_t offset, int64_t bytes, QEMUIOVector *qiov,
100
- BdrvRequestFlags flags);
101
- int coroutine_fn (*bdrv_co_pwritev_part)(BlockDriverState *bs,
102
- int64_t offset, int64_t bytes, QEMUIOVector *qiov, size_t qiov_offset,
103
+ int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_pwritev)(
104
+ BlockDriverState *bs, int64_t offset, int64_t bytes, QEMUIOVector *qiov,
105
BdrvRequestFlags flags);
106
+ int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_pwritev_part)(
107
+ BlockDriverState *bs, int64_t offset, int64_t bytes, QEMUIOVector *qiov,
108
+ size_t qiov_offset, BdrvRequestFlags flags);
109
110
/*
111
* Efficiently zero a region of the disk image. Typically an image format
112
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
113
BlockMeasureInfo *(*bdrv_measure)(QemuOpts *opts, BlockDriverState *in_bs,
114
Error **errp);
115
116
- int coroutine_fn (*bdrv_co_pwritev_compressed)(BlockDriverState *bs,
117
- int64_t offset, int64_t bytes, QEMUIOVector *qiov);
118
- int coroutine_fn (*bdrv_co_pwritev_compressed_part)(BlockDriverState *bs,
119
- int64_t offset, int64_t bytes, QEMUIOVector *qiov,
120
- size_t qiov_offset);
121
+ int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_pwritev_compressed)(
122
+ BlockDriverState *bs, int64_t offset, int64_t bytes,
123
+ QEMUIOVector *qiov);
124
+
125
+ int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_pwritev_compressed_part)(
126
+ BlockDriverState *bs, int64_t offset, int64_t bytes,
127
+ QEMUIOVector *qiov, size_t qiov_offset);
128
129
int coroutine_fn (*bdrv_co_get_info)(BlockDriverState *bs,
130
BlockDriverInfo *bdi);
131
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
132
BlockDriverState *bs, const char *name, Error **errp);
133
};
134
135
-static inline bool block_driver_can_compress(BlockDriver *drv)
136
+static inline bool TSA_NO_TSA block_driver_can_compress(BlockDriver *drv)
137
{
138
return drv->bdrv_co_pwritev_compressed ||
139
drv->bdrv_co_pwritev_compressed_part;
140
diff --git a/block/io.c b/block/io.c
141
index XXXXXXX..XXXXXXX 100644
142
--- a/block/io.c
143
+++ b/block/io.c
144
@@ -XXX,XX +XXX,XX @@ void bdrv_refresh_limits(BlockDriverState *bs, Transaction *tran, Error **errp)
145
bool have_limits;
146
147
GLOBAL_STATE_CODE();
148
+ assume_graph_lock(); /* FIXME */
149
150
if (tran) {
151
BdrvRefreshLimitsState *s = g_new(BdrvRefreshLimitsState, 1);
152
@@ -XXX,XX +XXX,XX @@ static void bdrv_co_io_em_complete(void *opaque, int ret)
153
aio_co_wake(co->coroutine);
154
}
155
156
-static int coroutine_fn bdrv_driver_preadv(BlockDriverState *bs,
157
- int64_t offset, int64_t bytes,
158
- QEMUIOVector *qiov,
159
- size_t qiov_offset, int flags)
160
+static int coroutine_fn GRAPH_RDLOCK
161
+bdrv_driver_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
162
+ QEMUIOVector *qiov, size_t qiov_offset, int flags)
163
{
164
BlockDriver *drv = bs->drv;
165
int64_t sector_num;
166
@@ -XXX,XX +XXX,XX @@ out:
167
return ret;
168
}
169
170
-static int coroutine_fn bdrv_driver_pwritev(BlockDriverState *bs,
171
- int64_t offset, int64_t bytes,
172
- QEMUIOVector *qiov,
173
- size_t qiov_offset,
174
- BdrvRequestFlags flags)
175
+static int coroutine_fn GRAPH_RDLOCK
176
+bdrv_driver_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
177
+ QEMUIOVector *qiov, size_t qiov_offset,
178
+ BdrvRequestFlags flags)
179
{
180
BlockDriver *drv = bs->drv;
181
bool emulate_fua = false;
182
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_driver_pwritev(BlockDriverState *bs,
183
QEMUIOVector local_qiov;
184
int ret;
185
186
- assume_graph_lock(); /* FIXME */
187
-
188
bdrv_check_qiov_request(offset, bytes, qiov, qiov_offset, &error_abort);
189
190
if (!drv) {
191
@@ -XXX,XX +XXX,XX @@ emulate_flags:
192
return ret;
193
}
194
195
-static int coroutine_fn
196
+static int coroutine_fn GRAPH_RDLOCK
197
bdrv_driver_pwritev_compressed(BlockDriverState *bs, int64_t offset,
198
int64_t bytes, QEMUIOVector *qiov,
199
size_t qiov_offset)
200
@@ -XXX,XX +XXX,XX @@ bdrv_driver_pwritev_compressed(BlockDriverState *bs, int64_t offset,
201
return ret;
202
}
203
204
-static int coroutine_fn bdrv_co_do_copy_on_readv(BdrvChild *child,
205
- int64_t offset, int64_t bytes, QEMUIOVector *qiov,
206
- size_t qiov_offset, int flags)
207
+static int coroutine_fn GRAPH_RDLOCK
208
+bdrv_co_do_copy_on_readv(BdrvChild *child, int64_t offset, int64_t bytes,
209
+ QEMUIOVector *qiov, size_t qiov_offset, int flags)
210
{
211
BlockDriverState *bs = child->bs;
212
213
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_co_do_copy_on_readv(BdrvChild *child,
214
int64_t progress = 0;
215
bool skip_write;
216
217
- assume_graph_lock(); /* FIXME */
218
-
219
bdrv_check_qiov_request(offset, bytes, qiov, qiov_offset, &error_abort);
220
221
if (!drv) {
222
@@ -XXX,XX +XXX,XX @@ err:
223
* handles copy on read, zeroing after EOF, and fragmentation of large
224
* reads; any other features must be implemented by the caller.
225
*/
226
-static int coroutine_fn bdrv_aligned_preadv(BdrvChild *child,
227
- BdrvTrackedRequest *req, int64_t offset, int64_t bytes,
228
- int64_t align, QEMUIOVector *qiov, size_t qiov_offset, int flags)
229
+static int coroutine_fn GRAPH_RDLOCK
230
+bdrv_aligned_preadv(BdrvChild *child, BdrvTrackedRequest *req,
231
+ int64_t offset, int64_t bytes, int64_t align,
232
+ QEMUIOVector *qiov, size_t qiov_offset, int flags)
233
{
234
BlockDriverState *bs = child->bs;
235
int64_t total_bytes, max_bytes;
236
@@ -XXX,XX +XXX,XX @@ static bool bdrv_init_padding(BlockDriverState *bs,
237
return true;
238
}
239
240
-static coroutine_fn int bdrv_padding_rmw_read(BdrvChild *child,
241
- BdrvTrackedRequest *req,
242
- BdrvRequestPadding *pad,
243
- bool zero_middle)
244
+static int coroutine_fn GRAPH_RDLOCK
245
+bdrv_padding_rmw_read(BdrvChild *child, BdrvTrackedRequest *req,
246
+ BdrvRequestPadding *pad, bool zero_middle)
247
{
248
QEMUIOVector local_qiov;
249
BlockDriverState *bs = child->bs;
250
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_preadv_part(BdrvChild *child,
251
int ret;
252
IO_CODE();
253
254
+ assume_graph_lock(); /* FIXME */
255
+
256
trace_bdrv_co_preadv_part(bs, offset, bytes, flags);
257
258
if (!bdrv_co_is_inserted(bs)) {
259
@@ -XXX,XX +XXX,XX @@ bdrv_co_write_req_finish(BdrvChild *child, int64_t offset, int64_t bytes,
260
* Forwards an already correctly aligned write request to the BlockDriver,
261
* after possibly fragmenting it.
262
*/
263
-static int coroutine_fn bdrv_aligned_pwritev(BdrvChild *child,
264
- BdrvTrackedRequest *req, int64_t offset, int64_t bytes,
265
- int64_t align, QEMUIOVector *qiov, size_t qiov_offset,
266
- BdrvRequestFlags flags)
267
+static int coroutine_fn GRAPH_RDLOCK
268
+bdrv_aligned_pwritev(BdrvChild *child, BdrvTrackedRequest *req,
269
+ int64_t offset, int64_t bytes, int64_t align,
270
+ QEMUIOVector *qiov, size_t qiov_offset,
271
+ BdrvRequestFlags flags)
272
{
273
BlockDriverState *bs = child->bs;
274
BlockDriver *drv = bs->drv;
275
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_aligned_pwritev(BdrvChild *child,
276
int64_t bytes_remaining = bytes;
277
int max_transfer;
278
279
- assume_graph_lock(); /* FIXME */
280
-
281
bdrv_check_qiov_request(offset, bytes, qiov, qiov_offset, &error_abort);
282
283
if (!drv) {
284
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_aligned_pwritev(BdrvChild *child,
285
return ret;
286
}
287
288
-static int coroutine_fn bdrv_co_do_zero_pwritev(BdrvChild *child,
289
- int64_t offset,
290
- int64_t bytes,
291
- BdrvRequestFlags flags,
292
- BdrvTrackedRequest *req)
293
+static int coroutine_fn GRAPH_RDLOCK
294
+bdrv_co_do_zero_pwritev(BdrvChild *child, int64_t offset, int64_t bytes,
295
+ BdrvRequestFlags flags, BdrvTrackedRequest *req)
296
{
297
BlockDriverState *bs = child->bs;
298
QEMUIOVector local_qiov;
299
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_pwritev_part(BdrvChild *child,
300
bool padded = false;
301
IO_CODE();
302
303
+ assume_graph_lock(); /* FIXME */
304
+
305
trace_bdrv_co_pwritev_part(child->bs, offset, bytes, flags);
306
307
if (!bdrv_co_is_inserted(bs)) {
308
diff --git a/block/parallels.c b/block/parallels.c
309
index XXXXXXX..XXXXXXX 100644
310
--- a/block/parallels.c
311
+++ b/block/parallels.c
312
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn parallels_co_block_status(BlockDriverState *bs,
313
return BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID;
314
}
315
316
-static coroutine_fn int parallels_co_writev(BlockDriverState *bs,
317
- int64_t sector_num, int nb_sectors,
318
- QEMUIOVector *qiov, int flags)
319
+static int coroutine_fn GRAPH_RDLOCK
320
+parallels_co_writev(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
321
+ QEMUIOVector *qiov, int flags)
322
{
323
BDRVParallelsState *s = bs->opaque;
324
uint64_t bytes_done = 0;
325
QEMUIOVector hd_qiov;
326
int ret = 0;
327
328
- assume_graph_lock(); /* FIXME */
329
-
330
qemu_iovec_init(&hd_qiov, qiov->niov);
331
332
while (nb_sectors > 0) {
333
diff --git a/block/qcow.c b/block/qcow.c
334
index XXXXXXX..XXXXXXX 100644
335
--- a/block/qcow.c
336
+++ b/block/qcow.c
337
@@ -XXX,XX +XXX,XX @@ static void qcow_refresh_limits(BlockDriverState *bs, Error **errp)
338
bs->bl.request_alignment = BDRV_SECTOR_SIZE;
339
}
340
341
-static coroutine_fn int qcow_co_preadv(BlockDriverState *bs, int64_t offset,
342
- int64_t bytes, QEMUIOVector *qiov,
343
- BdrvRequestFlags flags)
344
+static int coroutine_fn GRAPH_RDLOCK
345
+qcow_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
346
+ QEMUIOVector *qiov, BdrvRequestFlags flags)
347
{
348
BDRVQcowState *s = bs->opaque;
349
int offset_in_cluster;
350
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow_co_preadv(BlockDriverState *bs, int64_t offset,
351
uint8_t *buf;
352
void *orig_buf;
353
354
- assume_graph_lock(); /* FIXME */
355
-
356
if (qiov->niov > 1) {
357
buf = orig_buf = qemu_try_blockalign(bs, qiov->size);
358
if (buf == NULL) {
359
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow_co_preadv(BlockDriverState *bs, int64_t offset,
360
return ret;
361
}
362
363
-static coroutine_fn int qcow_co_pwritev(BlockDriverState *bs, int64_t offset,
364
- int64_t bytes, QEMUIOVector *qiov,
365
- BdrvRequestFlags flags)
366
+static int coroutine_fn GRAPH_RDLOCK
367
+qcow_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
368
+ QEMUIOVector *qiov, BdrvRequestFlags flags)
369
{
370
BDRVQcowState *s = bs->opaque;
371
int offset_in_cluster;
372
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow_co_pwritev(BlockDriverState *bs, int64_t offset,
373
uint8_t *buf;
374
void *orig_buf;
375
376
- assume_graph_lock(); /* FIXME */
377
-
378
s->cluster_cache_offset = -1; /* disable compressed cache */
379
380
/* We must always copy the iov when encrypting, so we
381
@@ -XXX,XX +XXX,XX @@ static int qcow_make_empty(BlockDriverState *bs)
382
383
/* XXX: put compressed sectors first, then all the cluster aligned
384
tables to avoid losing bytes in alignment */
385
-static coroutine_fn int
386
+static int coroutine_fn GRAPH_RDLOCK
387
qcow_co_pwritev_compressed(BlockDriverState *bs, int64_t offset, int64_t bytes,
388
QEMUIOVector *qiov)
389
{
390
@@ -XXX,XX +XXX,XX @@ qcow_co_pwritev_compressed(BlockDriverState *bs, int64_t offset, int64_t bytes,
391
uint8_t *buf, *out_buf;
392
uint64_t cluster_offset;
393
394
- assume_graph_lock(); /* FIXME */
395
-
396
buf = qemu_blockalign(bs, s->cluster_size);
397
if (bytes != s->cluster_size) {
398
if (bytes > s->cluster_size ||
399
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
400
index XXXXXXX..XXXXXXX 100644
401
--- a/block/qcow2-cluster.c
402
+++ b/block/qcow2-cluster.c
403
@@ -XXX,XX +XXX,XX @@ static int count_contiguous_subclusters(BlockDriverState *bs, int nb_clusters,
404
return count;
405
}
406
407
-static int coroutine_fn do_perform_cow_read(BlockDriverState *bs,
408
- uint64_t src_cluster_offset,
409
- unsigned offset_in_cluster,
410
- QEMUIOVector *qiov)
411
+static int coroutine_fn GRAPH_RDLOCK
412
+do_perform_cow_read(BlockDriverState *bs, uint64_t src_cluster_offset,
413
+ unsigned offset_in_cluster, QEMUIOVector *qiov)
414
{
415
int ret;
416
417
@@ -XXX,XX +XXX,XX @@ int coroutine_fn qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs,
418
return 0;
419
}
420
421
-static int coroutine_fn perform_cow(BlockDriverState *bs, QCowL2Meta *m)
422
+static int coroutine_fn GRAPH_RDLOCK
423
+perform_cow(BlockDriverState *bs, QCowL2Meta *m)
424
{
425
BDRVQcow2State *s = bs->opaque;
426
Qcow2COWRegion *start = &m->cow_start;
427
diff --git a/block/qcow2.c b/block/qcow2.c
428
index XXXXXXX..XXXXXXX 100644
429
--- a/block/qcow2.c
430
+++ b/block/qcow2.c
431
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_co_block_status(BlockDriverState *bs,
432
return status;
433
}
434
435
-static coroutine_fn int qcow2_handle_l2meta(BlockDriverState *bs,
436
- QCowL2Meta **pl2meta,
437
- bool link_l2)
438
+static int coroutine_fn GRAPH_RDLOCK
439
+qcow2_handle_l2meta(BlockDriverState *bs, QCowL2Meta **pl2meta, bool link_l2)
440
{
441
int ret = 0;
442
QCowL2Meta *l2meta = *pl2meta;
443
@@ -XXX,XX +XXX,XX @@ static coroutine_fn GRAPH_RDLOCK int qcow2_co_pwritev_task_entry(AioTask *task)
444
t->l2meta);
445
}
446
447
-static coroutine_fn int qcow2_co_pwritev_part(
448
- BlockDriverState *bs, int64_t offset, int64_t bytes,
449
- QEMUIOVector *qiov, size_t qiov_offset, BdrvRequestFlags flags)
450
+static int coroutine_fn GRAPH_RDLOCK
451
+qcow2_co_pwritev_part(BlockDriverState *bs, int64_t offset, int64_t bytes,
452
+ QEMUIOVector *qiov, size_t qiov_offset,
453
+ BdrvRequestFlags flags)
454
{
455
BDRVQcow2State *s = bs->opaque;
456
int offset_in_cluster;
457
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow2_co_pwritev_part(
458
QCowL2Meta *l2meta = NULL;
459
AioTaskPool *aio = NULL;
460
461
- assume_graph_lock(); /* FIXME */
462
-
463
trace_qcow2_writev_start_req(qemu_coroutine_self(), offset, bytes);
464
465
while (bytes != 0 && aio_task_pool_status(aio) == 0) {
466
@@ -XXX,XX +XXX,XX @@ qcow2_co_copy_range_to(BlockDriverState *bs,
467
uint64_t host_offset;
468
QCowL2Meta *l2meta = NULL;
469
470
+ assume_graph_lock(); /* FIXME */
471
assert(!bs->encrypted);
472
473
qemu_co_mutex_lock(&s->lock);
474
@@ -XXX,XX +XXX,XX @@ fail:
475
return ret;
476
}
477
478
-static coroutine_fn int
479
+static int coroutine_fn GRAPH_RDLOCK
480
qcow2_co_pwritev_compressed_task(BlockDriverState *bs,
481
uint64_t offset, uint64_t bytes,
482
QEMUIOVector *qiov, size_t qiov_offset)
483
@@ -XXX,XX +XXX,XX @@ fail:
484
return ret;
485
}
486
487
-static coroutine_fn int qcow2_co_pwritev_compressed_task_entry(AioTask *task)
488
+/*
489
+ * This function can count as GRAPH_RDLOCK because
490
+ * qcow2_co_pwritev_compressed_part() holds the graph lock and keeps it until
491
+ * this coroutine has terminated.
492
+ */
493
+static int coroutine_fn GRAPH_RDLOCK
494
+qcow2_co_pwritev_compressed_task_entry(AioTask *task)
495
{
496
Qcow2AioTask *t = container_of(task, Qcow2AioTask, task);
497
498
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow2_co_pwritev_compressed_task_entry(AioTask *task)
499
* XXX: put compressed sectors first, then all the cluster aligned
500
* tables to avoid losing bytes in alignment
501
*/
502
-static coroutine_fn int
503
+static int coroutine_fn GRAPH_RDLOCK
504
qcow2_co_pwritev_compressed_part(BlockDriverState *bs,
505
int64_t offset, int64_t bytes,
506
QEMUIOVector *qiov, size_t qiov_offset)
507
@@ -XXX,XX +XXX,XX @@ qcow2_co_pwritev_compressed_part(BlockDriverState *bs,
508
AioTaskPool *aio = NULL;
509
int ret = 0;
510
511
- assume_graph_lock(); /* FIXME */
512
-
513
if (has_data_file(bs)) {
514
return -ENOTSUP;
515
}
516
@@ -XXX,XX +XXX,XX @@ static int64_t qcow2_check_vmstate_request(BlockDriverState *bs,
517
return pos;
518
}
519
520
-static coroutine_fn int qcow2_co_save_vmstate(BlockDriverState *bs,
521
- QEMUIOVector *qiov, int64_t pos)
522
+static int coroutine_fn GRAPH_RDLOCK
523
+qcow2_co_save_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos)
524
{
525
int64_t offset = qcow2_check_vmstate_request(bs, qiov, pos);
526
if (offset < 0) {
527
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow2_co_save_vmstate(BlockDriverState *bs,
528
return bs->drv->bdrv_co_pwritev_part(bs, offset, qiov->size, qiov, 0, 0);
529
}
530
531
-static coroutine_fn int qcow2_co_load_vmstate(BlockDriverState *bs,
532
- QEMUIOVector *qiov, int64_t pos)
533
+static int coroutine_fn GRAPH_RDLOCK
534
+qcow2_co_load_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos)
535
{
536
int64_t offset = qcow2_check_vmstate_request(bs, qiov, pos);
537
if (offset < 0) {
538
diff --git a/block/qed.c b/block/qed.c
539
index XXXXXXX..XXXXXXX 100644
540
--- a/block/qed.c
541
+++ b/block/qed.c
542
@@ -XXX,XX +XXX,XX @@ qed_co_request(BlockDriverState *bs, int64_t sector_num, QEMUIOVector *qiov,
543
return qed_aio_next_io(&acb);
544
}
545
546
-static int coroutine_fn bdrv_qed_co_readv(BlockDriverState *bs,
547
- int64_t sector_num, int nb_sectors,
548
- QEMUIOVector *qiov)
549
+static int coroutine_fn GRAPH_RDLOCK
550
+bdrv_qed_co_readv(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
551
+ QEMUIOVector *qiov)
552
{
553
- assume_graph_lock(); /* FIXME */
554
return qed_co_request(bs, sector_num, qiov, nb_sectors, 0);
555
}
556
557
-static int coroutine_fn bdrv_qed_co_writev(BlockDriverState *bs,
558
- int64_t sector_num, int nb_sectors,
559
- QEMUIOVector *qiov, int flags)
560
+static int coroutine_fn GRAPH_RDLOCK
561
+bdrv_qed_co_writev(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
562
+ QEMUIOVector *qiov, int flags)
563
{
564
- assume_graph_lock(); /* FIXME */
565
return qed_co_request(bs, sector_num, qiov, nb_sectors, QED_AIOCB_WRITE);
566
}
567
568
diff --git a/block/quorum.c b/block/quorum.c
569
index XXXXXXX..XXXXXXX 100644
570
--- a/block/quorum.c
571
+++ b/block/quorum.c
572
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn GRAPH_RDLOCK write_quorum_entry(void *opaque)
573
}
574
}
575
576
-static int coroutine_fn quorum_co_pwritev(BlockDriverState *bs, int64_t offset,
577
- int64_t bytes, QEMUIOVector *qiov,
578
- BdrvRequestFlags flags)
579
+static int coroutine_fn GRAPH_RDLOCK
580
+quorum_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
581
+ QEMUIOVector *qiov, BdrvRequestFlags flags)
582
{
583
BDRVQuorumState *s = bs->opaque;
584
QuorumAIOCB *acb = quorum_aio_get(bs, qiov, offset, bytes, flags);
585
int i, ret;
586
587
- assume_graph_lock(); /* FIXME */
588
-
589
for (i = 0; i < s->num_children; i++) {
590
Coroutine *co;
591
QuorumCo data = {
592
diff --git a/block/vmdk.c b/block/vmdk.c
593
index XXXXXXX..XXXXXXX 100644
594
--- a/block/vmdk.c
595
+++ b/block/vmdk.c
596
@@ -XXX,XX +XXX,XX @@ vmdk_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
597
return ret;
598
}
599
600
-static int coroutine_fn
601
+static int coroutine_fn GRAPH_RDLOCK
602
vmdk_co_pwritev_compressed(BlockDriverState *bs, int64_t offset, int64_t bytes,
603
QEMUIOVector *qiov)
604
{
605
- assume_graph_lock(); /* FIXME */
606
-
607
if (bytes == 0) {
608
/* The caller will write bytes 0 to signal EOF.
609
* When receive it, we align EOF to a sector boundary. */
610
--
611
2.39.2
diff view generated by jsdifflib
Deleted patch
1
This adds GRAPH_RDLOCK annotations to declare that callers of
2
bdrv_co_pread*/pwrite*() need to hold a reader lock for the graph.
3
1
4
For some places, we know that they will hold the lock, but we don't have
5
the GRAPH_RDLOCK annotations yet. In this case, add assume_graph_lock()
6
with a FIXME comment. These places will be removed once everything is
7
properly annotated.
8
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
Message-Id: <20230203152202.49054-12-kwolf@redhat.com>
11
Reviewed-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
---
14
block/qcow2.h | 9 ++---
15
block/qed.h | 18 +++++-----
16
include/block/block_int-io.h | 14 ++++----
17
block/blkdebug.c | 4 +--
18
block/blklogwrites.c | 7 ++--
19
block/blkreplay.c | 10 +++---
20
block/block-backend.c | 2 ++
21
block/bochs.c | 2 +-
22
block/commit.c | 5 +--
23
block/copy-before-write.c | 16 ++++-----
24
block/copy-on-read.c | 26 ++++++---------
25
block/crypto.c | 4 +--
26
block/filter-compress.c | 19 +++++------
27
block/io.c | 7 ++--
28
block/mirror.c | 18 +++++-----
29
block/parallels.c | 8 +++--
30
block/preallocate.c | 18 +++++-----
31
block/qcow.c | 8 ++---
32
block/qcow2-cluster.c | 7 ++--
33
block/qcow2.c | 53 +++++++++++++++--------------
34
block/qed-table.c | 4 +--
35
block/qed.c | 31 +++++++++--------
36
block/quorum.c | 29 ++++++++++------
37
block/raw-format.c | 12 +++----
38
block/replication.c | 15 ++++-----
39
block/throttle.c | 21 +++++-------
40
block/vdi.c | 4 +--
41
block/vhdx.c | 11 +++---
42
block/vmdk.c | 65 +++++++++++++++---------------------
43
block/vpc.c | 4 +--
44
tests/unit/test-bdrv-drain.c | 20 ++++++-----
45
31 files changed, 233 insertions(+), 238 deletions(-)
46
47
diff --git a/block/qcow2.h b/block/qcow2.h
48
index XXXXXXX..XXXXXXX 100644
49
--- a/block/qcow2.h
50
+++ b/block/qcow2.h
51
@@ -XXX,XX +XXX,XX @@ int qcow2_validate_table(BlockDriverState *bs, uint64_t offset,
52
Error **errp);
53
54
/* qcow2-refcount.c functions */
55
-int coroutine_fn qcow2_refcount_init(BlockDriverState *bs);
56
+int coroutine_fn GRAPH_RDLOCK qcow2_refcount_init(BlockDriverState *bs);
57
void qcow2_refcount_close(BlockDriverState *bs);
58
59
int qcow2_get_refcount(BlockDriverState *bs, int64_t cluster_index,
60
@@ -XXX,XX +XXX,XX @@ void qcow2_free_snapshots(BlockDriverState *bs);
61
int qcow2_read_snapshots(BlockDriverState *bs, Error **errp);
62
int qcow2_write_snapshots(BlockDriverState *bs);
63
64
-int coroutine_fn qcow2_check_read_snapshot_table(BlockDriverState *bs,
65
- BdrvCheckResult *result,
66
- BdrvCheckMode fix);
67
+int coroutine_fn GRAPH_RDLOCK
68
+qcow2_check_read_snapshot_table(BlockDriverState *bs, BdrvCheckResult *result,
69
+ BdrvCheckMode fix);
70
+
71
int coroutine_fn qcow2_check_fix_snapshot_table(BlockDriverState *bs,
72
BdrvCheckResult *result,
73
BdrvCheckMode fix);
74
diff --git a/block/qed.h b/block/qed.h
75
index XXXXXXX..XXXXXXX 100644
76
--- a/block/qed.h
77
+++ b/block/qed.h
78
@@ -XXX,XX +XXX,XX @@ void qed_commit_l2_cache_entry(L2TableCache *l2_cache, CachedL2Table *l2_table);
79
/**
80
* Table I/O functions
81
*/
82
-int coroutine_fn qed_read_l1_table_sync(BDRVQEDState *s);
83
+int coroutine_fn GRAPH_RDLOCK qed_read_l1_table_sync(BDRVQEDState *s);
84
85
int coroutine_fn GRAPH_RDLOCK
86
qed_write_l1_table(BDRVQEDState *s, unsigned int index, unsigned int n);
87
@@ -XXX,XX +XXX,XX @@ qed_write_l1_table(BDRVQEDState *s, unsigned int index, unsigned int n);
88
int coroutine_fn GRAPH_RDLOCK
89
qed_write_l1_table_sync(BDRVQEDState *s, unsigned int index, unsigned int n);
90
91
-int coroutine_fn qed_read_l2_table_sync(BDRVQEDState *s, QEDRequest *request,
92
- uint64_t offset);
93
-int coroutine_fn qed_read_l2_table(BDRVQEDState *s, QEDRequest *request,
94
- uint64_t offset);
95
+int coroutine_fn GRAPH_RDLOCK
96
+qed_read_l2_table_sync(BDRVQEDState *s, QEDRequest *request, uint64_t offset);
97
+
98
+int coroutine_fn GRAPH_RDLOCK
99
+qed_read_l2_table(BDRVQEDState *s, QEDRequest *request, uint64_t offset);
100
101
int coroutine_fn GRAPH_RDLOCK
102
qed_write_l2_table(BDRVQEDState *s, QEDRequest *request, unsigned int index,
103
@@ -XXX,XX +XXX,XX @@ qed_write_l2_table_sync(BDRVQEDState *s, QEDRequest *request,
104
/**
105
* Cluster functions
106
*/
107
-int coroutine_fn qed_find_cluster(BDRVQEDState *s, QEDRequest *request,
108
- uint64_t pos, size_t *len,
109
- uint64_t *img_offset);
110
+int coroutine_fn GRAPH_RDLOCK
111
+qed_find_cluster(BDRVQEDState *s, QEDRequest *request, uint64_t pos,
112
+ size_t *len, uint64_t *img_offset);
113
114
/**
115
* Consistency check
116
@@ -XXX,XX +XXX,XX @@ int coroutine_fn qed_find_cluster(BDRVQEDState *s, QEDRequest *request,
117
int coroutine_fn GRAPH_RDLOCK
118
qed_check(BDRVQEDState *s, BdrvCheckResult *result, bool fix);
119
120
-
121
QEDTable *qed_alloc_table(BDRVQEDState *s);
122
123
/**
124
diff --git a/include/block/block_int-io.h b/include/block/block_int-io.h
125
index XXXXXXX..XXXXXXX 100644
126
--- a/include/block/block_int-io.h
127
+++ b/include/block/block_int-io.h
128
@@ -XXX,XX +XXX,XX @@ int coroutine_fn GRAPH_RDLOCK bdrv_co_pdiscard_snapshot(BlockDriverState *bs,
129
int64_t offset, int64_t bytes);
130
131
132
-int coroutine_fn bdrv_co_preadv(BdrvChild *child,
133
+int coroutine_fn GRAPH_RDLOCK bdrv_co_preadv(BdrvChild *child,
134
int64_t offset, int64_t bytes, QEMUIOVector *qiov,
135
BdrvRequestFlags flags);
136
-int coroutine_fn bdrv_co_preadv_part(BdrvChild *child,
137
+int coroutine_fn GRAPH_RDLOCK bdrv_co_preadv_part(BdrvChild *child,
138
int64_t offset, int64_t bytes,
139
QEMUIOVector *qiov, size_t qiov_offset, BdrvRequestFlags flags);
140
-int coroutine_fn bdrv_co_pwritev(BdrvChild *child,
141
+int coroutine_fn GRAPH_RDLOCK bdrv_co_pwritev(BdrvChild *child,
142
int64_t offset, int64_t bytes, QEMUIOVector *qiov,
143
BdrvRequestFlags flags);
144
-int coroutine_fn bdrv_co_pwritev_part(BdrvChild *child,
145
+int coroutine_fn GRAPH_RDLOCK bdrv_co_pwritev_part(BdrvChild *child,
146
int64_t offset, int64_t bytes,
147
QEMUIOVector *qiov, size_t qiov_offset, BdrvRequestFlags flags);
148
149
-static inline int coroutine_fn bdrv_co_pread(BdrvChild *child,
150
+static inline int coroutine_fn GRAPH_RDLOCK bdrv_co_pread(BdrvChild *child,
151
int64_t offset, int64_t bytes, void *buf, BdrvRequestFlags flags)
152
{
153
QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, bytes);
154
IO_CODE();
155
+ assert_bdrv_graph_readable();
156
157
return bdrv_co_preadv(child, offset, bytes, &qiov, flags);
158
}
159
160
-static inline int coroutine_fn bdrv_co_pwrite(BdrvChild *child,
161
+static inline int coroutine_fn GRAPH_RDLOCK bdrv_co_pwrite(BdrvChild *child,
162
int64_t offset, int64_t bytes, const void *buf, BdrvRequestFlags flags)
163
{
164
QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, bytes);
165
IO_CODE();
166
+ assert_bdrv_graph_readable();
167
168
return bdrv_co_pwritev(child, offset, bytes, &qiov, flags);
169
}
170
diff --git a/block/blkdebug.c b/block/blkdebug.c
171
index XXXXXXX..XXXXXXX 100644
172
--- a/block/blkdebug.c
173
+++ b/block/blkdebug.c
174
@@ -XXX,XX +XXX,XX @@ static int rule_check(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
175
return -error;
176
}
177
178
-static int coroutine_fn
179
+static int coroutine_fn GRAPH_RDLOCK
180
blkdebug_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
181
QEMUIOVector *qiov, BdrvRequestFlags flags)
182
{
183
@@ -XXX,XX +XXX,XX @@ blkdebug_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
184
return bdrv_co_preadv(bs->file, offset, bytes, qiov, flags);
185
}
186
187
-static int coroutine_fn
188
+static int coroutine_fn GRAPH_RDLOCK
189
blkdebug_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
190
QEMUIOVector *qiov, BdrvRequestFlags flags)
191
{
192
diff --git a/block/blklogwrites.c b/block/blklogwrites.c
193
index XXXXXXX..XXXXXXX 100644
194
--- a/block/blklogwrites.c
195
+++ b/block/blklogwrites.c
196
@@ -XXX,XX +XXX,XX @@ static void blk_log_writes_refresh_limits(BlockDriverState *bs, Error **errp)
197
bs->bl.request_alignment = s->sectorsize;
198
}
199
200
-static int coroutine_fn
201
+static int coroutine_fn GRAPH_RDLOCK
202
blk_log_writes_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
203
QEMUIOVector *qiov, BdrvRequestFlags flags)
204
{
205
@@ -XXX,XX +XXX,XX @@ blk_log_writes_co_log(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
206
return fr.file_ret;
207
}
208
209
-static int coroutine_fn
210
+static int coroutine_fn GRAPH_RDLOCK
211
blk_log_writes_co_do_file_pwritev(BlkLogWritesFileReq *fr)
212
{
213
return bdrv_co_pwritev(fr->bs->file, fr->offset, fr->bytes,
214
@@ -XXX,XX +XXX,XX @@ blk_log_writes_co_do_file_pdiscard(BlkLogWritesFileReq *fr)
215
return bdrv_co_pdiscard(fr->bs->file, fr->offset, fr->bytes);
216
}
217
218
-static int coroutine_fn
219
+static int coroutine_fn GRAPH_RDLOCK
220
blk_log_writes_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
221
QEMUIOVector *qiov, BdrvRequestFlags flags)
222
{
223
- assume_graph_lock(); /* FIXME */
224
return blk_log_writes_co_log(bs, offset, bytes, qiov, flags,
225
blk_log_writes_co_do_file_pwritev, 0, false);
226
}
227
diff --git a/block/blkreplay.c b/block/blkreplay.c
228
index XXXXXXX..XXXXXXX 100644
229
--- a/block/blkreplay.c
230
+++ b/block/blkreplay.c
231
@@ -XXX,XX +XXX,XX @@ static void block_request_create(uint64_t reqid, BlockDriverState *bs,
232
replay_block_event(req->bh, reqid);
233
}
234
235
-static int coroutine_fn blkreplay_co_preadv(BlockDriverState *bs,
236
- int64_t offset, int64_t bytes, QEMUIOVector *qiov, BdrvRequestFlags flags)
237
+static int coroutine_fn GRAPH_RDLOCK
238
+blkreplay_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
239
+ QEMUIOVector *qiov, BdrvRequestFlags flags)
240
{
241
uint64_t reqid = blkreplay_next_id();
242
int ret = bdrv_co_preadv(bs->file, offset, bytes, qiov, flags);
243
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn blkreplay_co_preadv(BlockDriverState *bs,
244
return ret;
245
}
246
247
-static int coroutine_fn blkreplay_co_pwritev(BlockDriverState *bs,
248
- int64_t offset, int64_t bytes, QEMUIOVector *qiov, BdrvRequestFlags flags)
249
+static int coroutine_fn GRAPH_RDLOCK
250
+blkreplay_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
251
+ QEMUIOVector *qiov, BdrvRequestFlags flags)
252
{
253
uint64_t reqid = blkreplay_next_id();
254
int ret = bdrv_co_pwritev(bs->file, offset, bytes, qiov, flags);
255
diff --git a/block/block-backend.c b/block/block-backend.c
256
index XXXXXXX..XXXXXXX 100644
257
--- a/block/block-backend.c
258
+++ b/block/block-backend.c
259
@@ -XXX,XX +XXX,XX @@ blk_co_do_preadv_part(BlockBackend *blk, int64_t offset, int64_t bytes,
260
IO_CODE();
261
262
blk_wait_while_drained(blk);
263
+ GRAPH_RDLOCK_GUARD();
264
265
/* Call blk_bs() only after waiting, the graph may have changed */
266
bs = blk_bs(blk);
267
@@ -XXX,XX +XXX,XX @@ blk_co_do_pwritev_part(BlockBackend *blk, int64_t offset, int64_t bytes,
268
IO_CODE();
269
270
blk_wait_while_drained(blk);
271
+ GRAPH_RDLOCK_GUARD();
272
273
/* Call blk_bs() only after waiting, the graph may have changed */
274
bs = blk_bs(blk);
275
diff --git a/block/bochs.c b/block/bochs.c
276
index XXXXXXX..XXXXXXX 100644
277
--- a/block/bochs.c
278
+++ b/block/bochs.c
279
@@ -XXX,XX +XXX,XX @@ static int64_t seek_to_sector(BlockDriverState *bs, int64_t sector_num)
280
return bitmap_offset + (512 * (s->bitmap_blocks + extent_offset));
281
}
282
283
-static int coroutine_fn
284
+static int coroutine_fn GRAPH_RDLOCK
285
bochs_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
286
QEMUIOVector *qiov, BdrvRequestFlags flags)
287
{
288
diff --git a/block/commit.c b/block/commit.c
289
index XXXXXXX..XXXXXXX 100644
290
--- a/block/commit.c
291
+++ b/block/commit.c
292
@@ -XXX,XX +XXX,XX @@ static const BlockJobDriver commit_job_driver = {
293
},
294
};
295
296
-static int coroutine_fn bdrv_commit_top_preadv(BlockDriverState *bs,
297
- int64_t offset, int64_t bytes, QEMUIOVector *qiov, BdrvRequestFlags flags)
298
+static int coroutine_fn GRAPH_RDLOCK
299
+bdrv_commit_top_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
300
+ QEMUIOVector *qiov, BdrvRequestFlags flags)
301
{
302
return bdrv_co_preadv(bs->backing, offset, bytes, qiov, flags);
303
}
304
diff --git a/block/copy-before-write.c b/block/copy-before-write.c
305
index XXXXXXX..XXXXXXX 100644
306
--- a/block/copy-before-write.c
307
+++ b/block/copy-before-write.c
308
@@ -XXX,XX +XXX,XX @@ typedef struct BDRVCopyBeforeWriteState {
309
int snapshot_error;
310
} BDRVCopyBeforeWriteState;
311
312
-static coroutine_fn int cbw_co_preadv(
313
- BlockDriverState *bs, int64_t offset, int64_t bytes,
314
- QEMUIOVector *qiov, BdrvRequestFlags flags)
315
+static int coroutine_fn GRAPH_RDLOCK
316
+cbw_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
317
+ QEMUIOVector *qiov, BdrvRequestFlags flags)
318
{
319
return bdrv_co_preadv(bs->file, offset, bytes, qiov, flags);
320
}
321
@@ -XXX,XX +XXX,XX @@ cbw_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes,
322
return bdrv_co_pwrite_zeroes(bs->file, offset, bytes, flags);
323
}
324
325
-static coroutine_fn int cbw_co_pwritev(BlockDriverState *bs,
326
- int64_t offset,
327
- int64_t bytes,
328
- QEMUIOVector *qiov,
329
- BdrvRequestFlags flags)
330
+static coroutine_fn GRAPH_RDLOCK
331
+int cbw_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
332
+ QEMUIOVector *qiov, BdrvRequestFlags flags)
333
{
334
int ret = cbw_do_copy_before_write(bs, offset, bytes, flags);
335
if (ret < 0) {
336
@@ -XXX,XX +XXX,XX @@ cbw_co_preadv_snapshot(BlockDriverState *bs, int64_t offset, int64_t bytes,
337
BdrvChild *file;
338
int ret;
339
340
+ assume_graph_lock(); /* FIXME */
341
+
342
/* TODO: upgrade to async loop using AioTask */
343
while (bytes) {
344
int64_t cur_bytes;
345
diff --git a/block/copy-on-read.c b/block/copy-on-read.c
346
index XXXXXXX..XXXXXXX 100644
347
--- a/block/copy-on-read.c
348
+++ b/block/copy-on-read.c
349
@@ -XXX,XX +XXX,XX @@ static int64_t coroutine_fn cor_co_getlength(BlockDriverState *bs)
350
}
351
352
353
-static int coroutine_fn cor_co_preadv_part(BlockDriverState *bs,
354
- int64_t offset, int64_t bytes,
355
- QEMUIOVector *qiov,
356
- size_t qiov_offset,
357
- BdrvRequestFlags flags)
358
+static int coroutine_fn GRAPH_RDLOCK
359
+cor_co_preadv_part(BlockDriverState *bs, int64_t offset, int64_t bytes,
360
+ QEMUIOVector *qiov, size_t qiov_offset,
361
+ BdrvRequestFlags flags)
362
{
363
int64_t n;
364
int local_flags;
365
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn cor_co_preadv_part(BlockDriverState *bs,
366
}
367
368
369
-static int coroutine_fn cor_co_pwritev_part(BlockDriverState *bs,
370
- int64_t offset,
371
- int64_t bytes,
372
- QEMUIOVector *qiov,
373
- size_t qiov_offset,
374
- BdrvRequestFlags flags)
375
+static int coroutine_fn GRAPH_RDLOCK
376
+cor_co_pwritev_part(BlockDriverState *bs, int64_t offset, int64_t bytes,
377
+ QEMUIOVector *qiov, size_t qiov_offset,
378
+ BdrvRequestFlags flags)
379
{
380
return bdrv_co_pwritev_part(bs->file, offset, bytes, qiov, qiov_offset,
381
flags);
382
@@ -XXX,XX +XXX,XX @@ cor_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes)
383
}
384
385
386
-static int coroutine_fn cor_co_pwritev_compressed(BlockDriverState *bs,
387
- int64_t offset,
388
- int64_t bytes,
389
- QEMUIOVector *qiov)
390
+static int coroutine_fn GRAPH_RDLOCK
391
+cor_co_pwritev_compressed(BlockDriverState *bs, int64_t offset, int64_t bytes,
392
+ QEMUIOVector *qiov)
393
{
394
return bdrv_co_pwritev(bs->file, offset, bytes, qiov,
395
BDRV_REQ_WRITE_COMPRESSED);
396
diff --git a/block/crypto.c b/block/crypto.c
397
index XXXXXXX..XXXXXXX 100644
398
--- a/block/crypto.c
399
+++ b/block/crypto.c
400
@@ -XXX,XX +XXX,XX @@ static int block_crypto_reopen_prepare(BDRVReopenState *state,
401
*/
402
#define BLOCK_CRYPTO_MAX_IO_SIZE (1024 * 1024)
403
404
-static coroutine_fn int
405
+static int coroutine_fn GRAPH_RDLOCK
406
block_crypto_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
407
QEMUIOVector *qiov, BdrvRequestFlags flags)
408
{
409
@@ -XXX,XX +XXX,XX @@ block_crypto_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
410
}
411
412
413
-static coroutine_fn int
414
+static int coroutine_fn GRAPH_RDLOCK
415
block_crypto_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
416
QEMUIOVector *qiov, BdrvRequestFlags flags)
417
{
418
diff --git a/block/filter-compress.c b/block/filter-compress.c
419
index XXXXXXX..XXXXXXX 100644
420
--- a/block/filter-compress.c
421
+++ b/block/filter-compress.c
422
@@ -XXX,XX +XXX,XX @@ static int64_t coroutine_fn compress_co_getlength(BlockDriverState *bs)
423
}
424
425
426
-static int coroutine_fn compress_co_preadv_part(BlockDriverState *bs,
427
- int64_t offset, int64_t bytes,
428
- QEMUIOVector *qiov,
429
- size_t qiov_offset,
430
- BdrvRequestFlags flags)
431
+static int coroutine_fn GRAPH_RDLOCK
432
+compress_co_preadv_part(BlockDriverState *bs, int64_t offset, int64_t bytes,
433
+ QEMUIOVector *qiov, size_t qiov_offset,
434
+ BdrvRequestFlags flags)
435
{
436
return bdrv_co_preadv_part(bs->file, offset, bytes, qiov, qiov_offset,
437
flags);
438
}
439
440
441
-static int coroutine_fn compress_co_pwritev_part(BlockDriverState *bs,
442
- int64_t offset,
443
- int64_t bytes,
444
- QEMUIOVector *qiov,
445
- size_t qiov_offset,
446
- BdrvRequestFlags flags)
447
+static int coroutine_fn GRAPH_RDLOCK
448
+compress_co_pwritev_part(BlockDriverState *bs, int64_t offset, int64_t bytes,
449
+ QEMUIOVector *qiov, size_t qiov_offset,
450
+ BdrvRequestFlags flags)
451
{
452
return bdrv_co_pwritev_part(bs->file, offset, bytes, qiov, qiov_offset,
453
flags | BDRV_REQ_WRITE_COMPRESSED);
454
diff --git a/block/io.c b/block/io.c
455
index XXXXXXX..XXXXXXX 100644
456
--- a/block/io.c
457
+++ b/block/io.c
458
@@ -XXX,XX +XXX,XX @@ bdrv_driver_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
459
unsigned int nb_sectors;
460
QEMUIOVector local_qiov;
461
int ret;
462
+ assert_bdrv_graph_readable();
463
464
bdrv_check_qiov_request(offset, bytes, qiov, qiov_offset, &error_abort);
465
assert(!(flags & ~bs->supported_read_flags));
466
@@ -XXX,XX +XXX,XX @@ bdrv_driver_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
467
unsigned int nb_sectors;
468
QEMUIOVector local_qiov;
469
int ret;
470
+ assert_bdrv_graph_readable();
471
472
bdrv_check_qiov_request(offset, bytes, qiov, qiov_offset, &error_abort);
473
474
@@ -XXX,XX +XXX,XX @@ bdrv_driver_pwritev_compressed(BlockDriverState *bs, int64_t offset,
475
BlockDriver *drv = bs->drv;
476
QEMUIOVector local_qiov;
477
int ret;
478
+ assert_bdrv_graph_readable();
479
480
bdrv_check_qiov_request(offset, bytes, qiov, qiov_offset, &error_abort);
481
482
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_preadv_part(BdrvChild *child,
483
int ret;
484
IO_CODE();
485
486
- assume_graph_lock(); /* FIXME */
487
-
488
trace_bdrv_co_preadv_part(bs, offset, bytes, flags);
489
490
if (!bdrv_co_is_inserted(bs)) {
491
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_pwritev_part(BdrvChild *child,
492
bool padded = false;
493
IO_CODE();
494
495
- assume_graph_lock(); /* FIXME */
496
-
497
trace_bdrv_co_pwritev_part(child->bs, offset, bytes, flags);
498
499
if (!bdrv_co_is_inserted(bs)) {
500
diff --git a/block/mirror.c b/block/mirror.c
501
index XXXXXXX..XXXXXXX 100644
502
--- a/block/mirror.c
503
+++ b/block/mirror.c
504
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn mirror_co_read(void *opaque)
505
op->is_in_flight = true;
506
trace_mirror_one_iteration(s, op->offset, op->bytes);
507
508
- ret = bdrv_co_preadv(s->mirror_top_bs->backing, op->offset, op->bytes,
509
- &op->qiov, 0);
510
+ WITH_GRAPH_RDLOCK_GUARD() {
511
+ ret = bdrv_co_preadv(s->mirror_top_bs->backing, op->offset, op->bytes,
512
+ &op->qiov, 0);
513
+ }
514
mirror_read_complete(op, ret);
515
}
516
517
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn active_write_settle(MirrorOp *op)
518
g_free(op);
519
}
520
521
-static int coroutine_fn bdrv_mirror_top_preadv(BlockDriverState *bs,
522
- int64_t offset, int64_t bytes, QEMUIOVector *qiov, BdrvRequestFlags flags)
523
+static int coroutine_fn GRAPH_RDLOCK
524
+bdrv_mirror_top_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
525
+ QEMUIOVector *qiov, BdrvRequestFlags flags)
526
{
527
return bdrv_co_preadv(bs->backing, offset, bytes, qiov, flags);
528
}
529
@@ -XXX,XX +XXX,XX @@ out:
530
return ret;
531
}
532
533
-static int coroutine_fn bdrv_mirror_top_pwritev(BlockDriverState *bs,
534
- int64_t offset, int64_t bytes, QEMUIOVector *qiov, BdrvRequestFlags flags)
535
+static int coroutine_fn GRAPH_RDLOCK
536
+bdrv_mirror_top_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
537
+ QEMUIOVector *qiov, BdrvRequestFlags flags)
538
{
539
MirrorBDSOpaque *s = bs->opaque;
540
QEMUIOVector bounce_qiov;
541
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_mirror_top_pwritev(BlockDriverState *bs,
542
int ret = 0;
543
bool copy_to_target = false;
544
545
- assume_graph_lock(); /* FIXME */
546
-
547
if (s->job) {
548
copy_to_target = s->job->ret >= 0 &&
549
!job_is_cancelled(&s->job->common.job) &&
550
diff --git a/block/parallels.c b/block/parallels.c
551
index XXXXXXX..XXXXXXX 100644
552
--- a/block/parallels.c
553
+++ b/block/parallels.c
554
@@ -XXX,XX +XXX,XX @@ allocate_clusters(BlockDriverState *bs, int64_t sector_num,
555
}
556
557
558
-static coroutine_fn int parallels_co_flush_to_os(BlockDriverState *bs)
559
+static int coroutine_fn GRAPH_RDLOCK
560
+parallels_co_flush_to_os(BlockDriverState *bs)
561
{
562
BDRVParallelsState *s = bs->opaque;
563
unsigned long size = DIV_ROUND_UP(s->header_size, s->bat_dirty_block);
564
@@ -XXX,XX +XXX,XX @@ parallels_co_writev(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
565
return ret;
566
}
567
568
-static coroutine_fn int parallels_co_readv(BlockDriverState *bs,
569
- int64_t sector_num, int nb_sectors, QEMUIOVector *qiov)
570
+static int coroutine_fn GRAPH_RDLOCK
571
+parallels_co_readv(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
572
+ QEMUIOVector *qiov)
573
{
574
BDRVParallelsState *s = bs->opaque;
575
uint64_t bytes_done = 0;
576
diff --git a/block/preallocate.c b/block/preallocate.c
577
index XXXXXXX..XXXXXXX 100644
578
--- a/block/preallocate.c
579
+++ b/block/preallocate.c
580
@@ -XXX,XX +XXX,XX @@ static void preallocate_reopen_abort(BDRVReopenState *state)
581
state->opaque = NULL;
582
}
583
584
-static coroutine_fn int preallocate_co_preadv_part(
585
- BlockDriverState *bs, int64_t offset, int64_t bytes,
586
- QEMUIOVector *qiov, size_t qiov_offset, BdrvRequestFlags flags)
587
+static int coroutine_fn GRAPH_RDLOCK
588
+preallocate_co_preadv_part(BlockDriverState *bs, int64_t offset, int64_t bytes,
589
+ QEMUIOVector *qiov, size_t qiov_offset,
590
+ BdrvRequestFlags flags)
591
{
592
return bdrv_co_preadv_part(bs->file, offset, bytes, qiov, qiov_offset,
593
flags);
594
@@ -XXX,XX +XXX,XX @@ preallocate_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset,
595
return bdrv_co_pwrite_zeroes(bs->file, offset, bytes, flags);
596
}
597
598
-static coroutine_fn int preallocate_co_pwritev_part(BlockDriverState *bs,
599
- int64_t offset,
600
- int64_t bytes,
601
- QEMUIOVector *qiov,
602
- size_t qiov_offset,
603
- BdrvRequestFlags flags)
604
+static int coroutine_fn GRAPH_RDLOCK
605
+preallocate_co_pwritev_part(BlockDriverState *bs, int64_t offset, int64_t bytes,
606
+ QEMUIOVector *qiov, size_t qiov_offset,
607
+ BdrvRequestFlags flags)
608
{
609
- assume_graph_lock(); /* FIXME */
610
handle_write(bs, offset, bytes, false);
611
612
return bdrv_co_pwritev_part(bs->file, offset, bytes, qiov, qiov_offset,
613
diff --git a/block/qcow.c b/block/qcow.c
614
index XXXXXXX..XXXXXXX 100644
615
--- a/block/qcow.c
616
+++ b/block/qcow.c
617
@@ -XXX,XX +XXX,XX @@ typedef struct BDRVQcowState {
618
619
static QemuOptsList qcow_create_opts;
620
621
-static int coroutine_fn decompress_cluster(BlockDriverState *bs,
622
- uint64_t cluster_offset);
623
+static int coroutine_fn GRAPH_RDLOCK
624
+decompress_cluster(BlockDriverState *bs, uint64_t cluster_offset);
625
626
static int qcow_probe(const uint8_t *buf, int buf_size, const char *filename)
627
{
628
@@ -XXX,XX +XXX,XX @@ static int decompress_buffer(uint8_t *out_buf, int out_buf_size,
629
return 0;
630
}
631
632
-static int coroutine_fn decompress_cluster(BlockDriverState *bs,
633
- uint64_t cluster_offset)
634
+static int coroutine_fn GRAPH_RDLOCK
635
+decompress_cluster(BlockDriverState *bs, uint64_t cluster_offset)
636
{
637
BDRVQcowState *s = bs->opaque;
638
int ret, csize;
639
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
640
index XXXXXXX..XXXXXXX 100644
641
--- a/block/qcow2-cluster.c
642
+++ b/block/qcow2-cluster.c
643
@@ -XXX,XX +XXX,XX @@ do_perform_cow_read(BlockDriverState *bs, uint64_t src_cluster_offset,
644
return 0;
645
}
646
647
-static int coroutine_fn do_perform_cow_write(BlockDriverState *bs,
648
- uint64_t cluster_offset,
649
- unsigned offset_in_cluster,
650
- QEMUIOVector *qiov)
651
+static int coroutine_fn GRAPH_RDLOCK
652
+do_perform_cow_write(BlockDriverState *bs, uint64_t cluster_offset,
653
+ unsigned offset_in_cluster, QEMUIOVector *qiov)
654
{
655
BDRVQcow2State *s = bs->opaque;
656
int ret;
657
diff --git a/block/qcow2.c b/block/qcow2.c
658
index XXXXXXX..XXXXXXX 100644
659
--- a/block/qcow2.c
660
+++ b/block/qcow2.c
661
@@ -XXX,XX +XXX,XX @@ static void qcow2_add_check_result(BdrvCheckResult *out,
662
}
663
}
664
665
-static int coroutine_fn qcow2_co_check_locked(BlockDriverState *bs,
666
- BdrvCheckResult *result,
667
- BdrvCheckMode fix)
668
+static int coroutine_fn GRAPH_RDLOCK
669
+qcow2_co_check_locked(BlockDriverState *bs, BdrvCheckResult *result,
670
+ BdrvCheckMode fix)
671
{
672
BdrvCheckResult snapshot_res = {};
673
BdrvCheckResult refcount_res = {};
674
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qcow2_co_check_locked(BlockDriverState *bs,
675
return ret;
676
}
677
678
-static int coroutine_fn qcow2_co_check(BlockDriverState *bs,
679
- BdrvCheckResult *result,
680
- BdrvCheckMode fix)
681
+static int coroutine_fn GRAPH_RDLOCK
682
+qcow2_co_check(BlockDriverState *bs, BdrvCheckResult *result,
683
+ BdrvCheckMode fix)
684
{
685
BDRVQcow2State *s = bs->opaque;
686
int ret;
687
@@ -XXX,XX +XXX,XX @@ static int validate_compression_type(BDRVQcow2State *s, Error **errp)
688
}
689
690
/* Called with s->lock held. */
691
-static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options,
692
- int flags, bool open_data_file,
693
- Error **errp)
694
+static int coroutine_fn GRAPH_RDLOCK
695
+qcow2_do_open(BlockDriverState *bs, QDict *options, int flags,
696
+ bool open_data_file, Error **errp)
697
{
698
ERRP_GUARD();
699
BDRVQcow2State *s = bs->opaque;
700
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn qcow2_open_entry(void *opaque)
701
QCow2OpenCo *qoc = opaque;
702
BDRVQcow2State *s = qoc->bs->opaque;
703
704
+ assume_graph_lock(); /* FIXME */
705
+
706
qemu_co_mutex_lock(&s->lock);
707
qoc->ret = qcow2_do_open(qoc->bs, qoc->options, qoc->flags, true,
708
qoc->errp);
709
@@ -XXX,XX +XXX,XX @@ out:
710
return ret;
711
}
712
713
-static coroutine_fn int
714
+static int coroutine_fn GRAPH_RDLOCK
715
qcow2_co_preadv_encrypted(BlockDriverState *bs,
716
uint64_t host_offset,
717
uint64_t offset,
718
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow2_add_task(BlockDriverState *bs,
719
return 0;
720
}
721
722
-static coroutine_fn int qcow2_co_preadv_task(BlockDriverState *bs,
723
- QCow2SubclusterType subc_type,
724
- uint64_t host_offset,
725
- uint64_t offset, uint64_t bytes,
726
- QEMUIOVector *qiov,
727
- size_t qiov_offset)
728
+static int coroutine_fn GRAPH_RDLOCK
729
+qcow2_co_preadv_task(BlockDriverState *bs, QCow2SubclusterType subc_type,
730
+ uint64_t host_offset, uint64_t offset, uint64_t bytes,
731
+ QEMUIOVector *qiov, size_t qiov_offset)
732
{
733
BDRVQcow2State *s = bs->opaque;
734
735
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow2_co_preadv_task(BlockDriverState *bs,
736
g_assert_not_reached();
737
}
738
739
-static coroutine_fn int qcow2_co_preadv_task_entry(AioTask *task)
740
+/*
741
+ * This function can count as GRAPH_RDLOCK because qcow2_co_preadv_part() holds
742
+ * the graph lock and keeps it until this coroutine has terminated.
743
+ */
744
+static int coroutine_fn GRAPH_RDLOCK qcow2_co_preadv_task_entry(AioTask *task)
745
{
746
Qcow2AioTask *t = container_of(task, Qcow2AioTask, task);
747
748
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow2_co_preadv_task_entry(AioTask *task)
749
t->qiov, t->qiov_offset);
750
}
751
752
-static coroutine_fn int qcow2_co_preadv_part(BlockDriverState *bs,
753
- int64_t offset, int64_t bytes,
754
- QEMUIOVector *qiov,
755
- size_t qiov_offset,
756
- BdrvRequestFlags flags)
757
+static int coroutine_fn GRAPH_RDLOCK
758
+qcow2_co_preadv_part(BlockDriverState *bs, int64_t offset, int64_t bytes,
759
+ QEMUIOVector *qiov, size_t qiov_offset,
760
+ BdrvRequestFlags flags)
761
{
762
BDRVQcow2State *s = bs->opaque;
763
int ret = 0;
764
@@ -XXX,XX +XXX,XX @@ static void qcow2_close(BlockDriverState *bs)
765
qcow2_do_close(bs, true);
766
}
767
768
-static void coroutine_fn qcow2_co_invalidate_cache(BlockDriverState *bs,
769
- Error **errp)
770
+static void coroutine_fn GRAPH_RDLOCK
771
+qcow2_co_invalidate_cache(BlockDriverState *bs, Error **errp)
772
{
773
ERRP_GUARD();
774
BDRVQcow2State *s = bs->opaque;
775
@@ -XXX,XX +XXX,XX @@ qcow2_co_pwritev_compressed_part(BlockDriverState *bs,
776
return ret;
777
}
778
779
-static int coroutine_fn
780
+static int coroutine_fn GRAPH_RDLOCK
781
qcow2_co_preadv_compressed(BlockDriverState *bs,
782
uint64_t l2_entry,
783
uint64_t offset,
784
diff --git a/block/qed-table.c b/block/qed-table.c
785
index XXXXXXX..XXXXXXX 100644
786
--- a/block/qed-table.c
787
+++ b/block/qed-table.c
788
@@ -XXX,XX +XXX,XX @@
789
#include "qemu/memalign.h"
790
791
/* Called with table_lock held. */
792
-static int coroutine_fn qed_read_table(BDRVQEDState *s, uint64_t offset,
793
- QEDTable *table)
794
+static int coroutine_fn GRAPH_RDLOCK
795
+qed_read_table(BDRVQEDState *s, uint64_t offset, QEDTable *table)
796
{
797
unsigned int bytes = s->header.cluster_size * s->header.table_size;
798
799
diff --git a/block/qed.c b/block/qed.c
800
index XXXXXXX..XXXXXXX 100644
801
--- a/block/qed.c
802
+++ b/block/qed.c
803
@@ -XXX,XX +XXX,XX @@ int qed_write_header_sync(BDRVQEDState *s)
804
*
805
* No new allocating reqs can start while this function runs.
806
*/
807
-static int coroutine_fn qed_write_header(BDRVQEDState *s)
808
+static int coroutine_fn GRAPH_RDLOCK qed_write_header(BDRVQEDState *s)
809
{
810
/* We must write full sectors for O_DIRECT but cannot necessarily generate
811
* the data following the header if an unrecognized compat feature is
812
@@ -XXX,XX +XXX,XX @@ fail:
813
return ret;
814
}
815
816
-static int coroutine_fn bdrv_qed_co_block_status(BlockDriverState *bs,
817
- bool want_zero,
818
- int64_t pos, int64_t bytes,
819
- int64_t *pnum, int64_t *map,
820
- BlockDriverState **file)
821
+static int coroutine_fn GRAPH_RDLOCK
822
+bdrv_qed_co_block_status(BlockDriverState *bs, bool want_zero, int64_t pos,
823
+ int64_t bytes, int64_t *pnum, int64_t *map,
824
+ BlockDriverState **file)
825
{
826
BDRVQEDState *s = bs->opaque;
827
size_t len = MIN(bytes, SIZE_MAX);
828
@@ -XXX,XX +XXX,XX @@ static BDRVQEDState *acb_to_s(QEDAIOCB *acb)
829
* This function reads qiov->size bytes starting at pos from the backing file.
830
* If there is no backing file then zeroes are read.
831
*/
832
-static int coroutine_fn qed_read_backing_file(BDRVQEDState *s, uint64_t pos,
833
- QEMUIOVector *qiov)
834
+static int coroutine_fn GRAPH_RDLOCK
835
+qed_read_backing_file(BDRVQEDState *s, uint64_t pos, QEMUIOVector *qiov)
836
{
837
if (s->bs->backing) {
838
BLKDBG_EVENT(s->bs->file, BLKDBG_READ_BACKING_AIO);
839
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn qed_read_backing_file(BDRVQEDState *s, uint64_t pos,
840
* @len: Number of bytes
841
* @offset: Byte offset in image file
842
*/
843
-static int coroutine_fn qed_copy_from_backing_file(BDRVQEDState *s,
844
- uint64_t pos, uint64_t len,
845
- uint64_t offset)
846
+static int coroutine_fn GRAPH_RDLOCK
847
+qed_copy_from_backing_file(BDRVQEDState *s, uint64_t pos, uint64_t len,
848
+ uint64_t offset)
849
{
850
QEMUIOVector qiov;
851
int ret;
852
@@ -XXX,XX +XXX,XX @@ qed_aio_write_l2_update(QEDAIOCB *acb, uint64_t offset)
853
*
854
* Called with table_lock *not* held.
855
*/
856
-static int coroutine_fn qed_aio_write_main(QEDAIOCB *acb)
857
+static int coroutine_fn GRAPH_RDLOCK qed_aio_write_main(QEDAIOCB *acb)
858
{
859
BDRVQEDState *s = acb_to_s(acb);
860
uint64_t offset = acb->cur_cluster +
861
@@ -XXX,XX +XXX,XX @@ qed_aio_write_alloc(QEDAIOCB *acb, size_t len)
862
*
863
* Called with table_lock held.
864
*/
865
-static int coroutine_fn qed_aio_write_inplace(QEDAIOCB *acb, uint64_t offset,
866
- size_t len)
867
+static int coroutine_fn GRAPH_RDLOCK
868
+qed_aio_write_inplace(QEDAIOCB *acb, uint64_t offset, size_t len)
869
{
870
BDRVQEDState *s = acb_to_s(acb);
871
int r;
872
@@ -XXX,XX +XXX,XX @@ qed_aio_write_data(void *opaque, int ret, uint64_t offset, size_t len)
873
*
874
* Called with table_lock held.
875
*/
876
-static int coroutine_fn qed_aio_read_data(void *opaque, int ret,
877
- uint64_t offset, size_t len)
878
+static int coroutine_fn GRAPH_RDLOCK
879
+qed_aio_read_data(void *opaque, int ret, uint64_t offset, size_t len)
880
{
881
QEDAIOCB *acb = opaque;
882
BDRVQEDState *s = acb_to_s(acb);
883
diff --git a/block/quorum.c b/block/quorum.c
884
index XXXXXXX..XXXXXXX 100644
885
--- a/block/quorum.c
886
+++ b/block/quorum.c
887
@@ -XXX,XX +XXX,XX @@ static void quorum_report_bad_versions(BDRVQuorumState *s,
888
}
889
}
890
891
-static void coroutine_fn quorum_rewrite_entry(void *opaque)
892
+/*
893
+ * This function can count as GRAPH_RDLOCK because read_quorum_children() holds
894
+ * the graph lock and keeps it until this coroutine has terminated.
895
+ */
896
+static void coroutine_fn GRAPH_RDLOCK quorum_rewrite_entry(void *opaque)
897
{
898
QuorumCo *co = opaque;
899
QuorumAIOCB *acb = co->acb;
900
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn quorum_rewrite_entry(void *opaque)
901
}
902
}
903
904
-static bool quorum_rewrite_bad_versions(QuorumAIOCB *acb,
905
- QuorumVoteValue *value)
906
+static bool coroutine_fn GRAPH_RDLOCK
907
+quorum_rewrite_bad_versions(QuorumAIOCB *acb, QuorumVoteValue *value)
908
{
909
QuorumVoteVersion *version;
910
QuorumVoteItem *item;
911
@@ -XXX,XX +XXX,XX @@ static int quorum_vote_error(QuorumAIOCB *acb)
912
return ret;
913
}
914
915
-static void quorum_vote(QuorumAIOCB *acb)
916
+static void coroutine_fn GRAPH_RDLOCK quorum_vote(QuorumAIOCB *acb)
917
{
918
bool quorum = true;
919
int i, j, ret;
920
@@ -XXX,XX +XXX,XX @@ free_exit:
921
quorum_free_vote_list(&acb->votes);
922
}
923
924
-static void coroutine_fn read_quorum_children_entry(void *opaque)
925
+/*
926
+ * This function can count as GRAPH_RDLOCK because read_quorum_children() holds
927
+ * the graph lock and keeps it until this coroutine has terminated.
928
+ */
929
+static void coroutine_fn GRAPH_RDLOCK read_quorum_children_entry(void *opaque)
930
{
931
QuorumCo *co = opaque;
932
QuorumAIOCB *acb = co->acb;
933
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn read_quorum_children_entry(void *opaque)
934
}
935
}
936
937
-static int coroutine_fn read_quorum_children(QuorumAIOCB *acb)
938
+static int coroutine_fn GRAPH_RDLOCK read_quorum_children(QuorumAIOCB *acb)
939
{
940
BDRVQuorumState *s = acb->bs->opaque;
941
int i;
942
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn read_quorum_children(QuorumAIOCB *acb)
943
return acb->vote_ret;
944
}
945
946
-static int coroutine_fn read_fifo_child(QuorumAIOCB *acb)
947
+static int coroutine_fn GRAPH_RDLOCK read_fifo_child(QuorumAIOCB *acb)
948
{
949
BDRVQuorumState *s = acb->bs->opaque;
950
int n, ret;
951
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn read_fifo_child(QuorumAIOCB *acb)
952
return ret;
953
}
954
955
-static int coroutine_fn quorum_co_preadv(BlockDriverState *bs,
956
- int64_t offset, int64_t bytes,
957
- QEMUIOVector *qiov,
958
- BdrvRequestFlags flags)
959
+static int coroutine_fn GRAPH_RDLOCK
960
+quorum_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
961
+ QEMUIOVector *qiov, BdrvRequestFlags flags)
962
{
963
BDRVQuorumState *s = bs->opaque;
964
QuorumAIOCB *acb = quorum_aio_get(bs, qiov, offset, bytes, flags);
965
diff --git a/block/raw-format.c b/block/raw-format.c
966
index XXXXXXX..XXXXXXX 100644
967
--- a/block/raw-format.c
968
+++ b/block/raw-format.c
969
@@ -XXX,XX +XXX,XX @@ static inline int raw_adjust_offset(BlockDriverState *bs, int64_t *offset,
970
return 0;
971
}
972
973
-static int coroutine_fn raw_co_preadv(BlockDriverState *bs, int64_t offset,
974
- int64_t bytes, QEMUIOVector *qiov,
975
- BdrvRequestFlags flags)
976
+static int coroutine_fn GRAPH_RDLOCK
977
+raw_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
978
+ QEMUIOVector *qiov, BdrvRequestFlags flags)
979
{
980
int ret;
981
982
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn raw_co_preadv(BlockDriverState *bs, int64_t offset,
983
return bdrv_co_preadv(bs->file, offset, bytes, qiov, flags);
984
}
985
986
-static int coroutine_fn raw_co_pwritev(BlockDriverState *bs, int64_t offset,
987
- int64_t bytes, QEMUIOVector *qiov,
988
- BdrvRequestFlags flags)
989
+static int coroutine_fn GRAPH_RDLOCK
990
+raw_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
991
+ QEMUIOVector *qiov, BdrvRequestFlags flags)
992
{
993
void *buf = NULL;
994
BlockDriver *drv;
995
diff --git a/block/replication.c b/block/replication.c
996
index XXXXXXX..XXXXXXX 100644
997
--- a/block/replication.c
998
+++ b/block/replication.c
999
@@ -XXX,XX +XXX,XX @@ static int replication_return_value(BDRVReplicationState *s, int ret)
1000
return ret;
1001
}
1002
1003
-static coroutine_fn int replication_co_readv(BlockDriverState *bs,
1004
- int64_t sector_num,
1005
- int remaining_sectors,
1006
- QEMUIOVector *qiov)
1007
+static int coroutine_fn GRAPH_RDLOCK
1008
+replication_co_readv(BlockDriverState *bs, int64_t sector_num,
1009
+ int remaining_sectors, QEMUIOVector *qiov)
1010
{
1011
BDRVReplicationState *s = bs->opaque;
1012
int ret;
1013
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int replication_co_readv(BlockDriverState *bs,
1014
return replication_return_value(s, ret);
1015
}
1016
1017
-static coroutine_fn int replication_co_writev(BlockDriverState *bs,
1018
- int64_t sector_num,
1019
- int remaining_sectors,
1020
- QEMUIOVector *qiov,
1021
- int flags)
1022
+static int coroutine_fn GRAPH_RDLOCK
1023
+replication_co_writev(BlockDriverState *bs, int64_t sector_num,
1024
+ int remaining_sectors, QEMUIOVector *qiov, int flags)
1025
{
1026
BDRVReplicationState *s = bs->opaque;
1027
QEMUIOVector hd_qiov;
1028
diff --git a/block/throttle.c b/block/throttle.c
1029
index XXXXXXX..XXXXXXX 100644
1030
--- a/block/throttle.c
1031
+++ b/block/throttle.c
1032
@@ -XXX,XX +XXX,XX @@ static int64_t coroutine_fn throttle_co_getlength(BlockDriverState *bs)
1033
return bdrv_co_getlength(bs->file->bs);
1034
}
1035
1036
-static int coroutine_fn throttle_co_preadv(BlockDriverState *bs,
1037
- int64_t offset, int64_t bytes,
1038
- QEMUIOVector *qiov,
1039
- BdrvRequestFlags flags)
1040
+static int coroutine_fn GRAPH_RDLOCK
1041
+throttle_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
1042
+ QEMUIOVector *qiov, BdrvRequestFlags flags)
1043
{
1044
1045
ThrottleGroupMember *tgm = bs->opaque;
1046
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn throttle_co_preadv(BlockDriverState *bs,
1047
return bdrv_co_preadv(bs->file, offset, bytes, qiov, flags);
1048
}
1049
1050
-static int coroutine_fn throttle_co_pwritev(BlockDriverState *bs,
1051
- int64_t offset, int64_t bytes,
1052
- QEMUIOVector *qiov,
1053
- BdrvRequestFlags flags)
1054
+static int coroutine_fn GRAPH_RDLOCK
1055
+throttle_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
1056
+ QEMUIOVector *qiov, BdrvRequestFlags flags)
1057
{
1058
ThrottleGroupMember *tgm = bs->opaque;
1059
throttle_group_co_io_limits_intercept(tgm, bytes, true);
1060
@@ -XXX,XX +XXX,XX @@ throttle_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes)
1061
return bdrv_co_pdiscard(bs->file, offset, bytes);
1062
}
1063
1064
-static int coroutine_fn throttle_co_pwritev_compressed(BlockDriverState *bs,
1065
- int64_t offset,
1066
- int64_t bytes,
1067
- QEMUIOVector *qiov)
1068
+static int coroutine_fn GRAPH_RDLOCK
1069
+throttle_co_pwritev_compressed(BlockDriverState *bs, int64_t offset,
1070
+ int64_t bytes, QEMUIOVector *qiov)
1071
{
1072
return throttle_co_pwritev(bs, offset, bytes, qiov,
1073
BDRV_REQ_WRITE_COMPRESSED);
1074
diff --git a/block/vdi.c b/block/vdi.c
1075
index XXXXXXX..XXXXXXX 100644
1076
--- a/block/vdi.c
1077
+++ b/block/vdi.c
1078
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn vdi_co_block_status(BlockDriverState *bs,
1079
(s->header.image_type == VDI_TYPE_STATIC ? BDRV_BLOCK_RECURSE : 0);
1080
}
1081
1082
-static int coroutine_fn
1083
+static int coroutine_fn GRAPH_RDLOCK
1084
vdi_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
1085
QEMUIOVector *qiov, BdrvRequestFlags flags)
1086
{
1087
@@ -XXX,XX +XXX,XX @@ vdi_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
1088
return ret;
1089
}
1090
1091
-static int coroutine_fn
1092
+static int coroutine_fn GRAPH_RDLOCK
1093
vdi_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
1094
QEMUIOVector *qiov, BdrvRequestFlags flags)
1095
{
1096
diff --git a/block/vhdx.c b/block/vhdx.c
1097
index XXXXXXX..XXXXXXX 100644
1098
--- a/block/vhdx.c
1099
+++ b/block/vhdx.c
1100
@@ -XXX,XX +XXX,XX @@ vhdx_co_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
1101
}
1102
1103
1104
-static coroutine_fn int vhdx_co_readv(BlockDriverState *bs, int64_t sector_num,
1105
- int nb_sectors, QEMUIOVector *qiov)
1106
+static int coroutine_fn GRAPH_RDLOCK
1107
+vhdx_co_readv(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
1108
+ QEMUIOVector *qiov)
1109
{
1110
BDRVVHDXState *s = bs->opaque;
1111
int ret = 0;
1112
@@ -XXX,XX +XXX,XX @@ int vhdx_user_visible_write(BlockDriverState *bs, BDRVVHDXState *s)
1113
return ret;
1114
}
1115
1116
-static coroutine_fn int vhdx_co_writev(BlockDriverState *bs, int64_t sector_num,
1117
- int nb_sectors, QEMUIOVector *qiov,
1118
- int flags)
1119
+static int coroutine_fn GRAPH_RDLOCK
1120
+vhdx_co_writev(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
1121
+ QEMUIOVector *qiov, int flags)
1122
{
1123
int ret = -ENOTSUP;
1124
BDRVVHDXState *s = bs->opaque;
1125
diff --git a/block/vmdk.c b/block/vmdk.c
1126
index XXXXXXX..XXXXXXX 100644
1127
--- a/block/vmdk.c
1128
+++ b/block/vmdk.c
1129
@@ -XXX,XX +XXX,XX @@ static void vmdk_refresh_limits(BlockDriverState *bs, Error **errp)
1130
* [@skip_start_sector, @skip_end_sector) is not copied or written, and leave
1131
* it for call to write user data in the request.
1132
*/
1133
-static int coroutine_fn get_whole_cluster(BlockDriverState *bs,
1134
- VmdkExtent *extent,
1135
- uint64_t cluster_offset,
1136
- uint64_t offset,
1137
- uint64_t skip_start_bytes,
1138
- uint64_t skip_end_bytes,
1139
- bool zeroed)
1140
+static int coroutine_fn GRAPH_RDLOCK
1141
+get_whole_cluster(BlockDriverState *bs, VmdkExtent *extent,
1142
+ uint64_t cluster_offset, uint64_t offset,
1143
+ uint64_t skip_start_bytes, uint64_t skip_end_bytes,
1144
+ bool zeroed)
1145
{
1146
int ret = VMDK_OK;
1147
int64_t cluster_bytes;
1148
@@ -XXX,XX +XXX,XX @@ vmdk_L2update(VmdkExtent *extent, VmdkMetaData *m_data, uint32_t offset)
1149
* VMDK_UNALLOC if cluster is not mapped and @allocate is false.
1150
* VMDK_ERROR if failed.
1151
*/
1152
-static int coroutine_fn get_cluster_offset(BlockDriverState *bs,
1153
- VmdkExtent *extent,
1154
- VmdkMetaData *m_data,
1155
- uint64_t offset,
1156
- bool allocate,
1157
- uint64_t *cluster_offset,
1158
- uint64_t skip_start_bytes,
1159
- uint64_t skip_end_bytes)
1160
+static int coroutine_fn GRAPH_RDLOCK
1161
+get_cluster_offset(BlockDriverState *bs, VmdkExtent *extent,
1162
+ VmdkMetaData *m_data, uint64_t offset, bool allocate,
1163
+ uint64_t *cluster_offset, uint64_t skip_start_bytes,
1164
+ uint64_t skip_end_bytes)
1165
{
1166
unsigned int l1_index, l2_offset, l2_index;
1167
int min_index, i, j;
1168
@@ -XXX,XX +XXX,XX @@ static inline uint64_t vmdk_find_offset_in_cluster(VmdkExtent *extent,
1169
return extent_relative_offset % cluster_size;
1170
}
1171
1172
-static int coroutine_fn vmdk_co_block_status(BlockDriverState *bs,
1173
- bool want_zero,
1174
- int64_t offset, int64_t bytes,
1175
- int64_t *pnum, int64_t *map,
1176
- BlockDriverState **file)
1177
+static int coroutine_fn GRAPH_RDLOCK
1178
+vmdk_co_block_status(BlockDriverState *bs, bool want_zero,
1179
+ int64_t offset, int64_t bytes, int64_t *pnum,
1180
+ int64_t *map, BlockDriverState **file)
1181
{
1182
BDRVVmdkState *s = bs->opaque;
1183
int64_t index_in_cluster, n, ret;
1184
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn vmdk_co_block_status(BlockDriverState *bs,
1185
return ret;
1186
}
1187
1188
-static int coroutine_fn
1189
+static int coroutine_fn GRAPH_RDLOCK
1190
vmdk_write_extent(VmdkExtent *extent, int64_t cluster_offset,
1191
int64_t offset_in_cluster, QEMUIOVector *qiov,
1192
uint64_t qiov_offset, uint64_t n_bytes,
1193
@@ -XXX,XX +XXX,XX @@ vmdk_write_extent(VmdkExtent *extent, int64_t cluster_offset,
1194
return ret;
1195
}
1196
1197
-static int coroutine_fn
1198
+static int coroutine_fn GRAPH_RDLOCK
1199
vmdk_read_extent(VmdkExtent *extent, int64_t cluster_offset,
1200
- int64_t offset_in_cluster, QEMUIOVector *qiov,
1201
- int bytes)
1202
+ int64_t offset_in_cluster, QEMUIOVector *qiov, int bytes)
1203
{
1204
int ret;
1205
int cluster_bytes, buf_bytes;
1206
@@ -XXX,XX +XXX,XX @@ vmdk_read_extent(VmdkExtent *extent, int64_t cluster_offset,
1207
return ret;
1208
}
1209
1210
-static int coroutine_fn
1211
+static int coroutine_fn GRAPH_RDLOCK
1212
vmdk_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
1213
QEMUIOVector *qiov, BdrvRequestFlags flags)
1214
{
1215
@@ -XXX,XX +XXX,XX @@ fail:
1216
*
1217
* Returns: error code with 0 for success.
1218
*/
1219
-static int coroutine_fn vmdk_pwritev(BlockDriverState *bs, uint64_t offset,
1220
- uint64_t bytes, QEMUIOVector *qiov,
1221
- bool zeroed, bool zero_dry_run)
1222
+static int coroutine_fn GRAPH_RDLOCK
1223
+vmdk_pwritev(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
1224
+ QEMUIOVector *qiov, bool zeroed, bool zero_dry_run)
1225
{
1226
BDRVVmdkState *s = bs->opaque;
1227
VmdkExtent *extent = NULL;
1228
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn vmdk_pwritev(BlockDriverState *bs, uint64_t offset,
1229
uint64_t bytes_done = 0;
1230
VmdkMetaData m_data;
1231
1232
- assume_graph_lock(); /* FIXME */
1233
-
1234
if (DIV_ROUND_UP(offset, BDRV_SECTOR_SIZE) > bs->total_sectors) {
1235
error_report("Wrong offset: offset=0x%" PRIx64
1236
" total_sectors=0x%" PRIx64,
1237
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn vmdk_pwritev(BlockDriverState *bs, uint64_t offset,
1238
return 0;
1239
}
1240
1241
-static int coroutine_fn
1242
+static int coroutine_fn GRAPH_RDLOCK
1243
vmdk_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
1244
QEMUIOVector *qiov, BdrvRequestFlags flags)
1245
{
1246
@@ -XXX,XX +XXX,XX @@ vmdk_co_pwritev_compressed(BlockDriverState *bs, int64_t offset, int64_t bytes,
1247
return vmdk_co_pwritev(bs, offset, bytes, qiov, 0);
1248
}
1249
1250
-static int coroutine_fn vmdk_co_pwrite_zeroes(BlockDriverState *bs,
1251
- int64_t offset,
1252
- int64_t bytes,
1253
- BdrvRequestFlags flags)
1254
+static int coroutine_fn GRAPH_RDLOCK
1255
+vmdk_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes,
1256
+ BdrvRequestFlags flags)
1257
{
1258
int ret;
1259
BDRVVmdkState *s = bs->opaque;
1260
@@ -XXX,XX +XXX,XX @@ static VmdkExtentInfo *vmdk_get_extent_info(VmdkExtent *extent)
1261
return info;
1262
}
1263
1264
-static int coroutine_fn vmdk_co_check(BlockDriverState *bs,
1265
- BdrvCheckResult *result,
1266
- BdrvCheckMode fix)
1267
+static int coroutine_fn GRAPH_RDLOCK
1268
+vmdk_co_check(BlockDriverState *bs, BdrvCheckResult *result, BdrvCheckMode fix)
1269
{
1270
BDRVVmdkState *s = bs->opaque;
1271
VmdkExtent *extent = NULL;
1272
diff --git a/block/vpc.c b/block/vpc.c
1273
index XXXXXXX..XXXXXXX 100644
1274
--- a/block/vpc.c
1275
+++ b/block/vpc.c
1276
@@ -XXX,XX +XXX,XX @@ vpc_co_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
1277
return 0;
1278
}
1279
1280
-static int coroutine_fn
1281
+static int coroutine_fn GRAPH_RDLOCK
1282
vpc_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
1283
QEMUIOVector *qiov, BdrvRequestFlags flags)
1284
{
1285
@@ -XXX,XX +XXX,XX @@ fail:
1286
return ret;
1287
}
1288
1289
-static int coroutine_fn
1290
+static int coroutine_fn GRAPH_RDLOCK
1291
vpc_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
1292
QEMUIOVector *qiov, BdrvRequestFlags flags)
1293
{
1294
diff --git a/tests/unit/test-bdrv-drain.c b/tests/unit/test-bdrv-drain.c
1295
index XXXXXXX..XXXXXXX 100644
1296
--- a/tests/unit/test-bdrv-drain.c
1297
+++ b/tests/unit/test-bdrv-drain.c
1298
@@ -XXX,XX +XXX,XX @@ static void bdrv_test_top_close(BlockDriverState *bs)
1299
}
1300
}
1301
1302
-static int coroutine_fn bdrv_test_top_co_preadv(BlockDriverState *bs,
1303
- int64_t offset, int64_t bytes,
1304
- QEMUIOVector *qiov,
1305
- BdrvRequestFlags flags)
1306
+static int coroutine_fn GRAPH_RDLOCK
1307
+bdrv_test_top_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
1308
+ QEMUIOVector *qiov, BdrvRequestFlags flags)
1309
{
1310
BDRVTestTopState *tts = bs->opaque;
1311
return bdrv_co_preadv(tts->wait_child, offset, bytes, qiov, flags);
1312
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn test_co_delete_by_drain(void *opaque)
1313
void *buffer = g_malloc(65536);
1314
QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buffer, 65536);
1315
1316
+ GRAPH_RDLOCK_GUARD();
1317
+
1318
/* Pretend some internal write operation from parent to child.
1319
* Important: We have to read from the child, not from the parent!
1320
* Draining works by first propagating it all up the tree to the
1321
@@ -XXX,XX +XXX,XX @@ static void bdrv_replace_test_close(BlockDriverState *bs)
1322
* Otherwise:
1323
* Set .has_read to true and return success.
1324
*/
1325
-static int coroutine_fn bdrv_replace_test_co_preadv(BlockDriverState *bs,
1326
- int64_t offset,
1327
- int64_t bytes,
1328
- QEMUIOVector *qiov,
1329
- BdrvRequestFlags flags)
1330
+static int coroutine_fn GRAPH_RDLOCK
1331
+bdrv_replace_test_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
1332
+ QEMUIOVector *qiov, BdrvRequestFlags flags)
1333
{
1334
BDRVReplaceTestState *s = bs->opaque;
1335
1336
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn bdrv_replace_test_read_entry(void *opaque)
1337
int ret;
1338
1339
/* Queue a read request post-drain */
1340
+ bdrv_graph_co_rdlock();
1341
ret = bdrv_replace_test_co_preadv(bs, 0, 1, &qiov, 0);
1342
+ bdrv_graph_co_rdunlock();
1343
+
1344
g_assert(ret >= 0);
1345
bdrv_dec_in_flight(bs);
1346
}
1347
--
1348
2.39.2
diff view generated by jsdifflib
Deleted patch
1
This adds GRAPH_RDLOCK annotations to declare that callers of
2
bdrv_co_pwrite_sync() need to hold a reader lock for the graph.
3
1
4
For some places, we know that they will hold the lock, but we don't have
5
the GRAPH_RDLOCK annotations yet. In this case, add assume_graph_lock()
6
with a FIXME comment. These places will be removed once everything is
7
properly annotated.
8
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
Message-Id: <20230203152202.49054-13-kwolf@redhat.com>
11
Reviewed-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
12
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
13
---
14
block/qcow2.h | 2 +-
15
include/block/block-io.h | 7 ++++---
16
block/io.c | 3 +--
17
3 files changed, 6 insertions(+), 6 deletions(-)
18
19
diff --git a/block/qcow2.h b/block/qcow2.h
20
index XXXXXXX..XXXXXXX 100644
21
--- a/block/qcow2.h
22
+++ b/block/qcow2.h
23
@@ -XXX,XX +XXX,XX @@ int qcow2_inc_refcounts_imrt(BlockDriverState *bs, BdrvCheckResult *res,
24
int qcow2_change_refcount_order(BlockDriverState *bs, int refcount_order,
25
BlockDriverAmendStatusCB *status_cb,
26
void *cb_opaque, Error **errp);
27
-int coroutine_fn qcow2_shrink_reftable(BlockDriverState *bs);
28
+int coroutine_fn GRAPH_RDLOCK qcow2_shrink_reftable(BlockDriverState *bs);
29
int64_t qcow2_get_last_cluster(BlockDriverState *bs, int64_t size);
30
int coroutine_fn qcow2_detect_metadata_preallocation(BlockDriverState *bs);
31
32
diff --git a/include/block/block-io.h b/include/block/block-io.h
33
index XXXXXXX..XXXXXXX 100644
34
--- a/include/block/block-io.h
35
+++ b/include/block/block-io.h
36
@@ -XXX,XX +XXX,XX @@ int co_wrapper_mixed_bdrv_rdlock
37
bdrv_pwrite_sync(BdrvChild *child, int64_t offset, int64_t bytes,
38
const void *buf, BdrvRequestFlags flags);
39
40
-int coroutine_fn bdrv_co_pwrite_sync(BdrvChild *child, int64_t offset,
41
- int64_t bytes, const void *buf,
42
- BdrvRequestFlags flags);
43
+int coroutine_fn GRAPH_RDLOCK
44
+bdrv_co_pwrite_sync(BdrvChild *child, int64_t offset, int64_t bytes,
45
+ const void *buf, BdrvRequestFlags flags);
46
+
47
/*
48
* Efficiently zero a region of the disk image. Note that this is a regular
49
* I/O request like read or write and should have a reasonable size. This
50
diff --git a/block/io.c b/block/io.c
51
index XXXXXXX..XXXXXXX 100644
52
--- a/block/io.c
53
+++ b/block/io.c
54
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_pwrite_sync(BdrvChild *child, int64_t offset,
55
{
56
int ret;
57
IO_CODE();
58
-
59
- assume_graph_lock(); /* FIXME */
60
+ assert_bdrv_graph_readable();
61
62
ret = bdrv_co_pwrite(child, offset, bytes, buf, flags);
63
if (ret < 0) {
64
--
65
2.39.2
diff view generated by jsdifflib
Deleted patch
1
All callers are already GRAPH_RDLOCK, so just add the annotation and
2
remove assume_graph_lock().
3
1
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
Message-Id: <20230203152202.49054-14-kwolf@redhat.com>
6
Reviewed-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
---
9
block/io.c | 7 +++----
10
1 file changed, 3 insertions(+), 4 deletions(-)
11
12
diff --git a/block/io.c b/block/io.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/block/io.c
15
+++ b/block/io.c
16
@@ -XXX,XX +XXX,XX @@ fail:
17
return ret;
18
}
19
20
-static int coroutine_fn bdrv_co_do_pwrite_zeroes(BlockDriverState *bs,
21
- int64_t offset, int64_t bytes, BdrvRequestFlags flags)
22
+static int coroutine_fn GRAPH_RDLOCK
23
+bdrv_co_do_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes,
24
+ BdrvRequestFlags flags)
25
{
26
BlockDriver *drv = bs->drv;
27
QEMUIOVector qiov;
28
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn bdrv_co_do_pwrite_zeroes(BlockDriverState *bs,
29
int head = 0;
30
int tail = 0;
31
32
- assume_graph_lock(); /* FIXME */
33
-
34
int64_t max_write_zeroes = MIN_NON_ZERO(bs->bl.max_pwrite_zeroes,
35
INT64_MAX);
36
int alignment = MAX(bs->bl.pwrite_zeroes_alignment,
37
--
38
2.39.2
diff view generated by jsdifflib
Deleted patch
1
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
2
1
3
This adds GRAPH_RDLOCK annotations to declare that callers of
4
bdrv_co_copy_range() need to hold a reader lock for the graph.
5
6
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
Message-Id: <20230203152202.49054-15-kwolf@redhat.com>
9
Reviewed-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
10
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
11
---
12
include/block/block-io.h | 9 +++++----
13
include/block/block_int-common.h | 24 ++++++++----------------
14
include/block/block_int-io.h | 20 ++++++++++----------
15
block/block-backend.c | 2 ++
16
block/file-posix.c | 16 +++++++---------
17
block/io.c | 7 +++++--
18
block/iscsi.c | 28 ++++++++++++----------------
19
block/qcow2.c | 5 ++---
20
block/raw-format.c | 28 ++++++++++++----------------
21
qemu-img.c | 4 +++-
22
10 files changed, 66 insertions(+), 77 deletions(-)
23
24
diff --git a/include/block/block-io.h b/include/block/block-io.h
25
index XXXXXXX..XXXXXXX 100644
26
--- a/include/block/block-io.h
27
+++ b/include/block/block-io.h
28
@@ -XXX,XX +XXX,XX @@ bool co_wrapper bdrv_can_store_new_dirty_bitmap(BlockDriverState *bs,
29
*
30
* Returns: 0 if succeeded; negative error code if failed.
31
**/
32
-int coroutine_fn bdrv_co_copy_range(BdrvChild *src, int64_t src_offset,
33
- BdrvChild *dst, int64_t dst_offset,
34
- int64_t bytes, BdrvRequestFlags read_flags,
35
- BdrvRequestFlags write_flags);
36
+int coroutine_fn GRAPH_RDLOCK
37
+bdrv_co_copy_range(BdrvChild *src, int64_t src_offset,
38
+ BdrvChild *dst, int64_t dst_offset,
39
+ int64_t bytes, BdrvRequestFlags read_flags,
40
+ BdrvRequestFlags write_flags);
41
42
/*
43
* "I/O or GS" API functions. These functions can run without
44
diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h
45
index XXXXXXX..XXXXXXX 100644
46
--- a/include/block/block_int-common.h
47
+++ b/include/block/block_int-common.h
48
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
49
* See the comment of bdrv_co_copy_range for the parameter and return value
50
* semantics.
51
*/
52
- int coroutine_fn (*bdrv_co_copy_range_from)(BlockDriverState *bs,
53
- BdrvChild *src,
54
- int64_t offset,
55
- BdrvChild *dst,
56
- int64_t dst_offset,
57
- int64_t bytes,
58
- BdrvRequestFlags read_flags,
59
- BdrvRequestFlags write_flags);
60
+ int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_copy_range_from)(
61
+ BlockDriverState *bs, BdrvChild *src, int64_t offset,
62
+ BdrvChild *dst, int64_t dst_offset, int64_t bytes,
63
+ BdrvRequestFlags read_flags, BdrvRequestFlags write_flags);
64
65
/*
66
* Map [offset, offset + nbytes) range onto a child of bs to copy data to,
67
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
68
* See the comment of bdrv_co_copy_range for the parameter and return value
69
* semantics.
70
*/
71
- int coroutine_fn (*bdrv_co_copy_range_to)(BlockDriverState *bs,
72
- BdrvChild *src,
73
- int64_t src_offset,
74
- BdrvChild *dst,
75
- int64_t dst_offset,
76
- int64_t bytes,
77
- BdrvRequestFlags read_flags,
78
- BdrvRequestFlags write_flags);
79
+ int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_copy_range_to)(
80
+ BlockDriverState *bs, BdrvChild *src, int64_t src_offset,
81
+ BdrvChild *dst, int64_t dst_offset, int64_t bytes,
82
+ BdrvRequestFlags read_flags, BdrvRequestFlags write_flags);
83
84
/*
85
* Building block for bdrv_block_status[_above] and
86
diff --git a/include/block/block_int-io.h b/include/block/block_int-io.h
87
index XXXXXXX..XXXXXXX 100644
88
--- a/include/block/block_int-io.h
89
+++ b/include/block/block_int-io.h
90
@@ -XXX,XX +XXX,XX @@ void bdrv_dirty_bitmap_merge_internal(BdrvDirtyBitmap *dest,
91
void bdrv_inc_in_flight(BlockDriverState *bs);
92
void bdrv_dec_in_flight(BlockDriverState *bs);
93
94
-int coroutine_fn bdrv_co_copy_range_from(BdrvChild *src, int64_t src_offset,
95
- BdrvChild *dst, int64_t dst_offset,
96
- int64_t bytes,
97
- BdrvRequestFlags read_flags,
98
- BdrvRequestFlags write_flags);
99
-int coroutine_fn bdrv_co_copy_range_to(BdrvChild *src, int64_t src_offset,
100
- BdrvChild *dst, int64_t dst_offset,
101
- int64_t bytes,
102
- BdrvRequestFlags read_flags,
103
- BdrvRequestFlags write_flags);
104
+int coroutine_fn GRAPH_RDLOCK
105
+bdrv_co_copy_range_from(BdrvChild *src, int64_t src_offset,
106
+ BdrvChild *dst, int64_t dst_offset,
107
+ int64_t bytes, BdrvRequestFlags read_flags,
108
+ BdrvRequestFlags write_flags);
109
+int coroutine_fn GRAPH_RDLOCK
110
+bdrv_co_copy_range_to(BdrvChild *src, int64_t src_offset,
111
+ BdrvChild *dst, int64_t dst_offset,
112
+ int64_t bytes, BdrvRequestFlags read_flags,
113
+ BdrvRequestFlags write_flags);
114
115
int coroutine_fn bdrv_co_refresh_total_sectors(BlockDriverState *bs,
116
int64_t hint);
117
diff --git a/block/block-backend.c b/block/block-backend.c
118
index XXXXXXX..XXXXXXX 100644
119
--- a/block/block-backend.c
120
+++ b/block/block-backend.c
121
@@ -XXX,XX +XXX,XX @@ int coroutine_fn blk_co_copy_range(BlockBackend *blk_in, int64_t off_in,
122
if (r) {
123
return r;
124
}
125
+
126
+ GRAPH_RDLOCK_GUARD();
127
return bdrv_co_copy_range(blk_in->root, off_in,
128
blk_out->root, off_out,
129
bytes, read_flags, write_flags);
130
diff --git a/block/file-posix.c b/block/file-posix.c
131
index XXXXXXX..XXXXXXX 100644
132
--- a/block/file-posix.c
133
+++ b/block/file-posix.c
134
@@ -XXX,XX +XXX,XX @@ static void raw_abort_perm_update(BlockDriverState *bs)
135
raw_handle_perm_lock(bs, RAW_PL_ABORT, 0, 0, NULL);
136
}
137
138
-static int coroutine_fn raw_co_copy_range_from(
139
+static int coroutine_fn GRAPH_RDLOCK raw_co_copy_range_from(
140
BlockDriverState *bs, BdrvChild *src, int64_t src_offset,
141
BdrvChild *dst, int64_t dst_offset, int64_t bytes,
142
BdrvRequestFlags read_flags, BdrvRequestFlags write_flags)
143
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn raw_co_copy_range_from(
144
read_flags, write_flags);
145
}
146
147
-static int coroutine_fn raw_co_copy_range_to(BlockDriverState *bs,
148
- BdrvChild *src,
149
- int64_t src_offset,
150
- BdrvChild *dst,
151
- int64_t dst_offset,
152
- int64_t bytes,
153
- BdrvRequestFlags read_flags,
154
- BdrvRequestFlags write_flags)
155
+static int coroutine_fn GRAPH_RDLOCK
156
+raw_co_copy_range_to(BlockDriverState *bs,
157
+ BdrvChild *src, int64_t src_offset,
158
+ BdrvChild *dst, int64_t dst_offset,
159
+ int64_t bytes, BdrvRequestFlags read_flags,
160
+ BdrvRequestFlags write_flags)
161
{
162
RawPosixAIOData acb;
163
BDRVRawState *s = bs->opaque;
164
diff --git a/block/io.c b/block/io.c
165
index XXXXXXX..XXXXXXX 100644
166
--- a/block/io.c
167
+++ b/block/io.c
168
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn GRAPH_RDLOCK bdrv_co_copy_range_internal(
169
{
170
BdrvTrackedRequest req;
171
int ret;
172
+ assert_bdrv_graph_readable();
173
174
/* TODO We can support BDRV_REQ_NO_FALLBACK here */
175
assert(!(read_flags & BDRV_REQ_NO_FALLBACK));
176
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_copy_range_from(BdrvChild *src, int64_t src_offset,
177
BdrvRequestFlags write_flags)
178
{
179
IO_CODE();
180
- assume_graph_lock(); /* FIXME */
181
+ assert_bdrv_graph_readable();
182
trace_bdrv_co_copy_range_from(src, src_offset, dst, dst_offset, bytes,
183
read_flags, write_flags);
184
return bdrv_co_copy_range_internal(src, src_offset, dst, dst_offset,
185
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_copy_range_to(BdrvChild *src, int64_t src_offset,
186
BdrvRequestFlags write_flags)
187
{
188
IO_CODE();
189
- assume_graph_lock(); /* FIXME */
190
+ assert_bdrv_graph_readable();
191
trace_bdrv_co_copy_range_to(src, src_offset, dst, dst_offset, bytes,
192
read_flags, write_flags);
193
return bdrv_co_copy_range_internal(src, src_offset, dst, dst_offset,
194
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_copy_range(BdrvChild *src, int64_t src_offset,
195
BdrvRequestFlags write_flags)
196
{
197
IO_CODE();
198
+ assert_bdrv_graph_readable();
199
+
200
return bdrv_co_copy_range_from(src, src_offset,
201
dst, dst_offset,
202
bytes, read_flags, write_flags);
203
diff --git a/block/iscsi.c b/block/iscsi.c
204
index XXXXXXX..XXXXXXX 100644
205
--- a/block/iscsi.c
206
+++ b/block/iscsi.c
207
@@ -XXX,XX +XXX,XX @@ static void coroutine_fn iscsi_co_invalidate_cache(BlockDriverState *bs,
208
iscsi_allocmap_invalidate(iscsilun);
209
}
210
211
-static int coroutine_fn iscsi_co_copy_range_from(BlockDriverState *bs,
212
- BdrvChild *src,
213
- int64_t src_offset,
214
- BdrvChild *dst,
215
- int64_t dst_offset,
216
- int64_t bytes,
217
- BdrvRequestFlags read_flags,
218
- BdrvRequestFlags write_flags)
219
+static int coroutine_fn GRAPH_RDLOCK
220
+iscsi_co_copy_range_from(BlockDriverState *bs,
221
+ BdrvChild *src, int64_t src_offset,
222
+ BdrvChild *dst, int64_t dst_offset,
223
+ int64_t bytes, BdrvRequestFlags read_flags,
224
+ BdrvRequestFlags write_flags)
225
{
226
return bdrv_co_copy_range_to(src, src_offset, dst, dst_offset, bytes,
227
read_flags, write_flags);
228
@@ -XXX,XX +XXX,XX @@ static void iscsi_xcopy_data(struct iscsi_data *data,
229
src_lba, dst_lba);
230
}
231
232
-static int coroutine_fn iscsi_co_copy_range_to(BlockDriverState *bs,
233
- BdrvChild *src,
234
- int64_t src_offset,
235
- BdrvChild *dst,
236
- int64_t dst_offset,
237
- int64_t bytes,
238
- BdrvRequestFlags read_flags,
239
- BdrvRequestFlags write_flags)
240
+static int coroutine_fn GRAPH_RDLOCK
241
+iscsi_co_copy_range_to(BlockDriverState *bs,
242
+ BdrvChild *src, int64_t src_offset,
243
+ BdrvChild *dst, int64_t dst_offset,
244
+ int64_t bytes, BdrvRequestFlags read_flags,
245
+ BdrvRequestFlags write_flags)
246
{
247
IscsiLun *dst_lun = dst->bs->opaque;
248
IscsiLun *src_lun;
249
diff --git a/block/qcow2.c b/block/qcow2.c
250
index XXXXXXX..XXXXXXX 100644
251
--- a/block/qcow2.c
252
+++ b/block/qcow2.c
253
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int qcow2_co_pdiscard(BlockDriverState *bs,
254
return ret;
255
}
256
257
-static int coroutine_fn
258
+static int coroutine_fn GRAPH_RDLOCK
259
qcow2_co_copy_range_from(BlockDriverState *bs,
260
BdrvChild *src, int64_t src_offset,
261
BdrvChild *dst, int64_t dst_offset,
262
@@ -XXX,XX +XXX,XX @@ out:
263
return ret;
264
}
265
266
-static int coroutine_fn
267
+static int coroutine_fn GRAPH_RDLOCK
268
qcow2_co_copy_range_to(BlockDriverState *bs,
269
BdrvChild *src, int64_t src_offset,
270
BdrvChild *dst, int64_t dst_offset,
271
@@ -XXX,XX +XXX,XX @@ qcow2_co_copy_range_to(BlockDriverState *bs,
272
uint64_t host_offset;
273
QCowL2Meta *l2meta = NULL;
274
275
- assume_graph_lock(); /* FIXME */
276
assert(!bs->encrypted);
277
278
qemu_co_mutex_lock(&s->lock);
279
diff --git a/block/raw-format.c b/block/raw-format.c
280
index XXXXXXX..XXXXXXX 100644
281
--- a/block/raw-format.c
282
+++ b/block/raw-format.c
283
@@ -XXX,XX +XXX,XX @@ static int raw_probe_geometry(BlockDriverState *bs, HDGeometry *geo)
284
return bdrv_probe_geometry(bs->file->bs, geo);
285
}
286
287
-static int coroutine_fn raw_co_copy_range_from(BlockDriverState *bs,
288
- BdrvChild *src,
289
- int64_t src_offset,
290
- BdrvChild *dst,
291
- int64_t dst_offset,
292
- int64_t bytes,
293
- BdrvRequestFlags read_flags,
294
- BdrvRequestFlags write_flags)
295
+static int coroutine_fn GRAPH_RDLOCK
296
+raw_co_copy_range_from(BlockDriverState *bs,
297
+ BdrvChild *src, int64_t src_offset,
298
+ BdrvChild *dst, int64_t dst_offset,
299
+ int64_t bytes, BdrvRequestFlags read_flags,
300
+ BdrvRequestFlags write_flags)
301
{
302
int ret;
303
304
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn raw_co_copy_range_from(BlockDriverState *bs,
305
bytes, read_flags, write_flags);
306
}
307
308
-static int coroutine_fn raw_co_copy_range_to(BlockDriverState *bs,
309
- BdrvChild *src,
310
- int64_t src_offset,
311
- BdrvChild *dst,
312
- int64_t dst_offset,
313
- int64_t bytes,
314
- BdrvRequestFlags read_flags,
315
- BdrvRequestFlags write_flags)
316
+static int coroutine_fn GRAPH_RDLOCK
317
+raw_co_copy_range_to(BlockDriverState *bs,
318
+ BdrvChild *src, int64_t src_offset,
319
+ BdrvChild *dst, int64_t dst_offset,
320
+ int64_t bytes, BdrvRequestFlags read_flags,
321
+ BdrvRequestFlags write_flags)
322
{
323
int ret;
324
325
diff --git a/qemu-img.c b/qemu-img.c
326
index XXXXXXX..XXXXXXX 100644
327
--- a/qemu-img.c
328
+++ b/qemu-img.c
329
@@ -XXX,XX +XXX,XX @@ retry:
330
331
if (s->ret == -EINPROGRESS) {
332
if (copy_range) {
333
- ret = convert_co_copy_range(s, sector_num, n);
334
+ WITH_GRAPH_RDLOCK_GUARD() {
335
+ ret = convert_co_copy_range(s, sector_num, n);
336
+ }
337
if (ret) {
338
s->copy_range = false;
339
goto retry;
340
--
341
2.39.2
diff view generated by jsdifflib
Deleted patch
1
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2
Message-Id: <20230203152202.49054-16-kwolf@redhat.com>
3
Reviewed-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
---
6
include/block/block_int-common.h | 12 +++++++-----
7
include/block/block_int-io.h | 8 ++++----
8
block/copy-before-write.c | 6 ++----
9
block/io.c | 2 ++
10
block/snapshot-access.c | 4 ++--
11
5 files changed, 17 insertions(+), 15 deletions(-)
12
1
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 @@ struct BlockDriver {
18
* - receive the snapshot's actual length (which may differ from bs's
19
* length)
20
*/
21
- int coroutine_fn (*bdrv_co_preadv_snapshot)(BlockDriverState *bs,
22
- int64_t offset, int64_t bytes, QEMUIOVector *qiov, size_t qiov_offset);
23
- int coroutine_fn (*bdrv_co_snapshot_block_status)(BlockDriverState *bs,
24
- bool want_zero, int64_t offset, int64_t bytes, int64_t *pnum,
25
- int64_t *map, BlockDriverState **file);
26
+ int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_preadv_snapshot)(
27
+ BlockDriverState *bs, int64_t offset, int64_t bytes,
28
+ QEMUIOVector *qiov, size_t qiov_offset);
29
+
30
+ int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_snapshot_block_status)(
31
+ BlockDriverState *bs, bool want_zero, int64_t offset, int64_t bytes,
32
+ int64_t *pnum, int64_t *map, BlockDriverState **file);
33
34
int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_pdiscard_snapshot)(
35
BlockDriverState *bs, int64_t offset, int64_t bytes);
36
diff --git a/include/block/block_int-io.h b/include/block/block_int-io.h
37
index XXXXXXX..XXXXXXX 100644
38
--- a/include/block/block_int-io.h
39
+++ b/include/block/block_int-io.h
40
@@ -XXX,XX +XXX,XX @@
41
* the I/O API.
42
*/
43
44
-int coroutine_fn bdrv_co_preadv_snapshot(BdrvChild *child,
45
+int coroutine_fn GRAPH_RDLOCK bdrv_co_preadv_snapshot(BdrvChild *child,
46
int64_t offset, int64_t bytes, QEMUIOVector *qiov, size_t qiov_offset);
47
-int coroutine_fn bdrv_co_snapshot_block_status(BlockDriverState *bs,
48
- bool want_zero, int64_t offset, int64_t bytes, int64_t *pnum,
49
- int64_t *map, BlockDriverState **file);
50
+int coroutine_fn GRAPH_RDLOCK bdrv_co_snapshot_block_status(
51
+ BlockDriverState *bs, bool want_zero, int64_t offset, int64_t bytes,
52
+ int64_t *pnum, int64_t *map, BlockDriverState **file);
53
int coroutine_fn GRAPH_RDLOCK bdrv_co_pdiscard_snapshot(BlockDriverState *bs,
54
int64_t offset, int64_t bytes);
55
56
diff --git a/block/copy-before-write.c b/block/copy-before-write.c
57
index XXXXXXX..XXXXXXX 100644
58
--- a/block/copy-before-write.c
59
+++ b/block/copy-before-write.c
60
@@ -XXX,XX +XXX,XX @@ cbw_snapshot_read_unlock(BlockDriverState *bs, BlockReq *req)
61
g_free(req);
62
}
63
64
-static coroutine_fn int
65
+static int coroutine_fn GRAPH_RDLOCK
66
cbw_co_preadv_snapshot(BlockDriverState *bs, int64_t offset, int64_t bytes,
67
QEMUIOVector *qiov, size_t qiov_offset)
68
{
69
@@ -XXX,XX +XXX,XX @@ cbw_co_preadv_snapshot(BlockDriverState *bs, int64_t offset, int64_t bytes,
70
BdrvChild *file;
71
int ret;
72
73
- assume_graph_lock(); /* FIXME */
74
-
75
/* TODO: upgrade to async loop using AioTask */
76
while (bytes) {
77
int64_t cur_bytes;
78
@@ -XXX,XX +XXX,XX @@ cbw_co_preadv_snapshot(BlockDriverState *bs, int64_t offset, int64_t bytes,
79
return 0;
80
}
81
82
-static int coroutine_fn
83
+static int coroutine_fn GRAPH_RDLOCK
84
cbw_co_snapshot_block_status(BlockDriverState *bs,
85
bool want_zero, int64_t offset, int64_t bytes,
86
int64_t *pnum, int64_t *map,
87
diff --git a/block/io.c b/block/io.c
88
index XXXXXXX..XXXXXXX 100644
89
--- a/block/io.c
90
+++ b/block/io.c
91
@@ -XXX,XX +XXX,XX @@ bdrv_co_preadv_snapshot(BdrvChild *child, int64_t offset, int64_t bytes,
92
BlockDriver *drv = bs->drv;
93
int ret;
94
IO_CODE();
95
+ assert_bdrv_graph_readable();
96
97
if (!drv) {
98
return -ENOMEDIUM;
99
@@ -XXX,XX +XXX,XX @@ bdrv_co_snapshot_block_status(BlockDriverState *bs,
100
BlockDriver *drv = bs->drv;
101
int ret;
102
IO_CODE();
103
+ assert_bdrv_graph_readable();
104
105
if (!drv) {
106
return -ENOMEDIUM;
107
diff --git a/block/snapshot-access.c b/block/snapshot-access.c
108
index XXXXXXX..XXXXXXX 100644
109
--- a/block/snapshot-access.c
110
+++ b/block/snapshot-access.c
111
@@ -XXX,XX +XXX,XX @@
112
#include "qemu/cutils.h"
113
#include "block/block_int.h"
114
115
-static coroutine_fn int
116
+static int coroutine_fn GRAPH_RDLOCK
117
snapshot_access_co_preadv_part(BlockDriverState *bs,
118
int64_t offset, int64_t bytes,
119
QEMUIOVector *qiov, size_t qiov_offset,
120
@@ -XXX,XX +XXX,XX @@ snapshot_access_co_preadv_part(BlockDriverState *bs,
121
return bdrv_co_preadv_snapshot(bs->file, offset, bytes, qiov, qiov_offset);
122
}
123
124
-static int coroutine_fn
125
+static int coroutine_fn GRAPH_RDLOCK
126
snapshot_access_co_block_status(BlockDriverState *bs,
127
bool want_zero, int64_t offset,
128
int64_t bytes, int64_t *pnum,
129
--
130
2.39.2
diff view generated by jsdifflib
Deleted patch
1
This adds GRAPH_RDLOCK annotations to declare that callers of
2
bdrv_co_create() need to hold a reader lock for the graph.
3
1
4
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
Message-Id: <20230203152202.49054-17-kwolf@redhat.com>
7
Reviewed-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
---
10
include/block/block-global-state.h | 14 ++++---
11
include/block/block_int-common.h | 11 +++---
12
block.c | 1 +
13
block/create.c | 9 ++++-
14
block/crypto.c | 7 ++--
15
block/file-posix.c | 7 ++--
16
block/file-win32.c | 7 ++--
17
block/parallels.c | 7 ++--
18
block/qcow.c | 6 +--
19
block/qcow2.c | 7 ++--
20
block/qed.c | 7 ++--
21
block/raw-format.c | 7 ++--
22
block/vdi.c | 7 ++--
23
block/vhdx.c | 7 ++--
24
block/vmdk.c | 63 ++++++++++++++----------------
25
block/vpc.c | 7 ++--
26
16 files changed, 84 insertions(+), 90 deletions(-)
27
28
diff --git a/include/block/block-global-state.h b/include/block/block-global-state.h
29
index XXXXXXX..XXXXXXX 100644
30
--- a/include/block/block-global-state.h
31
+++ b/include/block/block-global-state.h
32
@@ -XXX,XX +XXX,XX @@ BlockDriver *bdrv_find_protocol(const char *filename,
33
Error **errp);
34
BlockDriver *bdrv_find_format(const char *format_name);
35
36
-int coroutine_fn bdrv_co_create(BlockDriver *drv, const char *filename,
37
- QemuOpts *opts, Error **errp);
38
-int co_wrapper bdrv_create(BlockDriver *drv, const char *filename,
39
- QemuOpts *opts, Error **errp);
40
+int coroutine_fn GRAPH_RDLOCK
41
+bdrv_co_create(BlockDriver *drv, const char *filename, QemuOpts *opts,
42
+ Error **errp);
43
44
-int coroutine_fn bdrv_co_create_file(const char *filename, QemuOpts *opts,
45
- Error **errp);
46
+int co_wrapper_bdrv_rdlock bdrv_create(BlockDriver *drv, const char *filename,
47
+ QemuOpts *opts, Error **errp);
48
+
49
+int coroutine_fn GRAPH_RDLOCK
50
+bdrv_co_create_file(const char *filename, QemuOpts *opts, Error **errp);
51
52
BlockDriverState *bdrv_new(void);
53
int bdrv_append(BlockDriverState *bs_new, BlockDriverState *bs_top,
54
diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h
55
index XXXXXXX..XXXXXXX 100644
56
--- a/include/block/block_int-common.h
57
+++ b/include/block/block_int-common.h
58
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
59
Error **errp);
60
void (*bdrv_close)(BlockDriverState *bs);
61
62
- int coroutine_fn (*bdrv_co_create)(BlockdevCreateOptions *opts,
63
- Error **errp);
64
- int coroutine_fn (*bdrv_co_create_opts)(BlockDriver *drv,
65
- const char *filename,
66
- QemuOpts *opts,
67
- Error **errp);
68
+ int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_create)(
69
+ BlockdevCreateOptions *opts, Error **errp);
70
+
71
+ int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_create_opts)(
72
+ BlockDriver *drv, const char *filename, QemuOpts *opts, Error **errp);
73
74
int (*bdrv_amend_options)(BlockDriverState *bs,
75
QemuOpts *opts,
76
diff --git a/block.c b/block.c
77
index XXXXXXX..XXXXXXX 100644
78
--- a/block.c
79
+++ b/block.c
80
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_create(BlockDriver *drv, const char *filename,
81
int ret;
82
GLOBAL_STATE_CODE();
83
ERRP_GUARD();
84
+ assert_bdrv_graph_readable();
85
86
if (!drv->bdrv_co_create_opts) {
87
error_setg(errp, "Driver '%s' does not support image creation",
88
diff --git a/block/create.c b/block/create.c
89
index XXXXXXX..XXXXXXX 100644
90
--- a/block/create.c
91
+++ b/block/create.c
92
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn blockdev_create_run(Job *job, Error **errp)
93
int ret;
94
95
GLOBAL_STATE_CODE();
96
+ GRAPH_RDLOCK_GUARD();
97
98
job_progress_set_remaining(&s->common, 1);
99
ret = s->drv->bdrv_co_create(s->opts, errp);
100
@@ -XXX,XX +XXX,XX @@ static const JobDriver blockdev_create_job_driver = {
101
.run = blockdev_create_run,
102
};
103
104
+/* Checking whether the function is present doesn't require the graph lock */
105
+static inline bool TSA_NO_TSA has_bdrv_co_create(BlockDriver *drv)
106
+{
107
+ return drv->bdrv_co_create;
108
+}
109
+
110
void qmp_blockdev_create(const char *job_id, BlockdevCreateOptions *options,
111
Error **errp)
112
{
113
@@ -XXX,XX +XXX,XX @@ void qmp_blockdev_create(const char *job_id, BlockdevCreateOptions *options,
114
}
115
116
/* Error out if the driver doesn't support .bdrv_co_create */
117
- if (!drv->bdrv_co_create) {
118
+ if (!has_bdrv_co_create(drv)) {
119
error_setg(errp, "Driver does not support blockdev-create");
120
return;
121
}
122
diff --git a/block/crypto.c b/block/crypto.c
123
index XXXXXXX..XXXXXXX 100644
124
--- a/block/crypto.c
125
+++ b/block/crypto.c
126
@@ -XXX,XX +XXX,XX @@ fail:
127
return ret;
128
}
129
130
-static int coroutine_fn block_crypto_co_create_opts_luks(BlockDriver *drv,
131
- const char *filename,
132
- QemuOpts *opts,
133
- Error **errp)
134
+static int coroutine_fn GRAPH_RDLOCK
135
+block_crypto_co_create_opts_luks(BlockDriver *drv, const char *filename,
136
+ QemuOpts *opts, Error **errp)
137
{
138
QCryptoBlockCreateOptions *create_opts = NULL;
139
BlockDriverState *bs = NULL;
140
diff --git a/block/file-posix.c b/block/file-posix.c
141
index XXXXXXX..XXXXXXX 100644
142
--- a/block/file-posix.c
143
+++ b/block/file-posix.c
144
@@ -XXX,XX +XXX,XX @@ out:
145
return result;
146
}
147
148
-static int coroutine_fn raw_co_create_opts(BlockDriver *drv,
149
- const char *filename,
150
- QemuOpts *opts,
151
- Error **errp)
152
+static int coroutine_fn GRAPH_RDLOCK
153
+raw_co_create_opts(BlockDriver *drv, const char *filename,
154
+ QemuOpts *opts, Error **errp)
155
{
156
BlockdevCreateOptions options;
157
int64_t total_size = 0;
158
diff --git a/block/file-win32.c b/block/file-win32.c
159
index XXXXXXX..XXXXXXX 100644
160
--- a/block/file-win32.c
161
+++ b/block/file-win32.c
162
@@ -XXX,XX +XXX,XX @@ static int raw_co_create(BlockdevCreateOptions *options, Error **errp)
163
return 0;
164
}
165
166
-static int coroutine_fn raw_co_create_opts(BlockDriver *drv,
167
- const char *filename,
168
- QemuOpts *opts,
169
- Error **errp)
170
+static int coroutine_fn GRAPH_RDLOCK
171
+raw_co_create_opts(BlockDriver *drv, const char *filename,
172
+ QemuOpts *opts, Error **errp)
173
{
174
BlockdevCreateOptions options;
175
int64_t total_size = 0;
176
diff --git a/block/parallels.c b/block/parallels.c
177
index XXXXXXX..XXXXXXX 100644
178
--- a/block/parallels.c
179
+++ b/block/parallels.c
180
@@ -XXX,XX +XXX,XX @@ exit:
181
goto out;
182
}
183
184
-static int coroutine_fn parallels_co_create_opts(BlockDriver *drv,
185
- const char *filename,
186
- QemuOpts *opts,
187
- Error **errp)
188
+static int coroutine_fn GRAPH_RDLOCK
189
+parallels_co_create_opts(BlockDriver *drv, const char *filename,
190
+ QemuOpts *opts, Error **errp)
191
{
192
BlockdevCreateOptions *create_options = NULL;
193
BlockDriverState *bs = NULL;
194
diff --git a/block/qcow.c b/block/qcow.c
195
index XXXXXXX..XXXXXXX 100644
196
--- a/block/qcow.c
197
+++ b/block/qcow.c
198
@@ -XXX,XX +XXX,XX @@ exit:
199
return ret;
200
}
201
202
-static int coroutine_fn qcow_co_create_opts(BlockDriver *drv,
203
- const char *filename,
204
- QemuOpts *opts, Error **errp)
205
+static int coroutine_fn GRAPH_RDLOCK
206
+qcow_co_create_opts(BlockDriver *drv, const char *filename,
207
+ QemuOpts *opts, Error **errp)
208
{
209
BlockdevCreateOptions *create_options = NULL;
210
BlockDriverState *bs = NULL;
211
diff --git a/block/qcow2.c b/block/qcow2.c
212
index XXXXXXX..XXXXXXX 100644
213
--- a/block/qcow2.c
214
+++ b/block/qcow2.c
215
@@ -XXX,XX +XXX,XX @@ out:
216
return ret;
217
}
218
219
-static int coroutine_fn qcow2_co_create_opts(BlockDriver *drv,
220
- const char *filename,
221
- QemuOpts *opts,
222
- Error **errp)
223
+static int coroutine_fn GRAPH_RDLOCK
224
+qcow2_co_create_opts(BlockDriver *drv, const char *filename, QemuOpts *opts,
225
+ Error **errp)
226
{
227
BlockdevCreateOptions *create_options = NULL;
228
QDict *qdict;
229
diff --git a/block/qed.c b/block/qed.c
230
index XXXXXXX..XXXXXXX 100644
231
--- a/block/qed.c
232
+++ b/block/qed.c
233
@@ -XXX,XX +XXX,XX @@ out:
234
return ret;
235
}
236
237
-static int coroutine_fn bdrv_qed_co_create_opts(BlockDriver *drv,
238
- const char *filename,
239
- QemuOpts *opts,
240
- Error **errp)
241
+static int coroutine_fn GRAPH_RDLOCK
242
+bdrv_qed_co_create_opts(BlockDriver *drv, const char *filename,
243
+ QemuOpts *opts, Error **errp)
244
{
245
BlockdevCreateOptions *create_options = NULL;
246
QDict *qdict;
247
diff --git a/block/raw-format.c b/block/raw-format.c
248
index XXXXXXX..XXXXXXX 100644
249
--- a/block/raw-format.c
250
+++ b/block/raw-format.c
251
@@ -XXX,XX +XXX,XX @@ static int raw_has_zero_init(BlockDriverState *bs)
252
return bdrv_has_zero_init(bs->file->bs);
253
}
254
255
-static int coroutine_fn raw_co_create_opts(BlockDriver *drv,
256
- const char *filename,
257
- QemuOpts *opts,
258
- Error **errp)
259
+static int coroutine_fn GRAPH_RDLOCK
260
+raw_co_create_opts(BlockDriver *drv, const char *filename,
261
+ QemuOpts *opts, Error **errp)
262
{
263
return bdrv_co_create_file(filename, opts, errp);
264
}
265
diff --git a/block/vdi.c b/block/vdi.c
266
index XXXXXXX..XXXXXXX 100644
267
--- a/block/vdi.c
268
+++ b/block/vdi.c
269
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn vdi_co_create(BlockdevCreateOptions *create_options,
270
return vdi_co_do_create(create_options, DEFAULT_CLUSTER_SIZE, errp);
271
}
272
273
-static int coroutine_fn vdi_co_create_opts(BlockDriver *drv,
274
- const char *filename,
275
- QemuOpts *opts,
276
- Error **errp)
277
+static int coroutine_fn GRAPH_RDLOCK
278
+vdi_co_create_opts(BlockDriver *drv, const char *filename,
279
+ QemuOpts *opts, Error **errp)
280
{
281
QDict *qdict = NULL;
282
BlockdevCreateOptions *create_options = NULL;
283
diff --git a/block/vhdx.c b/block/vhdx.c
284
index XXXXXXX..XXXXXXX 100644
285
--- a/block/vhdx.c
286
+++ b/block/vhdx.c
287
@@ -XXX,XX +XXX,XX @@ delete_and_exit:
288
return ret;
289
}
290
291
-static int coroutine_fn vhdx_co_create_opts(BlockDriver *drv,
292
- const char *filename,
293
- QemuOpts *opts,
294
- Error **errp)
295
+static int coroutine_fn GRAPH_RDLOCK
296
+vhdx_co_create_opts(BlockDriver *drv, const char *filename,
297
+ QemuOpts *opts, Error **errp)
298
{
299
BlockdevCreateOptions *create_options = NULL;
300
QDict *qdict;
301
diff --git a/block/vmdk.c b/block/vmdk.c
302
index XXXXXXX..XXXXXXX 100644
303
--- a/block/vmdk.c
304
+++ b/block/vmdk.c
305
@@ -XXX,XX +XXX,XX @@ exit:
306
return ret;
307
}
308
309
-static int coroutine_fn vmdk_create_extent(const char *filename,
310
- int64_t filesize, bool flat,
311
- bool compress, bool zeroed_grain,
312
- BlockBackend **pbb,
313
- QemuOpts *opts, Error **errp)
314
+static int coroutine_fn GRAPH_RDLOCK
315
+vmdk_create_extent(const char *filename, int64_t filesize, bool flat,
316
+ bool compress, bool zeroed_grain, BlockBackend **pbb,
317
+ QemuOpts *opts, Error **errp)
318
{
319
int ret;
320
BlockBackend *blk = NULL;
321
@@ -XXX,XX +XXX,XX @@ static int filename_decompose(const char *filename, char *path, char *prefix,
322
* non-split format.
323
* idx >= 1: get the n-th extent if in a split subformat
324
*/
325
-typedef BlockBackend * coroutine_fn (*vmdk_create_extent_fn)(int64_t size,
326
- int idx,
327
- bool flat,
328
- bool split,
329
- bool compress,
330
- bool zeroed_grain,
331
- void *opaque,
332
- Error **errp);
333
+typedef BlockBackend * coroutine_fn /* GRAPH_RDLOCK */
334
+ (*vmdk_create_extent_fn)(int64_t size, int idx, bool flat, bool split,
335
+ bool compress, bool zeroed_grain, void *opaque,
336
+ Error **errp);
337
338
static void vmdk_desc_add_extent(GString *desc,
339
const char *extent_line_fmt,
340
@@ -XXX,XX +XXX,XX @@ static void vmdk_desc_add_extent(GString *desc,
341
g_free(basename);
342
}
343
344
-static int coroutine_fn vmdk_co_do_create(int64_t size,
345
- BlockdevVmdkSubformat subformat,
346
- BlockdevVmdkAdapterType adapter_type,
347
- const char *backing_file,
348
- const char *hw_version,
349
- const char *toolsversion,
350
- bool compat6,
351
- bool zeroed_grain,
352
- vmdk_create_extent_fn extent_fn,
353
- void *opaque,
354
- Error **errp)
355
+static int coroutine_fn GRAPH_RDLOCK
356
+vmdk_co_do_create(int64_t size,
357
+ BlockdevVmdkSubformat subformat,
358
+ BlockdevVmdkAdapterType adapter_type,
359
+ const char *backing_file,
360
+ const char *hw_version,
361
+ const char *toolsversion,
362
+ bool compat6,
363
+ bool zeroed_grain,
364
+ vmdk_create_extent_fn extent_fn,
365
+ void *opaque,
366
+ Error **errp)
367
{
368
int extent_idx;
369
BlockBackend *blk = NULL;
370
@@ -XXX,XX +XXX,XX @@ typedef struct {
371
QemuOpts *opts;
372
} VMDKCreateOptsData;
373
374
-static BlockBackend * coroutine_fn vmdk_co_create_opts_cb(int64_t size, int idx,
375
- bool flat, bool split, bool compress,
376
- bool zeroed_grain, void *opaque,
377
- Error **errp)
378
+static BlockBackend * coroutine_fn GRAPH_RDLOCK
379
+vmdk_co_create_opts_cb(int64_t size, int idx, bool flat, bool split,
380
+ bool compress, bool zeroed_grain, void *opaque,
381
+ Error **errp)
382
{
383
BlockBackend *blk = NULL;
384
BlockDriverState *bs = NULL;
385
@@ -XXX,XX +XXX,XX @@ exit:
386
return blk;
387
}
388
389
-static int coroutine_fn vmdk_co_create_opts(BlockDriver *drv,
390
- const char *filename,
391
- QemuOpts *opts,
392
- Error **errp)
393
+static int coroutine_fn GRAPH_RDLOCK
394
+vmdk_co_create_opts(BlockDriver *drv, const char *filename,
395
+ QemuOpts *opts, Error **errp)
396
{
397
Error *local_err = NULL;
398
char *desc = NULL;
399
@@ -XXX,XX +XXX,XX @@ static BlockBackend * coroutine_fn vmdk_co_create_cb(int64_t size, int idx,
400
return blk;
401
}
402
403
-static int coroutine_fn vmdk_co_create(BlockdevCreateOptions *create_options,
404
- Error **errp)
405
+static int coroutine_fn GRAPH_RDLOCK
406
+vmdk_co_create(BlockdevCreateOptions *create_options, Error **errp)
407
{
408
BlockdevCreateOptionsVmdk *opts;
409
410
diff --git a/block/vpc.c b/block/vpc.c
411
index XXXXXXX..XXXXXXX 100644
412
--- a/block/vpc.c
413
+++ b/block/vpc.c
414
@@ -XXX,XX +XXX,XX @@ out:
415
return ret;
416
}
417
418
-static int coroutine_fn vpc_co_create_opts(BlockDriver *drv,
419
- const char *filename,
420
- QemuOpts *opts,
421
- Error **errp)
422
+static int coroutine_fn GRAPH_RDLOCK
423
+vpc_co_create_opts(BlockDriver *drv, const char *filename,
424
+ QemuOpts *opts, Error **errp)
425
{
426
BlockdevCreateOptions *create_options = NULL;
427
QDict *qdict;
428
--
429
2.39.2
diff view generated by jsdifflib
Deleted patch
1
This adds GRAPH_RDLOCK annotations to declare that callers of
2
bdrv_co_io_plug() and bdrv_co_io_unplug() need to hold a reader lock for
3
the graph.
4
1
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
Message-Id: <20230203152202.49054-18-kwolf@redhat.com>
7
Reviewed-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
---
10
include/block/block-io.h | 4 ++--
11
include/block/block_int-common.h | 5 +++--
12
block/block-backend.c | 2 ++
13
block/io.c | 2 ++
14
4 files changed, 9 insertions(+), 4 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 coroutine_fn bdrv_co_leave(BlockDriverState *bs, AioContext *old_ctx);
21
22
AioContext *child_of_bds_get_parent_aio_context(BdrvChild *c);
23
24
-void coroutine_fn bdrv_co_io_plug(BlockDriverState *bs);
25
-void coroutine_fn bdrv_co_io_unplug(BlockDriverState *bs);
26
+void coroutine_fn GRAPH_RDLOCK bdrv_co_io_plug(BlockDriverState *bs);
27
+void coroutine_fn GRAPH_RDLOCK bdrv_co_io_unplug(BlockDriverState *bs);
28
29
bool coroutine_fn bdrv_co_can_store_new_dirty_bitmap(BlockDriverState *bs,
30
const char *name,
31
diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h
32
index XXXXXXX..XXXXXXX 100644
33
--- a/include/block/block_int-common.h
34
+++ b/include/block/block_int-common.h
35
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
36
BlkdebugEvent event);
37
38
/* io queue for linux-aio */
39
- void coroutine_fn (*bdrv_co_io_plug)(BlockDriverState *bs);
40
- void coroutine_fn (*bdrv_co_io_unplug)(BlockDriverState *bs);
41
+ void coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_io_plug)(BlockDriverState *bs);
42
+ void coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_io_unplug)(
43
+ BlockDriverState *bs);
44
45
/**
46
* bdrv_drain_begin is called if implemented in the beginning of a
47
diff --git a/block/block-backend.c b/block/block-backend.c
48
index XXXXXXX..XXXXXXX 100644
49
--- a/block/block-backend.c
50
+++ b/block/block-backend.c
51
@@ -XXX,XX +XXX,XX @@ void coroutine_fn blk_co_io_plug(BlockBackend *blk)
52
{
53
BlockDriverState *bs = blk_bs(blk);
54
IO_CODE();
55
+ GRAPH_RDLOCK_GUARD();
56
57
if (bs) {
58
bdrv_co_io_plug(bs);
59
@@ -XXX,XX +XXX,XX @@ void coroutine_fn blk_co_io_unplug(BlockBackend *blk)
60
{
61
BlockDriverState *bs = blk_bs(blk);
62
IO_CODE();
63
+ GRAPH_RDLOCK_GUARD();
64
65
if (bs) {
66
bdrv_co_io_unplug(bs);
67
diff --git a/block/io.c b/block/io.c
68
index XXXXXXX..XXXXXXX 100644
69
--- a/block/io.c
70
+++ b/block/io.c
71
@@ -XXX,XX +XXX,XX @@ void coroutine_fn bdrv_co_io_plug(BlockDriverState *bs)
72
{
73
BdrvChild *child;
74
IO_CODE();
75
+ assert_bdrv_graph_readable();
76
77
QLIST_FOREACH(child, &bs->children, next) {
78
bdrv_co_io_plug(child->bs);
79
@@ -XXX,XX +XXX,XX @@ void coroutine_fn bdrv_co_io_unplug(BlockDriverState *bs)
80
{
81
BdrvChild *child;
82
IO_CODE();
83
+ assert_bdrv_graph_readable();
84
85
assert(bs->io_plugged);
86
if (qatomic_fetch_dec(&bs->io_plugged) == 1) {
87
--
88
2.39.2
diff view generated by jsdifflib
Deleted patch
1
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
2
1
3
This adds GRAPH_RDLOCK annotations to declare that callers of
4
bdrv_co_is_inserted() need to hold a reader lock for the graph.
5
6
blk_is_inserted() is done as a co_wrapper_mixed_bdrv_rdlock (unlike most
7
other blk_* functions) because it is called a lot from other blk_co_*()
8
functions that already hold the lock. These calls go through
9
blk_is_available(), which becomes a co_wrapper_mixed_bdrv_rdlock, too,
10
for the same reason.
11
12
Functions that run in a coroutine and can call bdrv_co_is_available()
13
directly are changed to do so, which results in better TSA coverage.
14
15
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
16
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
17
Message-Id: <20230203152202.49054-19-kwolf@redhat.com>
18
Reviewed-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
19
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
20
---
21
include/block/block-io.h | 4 ++--
22
include/block/block_int-common.h | 3 ++-
23
include/sysemu/block-backend-io.h | 7 ++++---
24
block.c | 1 +
25
block/block-backend.c | 25 ++++++++++++++-----------
26
5 files changed, 23 insertions(+), 17 deletions(-)
27
28
diff --git a/include/block/block-io.h b/include/block/block-io.h
29
index XXXXXXX..XXXXXXX 100644
30
--- a/include/block/block-io.h
31
+++ b/include/block/block-io.h
32
@@ -XXX,XX +XXX,XX @@ bool bdrv_is_writable(BlockDriverState *bs);
33
bool bdrv_is_sg(BlockDriverState *bs);
34
int bdrv_get_flags(BlockDriverState *bs);
35
36
-bool coroutine_fn bdrv_co_is_inserted(BlockDriverState *bs);
37
-bool co_wrapper bdrv_is_inserted(BlockDriverState *bs);
38
+bool coroutine_fn GRAPH_RDLOCK bdrv_co_is_inserted(BlockDriverState *bs);
39
+bool co_wrapper_bdrv_rdlock bdrv_is_inserted(BlockDriverState *bs);
40
41
void coroutine_fn bdrv_co_lock_medium(BlockDriverState *bs, bool locked);
42
void coroutine_fn bdrv_co_eject(BlockDriverState *bs, bool eject_flag);
43
diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h
44
index XXXXXXX..XXXXXXX 100644
45
--- a/include/block/block_int-common.h
46
+++ b/include/block/block_int-common.h
47
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
48
BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos);
49
50
/* removable device specific */
51
- bool coroutine_fn (*bdrv_co_is_inserted)(BlockDriverState *bs);
52
+ bool coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_is_inserted)(
53
+ BlockDriverState *bs);
54
void coroutine_fn (*bdrv_co_eject)(BlockDriverState *bs, bool eject_flag);
55
void coroutine_fn (*bdrv_co_lock_medium)(BlockDriverState *bs, bool locked);
56
57
diff --git a/include/sysemu/block-backend-io.h b/include/sysemu/block-backend-io.h
58
index XXXXXXX..XXXXXXX 100644
59
--- a/include/sysemu/block-backend-io.h
60
+++ b/include/sysemu/block-backend-io.h
61
@@ -XXX,XX +XXX,XX @@ BlockAIOCB *blk_aio_ioctl(BlockBackend *blk, unsigned long int req, void *buf,
62
void blk_inc_in_flight(BlockBackend *blk);
63
void blk_dec_in_flight(BlockBackend *blk);
64
65
-bool coroutine_fn blk_co_is_inserted(BlockBackend *blk);
66
-bool co_wrapper_mixed blk_is_inserted(BlockBackend *blk);
67
+bool coroutine_fn GRAPH_RDLOCK blk_co_is_inserted(BlockBackend *blk);
68
+bool co_wrapper_mixed_bdrv_rdlock blk_is_inserted(BlockBackend *blk);
69
70
-bool blk_is_available(BlockBackend *blk);
71
+bool coroutine_fn GRAPH_RDLOCK blk_co_is_available(BlockBackend *blk);
72
+bool co_wrapper_mixed_bdrv_rdlock blk_is_available(BlockBackend *blk);
73
74
void coroutine_fn blk_co_lock_medium(BlockBackend *blk, bool locked);
75
void co_wrapper blk_lock_medium(BlockBackend *blk, bool locked);
76
diff --git a/block.c b/block.c
77
index XXXXXXX..XXXXXXX 100644
78
--- a/block.c
79
+++ b/block.c
80
@@ -XXX,XX +XXX,XX @@ bool coroutine_fn bdrv_co_is_inserted(BlockDriverState *bs)
81
BlockDriver *drv = bs->drv;
82
BdrvChild *child;
83
IO_CODE();
84
+ assert_bdrv_graph_readable();
85
86
if (!drv) {
87
return false;
88
diff --git a/block/block-backend.c b/block/block-backend.c
89
index XXXXXXX..XXXXXXX 100644
90
--- a/block/block-backend.c
91
+++ b/block/block-backend.c
92
@@ -XXX,XX +XXX,XX @@ void blk_set_disable_request_queuing(BlockBackend *blk, bool disable)
93
blk->disable_request_queuing = disable;
94
}
95
96
-static coroutine_fn int blk_check_byte_request(BlockBackend *blk,
97
- int64_t offset, int64_t bytes)
98
+static int coroutine_fn GRAPH_RDLOCK
99
+blk_check_byte_request(BlockBackend *blk, int64_t offset, int64_t bytes)
100
{
101
int64_t len;
102
103
@@ -XXX,XX +XXX,XX @@ static coroutine_fn int blk_check_byte_request(BlockBackend *blk,
104
return -EIO;
105
}
106
107
- if (!blk_is_available(blk)) {
108
+ if (!blk_co_is_available(blk)) {
109
return -ENOMEDIUM;
110
}
111
112
@@ -XXX,XX +XXX,XX @@ BlockAIOCB *blk_aio_pwrite_zeroes(BlockBackend *blk, int64_t offset,
113
int64_t coroutine_fn blk_co_getlength(BlockBackend *blk)
114
{
115
IO_CODE();
116
+ GRAPH_RDLOCK_GUARD();
117
118
- if (!blk_is_available(blk)) {
119
+ if (!blk_co_is_available(blk)) {
120
return -ENOMEDIUM;
121
}
122
123
@@ -XXX,XX +XXX,XX @@ void blk_get_geometry(BlockBackend *blk, uint64_t *nb_sectors_ptr)
124
int64_t coroutine_fn blk_co_nb_sectors(BlockBackend *blk)
125
{
126
IO_CODE();
127
+ GRAPH_RDLOCK_GUARD();
128
129
- if (!blk_is_available(blk)) {
130
+ if (!blk_co_is_available(blk)) {
131
return -ENOMEDIUM;
132
}
133
134
@@ -XXX,XX +XXX,XX @@ blk_co_do_ioctl(BlockBackend *blk, unsigned long int req, void *buf)
135
blk_wait_while_drained(blk);
136
GRAPH_RDLOCK_GUARD();
137
138
- if (!blk_is_available(blk)) {
139
+ if (!blk_co_is_available(blk)) {
140
return -ENOMEDIUM;
141
}
142
143
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn blk_co_do_flush(BlockBackend *blk)
144
blk_wait_while_drained(blk);
145
GRAPH_RDLOCK_GUARD();
146
147
- if (!blk_is_available(blk)) {
148
+ if (!blk_co_is_available(blk)) {
149
return -ENOMEDIUM;
150
}
151
152
@@ -XXX,XX +XXX,XX @@ bool coroutine_fn blk_co_is_inserted(BlockBackend *blk)
153
{
154
BlockDriverState *bs = blk_bs(blk);
155
IO_CODE();
156
+ assert_bdrv_graph_readable();
157
158
return bs && bdrv_co_is_inserted(bs);
159
}
160
161
-bool blk_is_available(BlockBackend *blk)
162
+bool coroutine_fn blk_co_is_available(BlockBackend *blk)
163
{
164
IO_CODE();
165
- return blk_is_inserted(blk) && !blk_dev_is_tray_open(blk);
166
+ return blk_co_is_inserted(blk) && !blk_dev_is_tray_open(blk);
167
}
168
169
void coroutine_fn blk_co_lock_medium(BlockBackend *blk, bool locked)
170
@@ -XXX,XX +XXX,XX @@ int coroutine_fn blk_co_truncate(BlockBackend *blk, int64_t offset, bool exact,
171
{
172
IO_OR_GS_CODE();
173
GRAPH_RDLOCK_GUARD();
174
- if (!blk_is_available(blk)) {
175
+ if (!blk_co_is_available(blk)) {
176
error_setg(errp, "No medium inserted");
177
return -ENOMEDIUM;
178
}
179
@@ -XXX,XX +XXX,XX @@ int coroutine_fn blk_co_copy_range(BlockBackend *blk_in, int64_t off_in,
180
{
181
int r;
182
IO_CODE();
183
+ GRAPH_RDLOCK_GUARD();
184
185
r = blk_check_byte_request(blk_in, off_in, bytes);
186
if (r) {
187
@@ -XXX,XX +XXX,XX @@ int coroutine_fn blk_co_copy_range(BlockBackend *blk_in, int64_t off_in,
188
return r;
189
}
190
191
- GRAPH_RDLOCK_GUARD();
192
return bdrv_co_copy_range(blk_in->root, off_in,
193
blk_out->root, off_out,
194
bytes, read_flags, write_flags);
195
--
196
2.39.2
diff view generated by jsdifflib
Deleted patch
1
This adds GRAPH_RDLOCK annotations to declare that callers of
2
bdrv_co_eject() and bdrv_co_lock_medium() need to hold a reader lock for
3
the graph.
4
1
5
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
6
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
7
Message-Id: <20230203152202.49054-20-kwolf@redhat.com>
8
Reviewed-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
9
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
10
---
11
include/block/block-io.h | 7 +++++--
12
include/block/block_int-common.h | 6 ++++--
13
block.c | 2 ++
14
block/block-backend.c | 2 ++
15
block/copy-on-read.c | 6 ++++--
16
block/filter-compress.c | 4 ++--
17
block/raw-format.c | 6 ++++--
18
7 files changed, 23 insertions(+), 10 deletions(-)
19
20
diff --git a/include/block/block-io.h b/include/block/block-io.h
21
index XXXXXXX..XXXXXXX 100644
22
--- a/include/block/block-io.h
23
+++ b/include/block/block-io.h
24
@@ -XXX,XX +XXX,XX @@ int bdrv_get_flags(BlockDriverState *bs);
25
bool coroutine_fn GRAPH_RDLOCK bdrv_co_is_inserted(BlockDriverState *bs);
26
bool co_wrapper_bdrv_rdlock bdrv_is_inserted(BlockDriverState *bs);
27
28
-void coroutine_fn bdrv_co_lock_medium(BlockDriverState *bs, bool locked);
29
-void coroutine_fn bdrv_co_eject(BlockDriverState *bs, bool eject_flag);
30
+void coroutine_fn GRAPH_RDLOCK
31
+bdrv_co_lock_medium(BlockDriverState *bs, bool locked);
32
+
33
+void coroutine_fn GRAPH_RDLOCK
34
+bdrv_co_eject(BlockDriverState *bs, bool eject_flag);
35
36
const char *bdrv_get_format_name(BlockDriverState *bs);
37
38
diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h
39
index XXXXXXX..XXXXXXX 100644
40
--- a/include/block/block_int-common.h
41
+++ b/include/block/block_int-common.h
42
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
43
/* removable device specific */
44
bool coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_is_inserted)(
45
BlockDriverState *bs);
46
- void coroutine_fn (*bdrv_co_eject)(BlockDriverState *bs, bool eject_flag);
47
- void coroutine_fn (*bdrv_co_lock_medium)(BlockDriverState *bs, bool locked);
48
+ void coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_eject)(
49
+ BlockDriverState *bs, bool eject_flag);
50
+ void coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_lock_medium)(
51
+ BlockDriverState *bs, bool locked);
52
53
/* to control generic scsi devices */
54
BlockAIOCB *coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_aio_ioctl)(
55
diff --git a/block.c b/block.c
56
index XXXXXXX..XXXXXXX 100644
57
--- a/block.c
58
+++ b/block.c
59
@@ -XXX,XX +XXX,XX @@ void coroutine_fn bdrv_co_eject(BlockDriverState *bs, bool eject_flag)
60
{
61
BlockDriver *drv = bs->drv;
62
IO_CODE();
63
+ assert_bdrv_graph_readable();
64
65
if (drv && drv->bdrv_co_eject) {
66
drv->bdrv_co_eject(bs, eject_flag);
67
@@ -XXX,XX +XXX,XX @@ void coroutine_fn bdrv_co_lock_medium(BlockDriverState *bs, bool locked)
68
{
69
BlockDriver *drv = bs->drv;
70
IO_CODE();
71
+ assert_bdrv_graph_readable();
72
trace_bdrv_lock_medium(bs, locked);
73
74
if (drv && drv->bdrv_co_lock_medium) {
75
diff --git a/block/block-backend.c b/block/block-backend.c
76
index XXXXXXX..XXXXXXX 100644
77
--- a/block/block-backend.c
78
+++ b/block/block-backend.c
79
@@ -XXX,XX +XXX,XX @@ void coroutine_fn blk_co_lock_medium(BlockBackend *blk, bool locked)
80
{
81
BlockDriverState *bs = blk_bs(blk);
82
IO_CODE();
83
+ GRAPH_RDLOCK_GUARD();
84
85
if (bs) {
86
bdrv_co_lock_medium(bs, locked);
87
@@ -XXX,XX +XXX,XX @@ void coroutine_fn blk_co_eject(BlockBackend *blk, bool eject_flag)
88
BlockDriverState *bs = blk_bs(blk);
89
char *id;
90
IO_CODE();
91
+ GRAPH_RDLOCK_GUARD();
92
93
if (bs) {
94
bdrv_co_eject(bs, eject_flag);
95
diff --git a/block/copy-on-read.c b/block/copy-on-read.c
96
index XXXXXXX..XXXXXXX 100644
97
--- a/block/copy-on-read.c
98
+++ b/block/copy-on-read.c
99
@@ -XXX,XX +XXX,XX @@ cor_co_pwritev_compressed(BlockDriverState *bs, int64_t offset, int64_t bytes,
100
}
101
102
103
-static void coroutine_fn cor_co_eject(BlockDriverState *bs, bool eject_flag)
104
+static void coroutine_fn GRAPH_RDLOCK
105
+cor_co_eject(BlockDriverState *bs, bool eject_flag)
106
{
107
bdrv_co_eject(bs->file->bs, eject_flag);
108
}
109
110
111
-static void coroutine_fn cor_co_lock_medium(BlockDriverState *bs, bool locked)
112
+static void coroutine_fn GRAPH_RDLOCK
113
+cor_co_lock_medium(BlockDriverState *bs, bool locked)
114
{
115
bdrv_co_lock_medium(bs->file->bs, locked);
116
}
117
diff --git a/block/filter-compress.c b/block/filter-compress.c
118
index XXXXXXX..XXXXXXX 100644
119
--- a/block/filter-compress.c
120
+++ b/block/filter-compress.c
121
@@ -XXX,XX +XXX,XX @@ static void compress_refresh_limits(BlockDriverState *bs, Error **errp)
122
}
123
124
125
-static void coroutine_fn
126
+static void coroutine_fn GRAPH_RDLOCK
127
compress_co_eject(BlockDriverState *bs, bool eject_flag)
128
{
129
bdrv_co_eject(bs->file->bs, eject_flag);
130
}
131
132
133
-static void coroutine_fn
134
+static void coroutine_fn GRAPH_RDLOCK
135
compress_co_lock_medium(BlockDriverState *bs, bool locked)
136
{
137
bdrv_co_lock_medium(bs->file->bs, locked);
138
diff --git a/block/raw-format.c b/block/raw-format.c
139
index XXXXXXX..XXXXXXX 100644
140
--- a/block/raw-format.c
141
+++ b/block/raw-format.c
142
@@ -XXX,XX +XXX,XX @@ raw_co_truncate(BlockDriverState *bs, int64_t offset, bool exact,
143
return bdrv_co_truncate(bs->file, offset, exact, prealloc, flags, errp);
144
}
145
146
-static void coroutine_fn raw_co_eject(BlockDriverState *bs, bool eject_flag)
147
+static void coroutine_fn GRAPH_RDLOCK
148
+raw_co_eject(BlockDriverState *bs, bool eject_flag)
149
{
150
bdrv_co_eject(bs->file->bs, eject_flag);
151
}
152
153
-static void coroutine_fn raw_co_lock_medium(BlockDriverState *bs, bool locked)
154
+static void coroutine_fn GRAPH_RDLOCK
155
+raw_co_lock_medium(BlockDriverState *bs, bool locked)
156
{
157
bdrv_co_lock_medium(bs->file->bs, locked);
158
}
159
--
160
2.39.2
diff view generated by jsdifflib
Deleted patch
1
This adds GRAPH_RDLOCK annotations to declare that callers of
2
bdrv_register_buf() and bdrv_unregister_buf() need to hold a reader lock
3
for the graph.
4
1
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
Message-Id: <20230203152202.49054-21-kwolf@redhat.com>
7
Reviewed-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
---
10
include/block/block_int-common.h | 7 ++++---
11
block/io.c | 14 ++++++++++----
12
2 files changed, 14 insertions(+), 7 deletions(-)
13
14
diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/include/block/block_int-common.h
17
+++ b/include/block/block_int-common.h
18
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
19
*
20
* Returns: true on success, false on failure
21
*/
22
- bool (*bdrv_register_buf)(BlockDriverState *bs, void *host, size_t size,
23
- Error **errp);
24
- void (*bdrv_unregister_buf)(BlockDriverState *bs, void *host, size_t size);
25
+ bool GRAPH_RDLOCK_PTR (*bdrv_register_buf)(
26
+ BlockDriverState *bs, void *host, size_t size, Error **errp);
27
+ void GRAPH_RDLOCK_PTR (*bdrv_unregister_buf)(
28
+ BlockDriverState *bs, void *host, size_t size);
29
30
/*
31
* This field is modified only under the BQL, and is part of
32
diff --git a/block/io.c b/block/io.c
33
index XXXXXXX..XXXXXXX 100644
34
--- a/block/io.c
35
+++ b/block/io.c
36
@@ -XXX,XX +XXX,XX @@ void coroutine_fn bdrv_co_io_unplug(BlockDriverState *bs)
37
}
38
39
/* Helper that undoes bdrv_register_buf() when it fails partway through */
40
-static void bdrv_register_buf_rollback(BlockDriverState *bs,
41
- void *host,
42
- size_t size,
43
- BdrvChild *final_child)
44
+static void GRAPH_RDLOCK
45
+bdrv_register_buf_rollback(BlockDriverState *bs, void *host, size_t size,
46
+ BdrvChild *final_child)
47
{
48
BdrvChild *child;
49
50
+ GLOBAL_STATE_CODE();
51
+ assert_bdrv_graph_readable();
52
+
53
QLIST_FOREACH(child, &bs->children, next) {
54
if (child == final_child) {
55
break;
56
@@ -XXX,XX +XXX,XX @@ bool bdrv_register_buf(BlockDriverState *bs, void *host, size_t size,
57
BdrvChild *child;
58
59
GLOBAL_STATE_CODE();
60
+ GRAPH_RDLOCK_GUARD_MAINLOOP();
61
+
62
if (bs->drv && bs->drv->bdrv_register_buf) {
63
if (!bs->drv->bdrv_register_buf(bs, host, size, errp)) {
64
return false;
65
@@ -XXX,XX +XXX,XX @@ void bdrv_unregister_buf(BlockDriverState *bs, void *host, size_t size)
66
BdrvChild *child;
67
68
GLOBAL_STATE_CODE();
69
+ GRAPH_RDLOCK_GUARD_MAINLOOP();
70
+
71
if (bs->drv && bs->drv->bdrv_unregister_buf) {
72
bs->drv->bdrv_unregister_buf(bs, host, size);
73
}
74
--
75
2.39.2
diff view generated by jsdifflib
Deleted patch
1
This adds GRAPH_RDLOCK annotations to declare that callers of
2
bdrv_co_delete_file() need to hold a reader lock for the graph.
3
1
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
Message-Id: <20230203152202.49054-22-kwolf@redhat.com>
6
Reviewed-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
---
9
include/block/block-io.h | 8 ++++++--
10
include/block/block_int-common.h | 4 ++--
11
block.c | 1 +
12
3 files changed, 9 insertions(+), 4 deletions(-)
13
14
diff --git a/include/block/block-io.h b/include/block/block-io.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/include/block/block-io.h
17
+++ b/include/block/block-io.h
18
@@ -XXX,XX +XXX,XX @@ int64_t co_wrapper bdrv_get_allocated_file_size(BlockDriverState *bs);
19
BlockMeasureInfo *bdrv_measure(BlockDriver *drv, QemuOpts *opts,
20
BlockDriverState *in_bs, Error **errp);
21
void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr);
22
-int coroutine_fn bdrv_co_delete_file(BlockDriverState *bs, Error **errp);
23
-void coroutine_fn bdrv_co_delete_file_noerr(BlockDriverState *bs);
24
+
25
+int coroutine_fn GRAPH_RDLOCK
26
+bdrv_co_delete_file(BlockDriverState *bs, Error **errp);
27
+
28
+void coroutine_fn GRAPH_RDLOCK
29
+bdrv_co_delete_file_noerr(BlockDriverState *bs);
30
31
32
/* async block I/O */
33
diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h
34
index XXXXXXX..XXXXXXX 100644
35
--- a/include/block/block_int-common.h
36
+++ b/include/block/block_int-common.h
37
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
38
int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_flush)(BlockDriverState *bs);
39
40
/* Delete a created file. */
41
- int coroutine_fn (*bdrv_co_delete_file)(BlockDriverState *bs,
42
- Error **errp);
43
+ int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_delete_file)(
44
+ BlockDriverState *bs, Error **errp);
45
46
/*
47
* Flushes all data that was already written to the OS all the way down to
48
diff --git a/block.c b/block.c
49
index XXXXXXX..XXXXXXX 100644
50
--- a/block.c
51
+++ b/block.c
52
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_delete_file(BlockDriverState *bs, Error **errp)
53
54
IO_CODE();
55
assert(bs != NULL);
56
+ assert_bdrv_graph_readable();
57
58
if (!bs->drv) {
59
error_setg(errp, "Block node '%s' is not opened", bs->filename);
60
--
61
2.39.2
diff view generated by jsdifflib
Deleted patch
1
This adds GRAPH_RDLOCK annotations to declare that callers of
2
bdrv_*_dirty_bitmap() need to hold a reader lock for the graph.
3
1
4
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5
Message-Id: <20230203152202.49054-23-kwolf@redhat.com>
6
Reviewed-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
---
9
include/block/block-io.h | 14 ++++++--------
10
include/block/block_int-common.h | 6 ++++--
11
include/block/dirty-bitmap.h | 12 ++++++------
12
block/dirty-bitmap.c | 2 ++
13
4 files changed, 18 insertions(+), 16 deletions(-)
14
15
diff --git a/include/block/block-io.h b/include/block/block-io.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/include/block/block-io.h
18
+++ b/include/block/block-io.h
19
@@ -XXX,XX +XXX,XX @@ AioContext *child_of_bds_get_parent_aio_context(BdrvChild *c);
20
void coroutine_fn GRAPH_RDLOCK bdrv_co_io_plug(BlockDriverState *bs);
21
void coroutine_fn GRAPH_RDLOCK bdrv_co_io_unplug(BlockDriverState *bs);
22
23
-bool coroutine_fn bdrv_co_can_store_new_dirty_bitmap(BlockDriverState *bs,
24
- const char *name,
25
- uint32_t granularity,
26
- Error **errp);
27
-bool co_wrapper bdrv_can_store_new_dirty_bitmap(BlockDriverState *bs,
28
- const char *name,
29
- uint32_t granularity,
30
- Error **errp);
31
+bool coroutine_fn GRAPH_RDLOCK
32
+bdrv_co_can_store_new_dirty_bitmap(BlockDriverState *bs, const char *name,
33
+ uint32_t granularity, Error **errp);
34
+bool co_wrapper_bdrv_rdlock
35
+bdrv_can_store_new_dirty_bitmap(BlockDriverState *bs, const char *name,
36
+ uint32_t granularity, Error **errp);
37
38
/**
39
*
40
diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h
41
index XXXXXXX..XXXXXXX 100644
42
--- a/include/block/block_int-common.h
43
+++ b/include/block/block_int-common.h
44
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
45
void (*bdrv_drain_end)(BlockDriverState *bs);
46
47
bool (*bdrv_supports_persistent_dirty_bitmap)(BlockDriverState *bs);
48
- bool coroutine_fn (*bdrv_co_can_store_new_dirty_bitmap)(
49
+
50
+ bool coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_can_store_new_dirty_bitmap)(
51
BlockDriverState *bs, const char *name, uint32_t granularity,
52
Error **errp);
53
- int coroutine_fn (*bdrv_co_remove_persistent_dirty_bitmap)(
54
+
55
+ int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_remove_persistent_dirty_bitmap)(
56
BlockDriverState *bs, const char *name, Error **errp);
57
};
58
59
diff --git a/include/block/dirty-bitmap.h b/include/block/dirty-bitmap.h
60
index XXXXXXX..XXXXXXX 100644
61
--- a/include/block/dirty-bitmap.h
62
+++ b/include/block/dirty-bitmap.h
63
@@ -XXX,XX +XXX,XX @@ int bdrv_dirty_bitmap_check(const BdrvDirtyBitmap *bitmap, uint32_t flags,
64
void bdrv_release_dirty_bitmap(BdrvDirtyBitmap *bitmap);
65
void bdrv_release_named_dirty_bitmaps(BlockDriverState *bs);
66
67
-int coroutine_fn bdrv_co_remove_persistent_dirty_bitmap(BlockDriverState *bs,
68
- const char *name,
69
- Error **errp);
70
-int co_wrapper bdrv_remove_persistent_dirty_bitmap(BlockDriverState *bs,
71
- const char *name,
72
- Error **errp);
73
+int coroutine_fn GRAPH_RDLOCK
74
+bdrv_co_remove_persistent_dirty_bitmap(BlockDriverState *bs, const char *name,
75
+ Error **errp);
76
+int co_wrapper_bdrv_rdlock
77
+bdrv_remove_persistent_dirty_bitmap(BlockDriverState *bs, const char *name,
78
+ Error **errp);
79
80
void bdrv_disable_dirty_bitmap(BdrvDirtyBitmap *bitmap);
81
void bdrv_enable_dirty_bitmap(BdrvDirtyBitmap *bitmap);
82
diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c
83
index XXXXXXX..XXXXXXX 100644
84
--- a/block/dirty-bitmap.c
85
+++ b/block/dirty-bitmap.c
86
@@ -XXX,XX +XXX,XX @@ int coroutine_fn
87
bdrv_co_remove_persistent_dirty_bitmap(BlockDriverState *bs, const char *name,
88
Error **errp)
89
{
90
+ assert_bdrv_graph_readable();
91
if (bs->drv && bs->drv->bdrv_co_remove_persistent_dirty_bitmap) {
92
return bs->drv->bdrv_co_remove_persistent_dirty_bitmap(bs, name, errp);
93
}
94
@@ -XXX,XX +XXX,XX @@ bdrv_co_can_store_new_dirty_bitmap(BlockDriverState *bs, const char *name,
95
uint32_t granularity, Error **errp)
96
{
97
BlockDriver *drv = bs->drv;
98
+ assert_bdrv_graph_readable();
99
100
if (!drv) {
101
error_setg_errno(errp, ENOMEDIUM,
102
--
103
2.39.2
diff view generated by jsdifflib
Deleted patch
1
This adds GRAPH_RDLOCK annotations to declare that callers of
2
bdrv_co_refresh_total_sectors() need to hold a reader lock for the
3
graph.
4
1
5
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6
Message-Id: <20230203152202.49054-24-kwolf@redhat.com>
7
Reviewed-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9
---
10
include/block/block-io.h | 8 ++++----
11
include/block/block_int-common.h | 4 +++-
12
include/block/block_int-io.h | 7 ++++---
13
block.c | 3 +++
14
block/blkdebug.c | 3 ++-
15
block/blklogwrites.c | 3 ++-
16
block/blkreplay.c | 3 ++-
17
block/blkverify.c | 3 ++-
18
block/copy-on-read.c | 2 +-
19
block/crypto.c | 3 ++-
20
block/filter-compress.c | 3 ++-
21
block/mirror.c | 3 +++
22
block/preallocate.c | 3 ++-
23
block/quorum.c | 3 ++-
24
block/raw-format.c | 3 ++-
25
block/replication.c | 3 ++-
26
block/stream.c | 8 +++++---
27
block/throttle.c | 3 ++-
28
18 files changed, 45 insertions(+), 23 deletions(-)
29
30
diff --git a/include/block/block-io.h b/include/block/block-io.h
31
index XXXXXXX..XXXXXXX 100644
32
--- a/include/block/block-io.h
33
+++ b/include/block/block-io.h
34
@@ -XXX,XX +XXX,XX @@ int coroutine_fn GRAPH_RDLOCK
35
bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact,
36
PreallocMode prealloc, BdrvRequestFlags flags, Error **errp);
37
38
-int64_t coroutine_fn bdrv_co_nb_sectors(BlockDriverState *bs);
39
-int64_t co_wrapper_mixed bdrv_nb_sectors(BlockDriverState *bs);
40
+int64_t coroutine_fn GRAPH_RDLOCK bdrv_co_nb_sectors(BlockDriverState *bs);
41
+int64_t co_wrapper_mixed_bdrv_rdlock bdrv_nb_sectors(BlockDriverState *bs);
42
43
-int64_t coroutine_fn bdrv_co_getlength(BlockDriverState *bs);
44
-int64_t co_wrapper_mixed bdrv_getlength(BlockDriverState *bs);
45
+int64_t coroutine_fn GRAPH_RDLOCK bdrv_co_getlength(BlockDriverState *bs);
46
+int64_t co_wrapper_mixed_bdrv_rdlock bdrv_getlength(BlockDriverState *bs);
47
48
int64_t coroutine_fn bdrv_co_get_allocated_file_size(BlockDriverState *bs);
49
int64_t co_wrapper bdrv_get_allocated_file_size(BlockDriverState *bs);
50
diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h
51
index XXXXXXX..XXXXXXX 100644
52
--- a/include/block/block_int-common.h
53
+++ b/include/block/block_int-common.h
54
@@ -XXX,XX +XXX,XX @@ struct BlockDriver {
55
BlockDriverState *bs, int64_t offset, bool exact,
56
PreallocMode prealloc, BdrvRequestFlags flags, Error **errp);
57
58
- int64_t coroutine_fn (*bdrv_co_getlength)(BlockDriverState *bs);
59
+ int64_t coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_getlength)(
60
+ BlockDriverState *bs);
61
+
62
int64_t coroutine_fn (*bdrv_co_get_allocated_file_size)(
63
BlockDriverState *bs);
64
65
diff --git a/include/block/block_int-io.h b/include/block/block_int-io.h
66
index XXXXXXX..XXXXXXX 100644
67
--- a/include/block/block_int-io.h
68
+++ b/include/block/block_int-io.h
69
@@ -XXX,XX +XXX,XX @@ bdrv_co_copy_range_to(BdrvChild *src, int64_t src_offset,
70
int64_t bytes, BdrvRequestFlags read_flags,
71
BdrvRequestFlags write_flags);
72
73
-int coroutine_fn bdrv_co_refresh_total_sectors(BlockDriverState *bs,
74
- int64_t hint);
75
-int co_wrapper_mixed
76
+int coroutine_fn GRAPH_RDLOCK
77
+bdrv_co_refresh_total_sectors(BlockDriverState *bs, int64_t hint);
78
+
79
+int co_wrapper_mixed_bdrv_rdlock
80
bdrv_refresh_total_sectors(BlockDriverState *bs, int64_t hint);
81
82
BdrvChild *bdrv_cow_child(BlockDriverState *bs);
83
diff --git a/block.c b/block.c
84
index XXXXXXX..XXXXXXX 100644
85
--- a/block.c
86
+++ b/block.c
87
@@ -XXX,XX +XXX,XX @@ int coroutine_fn bdrv_co_refresh_total_sectors(BlockDriverState *bs,
88
{
89
BlockDriver *drv = bs->drv;
90
IO_CODE();
91
+ assert_bdrv_graph_readable();
92
93
if (!drv) {
94
return -ENOMEDIUM;
95
@@ -XXX,XX +XXX,XX @@ int64_t coroutine_fn bdrv_co_nb_sectors(BlockDriverState *bs)
96
{
97
BlockDriver *drv = bs->drv;
98
IO_CODE();
99
+ assert_bdrv_graph_readable();
100
101
if (!drv)
102
return -ENOMEDIUM;
103
@@ -XXX,XX +XXX,XX @@ int64_t coroutine_fn bdrv_co_getlength(BlockDriverState *bs)
104
{
105
int64_t ret;
106
IO_CODE();
107
+ assert_bdrv_graph_readable();
108
109
ret = bdrv_co_nb_sectors(bs);
110
if (ret < 0) {
111
diff --git a/block/blkdebug.c b/block/blkdebug.c
112
index XXXXXXX..XXXXXXX 100644
113
--- a/block/blkdebug.c
114
+++ b/block/blkdebug.c
115
@@ -XXX,XX +XXX,XX @@ static bool blkdebug_debug_is_suspended(BlockDriverState *bs, const char *tag)
116
return false;
117
}
118
119
-static int64_t coroutine_fn blkdebug_co_getlength(BlockDriverState *bs)
120
+static int64_t coroutine_fn GRAPH_RDLOCK
121
+blkdebug_co_getlength(BlockDriverState *bs)
122
{
123
return bdrv_co_getlength(bs->file->bs);
124
}
125
diff --git a/block/blklogwrites.c b/block/blklogwrites.c
126
index XXXXXXX..XXXXXXX 100644
127
--- a/block/blklogwrites.c
128
+++ b/block/blklogwrites.c
129
@@ -XXX,XX +XXX,XX @@ static void blk_log_writes_close(BlockDriverState *bs)
130
s->log_file = NULL;
131
}
132
133
-static int64_t coroutine_fn blk_log_writes_co_getlength(BlockDriverState *bs)
134
+static int64_t coroutine_fn GRAPH_RDLOCK
135
+blk_log_writes_co_getlength(BlockDriverState *bs)
136
{
137
return bdrv_co_getlength(bs->file->bs);
138
}
139
diff --git a/block/blkreplay.c b/block/blkreplay.c
140
index XXXXXXX..XXXXXXX 100644
141
--- a/block/blkreplay.c
142
+++ b/block/blkreplay.c
143
@@ -XXX,XX +XXX,XX @@ fail:
144
return ret;
145
}
146
147
-static int64_t coroutine_fn blkreplay_co_getlength(BlockDriverState *bs)
148
+static int64_t coroutine_fn GRAPH_RDLOCK
149
+blkreplay_co_getlength(BlockDriverState *bs)
150
{
151
return bdrv_co_getlength(bs->file->bs);
152
}
153
diff --git a/block/blkverify.c b/block/blkverify.c
154
index XXXXXXX..XXXXXXX 100644
155
--- a/block/blkverify.c
156
+++ b/block/blkverify.c
157
@@ -XXX,XX +XXX,XX @@ static void blkverify_close(BlockDriverState *bs)
158
s->test_file = NULL;
159
}
160
161
-static int64_t coroutine_fn blkverify_co_getlength(BlockDriverState *bs)
162
+static int64_t coroutine_fn GRAPH_RDLOCK
163
+blkverify_co_getlength(BlockDriverState *bs)
164
{
165
BDRVBlkverifyState *s = bs->opaque;
166
167
diff --git a/block/copy-on-read.c b/block/copy-on-read.c
168
index XXXXXXX..XXXXXXX 100644
169
--- a/block/copy-on-read.c
170
+++ b/block/copy-on-read.c
171
@@ -XXX,XX +XXX,XX @@ static void cor_child_perm(BlockDriverState *bs, BdrvChild *c,
172
}
173
174
175
-static int64_t coroutine_fn cor_co_getlength(BlockDriverState *bs)
176
+static int64_t coroutine_fn GRAPH_RDLOCK cor_co_getlength(BlockDriverState *bs)
177
{
178
return bdrv_co_getlength(bs->file->bs);
179
}
180
diff --git a/block/crypto.c b/block/crypto.c
181
index XXXXXXX..XXXXXXX 100644
182
--- a/block/crypto.c
183
+++ b/block/crypto.c
184
@@ -XXX,XX +XXX,XX @@ static void block_crypto_refresh_limits(BlockDriverState *bs, Error **errp)
185
}
186
187
188
-static int64_t coroutine_fn block_crypto_co_getlength(BlockDriverState *bs)
189
+static int64_t coroutine_fn GRAPH_RDLOCK
190
+block_crypto_co_getlength(BlockDriverState *bs)
191
{
192
BlockCrypto *crypto = bs->opaque;
193
int64_t len = bdrv_co_getlength(bs->file->bs);
194
diff --git a/block/filter-compress.c b/block/filter-compress.c
195
index XXXXXXX..XXXXXXX 100644
196
--- a/block/filter-compress.c
197
+++ b/block/filter-compress.c
198
@@ -XXX,XX +XXX,XX @@ static int compress_open(BlockDriverState *bs, QDict *options, int flags,
199
}
200
201
202
-static int64_t coroutine_fn compress_co_getlength(BlockDriverState *bs)
203
+static int64_t coroutine_fn GRAPH_RDLOCK
204
+compress_co_getlength(BlockDriverState *bs)
205
{
206
return bdrv_co_getlength(bs->file->bs);
207
}
208
diff --git a/block/mirror.c b/block/mirror.c
209
index XXXXXXX..XXXXXXX 100644
210
--- a/block/mirror.c
211
+++ b/block/mirror.c
212
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn mirror_run(Job *job, Error **errp)
213
goto immediate_exit;
214
}
215
216
+ bdrv_graph_co_rdlock();
217
s->bdev_length = bdrv_co_getlength(bs);
218
+ bdrv_graph_co_rdunlock();
219
+
220
if (s->bdev_length < 0) {
221
ret = s->bdev_length;
222
goto immediate_exit;
223
diff --git a/block/preallocate.c b/block/preallocate.c
224
index XXXXXXX..XXXXXXX 100644
225
--- a/block/preallocate.c
226
+++ b/block/preallocate.c
227
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn GRAPH_RDLOCK preallocate_co_flush(BlockDriverState *bs)
228
return bdrv_co_flush(bs->file->bs);
229
}
230
231
-static int64_t coroutine_fn preallocate_co_getlength(BlockDriverState *bs)
232
+static int64_t coroutine_fn GRAPH_RDLOCK
233
+preallocate_co_getlength(BlockDriverState *bs)
234
{
235
int64_t ret;
236
BDRVPreallocateState *s = bs->opaque;
237
diff --git a/block/quorum.c b/block/quorum.c
238
index XXXXXXX..XXXXXXX 100644
239
--- a/block/quorum.c
240
+++ b/block/quorum.c
241
@@ -XXX,XX +XXX,XX @@ quorum_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes,
242
flags | BDRV_REQ_ZERO_WRITE);
243
}
244
245
-static int64_t coroutine_fn quorum_co_getlength(BlockDriverState *bs)
246
+static int64_t coroutine_fn GRAPH_RDLOCK
247
+quorum_co_getlength(BlockDriverState *bs)
248
{
249
BDRVQuorumState *s = bs->opaque;
250
int64_t result;
251
diff --git a/block/raw-format.c b/block/raw-format.c
252
index XXXXXXX..XXXXXXX 100644
253
--- a/block/raw-format.c
254
+++ b/block/raw-format.c
255
@@ -XXX,XX +XXX,XX @@ raw_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes)
256
return bdrv_co_pdiscard(bs->file, offset, bytes);
257
}
258
259
-static int64_t coroutine_fn raw_co_getlength(BlockDriverState *bs)
260
+static int64_t coroutine_fn GRAPH_RDLOCK
261
+raw_co_getlength(BlockDriverState *bs)
262
{
263
int64_t len;
264
BDRVRawState *s = bs->opaque;
265
diff --git a/block/replication.c b/block/replication.c
266
index XXXXXXX..XXXXXXX 100644
267
--- a/block/replication.c
268
+++ b/block/replication.c
269
@@ -XXX,XX +XXX,XX @@ static void replication_child_perm(BlockDriverState *bs, BdrvChild *c,
270
return;
271
}
272
273
-static int64_t coroutine_fn replication_co_getlength(BlockDriverState *bs)
274
+static int64_t coroutine_fn GRAPH_RDLOCK
275
+replication_co_getlength(BlockDriverState *bs)
276
{
277
return bdrv_co_getlength(bs->file->bs);
278
}
279
diff --git a/block/stream.c b/block/stream.c
280
index XXXXXXX..XXXXXXX 100644
281
--- a/block/stream.c
282
+++ b/block/stream.c
283
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn stream_run(Job *job, Error **errp)
284
return 0;
285
}
286
287
- len = bdrv_getlength(s->target_bs);
288
- if (len < 0) {
289
- return len;
290
+ WITH_GRAPH_RDLOCK_GUARD() {
291
+ len = bdrv_co_getlength(s->target_bs);
292
+ if (len < 0) {
293
+ return len;
294
+ }
295
}
296
job_progress_set_remaining(&s->common.job, len);
297
298
diff --git a/block/throttle.c b/block/throttle.c
299
index XXXXXXX..XXXXXXX 100644
300
--- a/block/throttle.c
301
+++ b/block/throttle.c
302
@@ -XXX,XX +XXX,XX @@ static void throttle_close(BlockDriverState *bs)
303
}
304
305
306
-static int64_t coroutine_fn throttle_co_getlength(BlockDriverState *bs)
307
+static int64_t coroutine_fn GRAPH_RDLOCK
308
+throttle_co_getlength(BlockDriverState *bs)
309
{
310
return bdrv_co_getlength(bs->file->bs);
311
}
312
--
313
2.39.2
diff view generated by jsdifflib
Deleted patch
1
From: Stefan Hajnoczi <stefanha@redhat.com>
2
1
3
If requests are being processed in the IOThread when a SCSIDevice is
4
unplugged, scsi_device_purge_requests() -> scsi_req_cancel_async() races
5
with I/O completion callbacks. Both threads load and store req->aiocb.
6
This can lead to assert(r->req.aiocb == NULL) failures and undefined
7
behavior.
8
9
Protect r->req.aiocb with the AioContext lock to prevent the race.
10
11
Reviewed-by: Eric Blake <eblake@redhat.com>
12
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
13
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
14
Message-Id: <20230221212218.1378734-2-stefanha@redhat.com>
15
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
16
---
17
hw/scsi/scsi-disk.c | 23 ++++++++++++++++-------
18
hw/scsi/scsi-generic.c | 11 ++++++-----
19
2 files changed, 22 insertions(+), 12 deletions(-)
20
21
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
22
index XXXXXXX..XXXXXXX 100644
23
--- a/hw/scsi/scsi-disk.c
24
+++ b/hw/scsi/scsi-disk.c
25
@@ -XXX,XX +XXX,XX @@ static void scsi_aio_complete(void *opaque, int ret)
26
SCSIDiskReq *r = (SCSIDiskReq *)opaque;
27
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
28
29
+ aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk));
30
+
31
assert(r->req.aiocb != NULL);
32
r->req.aiocb = NULL;
33
- aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk));
34
+
35
if (scsi_disk_req_check_error(r, ret, true)) {
36
goto done;
37
}
38
@@ -XXX,XX +XXX,XX @@ static void scsi_dma_complete(void *opaque, int ret)
39
SCSIDiskReq *r = (SCSIDiskReq *)opaque;
40
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
41
42
+ aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk));
43
+
44
assert(r->req.aiocb != NULL);
45
r->req.aiocb = NULL;
46
47
- aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk));
48
if (ret < 0) {
49
block_acct_failed(blk_get_stats(s->qdev.conf.blk), &r->acct);
50
} else {
51
@@ -XXX,XX +XXX,XX @@ static void scsi_read_complete(void *opaque, int ret)
52
SCSIDiskReq *r = (SCSIDiskReq *)opaque;
53
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
54
55
+ aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk));
56
+
57
assert(r->req.aiocb != NULL);
58
r->req.aiocb = NULL;
59
60
- aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk));
61
if (ret < 0) {
62
block_acct_failed(blk_get_stats(s->qdev.conf.blk), &r->acct);
63
} else {
64
@@ -XXX,XX +XXX,XX @@ static void scsi_do_read_cb(void *opaque, int ret)
65
SCSIDiskReq *r = (SCSIDiskReq *)opaque;
66
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
67
68
+ aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk));
69
+
70
assert (r->req.aiocb != NULL);
71
r->req.aiocb = NULL;
72
73
- aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk));
74
if (ret < 0) {
75
block_acct_failed(blk_get_stats(s->qdev.conf.blk), &r->acct);
76
} else {
77
@@ -XXX,XX +XXX,XX @@ static void scsi_write_complete(void * opaque, int ret)
78
SCSIDiskReq *r = (SCSIDiskReq *)opaque;
79
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
80
81
+ aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk));
82
+
83
assert (r->req.aiocb != NULL);
84
r->req.aiocb = NULL;
85
86
- aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk));
87
if (ret < 0) {
88
block_acct_failed(blk_get_stats(s->qdev.conf.blk), &r->acct);
89
} else {
90
@@ -XXX,XX +XXX,XX @@ static void scsi_unmap_complete(void *opaque, int ret)
91
SCSIDiskReq *r = data->r;
92
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
93
94
+ aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk));
95
+
96
assert(r->req.aiocb != NULL);
97
r->req.aiocb = NULL;
98
99
- aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk));
100
if (scsi_disk_req_check_error(r, ret, true)) {
101
scsi_req_unref(&r->req);
102
g_free(data);
103
@@ -XXX,XX +XXX,XX @@ static void scsi_write_same_complete(void *opaque, int ret)
104
SCSIDiskReq *r = data->r;
105
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
106
107
+ aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk));
108
+
109
assert(r->req.aiocb != NULL);
110
r->req.aiocb = NULL;
111
- aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk));
112
+
113
if (scsi_disk_req_check_error(r, ret, true)) {
114
goto done;
115
}
116
diff --git a/hw/scsi/scsi-generic.c b/hw/scsi/scsi-generic.c
117
index XXXXXXX..XXXXXXX 100644
118
--- a/hw/scsi/scsi-generic.c
119
+++ b/hw/scsi/scsi-generic.c
120
@@ -XXX,XX +XXX,XX @@ static void scsi_command_complete(void *opaque, int ret)
121
SCSIGenericReq *r = (SCSIGenericReq *)opaque;
122
SCSIDevice *s = r->req.dev;
123
124
+ aio_context_acquire(blk_get_aio_context(s->conf.blk));
125
+
126
assert(r->req.aiocb != NULL);
127
r->req.aiocb = NULL;
128
129
- aio_context_acquire(blk_get_aio_context(s->conf.blk));
130
scsi_command_complete_noio(r, ret);
131
aio_context_release(blk_get_aio_context(s->conf.blk));
132
}
133
@@ -XXX,XX +XXX,XX @@ static void scsi_read_complete(void * opaque, int ret)
134
SCSIDevice *s = r->req.dev;
135
int len;
136
137
+ aio_context_acquire(blk_get_aio_context(s->conf.blk));
138
+
139
assert(r->req.aiocb != NULL);
140
r->req.aiocb = NULL;
141
142
- aio_context_acquire(blk_get_aio_context(s->conf.blk));
143
-
144
if (ret || r->req.io_canceled) {
145
scsi_command_complete_noio(r, ret);
146
goto done;
147
@@ -XXX,XX +XXX,XX @@ static void scsi_write_complete(void * opaque, int ret)
148
149
trace_scsi_generic_write_complete(ret);
150
151
+ aio_context_acquire(blk_get_aio_context(s->conf.blk));
152
+
153
assert(r->req.aiocb != NULL);
154
r->req.aiocb = NULL;
155
156
- aio_context_acquire(blk_get_aio_context(s->conf.blk));
157
-
158
if (ret || r->req.io_canceled) {
159
scsi_command_complete_noio(r, ret);
160
goto done;
161
--
162
2.39.2
diff view generated by jsdifflib
Deleted patch
1
From: Stefan Hajnoczi <stefanha@redhat.com>
2
1
3
dma_blk_cb() only takes the AioContext lock around ->io_func(). That
4
means the rest of dma_blk_cb() is not protected. In particular, the
5
DMAAIOCB field accesses happen outside the lock.
6
7
There is a race when the main loop thread holds the AioContext lock and
8
invokes scsi_device_purge_requests() -> bdrv_aio_cancel() ->
9
dma_aio_cancel() while an IOThread executes dma_blk_cb(). The dbs->acb
10
field determines how cancellation proceeds. If dma_aio_cancel() sees
11
dbs->acb == NULL while dma_blk_cb() is still running, the request can be
12
completed twice (-ECANCELED and the actual return value).
13
14
The following assertion can occur with virtio-scsi when an IOThread is
15
used:
16
17
../hw/scsi/scsi-disk.c:368: scsi_dma_complete: Assertion `r->req.aiocb != NULL' failed.
18
19
Fix the race by holding the AioContext across dma_blk_cb(). Now
20
dma_aio_cancel() under the AioContext lock will not see
21
inconsistent/intermediate states.
22
23
Cc: Paolo Bonzini <pbonzini@redhat.com>
24
Reviewed-by: Eric Blake <eblake@redhat.com>
25
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
26
Message-Id: <20230221212218.1378734-3-stefanha@redhat.com>
27
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
28
---
29
hw/scsi/scsi-disk.c | 4 +---
30
softmmu/dma-helpers.c | 12 +++++++-----
31
2 files changed, 8 insertions(+), 8 deletions(-)
32
33
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/hw/scsi/scsi-disk.c
36
+++ b/hw/scsi/scsi-disk.c
37
@@ -XXX,XX +XXX,XX @@ done:
38
scsi_req_unref(&r->req);
39
}
40
41
+/* Called with AioContext lock held */
42
static void scsi_dma_complete(void *opaque, int ret)
43
{
44
SCSIDiskReq *r = (SCSIDiskReq *)opaque;
45
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
46
47
- aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk));
48
-
49
assert(r->req.aiocb != NULL);
50
r->req.aiocb = NULL;
51
52
@@ -XXX,XX +XXX,XX @@ static void scsi_dma_complete(void *opaque, int ret)
53
block_acct_done(blk_get_stats(s->qdev.conf.blk), &r->acct);
54
}
55
scsi_dma_complete_noio(r, ret);
56
- aio_context_release(blk_get_aio_context(s->qdev.conf.blk));
57
}
58
59
static void scsi_read_complete_noio(SCSIDiskReq *r, int ret)
60
diff --git a/softmmu/dma-helpers.c b/softmmu/dma-helpers.c
61
index XXXXXXX..XXXXXXX 100644
62
--- a/softmmu/dma-helpers.c
63
+++ b/softmmu/dma-helpers.c
64
@@ -XXX,XX +XXX,XX @@ static void dma_complete(DMAAIOCB *dbs, int ret)
65
static void dma_blk_cb(void *opaque, int ret)
66
{
67
DMAAIOCB *dbs = (DMAAIOCB *)opaque;
68
+ AioContext *ctx = dbs->ctx;
69
dma_addr_t cur_addr, cur_len;
70
void *mem;
71
72
trace_dma_blk_cb(dbs, ret);
73
74
+ aio_context_acquire(ctx);
75
dbs->acb = NULL;
76
dbs->offset += dbs->iov.size;
77
78
if (dbs->sg_cur_index == dbs->sg->nsg || ret < 0) {
79
dma_complete(dbs, ret);
80
- return;
81
+ goto out;
82
}
83
dma_blk_unmap(dbs);
84
85
@@ -XXX,XX +XXX,XX @@ static void dma_blk_cb(void *opaque, int ret)
86
87
if (dbs->iov.size == 0) {
88
trace_dma_map_wait(dbs);
89
- dbs->bh = aio_bh_new(dbs->ctx, reschedule_dma, dbs);
90
+ dbs->bh = aio_bh_new(ctx, reschedule_dma, dbs);
91
cpu_register_map_client(dbs->bh);
92
- return;
93
+ goto out;
94
}
95
96
if (!QEMU_IS_ALIGNED(dbs->iov.size, dbs->align)) {
97
@@ -XXX,XX +XXX,XX @@ static void dma_blk_cb(void *opaque, int ret)
98
QEMU_ALIGN_DOWN(dbs->iov.size, dbs->align));
99
}
100
101
- aio_context_acquire(dbs->ctx);
102
dbs->acb = dbs->io_func(dbs->offset, &dbs->iov,
103
dma_blk_cb, dbs, dbs->io_func_opaque);
104
- aio_context_release(dbs->ctx);
105
assert(dbs->acb);
106
+out:
107
+ aio_context_release(ctx);
108
}
109
110
static void dma_aio_cancel(BlockAIOCB *acb)
111
--
112
2.39.2
diff view generated by jsdifflib
Deleted patch
1
From: Stefan Hajnoczi <stefanha@redhat.com>
2
1
3
When an IOThread is configured, the ctrl virtqueue is processed in the
4
IOThread. TMFs that reset SCSI devices are currently called directly
5
from the IOThread and trigger an assertion failure in blk_drain() from
6
the following call stack:
7
8
virtio_scsi_handle_ctrl_req -> virtio_scsi_do_tmf -> device_code_reset
9
-> scsi_disk_reset -> scsi_device_purge_requests -> blk_drain
10
11
../block/block-backend.c:1780: void blk_drain(BlockBackend *): Assertion `qemu_in_main_thread()' failed.
12
13
The blk_drain() function is not designed to be called from an IOThread
14
because it needs the Big QEMU Lock (BQL).
15
16
This patch defers TMFs that reset SCSI devices to a Bottom Half (BH)
17
that runs in the main loop thread under the BQL. This way it's safe to
18
call blk_drain() and the assertion failure is avoided.
19
20
Introduce s->tmf_bh_list for tracking TMF requests that have been
21
deferred to the BH. When the BH runs it will grab the entire list and
22
process all requests. Care must be taken to clear the list when the
23
virtio-scsi device is reset or unrealized. Otherwise deferred TMF
24
requests could execute later and lead to use-after-free or other
25
undefined behavior.
26
27
The s->resetting counter that's used by TMFs that reset SCSI devices is
28
accessed from multiple threads. This patch makes that explicit by using
29
atomic accessor functions. With this patch applied the counter is only
30
modified by the main loop thread under the BQL but can be read by any
31
thread.
32
33
Reported-by: Qing Wang <qinwang@redhat.com>
34
Cc: Paolo Bonzini <pbonzini@redhat.com>
35
Reviewed-by: Eric Blake <eblake@redhat.com>
36
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
37
Message-Id: <20230221212218.1378734-4-stefanha@redhat.com>
38
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
39
---
40
include/hw/virtio/virtio-scsi.h | 11 ++-
41
hw/scsi/virtio-scsi.c | 169 +++++++++++++++++++++++++-------
42
2 files changed, 143 insertions(+), 37 deletions(-)
43
44
diff --git a/include/hw/virtio/virtio-scsi.h b/include/hw/virtio/virtio-scsi.h
45
index XXXXXXX..XXXXXXX 100644
46
--- a/include/hw/virtio/virtio-scsi.h
47
+++ b/include/hw/virtio/virtio-scsi.h
48
@@ -XXX,XX +XXX,XX @@ struct VirtIOSCSICommon {
49
VirtQueue **cmd_vqs;
50
};
51
52
+struct VirtIOSCSIReq;
53
+
54
struct VirtIOSCSI {
55
VirtIOSCSICommon parent_obj;
56
57
SCSIBus bus;
58
- int resetting;
59
+ int resetting; /* written from main loop thread, read from any thread */
60
bool events_dropped;
61
62
+ /*
63
+ * TMFs deferred to main loop BH. These fields are protected by
64
+ * virtio_scsi_acquire().
65
+ */
66
+ QEMUBH *tmf_bh;
67
+ QTAILQ_HEAD(, VirtIOSCSIReq) tmf_bh_list;
68
+
69
/* Fields for dataplane below */
70
AioContext *ctx; /* one iothread per virtio-scsi-pci for now */
71
72
diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c
73
index XXXXXXX..XXXXXXX 100644
74
--- a/hw/scsi/virtio-scsi.c
75
+++ b/hw/scsi/virtio-scsi.c
76
@@ -XXX,XX +XXX,XX @@ typedef struct VirtIOSCSIReq {
77
QEMUSGList qsgl;
78
QEMUIOVector resp_iov;
79
80
- union {
81
- /* Used for two-stage request submission */
82
- QTAILQ_ENTRY(VirtIOSCSIReq) next;
83
+ /* Used for two-stage request submission and TMFs deferred to BH */
84
+ QTAILQ_ENTRY(VirtIOSCSIReq) next;
85
86
- /* Used for cancellation of request during TMFs */
87
- int remaining;
88
- };
89
+ /* Used for cancellation of request during TMFs */
90
+ int remaining;
91
92
SCSIRequest *sreq;
93
size_t resp_size;
94
@@ -XXX,XX +XXX,XX @@ static inline void virtio_scsi_ctx_check(VirtIOSCSI *s, SCSIDevice *d)
95
}
96
}
97
98
+static void virtio_scsi_do_one_tmf_bh(VirtIOSCSIReq *req)
99
+{
100
+ VirtIOSCSI *s = req->dev;
101
+ SCSIDevice *d = virtio_scsi_device_get(s, req->req.tmf.lun);
102
+ BusChild *kid;
103
+ int target;
104
+
105
+ switch (req->req.tmf.subtype) {
106
+ case VIRTIO_SCSI_T_TMF_LOGICAL_UNIT_RESET:
107
+ if (!d) {
108
+ req->resp.tmf.response = VIRTIO_SCSI_S_BAD_TARGET;
109
+ goto out;
110
+ }
111
+ if (d->lun != virtio_scsi_get_lun(req->req.tmf.lun)) {
112
+ req->resp.tmf.response = VIRTIO_SCSI_S_INCORRECT_LUN;
113
+ goto out;
114
+ }
115
+ qatomic_inc(&s->resetting);
116
+ device_cold_reset(&d->qdev);
117
+ qatomic_dec(&s->resetting);
118
+ break;
119
+
120
+ case VIRTIO_SCSI_T_TMF_I_T_NEXUS_RESET:
121
+ target = req->req.tmf.lun[1];
122
+ qatomic_inc(&s->resetting);
123
+
124
+ rcu_read_lock();
125
+ QTAILQ_FOREACH_RCU(kid, &s->bus.qbus.children, sibling) {
126
+ SCSIDevice *d1 = SCSI_DEVICE(kid->child);
127
+ if (d1->channel == 0 && d1->id == target) {
128
+ device_cold_reset(&d1->qdev);
129
+ }
130
+ }
131
+ rcu_read_unlock();
132
+
133
+ qatomic_dec(&s->resetting);
134
+ break;
135
+
136
+ default:
137
+ g_assert_not_reached();
138
+ break;
139
+ }
140
+
141
+out:
142
+ object_unref(OBJECT(d));
143
+
144
+ virtio_scsi_acquire(s);
145
+ virtio_scsi_complete_req(req);
146
+ virtio_scsi_release(s);
147
+}
148
+
149
+/* Some TMFs must be processed from the main loop thread */
150
+static void virtio_scsi_do_tmf_bh(void *opaque)
151
+{
152
+ VirtIOSCSI *s = opaque;
153
+ QTAILQ_HEAD(, VirtIOSCSIReq) reqs = QTAILQ_HEAD_INITIALIZER(reqs);
154
+ VirtIOSCSIReq *req;
155
+ VirtIOSCSIReq *tmp;
156
+
157
+ GLOBAL_STATE_CODE();
158
+
159
+ virtio_scsi_acquire(s);
160
+
161
+ QTAILQ_FOREACH_SAFE(req, &s->tmf_bh_list, next, tmp) {
162
+ QTAILQ_REMOVE(&s->tmf_bh_list, req, next);
163
+ QTAILQ_INSERT_TAIL(&reqs, req, next);
164
+ }
165
+
166
+ qemu_bh_delete(s->tmf_bh);
167
+ s->tmf_bh = NULL;
168
+
169
+ virtio_scsi_release(s);
170
+
171
+ QTAILQ_FOREACH_SAFE(req, &reqs, next, tmp) {
172
+ QTAILQ_REMOVE(&reqs, req, next);
173
+ virtio_scsi_do_one_tmf_bh(req);
174
+ }
175
+}
176
+
177
+static void virtio_scsi_reset_tmf_bh(VirtIOSCSI *s)
178
+{
179
+ VirtIOSCSIReq *req;
180
+ VirtIOSCSIReq *tmp;
181
+
182
+ GLOBAL_STATE_CODE();
183
+
184
+ virtio_scsi_acquire(s);
185
+
186
+ if (s->tmf_bh) {
187
+ qemu_bh_delete(s->tmf_bh);
188
+ s->tmf_bh = NULL;
189
+ }
190
+
191
+ QTAILQ_FOREACH_SAFE(req, &s->tmf_bh_list, next, tmp) {
192
+ QTAILQ_REMOVE(&s->tmf_bh_list, req, next);
193
+
194
+ /* SAM-6 6.3.2 Hard reset */
195
+ req->resp.tmf.response = VIRTIO_SCSI_S_TARGET_FAILURE;
196
+ virtio_scsi_complete_req(req);
197
+ }
198
+
199
+ virtio_scsi_release(s);
200
+}
201
+
202
+static void virtio_scsi_defer_tmf_to_bh(VirtIOSCSIReq *req)
203
+{
204
+ VirtIOSCSI *s = req->dev;
205
+
206
+ QTAILQ_INSERT_TAIL(&s->tmf_bh_list, req, next);
207
+
208
+ if (!s->tmf_bh) {
209
+ s->tmf_bh = qemu_bh_new(virtio_scsi_do_tmf_bh, s);
210
+ qemu_bh_schedule(s->tmf_bh);
211
+ }
212
+}
213
+
214
/* Return 0 if the request is ready to be completed and return to guest;
215
* -EINPROGRESS if the request is submitted and will be completed later, in the
216
* case of async cancellation. */
217
@@ -XXX,XX +XXX,XX @@ static int virtio_scsi_do_tmf(VirtIOSCSI *s, VirtIOSCSIReq *req)
218
{
219
SCSIDevice *d = virtio_scsi_device_get(s, req->req.tmf.lun);
220
SCSIRequest *r, *next;
221
- BusChild *kid;
222
- int target;
223
int ret = 0;
224
225
virtio_scsi_ctx_check(s, d);
226
@@ -XXX,XX +XXX,XX @@ static int virtio_scsi_do_tmf(VirtIOSCSI *s, VirtIOSCSIReq *req)
227
break;
228
229
case VIRTIO_SCSI_T_TMF_LOGICAL_UNIT_RESET:
230
- if (!d) {
231
- goto fail;
232
- }
233
- if (d->lun != virtio_scsi_get_lun(req->req.tmf.lun)) {
234
- goto incorrect_lun;
235
- }
236
- s->resetting++;
237
- device_cold_reset(&d->qdev);
238
- s->resetting--;
239
+ case VIRTIO_SCSI_T_TMF_I_T_NEXUS_RESET:
240
+ virtio_scsi_defer_tmf_to_bh(req);
241
+ ret = -EINPROGRESS;
242
break;
243
244
case VIRTIO_SCSI_T_TMF_ABORT_TASK_SET:
245
@@ -XXX,XX +XXX,XX @@ static int virtio_scsi_do_tmf(VirtIOSCSI *s, VirtIOSCSIReq *req)
246
}
247
break;
248
249
- case VIRTIO_SCSI_T_TMF_I_T_NEXUS_RESET:
250
- target = req->req.tmf.lun[1];
251
- s->resetting++;
252
-
253
- rcu_read_lock();
254
- QTAILQ_FOREACH_RCU(kid, &s->bus.qbus.children, sibling) {
255
- SCSIDevice *d1 = SCSI_DEVICE(kid->child);
256
- if (d1->channel == 0 && d1->id == target) {
257
- device_cold_reset(&d1->qdev);
258
- }
259
- }
260
- rcu_read_unlock();
261
-
262
- s->resetting--;
263
- break;
264
-
265
case VIRTIO_SCSI_T_TMF_CLEAR_ACA:
266
default:
267
req->resp.tmf.response = VIRTIO_SCSI_S_FUNCTION_REJECTED;
268
@@ -XXX,XX +XXX,XX @@ static void virtio_scsi_request_cancelled(SCSIRequest *r)
269
if (!req) {
270
return;
271
}
272
- if (req->dev->resetting) {
273
+ if (qatomic_read(&req->dev->resetting)) {
274
req->resp.cmd.response = VIRTIO_SCSI_S_RESET;
275
} else {
276
req->resp.cmd.response = VIRTIO_SCSI_S_ABORTED;
277
@@ -XXX,XX +XXX,XX @@ static void virtio_scsi_reset(VirtIODevice *vdev)
278
VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(vdev);
279
280
assert(!s->dataplane_started);
281
- s->resetting++;
282
+
283
+ virtio_scsi_reset_tmf_bh(s);
284
+
285
+ qatomic_inc(&s->resetting);
286
bus_cold_reset(BUS(&s->bus));
287
- s->resetting--;
288
+ qatomic_dec(&s->resetting);
289
290
vs->sense_size = VIRTIO_SCSI_SENSE_DEFAULT_SIZE;
291
vs->cdb_size = VIRTIO_SCSI_CDB_DEFAULT_SIZE;
292
@@ -XXX,XX +XXX,XX @@ static void virtio_scsi_device_realize(DeviceState *dev, Error **errp)
293
VirtIOSCSI *s = VIRTIO_SCSI(dev);
294
Error *err = NULL;
295
296
+ QTAILQ_INIT(&s->tmf_bh_list);
297
+
298
virtio_scsi_common_realize(dev,
299
virtio_scsi_handle_ctrl,
300
virtio_scsi_handle_event,
301
@@ -XXX,XX +XXX,XX @@ static void virtio_scsi_device_unrealize(DeviceState *dev)
302
{
303
VirtIOSCSI *s = VIRTIO_SCSI(dev);
304
305
+ virtio_scsi_reset_tmf_bh(s);
306
+
307
qbus_set_hotplug_handler(BUS(&s->bus), NULL);
308
virtio_scsi_common_unrealize(dev);
309
}
310
--
311
2.39.2
diff view generated by jsdifflib
Deleted patch
1
From: Or Ozeri <oro@il.ibm.com>
2
1
3
Signed-off-by: Or Ozeri <oro@il.ibm.com>
4
Message-Id: <20230129113120.722708-2-oro@oro.sl.cloud9.ibm.com>
5
Reviewed-by: Ilya Dryomov <idryomov@gmail.com>
6
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
7
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
8
---
9
block/rbd.c | 16 ++++++----------
10
1 file changed, 6 insertions(+), 10 deletions(-)
11
12
diff --git a/block/rbd.c b/block/rbd.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/block/rbd.c
15
+++ b/block/rbd.c
16
@@ -XXX,XX +XXX,XX @@ static int qemu_rbd_encryption_format(rbd_image_t image,
17
{
18
int r = 0;
19
g_autofree char *passphrase = NULL;
20
- size_t passphrase_len;
21
rbd_encryption_format_t format;
22
rbd_encryption_options_t opts;
23
rbd_encryption_luks1_format_options_t luks_opts;
24
@@ -XXX,XX +XXX,XX @@ static int qemu_rbd_encryption_format(rbd_image_t image,
25
opts_size = sizeof(luks_opts);
26
r = qemu_rbd_convert_luks_create_options(
27
qapi_RbdEncryptionCreateOptionsLUKS_base(&encrypt->u.luks),
28
- &luks_opts.alg, &passphrase, &passphrase_len, errp);
29
+ &luks_opts.alg, &passphrase, &luks_opts.passphrase_size,
30
+ errp);
31
if (r < 0) {
32
return r;
33
}
34
luks_opts.passphrase = passphrase;
35
- luks_opts.passphrase_size = passphrase_len;
36
break;
37
}
38
case RBD_IMAGE_ENCRYPTION_FORMAT_LUKS2: {
39
@@ -XXX,XX +XXX,XX @@ static int qemu_rbd_encryption_format(rbd_image_t image,
40
r = qemu_rbd_convert_luks_create_options(
41
qapi_RbdEncryptionCreateOptionsLUKS2_base(
42
&encrypt->u.luks2),
43
- &luks2_opts.alg, &passphrase, &passphrase_len, errp);
44
+ &luks2_opts.alg, &passphrase, &luks2_opts.passphrase_size,
45
+ errp);
46
if (r < 0) {
47
return r;
48
}
49
luks2_opts.passphrase = passphrase;
50
- luks2_opts.passphrase_size = passphrase_len;
51
break;
52
}
53
default: {
54
@@ -XXX,XX +XXX,XX @@ static int qemu_rbd_encryption_load(rbd_image_t image,
55
{
56
int r = 0;
57
g_autofree char *passphrase = NULL;
58
- size_t passphrase_len;
59
rbd_encryption_luks1_format_options_t luks_opts;
60
rbd_encryption_luks2_format_options_t luks2_opts;
61
rbd_encryption_format_t format;
62
@@ -XXX,XX +XXX,XX @@ static int qemu_rbd_encryption_load(rbd_image_t image,
63
opts_size = sizeof(luks_opts);
64
r = qemu_rbd_convert_luks_options(
65
qapi_RbdEncryptionOptionsLUKS_base(&encrypt->u.luks),
66
- &passphrase, &passphrase_len, errp);
67
+ &passphrase, &luks_opts.passphrase_size, errp);
68
if (r < 0) {
69
return r;
70
}
71
luks_opts.passphrase = passphrase;
72
- luks_opts.passphrase_size = passphrase_len;
73
break;
74
}
75
case RBD_IMAGE_ENCRYPTION_FORMAT_LUKS2: {
76
@@ -XXX,XX +XXX,XX @@ static int qemu_rbd_encryption_load(rbd_image_t image,
77
opts_size = sizeof(luks2_opts);
78
r = qemu_rbd_convert_luks_options(
79
qapi_RbdEncryptionOptionsLUKS2_base(&encrypt->u.luks2),
80
- &passphrase, &passphrase_len, errp);
81
+ &passphrase, &luks2_opts.passphrase_size, errp);
82
if (r < 0) {
83
return r;
84
}
85
luks2_opts.passphrase = passphrase;
86
- luks2_opts.passphrase_size = passphrase_len;
87
break;
88
}
89
default: {
90
--
91
2.39.2
diff view generated by jsdifflib
Deleted patch
1
From: Or Ozeri <oro@il.ibm.com>
2
1
3
Ceph RBD encryption API required specifying the encryption format
4
for loading encryption. The supported formats were LUKS (v1) and LUKS2.
5
6
Starting from Reef release, RBD also supports loading with "luks-any" format,
7
which works for both versions of LUKS.
8
9
This commit extends the qemu rbd driver API to enable qemu users to use
10
this luks-any wildcard format.
11
12
Signed-off-by: Or Ozeri <oro@il.ibm.com>
13
Message-Id: <20230129113120.722708-3-oro@oro.sl.cloud9.ibm.com>
14
Reviewed-by: Ilya Dryomov <idryomov@gmail.com>
15
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
16
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
17
---
18
qapi/block-core.json | 16 ++++++++++++++--
19
block/rbd.c | 19 +++++++++++++++++++
20
2 files changed, 33 insertions(+), 2 deletions(-)
21
22
diff --git a/qapi/block-core.json b/qapi/block-core.json
23
index XXXXXXX..XXXXXXX 100644
24
--- a/qapi/block-core.json
25
+++ b/qapi/block-core.json
26
@@ -XXX,XX +XXX,XX @@
27
##
28
# @RbdImageEncryptionFormat:
29
#
30
+# @luks-any: Used for opening either luks or luks2 (Since 8.0)
31
+#
32
# Since: 6.1
33
##
34
{ 'enum': 'RbdImageEncryptionFormat',
35
- 'data': [ 'luks', 'luks2' ] }
36
+ 'data': [ 'luks', 'luks2', 'luks-any' ] }
37
38
##
39
# @RbdEncryptionOptionsLUKSBase:
40
@@ -XXX,XX +XXX,XX @@
41
'base': 'RbdEncryptionOptionsLUKSBase',
42
'data': { } }
43
44
+##
45
+# @RbdEncryptionOptionsLUKSAny:
46
+#
47
+# Since: 8.0
48
+##
49
+{ 'struct': 'RbdEncryptionOptionsLUKSAny',
50
+ 'base': 'RbdEncryptionOptionsLUKSBase',
51
+ 'data': { } }
52
+
53
##
54
# @RbdEncryptionCreateOptionsLUKS:
55
#
56
@@ -XXX,XX +XXX,XX @@
57
'base': { 'format': 'RbdImageEncryptionFormat' },
58
'discriminator': 'format',
59
'data': { 'luks': 'RbdEncryptionOptionsLUKS',
60
- 'luks2': 'RbdEncryptionOptionsLUKS2' } }
61
+ 'luks2': 'RbdEncryptionOptionsLUKS2',
62
+ 'luks-any': 'RbdEncryptionOptionsLUKSAny'} }
63
64
##
65
# @RbdEncryptionCreateOptions:
66
diff --git a/block/rbd.c b/block/rbd.c
67
index XXXXXXX..XXXXXXX 100644
68
--- a/block/rbd.c
69
+++ b/block/rbd.c
70
@@ -XXX,XX +XXX,XX @@ static int qemu_rbd_encryption_load(rbd_image_t image,
71
g_autofree char *passphrase = NULL;
72
rbd_encryption_luks1_format_options_t luks_opts;
73
rbd_encryption_luks2_format_options_t luks2_opts;
74
+#ifdef LIBRBD_SUPPORTS_ENCRYPTION_LOAD2
75
+ rbd_encryption_luks_format_options_t luks_any_opts;
76
+#endif
77
rbd_encryption_format_t format;
78
rbd_encryption_options_t opts;
79
size_t opts_size;
80
@@ -XXX,XX +XXX,XX @@ static int qemu_rbd_encryption_load(rbd_image_t image,
81
luks2_opts.passphrase = passphrase;
82
break;
83
}
84
+#ifdef LIBRBD_SUPPORTS_ENCRYPTION_LOAD2
85
+ case RBD_IMAGE_ENCRYPTION_FORMAT_LUKS_ANY: {
86
+ memset(&luks_any_opts, 0, sizeof(luks_any_opts));
87
+ format = RBD_ENCRYPTION_FORMAT_LUKS;
88
+ opts = &luks_any_opts;
89
+ opts_size = sizeof(luks_any_opts);
90
+ r = qemu_rbd_convert_luks_options(
91
+ qapi_RbdEncryptionOptionsLUKSAny_base(&encrypt->u.luks_any),
92
+ &passphrase, &luks_any_opts.passphrase_size, errp);
93
+ if (r < 0) {
94
+ return r;
95
+ }
96
+ luks_any_opts.passphrase = passphrase;
97
+ break;
98
+ }
99
+#endif
100
default: {
101
r = -ENOTSUP;
102
error_setg_errno(
103
--
104
2.39.2
diff view generated by jsdifflib
Deleted patch
1
From: Or Ozeri <oro@il.ibm.com>
2
1
3
Starting from ceph Reef, RBD has built-in support for layered encryption,
4
where each ancestor image (in a cloned image setting) can be possibly
5
encrypted using a unique passphrase.
6
7
A new function, rbd_encryption_load2, was added to librbd API.
8
This new function supports an array of passphrases (via "spec" structs).
9
10
This commit extends the qemu rbd driver API to use this new librbd API,
11
in order to support this new layered encryption feature.
12
13
Signed-off-by: Or Ozeri <oro@il.ibm.com>
14
Message-Id: <20230129113120.722708-4-oro@oro.sl.cloud9.ibm.com>
15
Reviewed-by: Ilya Dryomov <idryomov@gmail.com>
16
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
17
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
18
---
19
qapi/block-core.json | 11 +++-
20
block/rbd.c | 153 ++++++++++++++++++++++++++++++++++++++++++-
21
2 files changed, 162 insertions(+), 2 deletions(-)
22
23
diff --git a/qapi/block-core.json b/qapi/block-core.json
24
index XXXXXXX..XXXXXXX 100644
25
--- a/qapi/block-core.json
26
+++ b/qapi/block-core.json
27
@@ -XXX,XX +XXX,XX @@
28
##
29
# @RbdEncryptionOptions:
30
#
31
+# @format: Encryption format.
32
+#
33
+# @parent: Parent image encryption options (for cloned images).
34
+# Can be left unspecified if this cloned image is encrypted
35
+# using the same format and secret as its parent image (i.e.
36
+# not explicitly formatted) or if its parent image is not
37
+# encrypted. (Since 8.0)
38
+#
39
# Since: 6.1
40
##
41
{ 'union': 'RbdEncryptionOptions',
42
- 'base': { 'format': 'RbdImageEncryptionFormat' },
43
+ 'base': { 'format': 'RbdImageEncryptionFormat',
44
+ '*parent': 'RbdEncryptionOptions' },
45
'discriminator': 'format',
46
'data': { 'luks': 'RbdEncryptionOptionsLUKS',
47
'luks2': 'RbdEncryptionOptionsLUKS2',
48
diff --git a/block/rbd.c b/block/rbd.c
49
index XXXXXXX..XXXXXXX 100644
50
--- a/block/rbd.c
51
+++ b/block/rbd.c
52
@@ -XXX,XX +XXX,XX @@ static const char rbd_luks2_header_verification[
53
'L', 'U', 'K', 'S', 0xBA, 0xBE, 0, 2
54
};
55
56
+static const char rbd_layered_luks_header_verification[
57
+ RBD_ENCRYPTION_LUKS_HEADER_VERIFICATION_LEN] = {
58
+ 'R', 'B', 'D', 'L', 0xBA, 0xBE, 0, 1
59
+};
60
+
61
+static const char rbd_layered_luks2_header_verification[
62
+ RBD_ENCRYPTION_LUKS_HEADER_VERIFICATION_LEN] = {
63
+ 'R', 'B', 'D', 'L', 0xBA, 0xBE, 0, 2
64
+};
65
+
66
typedef enum {
67
RBD_AIO_READ,
68
RBD_AIO_WRITE,
69
@@ -XXX,XX +XXX,XX @@ static int qemu_rbd_encryption_load(rbd_image_t image,
70
71
return 0;
72
}
73
+
74
+#ifdef LIBRBD_SUPPORTS_ENCRYPTION_LOAD2
75
+static int qemu_rbd_encryption_load2(rbd_image_t image,
76
+ RbdEncryptionOptions *encrypt,
77
+ Error **errp)
78
+{
79
+ int r = 0;
80
+ int encrypt_count = 1;
81
+ int i;
82
+ RbdEncryptionOptions *curr_encrypt;
83
+ rbd_encryption_spec_t *specs;
84
+ rbd_encryption_luks1_format_options_t *luks_opts;
85
+ rbd_encryption_luks2_format_options_t *luks2_opts;
86
+ rbd_encryption_luks_format_options_t *luks_any_opts;
87
+
88
+ /* count encryption options */
89
+ for (curr_encrypt = encrypt->parent; curr_encrypt;
90
+ curr_encrypt = curr_encrypt->parent) {
91
+ ++encrypt_count;
92
+ }
93
+
94
+ specs = g_new0(rbd_encryption_spec_t, encrypt_count);
95
+
96
+ curr_encrypt = encrypt;
97
+ for (i = 0; i < encrypt_count; ++i) {
98
+ switch (curr_encrypt->format) {
99
+ case RBD_IMAGE_ENCRYPTION_FORMAT_LUKS: {
100
+ specs[i].format = RBD_ENCRYPTION_FORMAT_LUKS1;
101
+
102
+ luks_opts = g_new0(rbd_encryption_luks1_format_options_t, 1);
103
+ specs[i].opts = luks_opts;
104
+ specs[i].opts_size = sizeof(*luks_opts);
105
+
106
+ r = qemu_rbd_convert_luks_options(
107
+ qapi_RbdEncryptionOptionsLUKS_base(
108
+ &curr_encrypt->u.luks),
109
+ (char **)&luks_opts->passphrase,
110
+ &luks_opts->passphrase_size,
111
+ errp);
112
+ break;
113
+ }
114
+ case RBD_IMAGE_ENCRYPTION_FORMAT_LUKS2: {
115
+ specs[i].format = RBD_ENCRYPTION_FORMAT_LUKS2;
116
+
117
+ luks2_opts = g_new0(rbd_encryption_luks2_format_options_t, 1);
118
+ specs[i].opts = luks2_opts;
119
+ specs[i].opts_size = sizeof(*luks2_opts);
120
+
121
+ r = qemu_rbd_convert_luks_options(
122
+ qapi_RbdEncryptionOptionsLUKS2_base(
123
+ &curr_encrypt->u.luks2),
124
+ (char **)&luks2_opts->passphrase,
125
+ &luks2_opts->passphrase_size,
126
+ errp);
127
+ break;
128
+ }
129
+ case RBD_IMAGE_ENCRYPTION_FORMAT_LUKS_ANY: {
130
+ specs[i].format = RBD_ENCRYPTION_FORMAT_LUKS;
131
+
132
+ luks_any_opts = g_new0(rbd_encryption_luks_format_options_t, 1);
133
+ specs[i].opts = luks_any_opts;
134
+ specs[i].opts_size = sizeof(*luks_any_opts);
135
+
136
+ r = qemu_rbd_convert_luks_options(
137
+ qapi_RbdEncryptionOptionsLUKSAny_base(
138
+ &curr_encrypt->u.luks_any),
139
+ (char **)&luks_any_opts->passphrase,
140
+ &luks_any_opts->passphrase_size,
141
+ errp);
142
+ break;
143
+ }
144
+ default: {
145
+ r = -ENOTSUP;
146
+ error_setg_errno(
147
+ errp, -r, "unknown image encryption format: %u",
148
+ curr_encrypt->format);
149
+ }
150
+ }
151
+
152
+ if (r < 0) {
153
+ goto exit;
154
+ }
155
+
156
+ curr_encrypt = curr_encrypt->parent;
157
+ }
158
+
159
+ r = rbd_encryption_load2(image, specs, encrypt_count);
160
+ if (r < 0) {
161
+ error_setg_errno(errp, -r, "layered encryption load fail");
162
+ goto exit;
163
+ }
164
+
165
+exit:
166
+ for (i = 0; i < encrypt_count; ++i) {
167
+ if (!specs[i].opts) {
168
+ break;
169
+ }
170
+
171
+ switch (specs[i].format) {
172
+ case RBD_ENCRYPTION_FORMAT_LUKS1: {
173
+ luks_opts = specs[i].opts;
174
+ g_free((void *)luks_opts->passphrase);
175
+ break;
176
+ }
177
+ case RBD_ENCRYPTION_FORMAT_LUKS2: {
178
+ luks2_opts = specs[i].opts;
179
+ g_free((void *)luks2_opts->passphrase);
180
+ break;
181
+ }
182
+ case RBD_ENCRYPTION_FORMAT_LUKS: {
183
+ luks_any_opts = specs[i].opts;
184
+ g_free((void *)luks_any_opts->passphrase);
185
+ break;
186
+ }
187
+ }
188
+
189
+ g_free(specs[i].opts);
190
+ }
191
+ g_free(specs);
192
+ return r;
193
+}
194
+#endif
195
#endif
196
197
/* FIXME Deprecate and remove keypairs or make it available in QMP. */
198
@@ -XXX,XX +XXX,XX @@ static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags,
199
200
if (opts->encrypt) {
201
#ifdef LIBRBD_SUPPORTS_ENCRYPTION
202
- r = qemu_rbd_encryption_load(s->image, opts->encrypt, errp);
203
+ if (opts->encrypt->parent) {
204
+#ifdef LIBRBD_SUPPORTS_ENCRYPTION_LOAD2
205
+ r = qemu_rbd_encryption_load2(s->image, opts->encrypt, errp);
206
+#else
207
+ r = -ENOTSUP;
208
+ error_setg(errp, "RBD library does not support layered encryption");
209
+#endif
210
+ } else {
211
+ r = qemu_rbd_encryption_load(s->image, opts->encrypt, errp);
212
+ }
213
if (r < 0) {
214
goto failed_post_open;
215
}
216
@@ -XXX,XX +XXX,XX @@ static ImageInfoSpecific *qemu_rbd_get_specific_info(BlockDriverState *bs,
217
spec_info->u.rbd.data->encryption_format =
218
RBD_IMAGE_ENCRYPTION_FORMAT_LUKS2;
219
spec_info->u.rbd.data->has_encryption_format = true;
220
+ } else if (memcmp(buf, rbd_layered_luks_header_verification,
221
+ RBD_ENCRYPTION_LUKS_HEADER_VERIFICATION_LEN) == 0) {
222
+ spec_info->u.rbd.data->encryption_format =
223
+ RBD_IMAGE_ENCRYPTION_FORMAT_LUKS;
224
+ spec_info->u.rbd.data->has_encryption_format = true;
225
+ } else if (memcmp(buf, rbd_layered_luks2_header_verification,
226
+ RBD_ENCRYPTION_LUKS_HEADER_VERIFICATION_LEN) == 0) {
227
+ spec_info->u.rbd.data->encryption_format =
228
+ RBD_IMAGE_ENCRYPTION_FORMAT_LUKS2;
229
+ spec_info->u.rbd.data->has_encryption_format = true;
230
} else {
231
spec_info->u.rbd.data->has_encryption_format = false;
232
}
233
--
234
2.39.2
diff view generated by jsdifflib